GAGA LIFE.

インフラエンジニアブログ

スポンサーリンク

Dockerコンテナ操作

Dockerコンテナライフサイクル

f:id:undercovergeek:20181017101841j:plain

docker container run(コンテナ生成/起動)

docker container run [オプション] イメージ名[:タグ名] [引数]
Options Description
--attach,-a 標準入力(STDIN)/標準出力(STDOUT)/標準エラー出力(STDERR)にアタッチする
--cidfile コンテナIDをファイルに出力する
--detach,-d コンテナを生成し、バックグラウンドで実行する
--interactive,-l コンテナの標準入力を開く
--tty,-t 端末デバイスを使う

コンテナの対話的実行

docker container run -it --name "test1" centos /bin/cal
-------------------- --- -------------- ------ --------
         ①            ②         ③          ④       ⑤

①コンテナを作成/実行
②コンソールに結果を出すオプション
③コンテナ名
④イメージ名
⑤コンテナで実行するコマンド

実行例:calコマンドの実行によるカレンダー表示

docker@LesPaul:~$ docker container run -it --name "test" centos /bin/cal
    October 2018    
Su Mo Tu We Th Fr Sa
    1  2  3  4  5  6
 7  8  9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31

実行例:bash実行

docker@LesPaul:~$ docker container ls
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
docker@LesPaul:~$ docker container run -it --name "test3" centos /bin/bash
[root@941f4d465cc1 /]# 

docker container run(コンテナのバックグラウンド実行)

docker container run [実行オプション] イメージ名[:タグ名] [引数]
Options Description
--detach,-d バックグラウンドで実行する
--user,-u ユーザー名を指定
--restart=[no on-failure|on-failure:回数n|always|unless-stopped]|コマンドの実行結果によって再起動を行うオプション
--rm コマンド実行完了後にコンテナを自動で削除
docker container run -d centos /bin/ping localhost
-------------------- -- ------ -------------------
         ①           ②    ③            ④

①コンテナを作成/実行
②バックグラウンドで実行するオプション
③イメージ名
④コンテナで実行するコマンド

実行例:pingコマンド実行によるコンテナのバックグラウンド実行

docker@LesPaul:~$ docker container run -d centos /bin/ping localhost
2e797e7808541fc4cab1955428fbce0b7043aad0d4b69052b94f5de326af5e8c
docker@LesPaul:~$ docker container logs -t 2e797e7808541
2018-10-15T12:38:30.878982432Z PING localhost (127.0.0.1) 56(84) bytes of data.
2018-10-15T12:38:30.879017086Z 64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.031 ms
2018-10-15T12:38:31.902770242Z 64 bytes from localhost (127.0.0.1): icmp_seq=2 ttl=64 time=0.056 ms
2018-10-15T12:38:32.967861509Z 64 bytes from localhost (127.0.0.1): icmp_seq=3 ttl=64 time=0.187 ms
2018-10-15T12:38:33.987876299Z 64 bytes from localhost (127.0.0.1): icmp_seq=4 ttl=64 time=0.047 ms
2018-10-15T12:38:35.007728824Z 64 bytes from localhost (127.0.0.1): icmp_seq=5 ttl=64 time=0.039 ms
2018-10-15T12:38:36.133118054Z 64 bytes from localhost (127.0.0.1): icmp_seq=6 ttl=64 time=0.055 ms
2018-10-15T12:38:37.158863576Z 64 bytes from localhost (127.0.0.1): icmp_seq=7 ttl=64 time=0.056 ms
2018-10-15T12:38:38.174602788Z 64 bytes from localhost (127.0.0.1): icmp_seq=8 ttl=64 time=0.041 ms
2018-10-15T12:38:39.198465303Z 64 bytes from localhost (127.0.0.1): icmp_seq=9 ttl=64 time=0.042 ms
2018-10-15T12:38:40.222391461Z 64 bytes from localhost (127.0.0.1): icmp_seq=10 ttl=64 time=0.036 ms
2018-10-15T12:38:41.248841629Z 64 bytes from localhost (127.0.0.1): icmp_seq=11 ttl=64 time=0.034 ms
~中略~

--restartオプション

Options Description
no 再起動しない
on-failure 終了ステータスが0でないときに再起動する
on-failure:回数n 終了ステータスが0でないときにn回再起動する
always 常に再起動する
unless-stopped 直近のコンテナが停止状態でなければ、常に再起動する

実行例:コンテナの常時再起動

docker@LesPaul:~$ docker container run -it --restart=always centos /bin/bash
[root@793322f1986e /]# exit
exit
docker@LesPaul:~$ docker container ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
793322f1986e        centos              "/bin/bash"         11 seconds ago      Up 5 seconds                            dazzling_williams

docker container run(ネットワーク設定)

docker container run [ネットワークオプション] イメージ名[:タグ名] [引数]
Options Description
--add-host=[ホスト名:IPアドレス] コンテナの/etc/hostsにホスト名とIPアドレスを定義
--dns=[IPアドレス] コンテナ用のDNSサーバのIPアドレス指定
--expose 指定したレンジのポート番号を割り当てる
--mac-address=[MACアドレス] コンテナのMACアドレスを指定する
--net=[bridge none|container:<name|id>|host|NETWORK]|コンテナのネットワークを指定する
--hostname,-h コンテナ自身のホスト名を指定する
--publish,-p[ホストのポート番号]:[コンテナのボート番号] ホストとコンテナのポートマッピング
--publish-all,-p ホストの任意のポートをコンテナに割り当てる

例:コンテナのポートマッピング

$ docker container run -d -p 8080:80 nginx

例:コンテナのDNSサーバ指定

$ docker container run -d --dns 192.168.1.1 nginx

実行例:MACアドレスの指定

docker@LesPaul:~$ docker container run -d --mac-address="92:d0:c6:0a:29:33" centos
63eda262189afa50cd888bc8a2f5f0d86aefb753cc47ad2305e1b5d83ae7bbb0
docker@LesPaul:~$ docker container inspect --format="{{.Config.MacAddress}}" 63eda
92:d0:c6:0a:29:33

例:ホスト名とIPアドレス定義

$ docker container run -it--add-host test.com:192.168.1.1 centos

実行例:ホスト名指定(/etc/hosts)

docker@LesPaul:~$ docker container run -it --hostname www.test.com --add-host node1.test.com:192.168.1.1 centos
[root@www /]# cat /etc/hosts
127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
192.168.1.1     node1.test.com
172.17.0.2      www.test.com www
Options Description
bridge ブリッジ接続(デフォルト)を使う
none ネットワークに接続しない
container:[ name / id ] 他のコンテナのネットワークを使う
host コンテナがホストOSのネットワークを使う
NETWORK ユーザー定義ネットワークを使う

例:ユーザー定義ネットワークの作成

$ docker network create -d bridge webapp-net
$ docker container run --net=webap-net -it centos

docker container run(リソースを指定してコンテナ生成/実行)

docker container run [リソースオプション] イメージ名[:タグ名][引数]
Options Description
--cpu-shares,-c CPU使用の配分(比率)
--memory,-m 使用するメモリを制限して実行する(単位はb,k,m,gのいずれか)
--volume=[ホストのディレクトリ]:[コンテナのディレクトリ],-v ホストとコンテナのディレクトリを共有

例:CPU時間の相対割合とメモリ使用量を指定

$ docker container run --cpu-shares=512 --memory=1g centos

例:ディレクトリ共有(host:/home/docker/webap<->container:/usr/share/nginx/html)

docker container run -v /home/docker/webap:/usr/share/nginx/html nginx

docker container run(コンテナを生成/起動する環境を指定)

$ docker container run [環境設定オプション] イメージ名[:タグ名][引数]
Options Description
--env=[環境変数],-e 環境変数を設定する
--env-file=[ファイル名] 環境変数をファイルから設定する
--read-only=[true/false] コンテナのファイルシステムを読み込み専用にする
--workdir=[パス],-w コンテナの作業ディレクトリを指定する
-u,--user=[ユーザー名] ユーザー名をまたはUIDを指定する

実行例:環境変数設定

docker@LesPaul:~$ docker container run -it -e foo=bar centos /bin/bash
[root@22c2c9986493 /]# set | grep foo
foo=bar

実行例:環境変数一括設定

docker@LesPaul:~$ cat env_list 
hoge=fuga
foo=bar
docker@LesPaul:~$ docker container run -it --env-file=env_list centos /bin/bash
[root@7b4076d18618 /]# set | grep -e foo -e hoge 
foo=bar
hoge=fuga

実行例:作業ディレクトリの設定

docker@LesPaul:~$ docker container run -it -w=/tensorflow centos /bin/bash
[root@611d4e932f83 tensorflow]# pwd
/tensorflow

docker container ls(稼働コンテナの一覧表示)

docker container ls [オプション]
Options Description
--all,-a 起動中/停止中も含めてすべてのコンテナを表示する
--filter,-f 表示するコンテナのフィルタリング
--format 表示フォーマットを指定
--last,-n 最後に起動されてからn件のコンテナのみ表示
--latest,-l 最後に起動されたコンテナのみ表示
--no-trunc 情報を省略しないで表示する
--quiet,-q コンテナIDのみ表示
--size,-s ファイルサイズの表示

実行例:コンテナ一覧表示

docker@LesPaul:~$ docker container run -d -p 8080:80 nginx
4b86652223ba69970a8beb0474f99c7133551a8f182af55b1ef2bf8c4f657647
docker@LesPaul:~$ docker container ls
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
4b86652223ba        nginx               "nginx -g 'daemon of…"   2 seconds ago       Up 1 second         0.0.0.0:8080->80/tcp   serene_hamilton

docker image lsコマンド結果

Item Description
CONTAINER ID コンテナいID
IMAGE コンテナの基になっているイメージ
COMMAND コンテナ内で実行されているコマンド
CREATED コンテナ作成からの経過
STATUS コンテナの状態(restarting/runnning/paused/exited)
PORTS 割り当てられたポート
NAMES コンテナの名前

実行例:コマンドのフィルタリング

docker@LesPaul:~$ docker container ls -a -f name=test1
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
895e28d7f4da        centos              "/bin/cal"          7 seconds ago       Exited (0) 6 seconds ago                       test1

実行例:コマンドのフィルタリング2

docker@LesPaul:~$ docker container ls -a -f exited=0
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                      PORTS               NAMES
895e28d7f4da        centos              "/bin/cal"               47 seconds ago      Exited (0) 46 seconds ago                       test1
4b86652223ba        nginx               "nginx -g 'daemon of…"   3 minutes ago       Exited (0) 2 minutes ago                        serene_hamilton
611d4e932f83        centos              "/bin/bash"              4 minutes ago       Exited (0) 4 minutes ago                        reverent_curie
5a7b851453cc        centos              "/bin/bash"              5 minutes ago       Exited (0) 5 minutes ago                        epic_haibt
7b4076d18618        centos              "/bin/bash"              12 minutes ago      Exited (0) 6 minutes ago                        upbeat_roentgen
Placeholder Description
.ID コンテナID
.Image イメージID
.Command 実行コマンド
.CreateAt コンテナが作成された時間
.RunningFor コンテナの稼働時間
.Ports 公開ポート
.Status コンテナの状態
.Size コンテナのディスクサイズ
.Names コンテナ名
.Mounts ボリュームマウント
.Networks ネットワーク名

実行例:コマンドの出力形式の指定

docker@LesPaul:~$ docker container ls -a --format "{{.Names}}: {{.Status}}"
test1: Exited (0) 2 minutes ago

実行例:コマンドを表形式にする

docker@LesPaul:~$ docker container ls -a --format "table {{.Names}}\t{{.Status}}\t{{.Mounts}}"
NAMES               STATUS                        MOUNTS
test1               Exited (0) 2 minutes ago      

docker container stats(コンテナの稼働確認)

$ docker container stats [コンテナ識別子]

実行例:コンテナ稼働確認

docker@LesPaul:~$ docker container stats webserver
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS
43e7fd9aabb6        webserver           0.00%               0B / 0B             0.00%               0B / 0B             0B / 0B             0
Options Description
CONTAINER ID コンテナ識別子
NAME コンテナ名
CPU % CPU使用率
MEM USAGE/LIMIT メモリ使用量/コンテナで使用できるメモリ制限
MEM % メモリ使用率
NET I/O ネットワークI/O
BLOCK I/O ブロックI/O
PIDS PID(Windowsコンテナ除く)

実行例:プロセス確認

docker@LesPaul:~$ docker container start 43e7fd9aabb6
43e7fd9aabb6
docker@LesPaul:~$ docker container top webserver
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                15522               15499               0                   22:33               ?                   00:00:00            nginx: master process nginx -g daemon off;
systemd+            15576               15522               0                   22:33               ?                   00:00:00            nginx: worker process

docker container start(コンテナの起動)

$ docker container start[オプション] コンテナ識別子 [コンテナ識別子]
Options Description
--attach,-a 標準出力/標準エラー出力を開く
--intaractive,-i コンテナの標準入力を開く

例:Dockerコンテナ開始

$ docker container start 

docker container stop(コンテナの停止)

$ docker container stop [オプション] コンテナ識別子 [コンテナ識別子]
Options Description
--time,-t コンテナの停止時間を指定する(デフォルト10秒)

例:コンテナ停止(3秒後停止)

$ docker container stop -t 3 43e7fd9aabb6

docker container restart(コンテナの再起動)

$ docker container restart [オプション] コンテナ識別子 [コンテナ識別子]
Options Description
--time,-t コンテナの再起動時間を指定する(デフォルト10秒)

例:コンテナ再起動(3秒後再起動)

$ docker container restart -t 3 webserver

docker container rm(コンテナの削除)

docker container rm [オプション] コンテナ識別子 [コンテナ識別子]
Options Description
--force,-f 起動中のコンテナを強制的に削除する
--volumes,-v 割り当てたボリュームを削除する

例:コンテナ削除

$ docker container rm 43e7fd9aabb6

実行例:停止中のコンテナ削除

docker@LesPaul:~$ docker container ls -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                           PORTS                NAMES
895e28d7f4da        centos              "/bin/cal"               16 minutes ago      Exited (0) 16 minutes ago                             test1
43e7fd9aabb6        nginx               "nginx -g 'daemon of…"   12 days ago         Up 9 minutes                     0.0.0.0:80->80/tcp   webserver
docker@LesPaul:~$ docker container prune
WARNING! This will remove all stopped containers.
Are you sure you want to continue? [y/N] y
Deleted Containers:
895e28d7f4dab18bd61d3989b460e5a426b449fe283e10579a6695c42b74ac7c
~中略~

Total reclaimed space: 215B
docker@LesPaul:~$ docker container ls -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
43e7fd9aabb6        nginx               "nginx -g 'daemon of…"   12 days ago         Up 11 minutes       0.0.0.0:80->80/tcp   webserver

docker container pause/docker container unpause(コンテナの中断/再開)

$ docker container pause コンテナ識別子

実行例:コンテナ中断->再開

docker@LesPaul:~$ docker container ls -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
43e7fd9aabb6        nginx               "nginx -g 'daemon of…"   12 days ago         Up 11 minutes       0.0.0.0:80->80/tcp   webserver
docker@LesPaul:~$ 
docker@LesPaul:~$ 
docker@LesPaul:~$ docker container pause webserver
webserver
docker@LesPaul:~$ docker container ls
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                   PORTS                NAMES
43e7fd9aabb6        nginx               "nginx -g 'daemon of…"   12 days ago         Up 14 minutes (Paused)   0.0.0.0:80->80/tcp   webserver
docker@LesPaul:~$ docker container unpause webserver
webserver
docker@LesPaul:~$ docker container ls
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
43e7fd9aabb6        nginx               "nginx -g 'daemon of…"   12 days ago         Up 15 minutes       0.0.0.0:80->80/tcp   webserver

参考資料

https://docs.docker.com/engine/reference/commandline/container_run/
https://docs.docker.com/engine/reference/commandline/container_ls/
https://docs.docker.com/engine/reference/commandline/container_stats/
https://docs.docker.com/engine/reference/commandline/container_start/
https://docs.docker.com/engine/reference/commandline/container_stop/
https://docs.docker.com/engine/reference/commandline/container_restart/
https://docs.docker.com/engine/reference/commandline/container_rm/
https://docs.docker.com/engine/reference/commandline/container_pause/
https://docs.docker.com/engine/reference/commandline/container_unpause/

Dockerイメージ操作

docker image pull(イメージダウンロード)

docker image pull [options] イメージ名[:タグ名]

例:CentOSのバージョン7(タグ名:7)をダウンロードする

CentOSイメージ取得

docker@LesPaul:~$ docker image pull centos:7
7: Pulling from library/centos
256b176beaff: Pull complete 
Digest: sha256:6f6d986d425aeabdc3a02cb61c02abb2e78e57357e92417d6d58332856024faf
Status: Downloaded newer image for centos:7

※タグ名を省略すると最新版(latest)を取得する

CentOSの全てのタグのイメージ取得

「-a」オプションを指定すると全てのタグを取得可能。
「-a」オプションを指定する場合、Dockerイメージ名にタグを指定できないので注意。

$ docker image pull -a centos

Jenkinsイメージ取得

docker@LesPaul:~$ docker image pull jenkins:latest
latest: Pulling from library/jenkins
55cbf04beb70: Pull complete 
1607093a898c: Pull complete 
9a8ea045c926: Pull complete 
d4eee24d4dac: Pull complete 
c58988e753d7: Pull complete 
794a04897db9: Pull complete 
70fcfa476f73: Pull complete 
0539c80a02be: Pull complete 
54fefc6dcf80: Pull complete 
911bc90e47a8: Pull complete 
38430d93efed: Pull complete 
7e46ccda148a: Pull complete 
c0cbcb5ac747: Pull complete 
35ade7a86a8e: Pull complete 
aa433a6a56b1: Pull complete 
841c1dd38d62: Pull complete 
b865dcb08714: Pull complete 
5a3779030005: Pull complete 
12b47c68955c: Pull complete 
1322ea3e7bfd: Pull complete 
Digest: sha256:eeb4850eb65f2d92500e421b430ed1ec58a7ac909e91f518926e02473904f668
Status: Downloaded newer image for jenkins:latest

docker image ls(イメージ一覧表示)

docker image ls [options][リポジトリ[:タグ名]]
Options Description
-all,-a すべてのイメージを表示
--digests ダイジェストを表示するかどうか
--no-trunc 結果をすべて表示
--quiet,-q DockerイメージIDのみ表示

イメージ一覧表示

docker@LesPaul:~$ docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx               latest              be1f31be9a87        6 days ago          109MB
ubuntu              latest              cd6d8154f1e1        4 weeks ago         84.1MB
centos              7                   5182e96772bf        2 months ago        200MB

docker image lsコマンド結果

Item Description
REPOSITORY イメージ名
TAG イメージタグ名
IMAGE ID イメージID
CREATED 作成日
SIZE イメージサイズ

docker image inspect(イメージ詳細確認)

イメージ詳細表示

docker@LesPaul:~$ docker image inspect centos:7
[
    {
        "Id": "sha256:5182e96772bf11f4b912658e265dfe0db8bd314475443b6434ea708784192892", <---①
        "RepoTags": [
            "centos:7",
            "centos:centos7",
            "centos:latest"
        ],
        "RepoDigests": [
            "centos@sha256:6f6d986d425aeabdc3a02cb61c02abb2e78e57357e92417d6d58332856024faf"
        ],
        "Parent": "",
        "Comment": "",
        "Created": "2018-08-06T19:21:48.235227329Z", <---②
        "Container": "d60ffc9ddd12462af4bdcdbe45b74f3b3f99b46607ada80c3ed877b7def84250",
        "ContainerConfig": {
            "Hostname": "d60ffc9ddd12",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "/bin/sh",
                "-c",
                "#(nop) ",
                "CMD [\"/bin/bash\"]"
            ],
            "ArgsEscaped": true,
            "Image": "sha256:748eacc0f236df2fc9ba87c4d76a66cb10742120387e99e2acdb9454915c841d",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": {
                "org.label-schema.build-date": "20180804",
                "org.label-schema.license": "GPLv2",
                "org.label-schema.name": "CentOS Base Image",
                "org.label-schema.schema-version": "1.0",
                "org.label-schema.vendor": "CentOS"
            }
        },
        "DockerVersion": "17.06.2-ce", <---③
        "Author": "",
        "Config": {
            "Hostname": "",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "/bin/bash"
            ],
            "ArgsEscaped": true,
            "Image": "sha256:748eacc0f236df2fc9ba87c4d76a66cb10742120387e99e2acdb9454915c841d",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": {
                "org.label-schema.build-date": "20180804",
                "org.label-schema.license": "GPLv2",
                "org.label-schema.name": "CentOS Base Image",
                "org.label-schema.schema-version": "1.0",
                "org.label-schema.vendor": "CentOS"
            }
        },
        "Architecture": "amd64", <---④
        "Os": "linux",
        "Size": 199723824,
        "VirtualSize": 199723824,
        "GraphDriver": {
            "Data": {
                "MergedDir": "/var/lib/docker/overlay2/04d9e945bc770af8408522c65e76a6db03eda99c0c8ab5248366d208b5a89954/merged",
                "UpperDir": "/var/lib/docker/overlay2/04d9e945bc770af8408522c65e76a6db03eda99c0c8ab5248366d208b5a89954/diff",
                "WorkDir": "/var/lib/docker/overlay2/04d9e945bc770af8408522c65e76a6db03eda99c0c8ab5248366d208b5a89954/work"
            },
            "Name": "overlay2"
        },
        "RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:1d31b5806ba40b5f67bde96f18a181668348934a44c9253b420d5f04cfb4e37a"
            ]
        },
        "Metadata": {
            "LastTagTime": "0001-01-01T00:00:00Z"
        }
    }
]

①イメージID
②作成日
③Dockerバージョン
④CPUのアーキテクチャ
出力結果はJSON(JavaScript Object Notation)形式。

OS情報取得

docker@LesPaul:~$ docker image inspect --format="{{.Os}}" centos:7
linux

image情報取得

docker@LesPaul:~$ docker image inspect centos --format="{{.ContainerConfig.Image}}"
sha256:748eacc0f236df2fc9ba87c4d76a66cb10742120387e99e2acdb9454915c841d

docker image tag(イメージタグ設定)

Docker Hubに作成したイメージを登録するには以下の規則でイメージにユーザー名を付与します。

<Docker Hubのユーザー名>/イメージ名:[タグ名]

イメージへのタグ設定

例:nginxという名称のイメージに対し、ユーザー名がundercoverでコンテナ名がwebserverでタグにバージョン情報である1.0というタグを付与する。

docker@LesPaul:~$ docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx               latest              be1f31be9a87        6 days ago          109MB
ubuntu              latest              cd6d8154f1e1        4 weeks ago         84.1MB
centos              6.6                 48ac30562192        2 months ago        203MB
:
docker@LesPaul:~$ docker image tag nginx undercover/webserver:1.0
docker@LesPaul:~$ docker image ls
REPOSITORY             TAG                 IMAGE ID            CREATED             SIZE
nginx                  latest              be1f31be9a87        6 days ago          109MB
undercover/webserver   1.0                 be1f31be9a87        6 days ago          109MB
ubuntu                 latest              cd6d8154f1e1        4 weeks ago         84.1MB
centos                 6.6                 48ac30562192        2 months ago        203MB
:

docker search(イメージ検索)

Docker Hubに公開されているイメージを検索する。

docker search [options] keyword
Options Description
--no-trunc 結果をすべて表示
--limit n件の検索結果を表示
--filter=stars=n お気に入りの数(n以上)の指定

Docker Hubに公開されているイメージ検索

docker@LesPaul:~$ docker search nginx
NAME                                                   DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
nginx                                                  Official build of Nginx.                        9823                [OK]                
jwilder/nginx-proxy                                    Automated Nginx reverse proxy for docker con…   1425                                    [OK]
richarvey/nginx-php-fpm                                Container running Nginx + PHP-FPM capable of…   619                                     [OK]
jrcs/letsencrypt-nginx-proxy-companion                 LetsEncrypt container to use with nginx as p…   423                                     [OK]
kong                                                   Open-source Microservice & API Management la…   230                 [OK]                
webdevops/php-nginx                                    Nginx with PHP-FPM                              113                                     [OK]
kitematic/hello-world-nginx                            A light-weight nginx container that demonstr…   111                                     
zabbix/zabbix-web-nginx-mysql                          Zabbix frontend based on Nginx web-server wi…   72                                      [OK]
bitnami/nginx                                          Bitnami nginx Docker Image                      58                                      [OK]
1and1internet/ubuntu-16-nginx-php-phpmyadmin-mysql-5   ubuntu-16-nginx-php-phpmyadmin-mysql-5          45                                      [OK]
linuxserver/nginx                                      An Nginx container, brought to you by LinuxS…   40                                      
tobi312/rpi-nginx                                      NGINX on Raspberry Pi / armhf                   22                                      [OK]
blacklabelops/nginx                                    Dockerized Nginx Reverse Proxy Server.          12                                      [OK]
wodby/drupal-nginx                                     Nginx for Drupal container image                11                                      [OK]
nginxdemos/hello                                       NGINX webserver that serves a simple page co…   8                                       [OK]
centos/nginx-18-centos7                                Platform for running nginx 1.8 or building n…   8                                       
webdevops/nginx                                        Nginx container                                 8                                       [OK]
centos/nginx-112-centos7                               Platform for running nginx 1.12 or building …   5                                       
1science/nginx                                         Nginx Docker images that include Consul Temp…   4                                       [OK]
behance/docker-nginx                                   Provides base OS, patches and stable nginx f…   3                                       [OK]
pebbletech/nginx-proxy                                 nginx-proxy sets up a container running ngin…   2                                       [OK]
toccoag/openshift-nginx                                Nginx reverse proxy for Nice running on same…   1                                       [OK]
travix/nginx                                           NGinx reverse proxy                             1                                       [OK]
mailu/nginx                                            Mailu nginx frontend                            1                                       [OK]
ansibleplaybookbundle/nginx-apb                        An APB to deploy NGINX                          0                                       [OK]

docker searchコマンド結果

Item Description
NAME イメージ名
DESCRIPTION イメージの説明
STARS お気に入りの数
OFFICIAL 公式イメージか否か
AUTOMATED Dockerfileを基に自動生成されたイメージか否か

人気イメージの検索

例:STARSの件数が1000件以上のイメージの検索

docker@LesPaul:~$ docker search --filter=stars=1000 nginx
NAME                  DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
nginx                 Official build of Nginx.                        9823                [OK]                
jwilder/nginx-proxy   Automated Nginx reverse proxy for docker con…   1425                                    [OK]

n件の検索

例:mysqlを検索キーワードとして表示件数(5件)を制限して検索

docker@LesPaul:~$ docker search --limit 5 mysql
NAME                         DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
mysql                        MySQL is a widely used, open-source relation…   7099                [OK]                
mysql/mysql-server           Optimized MySQL Server Docker images. Create…   517                                     [OK]
zabbix/zabbix-server-mysql   Zabbix Server with MySQL database support       133                                     [OK]
mysql/mysql-cluster          Experimental MySQL Cluster Docker images. Cr…   33                                      
circleci/mysql               MySQL is a widely used, open-source relation…   7               

docker image rm(イメージの削除)

docker image rm [options] イメージ名 [イメージ名]
Options Description
--force,-f イメージを強制的に削除
--no-prun 中間イメージを削除しない

イメージの削除

例:REPOSITORYがnginxのイメージを削除する。

docker@LesPaul:~$ docker image ls
REPOSITORY             TAG                 IMAGE ID            CREATED             SIZE
nginx                  latest              be1f31be9a87        6 days ago          109MB
undercover/webserver   1.0                 be1f31be9a87        6 days ago          109MB
ubuntu                 latest              cd6d8154f1e1        4 weeks ago         84.1MB
jenkins                latest              cd14cecfdb3a        2 months ago        696MB
docker@LesPaul:~$ docker image rm nginx
Untagged: nginx:latest
Untagged: nginx@sha256:9ad0746d8f2ea6df3a17ba89eca40b48c47066dfab55a75e08e2b70fc80d929e
docker@LesPaul:~$ docker image ls
REPOSITORY             TAG                 IMAGE ID            CREATED             SIZE
undercover/webserver   1.0                 be1f31be9a87        6 days ago          109MB
ubuntu                 latest              cd6d8154f1e1        4 weeks ago         84.1MB
jenkins                latest              cd14cecfdb3a        2 months ago        696MB

未使用のDockerイメージを削除するときは、Docker image pruneコマンドを使用する。

docker image prune [options]
Options Description
--all,-a 使用していないイメージをすべて削除
--force,-f イメージを強制的に削除

docker login(Docker Hubログイン)

※アカウントが無い場合は、本セクションの実施前に下部「Appendix」を参考に登録を済ませてください。

docker login [options] [server]
Options Description
--password,-p パスワード
--username,-u ユーザー名
docker@LesPaul:~$ docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: 登録したユーザー名
Password: 登録したパスワード
WARNING! Your password will be stored unencrypted in /home/docker/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded
docker@LesPaul:~$ docker login -u <ユーザー名> -p <パスワード>
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
WARNING! Your password will be stored unencrypted in /home/docker/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

docker image push(イメージアップロード)

docker image push イメージ名[:タグ名]

Docker Hubにアップするイメージは以下のようにします。

<Docker Hubユーザー名>/イメージ名:[タグ名]

イメージアップロード

※事前にDocker Hubにログインしている必要があります。

docker@LesPaul:~$ docker image push undercoverism/webserver:1.0
The push refers to repository [docker.io/undercoverism/webserver]
92b86b4e7957: Mounted from library/nginx 
94ad191a291b: Mounted from library/nginx 
8b15606a9e3e: Mounted from library/nginx 
1.0: digest: sha256:204a9a8e65061b10b92ad361dd6f406248404fe60efd5d6a8f2595f18bb37aad size: 948

f:id:undercovergeek:20181011204725j:plain

docker logout(Docker Hubログアウト)

docker logout
docker@LesPaul:~$ docker logout
Removing login credentials for https://index.docker.io/v1/

Appendix

Docker Hub

DockerにはDockerレジストリと呼ばれる多くのDockerイメージを集権的に管理するためのホスティング機能があります。
Docker HubはDocker社が管理しているDockerレジストリです。
Docker Hubは、GitHubやBitbucket等のソースコード管理ツールと連携してコードをビルドする機能やアプリケーションのイメージを管理する機能などを備えています。
Docker Hubによって、物理サーバ/仮想マシン/クラウドにDockerイメージを配布可能となります。

アカウント登録

https://hub.docker.com
f:id:undercovergeek:20181011204840j:plain
フォームを入力し送信後にメールが送信されます。
メール記載の指示に従い、アクティベーションを済ませます。
f:id:undercovergeek:20181011204851j:plain f:id:undercovergeek:20181011204902j:plain

サインアップ

Welcomeページへの遷移(サインアップ完了)
f:id:undercovergeek:20181011204918j:plain f:id:undercovergeek:20181011204929j:plain

Docker上にNginx環境構築

概要

Docker環境にNginx(Webサーバー)を構築してみます。

Nginx

Nginx(エンジンエックス)は、OSSの高速Webサーバーソフトウェアで処理性能/並行処理/メモリ使用量削減に焦点を当てて開発されているWebサーバです。
ロードバランサーやHTTPキャッシュのなどの機能も備えています。
また、Webサーバとしてだけでなく、リバースプロキシやロードバランサとしても利用できます。
https://ja.wikipedia.org/wiki/Nginx
公式サイト:https://nginx.org/

環境情報

・ホストOS:Windows 10
・VirtualBox:Ver 5.2.18
・ゲストOS:Ubuntu 18.04
・Docker:18.06.1-ce

Dockerイメージダウンロード

Dockerコンテナを起動するためにDockerコンテナの基となるDockerイメージを入手します。
以下(Docker Hub)からNginxの公式イメージが提供されています。
https://hub.docker.com/_/nginx

イメージダウンロード

docker@LesPaul:~$ docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
802b00ed6f79: Pull complete 
5291925314b3: Pull complete 
bd9f53b2c2de: Pull complete 
Digest: sha256:9ad0746d8f2ea6df3a17ba89eca40b48c47066dfab55a75e08e2b70fc80d929e
Status: Downloaded newer image for nginx:latest

※公式イメージにはDockerでNginxを動作させるための必要なパッケージがインストールされています。

イメージ確認

docker@LesPaul:~$ docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx               latest              be1f31be9a87        42 hours ago        109MB
ubuntu              latest              cd6d8154f1e1        4 weeks ago         84.1MB

Nginx起動

Dockerコンテナの基になるDockerイメージを使用してNginxサーバを起動。
下記の例では、「nginx」を使用して「webserver」という名称のDockerコンテナを起動しています。
ブラウザからHTTP(port:80)アクセスを許可するために-pオプションでコンテナからの転送を許可してます。

docker@LesPaul:~$ docker container run --name webserver -d -p 80:80 nginx
43e7fd9aabb6d6407bf9cebd469f000ed4537f3eb2c7cc99b5757e5e9601270a

英数字の文字列は、コンテナIDと呼ばれ、Dockerコンテナの一意の識別子です。

Nginx動作確認

http://localhost:80
f:id:undercovergeek:20181004224106j:plain
上記のNginxのトップ画面が表示されれば、Webサーバは問題なく動作していると確認できます。

Nginxサーバ状態の確認

docker@LesPaul:~$ docker container ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
43e7fd9aabb6        nginx               "nginx -g 'daemon of…"   14 minutes ago      Up 14 minutes       0.0.0.0:80->80/tcp   webserver

---> 上記より「webserver」という名称のDockerコンテナでNginxのサーバプロセスが起動しており、ポート80番で転送しています。

Nginx起動/停止

コンテナ停止

docker@LesPaul:~$ docker stop webserver
webserver
docker@LesPaul:~$ docker container ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

f:id:undercovergeek:20181004224123j:plain

コンテナ起動

docker@LesPaul:~$ docker start webserver
webserver
docker@LesPaul:~$ docker container ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
43e7fd9aabb6        nginx               "nginx -g 'daemon of…"   22 minutes ago      Up 3 seconds        0.0.0.0:80->80/tcp   webserver

Dockerの動作原理(名前空間/cgroups)

概要

コンテナは、Linuxカーネルの技術をベースにLinux上の起動プロセスを隔離した状態で起動することです。
これを実現するためには複数の技術要素がありますが、コア機能としてはプロセス空間や名前空間の分離です。

Dockerの登場

概念としてのコンテナの登場は、プロセスコンテナ(process container)と呼ばれるLinuxカーネルに対するパッチセットとなります。 https://lwn.net/Articles/199643/ (2006/9/14投稿 Rohit Seth's container patch)

We use the term container to indicate a structure against which we track and charge utilization of system resources like memory, tasks etc for a workload. Containers will allow system admins to customize the underlying platform for different applications based on their performance and HW resource utilization needs. Containers contain enough infrastructure to allow optimal resource utilization without bogging down rest of the kernel. A system admin should be able to create, manage and free containers easily.

これは、Linux上のプロセスをコンテナと呼ばれる階層下にグループするための技術で、これらのプロセス群の周辺に壁を設けることがコンテナと呼ばれる技術の実装に該当します。
コンテナを実現するため、Linuxカーネルの「名前空間」と「cgroups」という機能を利用します。
どちらもプロセス間に壁を設け分離(isolate)ものですが、カバー範囲が異なります。
* 名前空間:プロセス間内で何が(ソフトウェア的に)見えるかを制限
* cgroups:プロセスグループが(ハードウェア的に)どれだけ利用できるかを制限

名前空間(namespace)

コンテナを区画化する仕組み
Linuxカーネルの名前空間(namespace)を制御して複数のプロセスが1つのマシン上にある1つのカーネルを共有可能にします。 その具体的な方法としてホスト上で実行するプロセス空間(ユーザー空間)を分離(isolate)しています。 Linuxカーネルのnamespace機能は、Linuxのオブジェクトに名前を付与することで下記の独立した環境を構築可能にします。 http://man7.org/linux/man-pages/man7/namespaces.7.html

namespace name description version
PID 実行するプロセスIDの分離 namespaceの異なるプロセス同士は互いにアクセス不可 Linux3.8-
Network ネットワークデバイス、ルーティングテーブル、ファイアウォールルール、ポートetcを分離 Linux3.0-
Cgroup プロセスの名前空間を分離するためルートディレクトリを扱う Linux4.6-
IPC System Vプロセス間通信(IPC:Inter Process Communication)とPOSIXメッセージキューを分離 Linux3.0-
Mount マウントポイント、ファイルシステムを分離 Linux3.8-
User ユーザーID(UID)、グループID(GID)の分離 Linux3.8-
UTS ホスト名(unameおよびhostnameコマンドで取得できる名前)の分離 Linux3.0-

名前空間は、プロセスを分離するだけではなく、複数の名前空間を組み合わせコンテナとして様々な名前空間を隔離した状態のプロセスを実行可能にします。

cgroups(コントロールグループ)

リソース管理の仕組み
cgroup(control groups:コントロールグループ)は、リソース管理・リソースの集計/追跡を実施します。
これはLinuxカーネルの機能で、プロセスの集まりに対してリソース使用を制限/割当/分離しています。
※リソース:CPU・メモリ・ディスクI/O・ネットワーク
上記の技術の基礎となったのは、「プロセスコンテナ(Process Container)」2006年にLinuxカーネルに送られたパッチです。さらに2007年に「Control Groups」への名称変更、2008年にKernel2.6.24で取り込まれたものです。
cgroupsでコンテナ内のプロセスに対してリソース制限をかけることで、例としてあるコンテナがホストOSのリソースを使いつくし、同じホストOS上で稼働している他のコンテナに影響を与えることを防止します。

cgroupsの主なサブシステム

項目 説明
cpu CPU使用量の制限
cpuacct CPU使用量の統計情報を提供
cpuset CPUやメモリの配置を制御
memory メモリやスワップの使用量の制限
devices デバイスへのアクセス許可/拒否
freezer グループに属するプロセスの停止/再開
net_cls ネットワーク制御のタグを付加
blkio ブロックデバイスの入出力量制御

cgroupsは、階層構造を使用してプロセスをグループ化して管理できます。

名前空間とcgroups

f:id:undercovergeek:20181001182532j:plain

Oracle 問合せ変換③ 述語のプッシュ(Predicate Push Down)

概要

述語のプッシュ(またはプッシュダウン)は、前回記事で説明したビュー・マージが不可能なビューに対する問合せであった場合に、主問合せの述語をビュー定義の中に組み入れる(プッシュ)ことによって、実行の初期段階で多くの行を絞り込むことが期待できます。
そのことで、以下のような効果があります。
- 索引アクセスが選択可能になる
- 次のオペレーション(ソート等)で処理するデータ量が少なくなり効率的になる
述語のプッシュは、以下の通り、2つのサブカテゴリがあります。
- フィルタプッシュダウン(Filter Push Down):
マージできないビューまたはインラインビュー内で制限(フィルタリング条件)をプッシュすること
- 結合述語プッシュダウン(Join Predicate Push Down):
マージできないビューまたはインライン・ビューの中で結合条件をプッシュすること
それぞれ、フィルタプッシュダウンはヒューリスティックベース、結合述語プッシュダウンはコストベースのクエリ変換です。

変換イメージ

Filter Push Down

SELECT *
 FROM
    (SELECT * FROM t1
        UNION
     SELECT * FROM t2
    )
 WHERE id = 1

↓↓↓変換↓↓↓

SELECT *
 FROM
    (SELECT * FROM t1
      WHERE id = 1
        UNION
     SELECT * FROM t2
      WHERE id = 1
    )

上記例では、インラインビュー内の制限(id = 1)をプッシュしています。 このことで以下の効果が得られます。
- 2つのテーブルにインデックスを介してアクセスできる。
- UNIONセット演算子に必要な並べ替え操作ができるだけ少ない行で処理される

Join Predicate Push Down

SELECT *
 FROM t1,
    (SELECT * FROM t2
        UNION
     SELECT * FROM t3
    ) t23
WHERE t1.id = t23.id

↓↓↓変換↓↓↓
SELECT *
 FROM t1,
    (SELECT * FROM t2
      WHERE t2.id = t1.id
       UNION
     SELECT * FROM t3
      WHERE t3.id = t1.id
    ) t23

上記例では、結合条件(t1.id = t23.id)をインライン・ビュー内にプッシュしています。
この変換によって得られる利点は、フィルタプッシュダウンに記載したのと同じ利点(インデックスアクセスを有効にし、ソートするデータ量を削減)です。
この特定のケースでは、追加のアクセス・パスにより、問合せオプティマイザは、使用可能なすべての「結合メソッド」と「結合順序」を自由に選択できるようになります。

実行例

下記は、結合述語プッシュダウン(JPPD)変換の例です。

Join Predicate Push Down

WITH agg_q
     AS (  SELECT s.cust_id
                 ,prod_id
                 ,SUM (s.amount_sold) total_amt_sold
             FROM sh.sales s JOIN sh.products p USING (prod_id)
         GROUP BY s.cust_id,prod_id)
SELECT cust_id
      ,c.cust_first_name
      ,c.cust_last_name
      ,c.cust_email
      ,agg_q.total_amt_sold
  FROM agg_q RIGHT JOIN sh.customers c USING (cust_id)
 WHERE cust_first_name = 'Abner' AND cust_last_name = 'Everett';

Plan hash value: 273701464

-----------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                                        | Name           | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
-----------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                                 |                |     1 |    63 |   478   (1)| 00:00:01 |       |       |
|   1 |  NESTED LOOPS OUTER                              |                |     1 |    63 |   478   (1)| 00:00:01 |       |       |
|*  2 |   TABLE ACCESS FULL                              | CUSTOMERS      |     1 |    48 |   423   (1)| 00:00:01 |       |       |
|   3 |   VIEW PUSHED PREDICATE                          |                |     1 |    15 |    56   (2)| 00:00:01 |       |       |
|   4 |    SORT GROUP BY                                 |                |    31 |   806 |    56   (2)| 00:00:01 |       |       |
|   5 |     NESTED LOOPS                                 |                |    43 |  1118 |    56   (2)| 00:00:01 |       |       |
|   6 |      VIEW                                        | VW_GBC_6       |    43 |   946 |    56   (2)| 00:00:01 |       |       |
|   7 |       SORT GROUP BY                              |                |    43 |   602 |    56   (2)| 00:00:01 |       |       |
|   8 |        PARTITION RANGE ALL                       |                |   130 |  1820 |    55   (0)| 00:00:01 |     1 |    28 |
|   9 |         TABLE ACCESS BY LOCAL INDEX ROWID BATCHED| SALES          |   130 |  1820 |    55   (0)| 00:00:01 |     1 |    28 |
|  10 |          BITMAP CONVERSION TO ROWIDS             |                |       |       |            |          |       |       |
|* 11 |           BITMAP INDEX SINGLE VALUE              | SALES_CUST_BIX |       |       |            |          |     1 |    28 |
|* 12 |      INDEX UNIQUE SCAN                           | PRODUCTS_PK    |     1 |     4 |     0   (0)| 00:00:01 |       |       |
-----------------------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - filter("C"."CUST_FIRST_NAME"='Abner' AND "C"."CUST_LAST_NAME"='Everett')
  11 - access("S"."CUST_ID"="C"."CUST_ID")
  12 - access("ITEM_1"="P"."PROD_ID")

変換されていない実行計画(NO_PUSH_PRED)

WITH agg_q
     AS (  SELECT /*+ no_push_pred */
                  s.cust_id
                 ,prod_id
                 ,SUM (s.amount_sold) total_amt_sold
             FROM sh.sales s JOIN sh.products p USING (prod_id)
         GROUP BY s.cust_id,prod_id)
SELECT cust_id
      ,c.cust_first_name
      ,c.cust_last_name
      ,c.cust_email
      ,agg_q.total_amt_sold
  FROM agg_q RIGHT JOIN sh.customers c USING (cust_id)
 WHERE cust_first_name = 'Abner' AND cust_last_name = 'Everett';

Plan hash value: 1957717102

------------------------------------------------------------------------------------------------------------------
| Id  | Operation                  | Name        | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     | Pstart| Pstop |
------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT           |             |     2 |   148 |       |  6358   (1)| 00:00:01 |       |       |
|*  1 |  HASH JOIN OUTER           |             |     2 |   148 |       |  6358   (1)| 00:00:01 |       |       |
|   2 |   JOIN FILTER CREATE       | :BF0000     |     1 |    48 |       |   423   (1)| 00:00:01 |       |       |
|*  3 |    TABLE ACCESS FULL       | CUSTOMERS   |     1 |    48 |       |   423   (1)| 00:00:01 |       |       |
|   4 |   VIEW                     |             |   359K|  9125K|       |  5934   (1)| 00:00:01 |       |       |
|   5 |    HASH GROUP BY           |             |   359K|  9125K|    12M|  5934   (1)| 00:00:01 |       |       |
|   6 |     JOIN FILTER USE        | :BF0000     |   359K|  9125K|       |  3275   (2)| 00:00:01 |       |       |
|*  7 |      HASH JOIN             |             |   359K|  9125K|       |  3275   (2)| 00:00:01 |       |       |
|   8 |       INDEX FULL SCAN      | PRODUCTS_PK |    72 |   288 |       |     1   (0)| 00:00:01 |       |       |
|   9 |       VIEW                 | VW_GBC_6    |   359K|  7721K|       |  3273   (2)| 00:00:01 |       |       |
|  10 |        HASH GROUP BY       |             |   359K|  4913K|    21M|  3273   (2)| 00:00:01 |       |       |
|  11 |         PARTITION RANGE ALL|             |   918K|    12M|       |   517   (2)| 00:00:01 |     1 |    28 |
|  12 |          TABLE ACCESS FULL | SALES       |   918K|    12M|       |   517   (2)| 00:00:01 |     1 |    28 |
------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - access("C"."CUST_ID"="AGG_Q"."CUST_ID"(+))
   3 - filter("C"."CUST_FIRST_NAME"='Abner' AND "C"."CUST_LAST_NAME"='Everett')
   7 - access("ITEM_1"="P"."PROD_ID")

最適化後のSQL(10053トレース)

SELECT
    "C"."CUST_ID" "CUST_ID",
    "C"."CUST_FIRST_NAME" "CUST_FIRST_NAME",
    "C"."CUST_LAST_NAME" "CUST_LAST_NAME",
    "C"."CUST_EMAIL" "CUST_EMAIL",
    "AGG_Q"."TOTAL_AMT_SOLD" "TOTAL_AMT_SOLD"
FROM
    "SH"."CUSTOMERS" "C",
    (
        SELECT
            "VW_GBC_6"."ITEM_3" "CUST_ID",
            "P"."PROD_ID" "PROD_ID",
            SUM("VW_GBC_6"."ITEM_2") "TOTAL_AMT_SOLD"
        FROM
            (
                SELECT
                    "S"."PROD_ID" "ITEM_1",
                    SUM("S"."AMOUNT_SOLD") "ITEM_2",
                    "S"."CUST_ID" "ITEM_3"
                FROM
                    "SH"."SALES" "S"
                WHERE
                    "S"."CUST_ID" = "C"."CUST_ID"
                GROUP BY
                    "S"."PROD_ID",
                    "S"."CUST_ID"
            ) "VW_GBC_6",
            "SH"."PRODUCTS" "P"
        WHERE
            "VW_GBC_6"."ITEM_1" = "P"."PROD_ID"
        GROUP BY
            "VW_GBC_6"."ITEM_3",
            "P"."PROD_ID"
    ) "AGG_Q"
WHERE
    "C"."CUST_FIRST_NAME" = 'Abner'
AND "C"."CUST_LAST_NAME" = 'Everett'

Appendix

ヒューリスティックベースのクエリ変換:特定の条件が満たされたときに適用される。ほとんどの状況でより良い実行計画につながると期待されている。
コストベースのクエリ変換:コスト見積もりによって計算されたコストに応じて、元のステートメントよりもコストが低い実行計画につながる場合に適用される

参考資料

Expert Oracle SQL

Expert Oracle SQL: Optimization, Deployment, and Statistics

Expert Oracle SQL: Optimization, Deployment, and Statistics

Troubleshooting Oracle Performance, Second Edition
Troubleshooting Oracle Performance

Troubleshooting Oracle Performance

https://docs.oracle.com/cd/E96517_01/tgsql/index.html
Oracle(R) Database SQLチューニング・ガイド 18c

Oracle 問合せ変換②-2 ビュー・マージ(Complex View Merging)

概要

前回のSimple View Mergingに引き続き、今回はComplex View Mergingについて記載します。
変換の目的についてはSimple/Complexで大きく変わらないため今回は記載しません。

実行例

Complex view merging

WITH agg_q
     AS (  SELECT /*+   merge */
                  s.cust_id, s.prod_id, SUM (s.amount_sold) total_amt_sold
             FROM sh.sales s
         GROUP BY s.cust_id, s.prod_id)
SELECT cust_id
      ,c.cust_first_name
      ,c.cust_last_name
      ,c.cust_email
      ,p.prod_name
      ,agg_q.total_amt_sold
  FROM agg_q
       JOIN sh.customers c USING (cust_id)
       JOIN sh.countries co USING (country_id)
       JOIN sh.products p USING (prod_id)
 WHERE     co.country_name = 'Japan'
       AND prod_category = 'Photo'
       AND total_amt_sold > 20000;

Plan hash value: 2615677739

-------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                              | Name                 | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
-------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                       |                      |   484 | 79860 |   951   (2)| 00:00:01 |       |       |
|*  1 |  FILTER                                |                      |       |       |            |          |       |       |
|   2 |   HASH GROUP BY                        |                      |   484 | 79860 |   951   (2)| 00:00:01 |       |       |
|*  3 |    HASH JOIN                           |                      |  9672 |  1558K|   949   (2)| 00:00:01 |       |       |
|   4 |     TABLE ACCESS BY INDEX ROWID BATCHED| PRODUCTS             |    14 |   826 |     3   (0)| 00:00:01 |       |       |
|*  5 |      INDEX RANGE SCAN                  | PRODUCTS_PROD_CAT_IX |    14 |       |     1   (0)| 00:00:01 |       |       |
|*  6 |     HASH JOIN                          |                      | 48360 |  5006K|   946   (2)| 00:00:01 |       |       |
|*  7 |      HASH JOIN                         |                      |  2921 |   262K|   426   (1)| 00:00:01 |       |       |
|*  8 |       TABLE ACCESS FULL                | COUNTRIES            |     1 |    27 |     3   (0)| 00:00:01 |       |       |
|   9 |       TABLE ACCESS FULL                | CUSTOMERS            | 55500 |  3522K|   423   (1)| 00:00:01 |       |       |
|  10 |      PARTITION RANGE ALL               |                      |   918K|    12M|   517   (2)| 00:00:01 |     1 |    28 |
|  11 |       TABLE ACCESS FULL                | SALES                |   918K|    12M|   517   (2)| 00:00:01 |     1 |    28 |
-------------------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter(SUM("S"."AMOUNT_SOLD")>20000)
   3 - access("S"."PROD_ID"="P"."PROD_ID")
   5 - access("P"."PROD_CATEGORY"='Photo')
   6 - access("S"."CUST_ID"="C"."CUST_ID")
   7 - access("C"."COUNTRY_ID"="CO"."COUNTRY_ID")
   8 - filter("CO"."COUNTRY_NAME"='Japan')

変換されていない実行計画(NO_MERGE)

WITH agg_q
     AS (  SELECT /* no_merge */
                  s.cust_id, s.prod_id, SUM (s.amount_sold) total_amt_sold
             FROM sh.sales s
         GROUP BY s.cust_id, s.prod_id)
SELECT cust_id
      ,c.cust_first_name
      ,c.cust_last_name
      ,c.cust_email
      ,p.prod_name
      ,agg_q.total_amt_sold
  FROM agg_q
       JOIN sh.customers c USING (cust_id)
       JOIN sh.countries co USING (country_id)
       JOIN sh.products p USING (prod_id)
 WHERE     co.country_name = 'Japan'
       AND prod_category = 'Photo'
       AND total_amt_sold > 20000;

Plan hash value: 2752099247

----------------------------------------------------------------------------------------------------------------
| Id  | Operation                       | Name         | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
----------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                |              |     1 |   154 |   545   (6)| 00:00:01 |       |       |
|   1 |  NESTED LOOPS                   |              |     1 |   154 |   545   (6)| 00:00:01 |       |       |
|   2 |   NESTED LOOPS                  |              |     1 |   154 |   545   (6)| 00:00:01 |       |       |
|   3 |    NESTED LOOPS                 |              |     1 |   107 |   544   (6)| 00:00:01 |       |       |
|   4 |     NESTED LOOPS                |              |     1 |    92 |   543   (6)| 00:00:01 |       |       |
|   5 |      VIEW                       |              |     1 |    39 |   542   (6)| 00:00:01 |       |       |
|*  6 |       FILTER                    |              |       |       |            |          |       |       |
|   7 |        HASH GROUP BY            |              |     1 |    14 |   542   (6)| 00:00:01 |       |       |
|   8 |         PARTITION RANGE ALL     |              |   918K|    12M|   517   (2)| 00:00:01 |     1 |    28 |
|   9 |          TABLE ACCESS FULL      | SALES        |   918K|    12M|   517   (2)| 00:00:01 |     1 |    28 |
|  10 |      TABLE ACCESS BY INDEX ROWID| CUSTOMERS    |     1 |    53 |     1   (0)| 00:00:01 |       |       |
|* 11 |       INDEX UNIQUE SCAN         | CUSTOMERS_PK |     1 |       |     0   (0)| 00:00:01 |       |       |
|* 12 |     TABLE ACCESS BY INDEX ROWID | COUNTRIES    |     1 |    15 |     1   (0)| 00:00:01 |       |       |
|* 13 |      INDEX UNIQUE SCAN          | COUNTRIES_PK |     1 |       |     0   (0)| 00:00:01 |       |       |
|* 14 |    INDEX UNIQUE SCAN            | PRODUCTS_PK  |     1 |       |     0   (0)| 00:00:01 |       |       |
|* 15 |   TABLE ACCESS BY INDEX ROWID   | PRODUCTS     |     1 |    47 |     1   (0)| 00:00:01 |       |       |
----------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   6 - filter(SUM("S"."AMOUNT_SOLD")>20000)
  11 - access("AGG_Q"."CUST_ID"="C"."CUST_ID")
  12 - filter("CO"."COUNTRY_NAME"='Japan')
  13 - access("C"."COUNTRY_ID"="CO"."COUNTRY_ID")
  14 - access("AGG_Q"."PROD_ID"="P"."PROD_ID")
  15 - filter("P"."PROD_CATEGORY"='Photo')

最適化後のSQL(10053トレース)

SELECT
    "C"."CUST_ID" "CUST_ID",
    "C"."CUST_FIRST_NAME" "CUST_FIRST_NAME",
    "C"."CUST_LAST_NAME" "CUST_LAST_NAME",
    "C"."CUST_EMAIL" "CUST_EMAIL",
    "P"."PROD_NAME" "PROD_NAME",
    SUM("S"."AMOUNT_SOLD") "TOTAL_AMT_SOLD"
FROM
    "SH"."SALES" "S",
    "SH"."CUSTOMERS" "C",
    "SH"."COUNTRIES" "CO",
    "SH"."PRODUCTS" "P"
WHERE
    "CO"."COUNTRY_NAME" = 'Japan'
AND "P"."PROD_CATEGORY" = 'Photo'
AND "S"."PROD_ID" = "P"."PROD_ID"
AND "C"."COUNTRY_ID" = "CO"."COUNTRY_ID"
AND "S"."CUST_ID" = "C"."CUST_ID"
GROUP BY
    "S"."CUST_ID",
    "S"."PROD_ID",
    "P".ROWID,
    "CO".ROWID,
    "C".ROWID,
    "P"."PROD_NAME",
    "C"."CUST_EMAIL",
    "C"."CUST_LAST_NAME",
    "C"."CUST_FIRST_NAME",
    "C"."CUST_ID"
HAVING SUM("S"."AMOUNT_SOLD") > 20000

関連パラメータ

_complex_view_merging
optimizer_secure_view_merging

参考資料

Expert Oracle SQL

Expert Oracle SQL: Optimization, Deployment, and Statistics

Expert Oracle SQL: Optimization, Deployment, and Statistics

https://docs.oracle.com/cd/E96517_01/tgsql/index.html
Oracle(R) Database SQLチューニング・ガイド 18c

Oracle 問合せ変換②-1 ビュー・マージ(Simple View Merging)

Oracle 問合せ変換②-1 ビュー・マージ(Simple View Merging)

概要

Oracleの問合せ変換の中の「ビュー・マージ(View Merging)」について記載します。
今回の実行例は、Simple View Merging編です。
- Simple View Merging:単純な結合のクエリブロックをマージするために使用される
- Complex View Merging:集計を含むクエリブロックをマージするために使用される要は、GROUP BYもしくはDISTINCTを含むビューがマージされる

目的

SQL内でビュー(インライン・ビューを含む)と実表とを結合するような場合、はじめにビューへの問合せが実行されます。しかしながら、それが非効率でパフォーマンスが出ない(※)場合があります。
※例:結合順序が悪い、元表のインデックスが使用できない

上記のような場合に、ビューに対する問合せをビューの元表に直接問い合わせるSELECT文に変換し、
そのSELECT文をユーザがビューに対して実行した問合せ内に組み入れる(マージ)ことで
オプティマイザが選択可能な実行計画の幅を拡げます。
例えば、ビューを元表へのSELECT文に変換したことで、ビュー→テーブルという結合順序を
テーブル→ビュー(SELECT変換後)のようにしたり、元表の索引が使用できるようになります。

実行例

Simple view merging

WITH q1
     AS (SELECT 
               CASE prod_category
                   WHEN 'Electronics' THEN amount_sold * 0.9
                   ELSE amount_sold
                END
                   AS adjusted_amount_sold
           FROM sh.sales JOIN sh.products USING (prod_id))
  SELECT adjusted_amount_sold, COUNT (*) cnt
    FROM q1
GROUP BY adjusted_amount_sold;

-------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                | Name                 | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     | Pstart| Pstop |
-------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT         |                      | 12679 |   371K|       |  3237   (2)| 00:00:01 |       |       |
|   1 |  HASH GROUP BY           |                      | 12679 |   371K|    35M|  3237   (2)| 00:00:01 |       |       |
|*  2 |   HASH JOIN              |                      |   918K|    26M|       |   522   (2)| 00:00:01 |       |       |
|   3 |    VIEW                  | index$_join$_002     |    72 |  1512 |       |     2   (0)| 00:00:01 |       |       |
|*  4 |     HASH JOIN            |                      |       |       |       |            |          |       |       |
|   5 |      INDEX FAST FULL SCAN| PRODUCTS_PK          |    72 |  1512 |       |     1   (0)| 00:00:01 |       |       |
|   6 |      INDEX FAST FULL SCAN| PRODUCTS_PROD_CAT_IX |    72 |  1512 |       |     1   (0)| 00:00:01 |       |       |
|   7 |    PARTITION RANGE ALL   |                      |   918K|  8075K|       |   517   (2)| 00:00:01 |     1 |    28 |
|   8 |     TABLE ACCESS FULL    | SALES                |   918K|  8075K|       |   517   (2)| 00:00:01 |     1 |    28 |
-------------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("SALES"."PROD_ID"="PRODUCTS"."PROD_ID")
   4 - access(ROWID=ROWID)

変換されていない実行計画(NO_MERGE)

WITH q1
     AS (SELECT /*+ NO_MERGE */
               CASE prod_category
                   WHEN 'Electronics' THEN amount_sold * 0.9
                   ELSE amount_sold
                END
                   AS adjusted_amount_sold
           FROM sh.sales JOIN sh.products USING (prod_id))
  SELECT adjusted_amount_sold, COUNT (*) cnt
    FROM q1
GROUP BY adjusted_amount_sold;

Plan hash value: 2089506595

------------------------------------------------------------------------------------------------------------------
| Id  | Operation                 | Name                 | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT          |                      |   918K|    11M|   546   (7)| 00:00:01 |       |       |
|   1 |  HASH GROUP BY            |                      |   918K|    11M|   546   (7)| 00:00:01 |       |       |
|   2 |   VIEW                    |                      |   918K|    11M|   522   (2)| 00:00:01 |       |       |
|*  3 |    HASH JOIN              |                      |   918K|    26M|   522   (2)| 00:00:01 |       |       |
|   4 |     VIEW                  | index$_join$_002     |    72 |  1512 |     2   (0)| 00:00:01 |       |       |
|*  5 |      HASH JOIN            |                      |       |       |            |          |       |       |
|   6 |       INDEX FAST FULL SCAN| PRODUCTS_PK          |    72 |  1512 |     1   (0)| 00:00:01 |       |       |
|   7 |       INDEX FAST FULL SCAN| PRODUCTS_PROD_CAT_IX |    72 |  1512 |     1   (0)| 00:00:01 |       |       |
|   8 |     PARTITION RANGE ALL   |                      |   918K|  8075K|   517   (2)| 00:00:01 |     1 |    28 |
|   9 |      TABLE ACCESS FULL    | SALES                |   918K|  8075K|   517   (2)| 00:00:01 |     1 |    28 |
------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   3 - access("SALES"."PROD_ID"="PRODUCTS"."PROD_ID")
   5 - access(ROWID=ROWID)

最適化後のSQL(10053トレース)

Final query after transformations:******* UNPARSED QUERY IS *******
SELECT
    CASE "PRODUCTS"."PROD_CATEGORY"
        WHEN 'Electronics' THEN "SALES"."AMOUNT_SOLD" * 0.9
        ELSE "SALES"."AMOUNT_SOLD"
    END "ADJUSTED_AMOUNT_SOLD",
    COUNT(*) "CNT"
FROM
    "SH"."SALES" "SALES",
    "SH"."PRODUCTS" "PRODUCTS"
WHERE
    "SALES"."PROD_ID" = "PRODUCTS"."PROD_ID"
GROUP BY
    CASE "PRODUCTS"."PROD_CATEGORY"
        WHEN 'Electronics' THEN "SALES"."AMOUNT_SOLD" * 0.9
        ELSE "SALES"."AMOUNT_SOLD"
    END

関連パラメータ

optimizer_secure_view_merging

参考資料

Expert Oracle SQL

Expert Oracle SQL: Optimization, Deployment, and Statistics

Expert Oracle SQL: Optimization, Deployment, and Statistics

https://docs.oracle.com/cd/E96517_01/tgsql/index.html
Oracle(R) Database SQLチューニング・ガイド 18c

スポンサーリンク