5 コンテナおよびイメージの操作

この章では、Docker Engineを使用してコンテナを実行する方法およびコンテナの作成に使用するイメージの取得方法について説明します。コンテナおよびイメージの構成に固有のその他の情報も示します。この章では、Oracle Linux 7でイメージおよびコンテナがホストされていることを前提としています。

コンテナ・レジストリからのOracle Linuxイメージのプル

Docker Engine上で実行するOracle LinuxイメージをDocker Hubのoraclelinuxリポジトリから取得できます。入手可能なOracle Linuxイメージのリストは、https://hub.docker.com/_/oraclelinux/を参照してください。

Docker HubまたはOracle Container Registryからイメージをプルするには、インターネット接続が必要です。プロキシ・サーバーを使用してインターネットにアクセスする場合は、「プロキシ・サーバーの構成」を参照してください。

Oracle Linuxイメージは、他の多くのOracle製品イメージとともに、Oracle Container Registry (https://container-registry.oracle.com)およびDocker Hub (https://hub.docker.com)でホストされています。Oracle Container Registryを使用してイメージをプルする方法の詳細は、「Oracle Container Registryからのイメージのプル」を参照してください。Docker Hubを使用する方法の詳細は、「サードパーティ・レジストリの使用方法」を参照してください。

Oracle Linuxイメージをダウンロードするには、docker pullコマンドを使用します。たとえば、Docker HubからOracle Linuxイメージをプルするには、次のようにします。

docker pull oraclelinux:7-slim
Trying to pull repository docker.io/library/oraclelinux ... 
7-slim: Pulling from docker.io/library/oraclelinux
977461c90301: Pull complete 
Digest: sha256:0743f72832d8744a89b7be31b38b9fb2e5390044cbb153cd97b3e797723e4704
Status: Downloaded newer image for oraclelinux:7-slim

システムにダウンロード済のイメージのリストを表示するには、次のようにdocker imagesコマンドを使用します。

docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
oraclelinux         7-slim              c2b5cb5bcd9d        7 days ago          118MB
oraclelinux         7                   31f4bed1dc33        7 days ago          232MB
oraclelinux         latest              31f4bed1dc33        7 days ago          232MB
oraclelinux         8                   8988c7081e1f        5 weeks ago         411MB

リポジトリ内の各イメージは、TAGの値と一意のIMAGE IDで識別されます。この例では、タグ7およびlatestはOracle Linux 7の同じイメージIDを参照します。

Oracle Linuxの更新用の新しいイメージが使用可能になると、oraclelinuxリポジトリ内のタグ78およびlatestが、該当する最新のバージョンを指すように更新されます。

イメージを代替レジストリからデフォルト・レジストリにダウンロードする場合、REPOSITORY値はイメージのプル元のレジストリも示します。たとえば:

docker images
REPOSITORY                                     TAG        IMAGE ID        CREATED       SIZE
container-registry.oracle.com/os/oraclelinux   latest     31f4bed1dc33    7 days ago    232MB

レジストリの追加およびデフォルト・レジストリの構成の詳細は、「コンテナ・レジストリ・オプションの設定」を参照してください。

 Docker Content Trustの有効化または無効化

Content Trustでは、Docker Hub Registryで使用可能になったDockerイメージの信憑性、整合性および公開日を検証できます。

デフォルトでは、Content Trustは無効になっています。Docker Hubのビルド、プッシュまたはプルを行うDockerイメージの署名および検証のためにContent Trustを有効にするには、たとえば次のように、DOCKER_CONTENT_TRUST環境変数を設定します。

export DOCKER_CONTENT_TRUST=1                  

sudoを使用してDockerコマンドを実行する場合、-Eオプションを指定して環境を保持するか、visudoを使用して次の行を/etc/sudoersに追加します。

Defaults        env_keep += "DOCKER_CONTENT_TRUST"

個々のdocker builddocker pushまたはdocker pullコマンドに対して、--disable-content-trust=falseおよび--disable-content-trust=trueオプションを指定して、Content Trustを有効化または無効化できます。

詳細は、https://docs.docker.com/engine/security/trust/content_trust/を参照してください。

コンテナでのFIPSモードの有効化

FIPSモードでコンテナを実行するには、まずOracle Linuxホスト・システムでFIPSモードを有効にする必要があります。

インストール可能なFIPS検証済暗号化モジュールがあるOracle Linux 7のリリースの詳細は、Oracle Linux 7: セキュリティ・ガイドを参照してください。

ノート:

Oracleは、slim-fipsタグを使用してFIPS準拠のコンテナ・イメージを提供します。FIPS準拠のタグが付いたコンテナ・イメージには、準拠した暗号化パッケージ・バージョンおよびコンテナFIPSモードに必要な初期イメージ設定が含まれています。詳細は、slimタグを参照してください。

Oracle Linux 7コンテナの場合:

Oracle Linux 7コンテナでFIPSモードを有効にするには、dracut-fipsパッケージをインストールするか、/etc/system-fipsをホストからをマウントします。コンテナ内からホスト・ファイルとディレクトリをマウントする方法の詳細は、「Dockerコンテナからの外部ファイルへのアクセス」を参照してください。

Oracle Linux 8コンテナの場合:

Oracle Linux 8コンテナでFIPSモードを有効にするには、/etc/system-fipsをホストからをマウントします。コンテナ内からホスト・ファイルとディレクトリをマウントする方法の詳細は、「Dockerコンテナからの外部ファイルへのアクセス」を参照してください。

さらに、コンテナ内のFIPS暗号化ポリシーを、/usr/share/crypto-policies/back-ends/FIPSから/etc/crypto-policies/back-endsにマウントします。

mount --bind /usr/share/crypto-policies/back-ends/FIPS /etc/crypto-policies/back-ends               

 Dockerコンテナの作成および実行

コンテナ内でアプリケーションを実行するには、次のようにdocker runコマンドを使用します。

docker run -i -t --name guest oraclelinux:7-slim
bash-4.2# cat /etc/oracle-release
Oracle Linux Server release 7.7
bash-4.2# exit              

この例では、oraclelinux:7-slimという名前のOracle Linux 7イメージを使用して対話型のbashシェルを実行し、コンテナを提供します。/bin/bashコマンドは、すべてのoraclelinuxベース・イメージに対して実行されるデフォルトのコマンドです。-tオプションと-iオプションを指定すると、擬似端末を使用してコンテナを対話的に実行できます。

次の例では、ホストとコンテナによってそれぞれ表示されるプロンプトを表すために、プロンプト[root@host ~] and [root@guest ~] (または同様のもの)を使用します。コンテナによって表示される実際のプロンプトは異なる場合があります。

--nameオプションでは、コンテナ・インスタンスの名前guestを指定します。

コンテナは終了時にDockerによって削除されないので、後で再起動できます。次に例を示します。

[root@host ~]# docker start guest
guest

イメージがまだシステムにない場合、Docker Engineはdocker pull操作を実行して、Docker Hubから(または指定した別のリポジトリから)イメージをダウンロードします(次の例を参照)。

[root@host ~]# docker run -i -t --rm container-registry.oracle.com/os/oraclelinux:7-slim

Unable to find image 'container-registry.oracle.com/os/oraclelinux:7-slim' locally
Trying to pull repository container-registry.oracle.com/os/oraclelinux ... 
7-slim: Pulling from container-registry.oracle.com/os/oraclelinux
Digest: sha256:267f37439471f1c5eae586394c85e743b887c7f97e4733e10e466158083c021e
Status: Downloaded newer image for container-registry.oracle.com/os/oraclelinux:7-slim
[root@guest /]# cat /etc/oracle-release 
Oracle Linux Server release 7.7
[root@guest /]# exit
exit
[root@host ~]# 

コンテナの名前を指定するかわりに、--rmオプションを指定したので、コンテナは終了時にDockerによって削除され、再起動できません。

次のように、別のシェル・ウィンドウからdocker psコマンドを使用して、現在実行中のコンテナに関する情報を表示できます。

[root@host ~]# docker ps
CONTAINER ID  IMAGE               COMMAND     CREATED       STATUS        PORTS  NAMES
68359521c0b7  oraclelinux:7-slim  "/bin/bash" 2 hours ago   Up 8 minutes         guest

IDが68359521c0b7guestという名前のコンテナは、現在コマンド/bin/bashを実行しています。コンテナの管理には、IDよりも名前を使用する方が便利です。

コンテナで実行中のプロセスを表示するには、docker topコマンドを使用します。

[root@host ~]# docker top guest
UID    PID    PPID   C   STIME   TTY     TIME       CMD
root   31252  31235  0   05:59   pts/0   00:00:00   /bin/bash

次のようにdocker execコマンドを使用して、すでに実行中のコンテナ内で追加のプロセスを実行できます。

[root@host ~]# docker exec -i -t guest bash
[root@guest ~]#

また、次のようにdocker createコマンドを使用して、コンテナを後で開始できるように設定できます。

[root@host ~]# docker create -i -t --name newguest oraclelinux:7-slim
b4c224f83e35927f67b973febb006b0af4d037f41c30e1f4bdcc4b822e12fd0f
[root@host ~]# docker start -a -i newguest
[root@newguest ~]#

docker start-aオプションと-iオプションを指定すると、現在のシェルの標準入力、出力およびエラー・ストリームはコンテナの標準入力、出力およびエラー・ストリームにアタッチされ、また、すべてのシグナルがコンテナに転送されるようになります。

コンテナを終了するには、コンテナ内でbashコマンド・プロンプトにCtrl-Dまたはexitと入力するか、docker stopコマンドを使用します。

[root@host ~]# docker stop guest

docker ps-aオプションを指定すると、現在実行中または終了済のすべてのコンテナが表示されます。

[root@host ~]# docker ps -a
CONTAINER ID  IMAGE              COMMAND  CREATED  STATUS                     PORTS  NAMES
b4c224f83e35  oraclelinux:7-slim ...      ...      Exited (0) About a minute ago     newguest
68359521c0b7  oraclelinux:7-slim ...      ...      Exited (137) 45 seconds ago       guest

docker startを使用して、停止されているコンテナを再起動できます。再アタッチ後のコンテナのコンテンツは、前回使用時のまま変更されていません。

[root@host ~]# docker start -a -i guest
[root@guest ~]# touch /tmp/foobar
[root@guest ~]# exit
[root@host ~]# docker start -a -i guest
[root@guest ~]# ls -l /tmp/foobar
-rw-r--r-- 1 root root 0 Nov 26 06:27 /tmp/foobar

コンテナでは加えられた変更はすべて保持されるので、変更の消失を懸念することなく、コンテナ内でファイルの再構成やパッケージのインストールを行えます。

次のように、docker logsコマンドを使用して、コンテナ内で発生しているイベントをウォッチできます。

[root@host ~]# docker logs -f guest
bash-4.2# exit
exit
bash-4.2# ls -l /tmp/foobar
-rw-r--r-- 1 root root 0 Nov 26 06:33 /tmp/foobar

-fオプションを指定すると、コンテナ内でイベントが発生した際にコマンドによって出力が更新されます。Ctrl-Cと入力してコマンドを終了します。

docker inspectコマンドを使用すると、コンテナに関する詳細情報をJSON形式で取得できます。このコマンドでは、次のように構成の特定の要素を取得することもできます。

[root@host ~]# docker inspect --format='{{ .State.Running }}' guest

同じ名前の新しいコンテナを作成できるように、コンテナを完全に削除する必要がある場合は、docker rmコマンドを使用します。

[root@host ~]# docker rm guest

ノート:

--rmオプションを指定してコンテナを実行すると、Dockerは該当するコンテナが存在する場合にそのコンテナを削除します。--rmオプションと-dオプションは併用できません。

-fオプションをdocker rmに指定すると、実行中のコンテナが強制終了してから削除されます。以前のバージョンで同じコマンドを実行すると、コンテナは削除前に停止されます。コンテナを安全に停止するには、docker stopを使用してください。

 Dockerがコンテナを再起動する処理の構成

コンテナの終了時にDockerでコンテナを処理する方法を指定するには、--restartオプションを使用してdocker runおよびdocker createを実行します。

--restart=always

Dockerはコンテナが終了すると常にコンテナの再起動を試行します。

--restart=no

Dockerはコンテナの終了時にコンテナの再起動を試行しません。これはデフォルトのポリシーです。

--restart=on-failure[:max-retry ]

Dockerは、コンテナがゼロ(0)以外の終了コードを返すと、コンテナの再起動を試行します。オプションで、Dockerがコンテナを再起動する最大試行回数を指定できます。

 機能の制御およびコンテナにホスト・デバイスの使用を許可する方法

--privileged=trueオプションをdocker createまたはdocker runに指定すると、コンテナはホスト上のすべてのデバイスにアクセスできるので、セキュリティ・リスクを招く可能性があります。より正確に制御するには、次のように--cap-addオプションと--cap-dropオプションを使用して、コンテナの機能を制限します。

[root@host ~]# docker run --cap-add=ALL --cap-drop=NET_ADMIN -i -t --rm oraclelinux:7
[root@guest /]# ip route del default
RTNETLINK answers: Operation not permitted

この例では、NET_ADMIN以外のすべての機能をコンテナに付与し、コンテナがネットワーク管理操作を実行できないようにします。詳細は、capabilities(7)マニュアル・ページを参照してください。

ホスト上の個別のデバイスのみをコンテナで使用できるようにするには、--deviceオプションを使用してdocker runおよびdocker createを実行します。

--device=host_devname [:container_devname [:permissions ]]

host_devnameはホスト・デバイスの名前です。

container_devnameはコンテナ内のデバイスの名前に対するオプション名です。

permissionsは次のコードの組合せで、デバイスに対するコンテナの権限を指定します(オプション)。

m

mknod権限を付与します。たとえば、mknodを使用すると、デバイス・ファイルの権限ビットまたはSELinuxコンテキストを設定できます。

r

読取り権限を付与します。

w

書込み権限を付与します。たとえば、mkfsなどのコマンドを使用して、デバイスをフォーマットできます。

たとえば、--device=/dev/sdd:/dev/xvdd:rは、ホスト・デバイス/dev/sddをデバイス/dev/xvddとして読取り専用権限でコンテナが使用できるようにします。

注意:

システムから簡単に取り外せるブロック・デバイスは、信用できないコンテナに対して使用可能にしないでください。

 ホストのプロセスIDネームスペースへのアクセス

docker run--pid=hostオプションを指定すると、コンテナ内からホストのプロセスIDネームスペースを参照できるようになります。このモードの推奨される用途は、コンテナ化されたデバッグ・ツールを使用したホスト・プロセスのデバッグです。

注意:

ホスト・モードは、コンテナにD-Busやホスト上の他のシステム・サービスへの完全なアクセスを提供するため、本質的に安全ではありません。

読取り専用モードでのホストのrootファイル・システムのマウント

docker createまたはdocker run--read-only=trueオプションを指定することによって、コンテナからホストのrootファイル・システムを読取り専用モードでマウントできます。このモードを使用して、コンテナ化されたアプリケーションによる書込みアクセス権を制限できます。

既存コンテナからのDockerイメージの作成

コンテナのコンテンツを変更する場合、docker commitコマンドを使用すると、コンテナの現在の状態をイメージとして保存できます。

次の例は、oraclelinux:7-slimイメージをベースとするコンテナを、Apache HTTPサーバーが実行できるように変更する方法を示しています。コンテナを停止した後で、そのイメージmymod/httpd:v1が作成されます。

ヒント:

oraclelinux:7-slimおよびoraclelinux:8-slimイメージは、Oracle Linux 7およびOracle Linux 8に必要な最小限のオペレーティング・システムを提供します。これらのイメージを使用すると、それらをベースとするコンテナを実行する際にリソースの使用量を減らすことができます。また、作成するイメージがアプリケーションの基本要件に制限されるようにすることもできます。

oraclelinux:7-slimコンテナからApacheサーバー・イメージを作成するには:

  1. httpd1という名前のコンテナ内でbashシェルを実行します。

    docker run -i -t --name httpd1 oraclelinux:7-slim /bin/bash
    [root@httpd1 ~]#
  2. Webプロキシを使用する場合は、Oracle Linux 7: ソフトウェアの管理で説明されているように、ゲスト上のyumの構成を編集します。

  3. httpdパッケージをインストールします。

    [root@httpd1 ~]# yum -y install httpd
  4. 必要な場合は、ゲスト上の/var/www/htmlディレクトリ階層以下に表示するWebコンテンツを作成します。

  5. 単に対話型ゲスト・セッション内からexitコマンドを使用するだけでゲストを終了できます。

    [root@httpd1 ~]# exit
    exit

    あるいは、ホスト上でdocker stopコマンドを使用します。

    docker stop httpd1
  6. 停止したコンテナのIDを使用して、タグv1の付いたイメージmymod/httpdを作成します。

    docker commit -m "ol7-slim + httpd" -a "A N Other" \
      `docker ps -l -q` mymod/httpd:v1
    sha256:b03fbc3216882a25e32c92caa2e797469a1ac98e5fc90affa07263b8cb0aa799

    イメージにメモや作成者を記述するには、-mオプションと-aオプションを使用します。このコマンドでは、新しいイメージのIDの完全バージョンが返されます。

    ヒント:

    docker ps -l -qコマンドは、最後に作成されたコンテナのIDを返します。例では、このコマンドを使用して、イメージの生成に使用するコンテナのIDを取得しています。あるいは、IDを直接指定したり、このコマンドで代替のバリエーションを使用して正しいIDを取得することもできます。

    ここでdocker imagesコマンドを使用すると、新しいイメージがリストに表示されます。

    docker images        
    REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    mymod/httpd         v1                  b03fbc321688        2 minutes ago       426MB
    oraclelinux         7-slim              c2b5cb5bcd9d        7 days ago          118MB
  7. httpd1という名前のコンテナを削除します。

    docker rm httpd1

これで、次のように新しいイメージを使用して、Webサーバーとして機能するコンテナを作成できます。

docker run -d --name newguest -p 8080:80 mymod/httpd:v1 /usr/sbin/httpd -D FOREGROUND

-dオプションを使用すると、コマンドはバックグラウンドで非対話的に実行され、一意のコンテナIDの完全バージョンが表示されます。-p 8080:80オプションは、ゲストのポート80をホストの8080にマップします。docker psを実行すると、ポート・マッピングを表示できます。次に例を示します。

docker ps
CONTAINER ID  IMAGE           COMMAND                 CREATED        STATUS        PORTS                 NAMES
154f05ea464e  mymod/httpd:v1  "/usr/sbin/httpd -D …"  2 minutes ago  Up 2 minutes  0.0.0.0:8080->80/tcp  newguest

かわりにdocker portコマンドを使用することもできます。次に例を示します。

docker port newguest 80
0.0.0.0:8080

ノート:

docker psコマンドでは、コンテナIDの短縮バージョンが表示されます。--no-truncオプションを使用すると、長いバージョンを表示できます。

デフォルトのIPアドレスの値0.0.0.0は、ホスト上のすべてのネットワーク・インタフェースにポート・マッピングが適用されることを意味します。再マッピングの適用先のIPアドレスを制限するには、次のように複数の-pオプションを使用します。

docker run -d --name newguest -p 127.0.0.1:8080:80 -p 192.168.1.2:8080:80 \
  mymod/httpd:v1 /usr/sbin/httpd -D FOREGROUND               

ゲストが提供しているWebコンテンツを表示するには、ブラウザがホストのポート8080を参照するように指定します。別のシステムからコンテンツにアクセスする場合は、次のようにホストのポートに対する着信接続の許可が必要になる可能性があります。

firewall-cmd --zone=public --permanent --add-port=8080/tcp               

イメージを削除する必要がある場合は、docker rmiコマンドを使用します。

docker rmi mymod/httpd:v1
Untagged: mymod/httpd:v1
Deleted: sha256:b03fbc3216882a25e32c92caa2e797469a1ac98e5fc90affa07263b8cb0aa799
Deleted: sha256:f10c5b69ca9c3df53412238eefac72522720bc7c1a6a8eb6d21801c23a81c126

ノート:

実行中のコンテナのイメージは削除できません。

本番環境でdocker commitコマンドを使用してイメージを作成すると、そのイメージの作成手順を記録できる便利な方法がないので、消失や破損したイメージの再作成が困難になる場合があります。イメージを作成する場合の推奨方法は、Dockerfileを設定して、ユーザーのかわりにDockerがイメージをビルドできるように命令を定義することです。「DockerfileからのDockerイメージの作成」を参照してください。

DockerfileからのDockerイメージの作成

Dockerfileに含まれている定義からDockerfileイメージを作成するには、docker buildコマンドを使用します。

次の例は、oraclelinux:7-slimイメージをベースとするタグv2の付いたmymod/httpdという名前のイメージをビルドして、Apache HTTPサーバーが実行できるようにする方法を示しています。

DockerfileからDockerイメージを作成するには:

  1. 次のようにして、Dockerfileの生成先ディレクトリを作成します。

    mkdir -p /var/docker_projects/mymod/httpd                     

    ノート:

    イメージから作成するコンテナのデプロイ先と同じシステムにDockerfileを作成する必要はありません。唯一の要件は、Docker EngineがDockerfileファイルにアクセスできることです。

  2. 新しいディレクトリに、通常はDockerfileという名前が付けられるDockerfileを作成します。次のDockerfileのコンテンツは、この例専用です。

    # Dockerfile that modifies oraclelinux:7-slim to include an Apache HTTP server
    FROM oraclelinux:7-slim
    MAINTAINER A N Other <another@example.com>
    RUN sed -i -e '/^\[main\]/aproxy=http://proxy.example.com:80' /etc/yum.conf
    RUN yum -y install httpd
    RUN echo "HTTP server running on guest" > /var/www/html/index.html
    EXPOSE 80
    ENTRYPOINT /usr/sbin/httpd -D FOREGROUND

    先頭行の#接頭辞は、その行がコメントであることを示します。その他の行は次の命令キーワードで始まり、Dockerによるイメージの作成方法を定義します。

    ENTRYPOINT

    イメージから作成されたコンテナが常に実行するコマンドを指定します。この例では、/usr/sbin/httpd -D FOREGROUNDがコマンドで、HTTPサーバー・プロセスを開始します。

    EXPOSE

    指定されたポートが着信リクエストに対応できることを示します。docker run-pオプションまたは-Pオプションを使用すると、このポートをホストの別のポートにマップできます。また、docker run--linkオプションを使用して、別のコンテナをDockerの内部ネットワーク経由でポートにアクセスできるようにすることも可能です(「Dockerコンテナ間の通信」を参照)。

    FROM

    Dockerが新しいイメージのベースとして使用するイメージを定義します。

    MAINTAINER

    Dockerfileの管理者を定義します。

    RUN

    新しいイメージを変更する際にDockerが実行するコマンドを定義します。この例では、RUN行でWebプロキシを設定し、httpdパッケージをインストールして、サーバー用の簡易ホーム・ページを作成します。

    Dockerfileで使用可能なその他の命令の詳細は、https://docs.docker.com/engine/reference/builder/を参照してください。

  3. docker buildコマンドを使用してイメージを作成します。

    docker build --tag="mymod/httpd:v2" /var/docker_projects/mymod/httpd/
    Sending build context to Docker daemon  2.048kB
    Step 1/6 : FROM oraclelinux:7-slim
    Trying to pull repository docker.io/library/oraclelinux ... 
    7-slim: Pulling from docker.io/library/oraclelinux
    a8d84c1f755a: Pull complete 
    Digest: sha256:d574213fa96c19ae00269730510c4d81a9979ce2a432ede7a62b62d594cc5f0b
    Status: Downloaded newer image for oraclelinux:7-slim
     ---> c3d869388183
    Step 2/6 : MAINTAINER A N Other <another@example.com>
     ---> Running in 26b0ba9f45e8
    Removing intermediate container 26b0ba9f45e8
     ---> f399f426b849
    Step 3/6 : RUN yum -y install httpd
     ---> Running in d75a9f312202
    Loaded plugins: ovl
    Resolving Dependencies
    --> Running transaction check
    ---> Package httpd.x86_64 0:2.4.6-88.0.1.el7 will be installed
    ...
    Complete!
    Removing intermediate container d75a9f312202
     ---> aa3ab87bcae3
    Step 4/6 : RUN echo "HTTP server running on guest" > /var/www/html/index.html
     ---> Running in dddedfc56849
    Removing intermediate container dddedfc56849
     ---> 8fedc8516013
    Step 5/6 : EXPOSE 80
     ---> Running in 6775d6e3996f
    Removing intermediate container 6775d6e3996f
     ---> 74a960cf0ae9
    Step 6/6 : ENTRYPOINT /usr/sbin/httpd -D FOREGROUND
     ---> Running in 8b6e6f61a2c7
    Removing intermediate container 8b6e6f61a2c7
     ---> b29dea525f0a
    Successfully built b29dea525f0a
    Successfully tagged mymod/httpd:v2

イメージがビルドされたら、httpd2という名前のコンテナ・インスタンスを作成してテストできます。

docker run -d --name httpd2 -P mymod/httpd:v2

ノート:

/usr/sbin/httpd -D FOREGROUNDはコンテナに組み込まれているので、このコマンドを指定する必要はありません。

-Pオプションは、Dockerがゲストによって公開されているポートを、ホスト上のランダムに使用可能な(30000を超える)高位ポートにマップすることを指定します。

docker inspectを使用すると、DockerがTCPポート80にマップするホスト・ポートが返されます。

docker inspect --format='{{ .NetworkSettings.Ports }}' httpd2
map[80/tcp:[map[HostIp:0.0.0.0 HostPort:49153]]]

この例では、ゲストのTCPポート80はホストのTCPポート49153にマップされています。

ゲストが提供しているWebコンテンツを表示するには、ブラウザがホストのポート49153を参照するように指定します。別のシステムからコンテンツにアクセスする場合は、ホストのポートに対する着信接続の許可が必要になる可能性があります。

ポートを開くには、ファイアウォールを更新します。

firewall-cmd --add-port=49153/tcp
firewall-cmd --permanent --add-port=49153/tcp

curlを使用して、サーバーが機能していることをテストすることも可能です。

curl http://localhost:49153
HTTP server running on guest

マルチステージDockerイメージ・ビルドの作成

Oracle Container Runtime for Docker 17.06から、単一のDockerfileからマルチステージ・ビルドを実行できます。これにより、最終イメージにすべてのビルド・ツールおよびアーティファクトを含めることなく、最終イメージの作成時に中間ビルドまたはコンパイル・ステップを実行できます。これにより、イメージ・サイズを小さくし、パフォーマンスを高めることができます。また、必要なバイナリのみが含まれ、バイナリの生成に必要になったいずれのレイヤーも含まれていないイメージを提供することもできます。

この項では、非常に単純なシナリオ例を示します。プログラムのソースが中間コンパイラ・イメージ内にビルドされ、その結果生成されたバイナリが別個のイメージにコピーされて最終ターゲット・イメージが生成されるというものです。このビルド全体が単一のDockerfileによって処理されます。

次のテキストをhello.cという名前のファイルに貼り付けて、Cで簡単なhello world形式のプログラムを作成します。

#include <stdio.h>

int
main (void)
{
  printf ("Hello, world!\n");
  return 0;
}

次のテキストが含まれているDockerfileを作成します。

FROM gcc AS BUILD
COPY . /usr/src/hello
WORKDIR /usr/src/hello
RUN gcc -Wall hello.c -o hello

FROM oraclelinux:7-slim
COPY --from=BUILD /usr/src/hello/hello hello
CMD ["./hello"]

このDockerfileには2つのFROM行があります。最初のFROM文は、Docker Hubから最新のgccイメージをプルし、AS構文を使用してイメージに名前を割り当てます。これにより、後でこの一時ビルド環境からターゲット・イメージに要素をコピーする際にそのイメージを参照できます。

ビルド環境では、ソース・ファイルがイメージにコピーされ、ソース・ファイルに対してgccコンパイラが実行されて、helloバイナリが生成されます。

2番目のFROM文は、oraclelinux:7-slimイメージをプルします。このイメージは、ビルド環境から直接コピーされるhelloバイナリをホストするために使用します。これにより、ソース、コンパイラおよびその他のビルド・アーティファクトを最終イメージから除外できます。

新しいイメージを作成して実行するには、次を実行します。

docker build -t hello-world ./
Sending build context to Docker daemon  35.38MB
Step 1/7 : FROM gcc AS BUILD
 ---> 7d9419e269c3
Step 2/7 : COPY . /usr/src/hello
 ---> ee7310cc4464
Removing intermediate container 1d51e6f16833
Step 3/7 : WORKDIR /usr/src/hello
 ---> 2c0298733ba0
Removing intermediate container 46a09ccc06d6
Step 4/7 : RUN gcc -Wall hello.c -o hello
 ---> Running in f003deeebc20
 ---> 67c85367cac1
Removing intermediate container f003deeebc20
Step 5/7 : FROM oraclelinux:7-slim
 ---> da5e55a16f7a
Step 6/7 : COPY --from=BUILD /usr/src/hello/hello hello
 ---> 8bd284b0d7eb
Removing intermediate container d71eee578325
Step 7/7 : CMD ./hello
 ---> Running in d6051d9e0a9d
 ---> dac5aa2d651d
Removing intermediate container d6051d9e0a9d
Successfully built dac5aa2d651d
Successfully tagged hello-world:latest
docker run hello-world
Hello, world!

hello-worldイメージは、helloバイナリを格納および実行するために生成されますが、バイナリのビルドに必要になったコンポーネントは含まれません。最終イメージは、レイヤー数が少なく、サイズが小さく、ビルド・ステップが履歴に含まれません。

Dockerネットワークについて

Dockerネットワーク機能によって、別々のコンテナで実行中でも通信できる、セキュアなWebアプリケーションのネットワークを作成できます。デフォルトでは、Dockerは(docker network lsコマンドで表示されるとおり) 2種類のネットワークを構成します。

host

docker createまたはdocker runコマンドで--net=hostオプションを指定すると、Dockerはコンテナに対してホストのネットワーク・スタックを使用します。コンテナのネットワーク構成はそのホストの構成と同じであり、コンテナはホストで使用できるサービス・ポートを共有します。この構成では、コンテナのネットワーク分離は行われません。

bridge

デフォルトでは、Dockerはbridgeというブリッジ・ネットワークにコンテナをアタッチします。ホスト上でip link showなどのコマンドを実行すると、ブリッジはdocker0ネットワーク・インタフェースとして表示されます。ブリッジ・ネットワークを使用すると、個々のアプリケーション・コンテナに接続できます。docker network inspect bridgeコマンドでは、JSON形式で表示されるブリッジのネットワーク構成を調査できます。Dockerはブリッジ・ネットワークのデフォルトのサブネット・アドレス、ネットワーク・マスク、およびゲートウェイを設定し、ブリッジ・ネットワークに追加するコンテナにサブネット・アドレスを自動的に割り当てます。デフォルトのブリッジ・ネットワーク上のコンテナは、このネットワーク上で直接相互に通信できます。ただし、このネットワーク内にはドメイン名解決があり、コンテナが互いを明確に認識できるようになっています。

コンテナはブリッジ・ネットワークを介して他のコンテナと通信できますが、その他のネットワークには、そのネットワークをアタッチしないかぎり通信できません。コンテナが使用するネットワークを定義するには、各ネットワークの--net= bridge-network-nameオプションをdocker createまたはdocker runコマンドに指定します。実行中のコンテナをネットワークにアタッチするには、docker network connect network-name container-nameコマンドを使用できます。

docker network create --driver bridge bridge-network-nameコマンドを使用すると、外部ネットワークおよびその他のコンテナからアクセスできるコンテナ・ネットワーク・ポートを公開するユーザー定義ブリッジ・ネットワークを作成できます。--net= bridge-network-namedocker createまたはdocker runに指定して、このネットワークにコンテナをアタッチします。ユーザー定義ネットワークの詳細は、「Dockerコンテナ間の通信」を参照してください。

マルチホスト・ネットワークについて

ブリッジ・ネットワークではネットワークを分離できますが、複合ユーザー定義ブリッジを使用しないかぎり、単一ホスト・システムへのコンテナ接続は制限されます。Dockerには、マルチホスト・ネットワークをサポートするVXLANベースのoverlayネットワーク・ドライバが含まれており、複数のDockerホスト上で実行されている別々のアプリケーション・コンテナを、同一の仮想オーバーレイ・ネットワークにアタッチできます。オーバーレイ・ネットワークを作成する前に、Consul、Etcd、ZooKeeperなど、Dockerホストがアクセスして、構成情報を共有できるキー値(KV)サービスを構成する必要があります。次に、各ホストにDockerデーモンを構成して、該当する値を–cluster-advertiseおよび--cluster-storeオプションに指定し、KVサーバーにアクセスします。次に、いずれかのホスト上でdocker network create -driver overlay multihost-network-nameコマンドを使用して、オーバーレイ・ネットワークを作成します。オーバーレイ・ネットワークを作成したら、--net= multihost-network-namedocker createまたはdocker runに指定して、このネットワークにコンテナをアタッチできます。

詳細は、https://docs.docker.com/engine/userguide/networking/を参照してください。

 Dockerコンテナ間の通信

すべてのコンテナがデフォルトのブリッジ・ネットワークに自動的に追加され、Docker EngineによってIPアドレスが割り当てられます。つまり、ブリッジ・ネットワークを使用してコンテナ同士が直接効果的に通信できます。ただし、デフォルトのブリッジ・ネットワークには自動サービス検出がありません。コンテナがIPアドレスをコンテナ名で解決する必要がある場合は、かわりにユーザー定義ネットワークを使用する必要があります。

docker run--linkオプションを使用すると、サーバー・コンテナに関するネットワーク接続情報をクライアント・コンテナで使用できます。たとえば、クライアント・コンテナclient1をサーバー・コンテナhttpd_serverにリンクするには、次のように実行できます。

docker run --rm -t -i --name client1 --link http-server:server oraclelinux /bin/bash       

クライアント・コンテナはプライベート・ネットワーク・インタフェースを使用して、サーバー・コンテナの公開ポートにアクセスします。Dockerは、利用可能なインタフェースとポートを示したサーバー・コンテナに関する環境変数をクライアント・コンテナに設定します。サーバー・コンテナ名とIPアドレスは、アクセスを容易にするために、クライアント・コンテナの/etc/hostsにも設定されています。

--linkオプションは、レガシー機能とみなされており、将来のリリースでは非推奨になる可能性があります。ほとんどの場合、お薦めしません。

コンテナ間に通信を確立するために推奨される方法は、ユーザー定義ネットワークを構築することです。これらのネットワークでは、より優れた分離を実現し、DNSによりIPアドレスをコンテナ名で解決できます。様々なネットワーク・ドライバを使用できますが、最もよく使用されるのはデフォルトのブリッジ・ネットワークと同様に動作しながらも追加の機能を備えたブリッジ・ネットワークです。

次の例は、簡単なユーザー定義ネットワーク・ブリッジを作成する方法と、それにコンテナを接続してコンテナが相互に簡単に通信できるようにする方法を示しています。

  1. ブリッジ・ドライバを使用してネットワークを構築します。

    docker network create --driver bridge http_network

    この例では、ネットワークの名前はhttp_networkです。

    ネットワークが構築され、そのネットワークが使用しているドライバを確認できます。

    docker network ls
    NETWORK ID          NAME                DRIVER              SCOPE
    094c50739e14        bridge              bridge              local
    7eff8115af9a        host                host                local
    4a03450bf054        http_network        bridge              local
    457c4070f5a2        none                null                local

    また、ネットワーク・オブジェクトを調べて、詳細を確認することもできます。

    docker network inspect http_network
    [
        {
            "Name": "http_network",
            "Id": "4a03450bf054a6d4d4db52da36eab8d934d35bf961b3b3adb4fe20be54c0fdac",
            "Created": "2019-02-06T04:40:47.177691733-08:00",
            "Scope": "local",
            "Driver": "bridge",
            "EnableIPv6": false,
            "IPAM": {
                "Driver": "default",
                "Options": {},
                "Config": [
                    {
                        "Subnet": "172.18.0.0/16",
                        "Gateway": "172.18.0.1"
                    }
                ]
            },
            "Internal": false,
            "Attachable": false,
            "Ingress": false,
            "ConfigFrom": {
                "Network": ""
            },
            "ConfigOnly": false,
            "Containers": {},
            "Options": {},
            "Labels": {}
        }
    ]
  2. 既存のコンテナをユーザー定義ネットワークに接続します。

    docker network connect http_network http-server
    docker network connect http_network client1

    この例では、http-serverclient1は、新しく作成されたhttp_networkブリッジ・ネットワークに接続されている既存のコンテナです。

  3. --networkオプションを使用して、新しいコンテナをユーザー定義ネットワークに接続します。

    docker run --rm -t -i --name client2 --network http_network oraclelinux:7 /bin/bash 

    ドメイン名解決がコンテナ内から機能していることを確認するには、そのコンテナ名でネットワーク上の他のコンテナにpingを実行します。

    [root@client1 ~]# ping -c 1 http-server
                            
    PING http-server (172.18.0.2) 56(84) bytes of data.
    64 bytes from http-server.http_network (172.18.0.2): icmp_seq=1 ttl=64 time=0.162 ms
    
    --- http-server ping statistics ---
    1 packets transmitted, 1 received, 0% packet loss, time 0ms
    rtt min/avg/max/mdev = 0.162/0.162/0.162/0.000 ms

    コンテナ名を使用して、ネットワーク内のコンテナ上にあるサービスにアクセスできます。たとえば:

    [root@client1 ~]# curl http://http-server
    HTTP server running on guest

詳細は、https://docs.docker.com/engine/userguide/networking/を参照してください。

Dockerコンテナからの外部ファイルへのアクセス

docker run-vオプションを使用すると、コンテナ内でファイルまたはファイル・システムを利用できるようになります。次の例は、コンテナ内で実行中のHTTPサーバーが、ホスト上のWebページを利用できるようにする方法を示しています。

ホスト上でファイル/var/www/html/index.htmlを作成し、このファイルをマウントするHTTPサーバー・コンテナを実行します。

echo "This text was created in a file on the host" > /var/www/html/index.html
docker run -d --name newguest3 -P \
  -v /var/www/html/index.html:/var/www/html/index.html:ro mymod/httpd:v2

:ro修飾子は、コンテナがファイルまたはファイル・システムを読取り専用でマウントすることを指定します。ファイルまたはファイル・システムを読取り/書込み可能でマウントするには、かわりに:rw修飾子を指定するか、修飾子全体を省略します。

HTTPサーバーがホスト上で実行されていないことを確認します。

[root@host ~]# curl http://localhost
curl: (7) couldn't connect to host
[root@host ~]# systemctl status httpd
httpd is stopped

HTTPサーバーがホスト上で直接実行されていない場合でも、newguest3コンテナが提供している新しいWebページを表示できます。

docker inspect --format='{{ .NetworkSettings.Ports }}' newguest3
map[80/tcp:[map[HostIp:0.0.0.0 HostPort:49153]]]
[root@host ~]# curl http://localhost:49153
This text was created in a file on the host

ホスト上の/var/www/html/index.htmlファイルに加えた変更は、コンテナ内のマウント済ファイルに反映されます。

echo "Change the file on the host" > /var/www/html/index.html 
[root@host ~]# curl http://localhost:49153
Change the file on the host

ホスト上のファイルを削除しても、コンテナでは引き続き表示されます。

rm -f /var/www/html/index.html 
[root@host ~]# ls -l /var/www/html/index.html
ls: cannot access /var/www/html/index.html: No such file or directory
[root@host ~]# curl http://localhost:49153
Change the file on the host

ホストからファイルまたはファイル・システムをマウントする方法を定義するためにDockerfileは使用できません。Dockerアプリケーションは可搬性を目的としているので、元のホスト上に存在するファイルまたはファイル・システムを別のシステム上に用意することはありません。外部ファイル・データに可搬性を持たせるには、そのデータをデータ・ボリューム・コンテナでカプセル化します。「データ・ボリューム・コンテナの作成と使用方法」を参照してください。

 データ・ボリューム・コンテナの作成と使用方法

1つのディレクトリ引数をdocker run-vオプションに指定すると、Dockerはコンテナ内にディレクトリを作成し、data volumeとしてマークして、これを他のコンテナがマウントできます。DockerfileのVOLUME命令を使用して、このデータ・ボリュームをイメージに作成することも可能です。このようなデータ・ボリュームが含まれるコンテナをデータ・ボリューム・コンテナと呼びます。データ・ボリュームにファイルを移入後、docker run--volumes-fromオプションを使用すると、他のコンテナがこのボリュームをマウントしてそのデータにアクセスできるようになります。

ノート:

docker rmを使用してデータ・ボリュームに関連付けられているコンテナを削除する場合は、-vオプションを指定してこれらのボリュームを削除します。関連付けが解除されたボリュームは、ディスク・スペースの無駄になり、削除が困難になります。

次の例では、HTTPサーバー・コンテナがWebコンテンツのソースとして使用可能なデータ・ボリューム・コンテナを作成します。

データ・ボリューム・コンテナのイメージを作成し、そのイメージからデータ・ボリューム・コンテナのインスタンスを作成するには:

  1. 次のようにして、データ・ボリューム・コンテナ・イメージのDockerfileの生成先ディレクトリを作成します。

    mkdir -p /var/docker_projects/mymod/dvc                     
  2. 新しいディレクトリ内に、データ・ボリューム・コンテナのイメージを定義するDockerfileをDockerfileという名前で作成します。

    # Dockerfile that modifies oraclelinux:7-slim to create a data volume container
    FROM oraclelinux:7-slim
    MAINTAINER A N Other <another@example.com>
    RUN mkdir -p /var/www/html
    RUN echo "This is the content for file1.html" > /var/www/html/file1.html
    RUN echo "This is the content for file2.html" > /var/www/html/file2.html
    RUN echo "This is the content for index.html" > /var/www/html/index.html
    VOLUME /var/www/html
    ENTRYPOINT /usr/bin/tail -f /dev/null

    RUN命令では、3つの簡易ファイルが格納された/var/www/htmlディレクトリを作成します。

    VOLUME命令では、docker run--volumes-fromオプションを使用して、他のコンテナがマウント可能なボリュームとしてディレクトリを利用できるようにします。

    ENTRYPOINT命令では、イメージから作成されたコンテナが常に実行するコマンドを指定します。コンテナが終了しないように、ユーザーがdocker stop dvc1などのコマンドを使用してコンテナを停止するまで、/usr/bin/tail -f /dev/nullコマンドはブロックされます。

  3. docker buildコマンドを使用してイメージを作成します。

    docker build --tag="mymod/dvc:v1" /var/docker_projects/mymod/dvc/
    Sending build context to Docker daemon  2.048kB
    Step 1/8 : FROM oraclelinux:7-slim
     ---> c2b5cb5bcd9d
    Step 2/8 : MAINTAINER A N Other <another@example.com>
     ---> Running in 56c7b79c246e
    Removing intermediate container 56c7b79c246e
     ---> 620ff82e21cb
    Step 3/8 : RUN mkdir -p /var/www/html
     ---> Running in ac91306f3d74
    Removing intermediate container ac91306f3d74
     ---> 379c58d9eab9
    Step 4/8 : RUN echo "This is the content for file1.html" > /var/www/html/file1.html
     ---> Running in 981773ba0210
    Removing intermediate container 981773ba0210
     ---> 2ee97d83b582
    Step 5/8 : RUN echo "This is the content for file2.html" > /var/www/html/file2.html
     ---> Running in 36e8550c9a8b
    Removing intermediate container 36e8550c9a8b
     ---> 4ba8d28df981
    Step 6/8 : RUN echo "This is the content for index.html" > /var/www/html/index.html
     ---> Running in 6f15a403b4f6
    Removing intermediate container 6f15a403b4f6
     ---> 550bb92c154b
    Step 7/8 : VOLUME /var/www/html
     ---> Running in 1806e5d6e643
    Removing intermediate container 1806e5d6e643
     ---> 0e3de4ac4c9c
    Step 8/8 : ENTRYPOINT /usr/bin/tail -f /dev/null
     ---> Running in 6cde4f965504
    Removing intermediate container 6cde4f965504
     ---> 5e4e2780503b
    Successfully built 5e4e2780503b
    Successfully tagged mymod/dvc:v1
  4. データ・ボリューム・コンテナのインスタンスを作成します。たとえば dvc1:

    docker run -d --name dvc1 mymod/dvc:v1 tail -f /dev/null

他のコンテナがデータ・ボリューム(/var/www/html)をdvc1からマウントできることをテストするため、HTTPサーバーを実行してそのデータ・ボリュームをdvc1からマウントするwebsvrというコンテナを作成します。

docker run -d --volumes-from dvc1 --name websvr -P mymod/httpd:v2

ホストで使用する適切なポートを確認後、curlを使用して、websvrがイメージに設定されている3つのファイルすべてのコンテンツを正常に提供していることをテストします。たとえば:

[root@host ~]# docker port websvr 80
0.0.0.0:32769
[root@host ~]# curl http://localhost:32769
This is the content for index.html
[root@host ~]# curl http://localhost:32769/file1.html
This is the content for file1.html
[root@host ~]# curl http://localhost:32769/file2.html
This is the content for file2.html

 Dockerコンテナとホスト間のデータの移動

docker run-vオプションを使用して、データ・ボリューム・コンテナとホストとの間でボリューム・データをコピーできます。たとえば、同じデータ・ボリューム・コンテナにリストアしたり、別のデータ・ボリューム・コンテナにコピーしたりできるように、データをバックアップする場合があります。

この項の各例では、Dockerがデータ・ボリューム・コンテナ・イメージmymod/dvc:v1(「データ・ボリューム・コンテナの作成と使用方法」を参照)の2つのインスタンスを実行していることを前提としています。これらのコンテナを起動するには、次のコマンドを使用します。
docker run -d --name dvc1 mymod/dvc:v1
docker run -d --name dvc2 mymod/dvc:v1                 
データ・ボリュームからホストにデータをコピーするには、次のように、別のコンテナからボリュームをマウントし、cpコマンドを使用してデータをホストにコピーします。
docker run --rm --volumes-from dvc1 -v /var/tmp:/host:rw oraclelinux:7-slim \
   cp -r /var/www/html /host/dvc1_files

コンテナはホスト・ディレクトリ/var/tmp/hostとして読取り/書込み可能でマウントし、すべてのボリューム(dvc1がエクスポートする/var/www/htmlを含む)をマウントして、/var/www/html以下のファイル階層を、ホスト上の/var/tmp/dvc1_filesに対応する/host/dvc1_filesにコピーします。

dvc1のデータのバックアップをホストから別のデータ・ボリューム・コンテナdvc2にコピーするには、次のようなコマンドを使用します。

docker run --rm --volumes-from dvc2 -v /var/tmp:/host:ro \
  oraclelinux:7-slim cp -a -T /host/dvc1_files /var/www/html               

コンテナはホスト・ディレクトリ/var/tmp/hostとして読取り専用でマウントし、dvc2によってエクスポートされたボリュームをマウントして、/host/dvc1_files以下のファイル階層(ホスト上の/var/tmp/dvc1_files)を、dvc2がエクスポートするボリュームに対応する/var/www/htmlにコピーします。

次のように、tarなどのコマンドを使用して、データを1つのアーカイブ・ファイルとしてバックアップおよびリストアすることも可能です。

docker run --rm --volumes-from dvc1 -v /var/tmp:/host:rw \
  oraclelinux:7-slim tar -cPvf /host/dvc1_files.tar /var/www/html
ls -l /var/tmp/dvc1_files.tar
-rw-r--r--. 1 root root 10240 Aug 31 14:37 /var/tmp/dvc1_files.tar
docker run --rm --volumes-from dvc2 -i -t --name guest -v /var/tmp:/host:ro \
  oraclelinux:7-slim /bin/bash

ゲストで、次のコマンドを実行します。

[root@guest ~]# rm /var/www/html/*.html
[root@guest ~]# ls -l /var/www/html/*.html
total 0
[root@guest ~]# tar -xPvf /host/dvc1_files.tar
var/www/html/
var/www/html/file1.html
var/www/html/file2.html
var/www/html/index.html
[root@guest ~]# ls -l /var/www/html
total 12
-rw-r--r--. 1 root root 35 Aug 30 09:02 file1.html
-rw-r--r--. 1 root root 35 Aug 30 09:03 file2.html
-rw-r--r--. 1 root root 35 Aug 30 09:03 index.html
[root@guest ~]# exit
exit

この例では、guestという名前の一時的な対話型コンテナを使用して、アーカイブのコンテンツをdvc2に抽出します。

 ラベルを使用したメタデータの定義

ラベルを使用してDockerデーモンやDockerコンテナおよびDockerイメージにメタデータを追加できるようになりました。Dockerfileでは、次のようにLABEL命令により、1つ以上のキーと値のペアを含むイメージ・ラベルを定義します。

LABEL com.mydom.dept="ITGROUP" \
      com.mydom.version="1.0.0-ga" \
      com.mydom.is-final \
      com.mydom.released="June 6, 2015"

この例では、名前空間の競合を防ぐために、逆引きDNSフォーマット(com.mydom.)で各キー名の先頭にデーモン名が付けられています。各キーは常に文字列として表され、Dockerによって解釈されません。値を省略すると、メタデータ内のキーの有無を使用して、リリース・ステータスなどの情報をエンコードできます。バックスラッシュ文字を使用すると、ラベル定義を複数の行にわたって拡張できます。

次のように、docker inspectコマンドを使用して、イメージに関連付けられているラベルを表示できます。

docker inspect 7ac15076dcc1
...
"Labels": {
    "com.mydom.dept": "ITGROUP",
    "com.mydom.version": "1.0.0-ga",
    "com.mydom.is-final": "",
    "com.mydom.release-date": "June 6, 2015"
}
...

次のように、docker imagesおよびdocker psコマンドで--filter "label=key [=value ]"オプションを指定して、メタデータ値が設定されているイメージおよび実行中のコンテナをリストできます。

docker images --filter "label=com.mydom.dept='DEVGROUP'"
docker ps --filter "label=com.mydom.is-beta2"
docker ps --filter "label=env=Oracle\ Linux\ 7"            

コンテナについては、次のようにdocker createおよびdocker runコマンドで--label key=[value]オプションを使用して、キーと値のペアを定義できます。

docker run -i -t --rm testapp:1.0 --label run="11" --label platform="Oracle Linux 7"            

Docker Engineの場合は、コマンドラインからdockerを開始するか、docker構成ファイル/etc/sysconfig/dockerを編集すると、--label key=[value]オプションを使用できます。

OPTIONS=" --label com.mydom.dept='DEVGROUP'"

あるいは、これらのオプションを/etc/docker/daemon.jsonファイルのリストに追加することもできます。次に例を示します。

{
  "labels": ["com.mydom.dept='DEVGROUP'", "com.mydom.version='1.0.0-ga'"]
}

ノート:

dockerサービスの実行中に構成ファイルを追加または変更した後、コマンドsystemctl daemon-reloadを実行し、systemdにサービスの構成をリロードするよう指示します。

コンテナおよびDockerデーモンは一時的なものであり、既知の環境で実行されているので、通常は、キー名に逆引きドメイン名の接頭辞を適用する必要はありません。

 ロギング・ドライバの定義

docker createおよびdocker runコマンドで--log-driverオプションを使用して、コンテナが使用する必要のあるロギング・ドライバを指定できるようになりました。

json-file

次のように、docker logsコマンドを使用して、確認が可能なJSONファイルにログ・メッセージを書き込みます。

docker logs --follow --timestamps=false container_name                     

これは、デフォルトのロギング・ドライバです。

none

ロギングを無効にします。

syslog

syslogにログ・メッセージを書き込みます。

イメージ・ダイジェストについて

レジストリ・バージョン2以上のイメージをダイジェストによって識別できるようになりました(sha256:digest_value_in_hexadecimal など)。ダイジェストをリストするには、docker imagesコマンドに--digestsオプションを指定します。ダイジェストは、docker createdocker pulldocker rmiおよびdocker runコマンドや、Dockerfile内のFROM命令で使用できます。

 コンテナのコントロール・グループの指定

docker createコマンドで--cgroup-parentオプションを使用して、コンテナを実行する必要があるコントロール・グループ(cgroup)を指定できます。

 コンテナによるCPU使用量の制限

コンテナのCPU使用量を制御するには、--cpu-periodおよび--cpu-quotaオプションを、docker createおよびdocker runコマンドとともに使用します。

--cpu-quotaオプションは、--cpu-periodによって指定された期間にコンテナがCPUリソースにアクセスできるマイクロ秒数を指定します。--cpu-periodのデフォルト値が100000であるため、--cpu-quotaの値を25000に設定すると、コンテナはCPUリソースの25%に制限されます。デフォルトで、コンテナは使用可能なすべてのCPUリソースを使用でき、--cpu-quotaの値-1に対応します。

コンテナによるホストのUTSネームスペースの使用の有効化

デフォルトで、コンテナは、ホストのUTSネームスペースとは異なる(システム名およびドメインを定義する) UTSネームスペースを使用して実行されます。コンテナがホストと同じUTSネームスペースを使用するようにするには、docker createおよびdocker runコマンドで--uts=hostオプションを使用します。この設定により、コンテナは、ホストのUTSネームスペースを追跡したり、コンテナからホスト名およびドメインを設定できます。

注意:

コンテナはホストのUTSネームスペースへのフル・アクセスが可能なため、この機能は本質的に安全ではありません。

コンテナのulimit値の設定

次のように、docker run--ulimitオプションを指定することで、コンテナのulimit値を指定できます。

docker run -i -t --rm myapp:2.0 --ulimit nofile=128:256 --ulimit nproc=32:64            

この例では、コンテナの128個のオープン・ファイルおよび32個の子プロセスのソフト制限と、256個のオープン・ファイルおよび64個の子プロセスのハード制限を設定します。

すべてのコンテナにデフォルトのulimit値を設定するには、/etc/docker/daemon.json構成ファイルでdefault-ulimitsオプションを指定します。次に例を示します。

"default-ulimits": {
  "nofile": {
      "Name": "nofile",
      "Hard": 128,
      "Soft": 256
    },
    "nproc" : {
      "Name": "nproc",
      "Hard": 32,
      "Soft": 64
    }
},

ノート:

dockerサービスの実行中に構成ファイルを追加または変更した後、コマンドsystemctl daemon-reloadを実行し、systemdにサービスの構成をリロードするように指示します。

コンテナに対して指定したulimit値は、デーモンに対して設定したデフォルト値をオーバーライドします。

リソース制約のあるイメージの作成

次のようにdocker buildにcgroupのリソース制約を指定できるようになりました。

docker build --cpu-shares=100 --memory=1024m \
   --tag="mymod/myapp:1.0" /var/docker_projects/mymod/myapp/

イメージから生成したコンテナはすべて、これらのリソース制約を継承します。

次のように、docker statsコマンドを使用して、コンテナのリソース使用率を表示できます。

docker stats cntr1 cntr2
CONTAINER ID     NAME          CPU %      MEM USAGE/LIMIT     MEM %     NET I/O            BLOCK I/O     PIDS
1ab12958b915     cntr1         0.05%      504 KiB/128 MiB     0.39%     2.033 KiB/40 B     13.7MB/1MB    1 
3cf41296a324     cntr2         0.08%      1.756 MiB/128 MiB   1.37%     5.002 KiB/92 B     15.8MB/3MB    1

イメージのコミット、エクスポートおよびインポート

docker commitコマンドを使用して、コンテナの現在の状態をイメージに保存できます。

docker commit \
  [--author="name"] \
  [--change="instructions"]... \
  [--message="text"] \
  [--pause=false] container [repository[:tag] 

このイメージを使用して、たとえば既存のコンテナとは独立してコンテナのデバッグを行う場合などに、新しいコンテナを作成できます。

docker exportコマンドを使用して、コンテナをimage tarファイルとして別のシステムにエクスポートできます。

docker export [--output="filename"] container               

ノート:

コンテナが使用するデータ・ボリュームはいずれも個別にエクスポートする必要があります。「Dockerコンテナとホスト間のデータの移動」を参照してください。

イメージtarファイルをインポートするには、docker importを使用し、イメージURLを指定するかまたは標準入力からファイルを読み取ります。

docker import [--change="instructions"]... URL [repository[:tag]
docker import [--change="instructions"]... - [repository[:tag] < filename

次のようにdocker commitおよびdocker import--changeオプションを使用して、イメージの構成を変更するDockerfile命令を指定できるようになりました。

docker commit --change "LABEL com.mydom.status='Debug'" 7ac15076dcc1 mymod/debugimage:v1      

docker commitの場合は、ADDCMDCOPYENTRYPOINTENVEXPOSEFROMLABELMAINTAINERRUNUSERVOLUMEおよびWORKDIRといった命令を指定できます。

docker importの場合は、CMDENTRYPOINTENVEXPOSEONBUILDUSERVOLUMEおよびWORKDIRといった命令を指定できます。