Docker run リファレンス

Docker は隔離されたコンテナでプロセスを実行します。コンテナはホスト上で動くプロセスです。ホストとはローカルまたはリモートの環境です。オペレータが docker run を実行すると、コンテナのプロセスを隔離して実行します。コンテナは自身ファイルシステムとネットワークを持ち、ホスト上の他のプロセス・ツリーからは隔離されています。

このページではコンテナ実行時にリソースを指定できるよう、 docker run コマンドの使い方の詳細を説明します。

一般的な形式

基本的な docker run コマンドの形式は、次の通りです。

$ docker run [オプション] イメージ[:タグ|@ダイジェスト値] [コマンド] [引数...]

docker run コマンドはコンテナを形成する元になる イメージ の指定が必要です。イメージの開発者はイメージに関連するデフォルト値を定義できます。

  • デタッチ、あるいはフォアグラウンドで実行するか
  • コンテナの識別
  • ネットワーク設定
  • 実行時の CPU とメモリの制限
  • 権限と LXC 設定

docker run [オプション] では、開発者がイメージに対して行ったデフォルト設定の変更や、設定の追加をオペレータが行えます。そして更に、オペレータは Docker で実行する時、すべてのデフォルト設定を上書きすることもできます。オペレータはイメージと Docker 実行時のデフォルト設定を上書きできるのは、 run コマンドは他の docker コマンドより多くのオプションがあるためです。

様々な種類の [オプション] を理解するには、 オプションの種類 をご覧ください。

注釈

Docker システムの設定によっては、 docker run コマンドを sudo で実行する必要があるかもしれません。 docker コマンドで sudo を使わないようにするには、システム管理者に docker という名称のグループの作成と、そこにユーザの追加を依頼してください。この設定に関するより詳しい情報は、各オペレーティング・システム向けのインストール用ドキュメントをご覧ください。

デタッチド vs フォアグラウンド

Docker コンテナの起動時には、まず、コンテナをバックグラウンドで「デタッチド」モード(detached mode)で実行するか、デフォルトのフォアグラウンド・モード(foreground mode)で実行するかを決める必要があります。

-d=false: Detached mode: Run container in the background, print new container id

デタッチド (-d)

コンテナをデタッチド・モードで起動するには、 -d=true-d オプションを使います。設計上、コンテナが実行するルート・プロセスが終了すると、デタッチド・モードで起動したコンテナも終了します。デタッチド・モードのコンテナは停止しても自動的に削除できません。つまり -d オプションで --rm を指定できません。

デタッチドのコンテナでは service x start コマンドは受け付けられません。例えば、次のコマンドは nginx サービスの起動を試みます。

$ docker run -d -p 80:80 my_image service nginx start

コンテナ内で nginx サービスの起動は成功します。しかしながら、デタッチド・コンテナの枠組み内では処理に失敗します。これはルート・プロセス( service nginx start )が終了するため、デタッチド・コンテナを停止させようとします。その結果、 nginx サービスは実行されますが、実行し続けることができません。この方法以外で nginx ウェブ・サーバのプロセスを実行するには、次のようにします。

$ docker run -d -p 80:80 my_image nginx -g 'daemon off;'

コンテナの入出力はネットワーク接続や共有ボリュームも扱えます。コマンドラインで docker run を実行し終わったあとでも、必要になることがあるでしょう。

デタッチド・コンテナに再度アタッチするには、 docker attach コマンドを使います。

フォアグラウンド

フォアグラウンド・モード( -d を指定しない場合のデフォルト )では、 docker run はコンテナの中でプロセスを開始し、プロセスの標準入出力・標準エラーをコンソールにアタッチします。これは TTY のふりをするだけでなく(TTY は大部分のコマンド・ラインで実行可能なものと想定しています)、シグナルも渡せます。

-a=[]           : Attach to `STDIN`, `STDOUT` and/or `STDERR`
-t=false        : Allocate a pseudo-tty
--sig-proxy=true: Proxify all received signal to the process (non-TTY mode only)
-i=false        : Keep STDIN open even if not attached

もし Docker で -a を指定しなければ、Docker は 自動的に全ての標準ストリームをアタッチ します。3つの標準ストリーム( STDINSTDOUTSTDERR )のうち、特定のものに対してのみ接続も可能です。

$ docker run -a stdin -a stdout -i -t ubuntu /bin/bash

(シェルのような)インタラクティブなプロセスでは、コンテナのプロセスに対して tty を割り当てるために、 -i -t を一緒に使う必要があります。 -i -t-it と書くこともできます。後の例で出てきます。 -t を指定すると、クライアント側の出力を echo test | docker run -i busybox cat のようにリダイレクトやパイプできます。

注釈

コンテナの中で PID 1 として実行しているプロセスは、Linux から特別に扱われます。デフォルトの操作では、あらゆるシグナルを無視します。そのため、プロセスは SIGINTSIGTERM で停止するようにコードを書かない限り、停止できません。

コンテナの識別

名前(–name)

オペレータはコンテナを3つの方法で識別できます。

  • UUID 長い(ロング)識別子(”f78375b1c487e03c9438c729345e54db9d20cfa2ac1fc3494b6eb60872e74778”)
  • UUID 短い(ショート)識別子(”f78375b1c487”)
  • 名前(”evil_ptolemy”)

UUID 識別子は Docker デーモンから与えられます。コンテナの名前を --name オプションで割り当てなければ、デーモンはランダムな文字列から名前を生成します。コンテナに対する目的を表すために、 name を定義するのが簡単な方法でしょう。 name を指定すると、これは Docker ネットワーク内でコンテナを参照するために使えます。この参照機能は、バックグラウンドでもフォアグラウンドでも、両方の Docker コンテナで動作します。

注釈

デフォルト・ブリッジ・ネットワーク内のコンテナは、相互に名前で通信するにはリンクする必要があります。

PID 相当

あとは、自動処理を簡単にするため、Docker は任意に選択したファイルに対してコンテナ ID を書き出せます。これは、プログラムがプロセス ID をファイルに書き出す(いわゆる PID ファイルのことです)のに似ています。

--cidfile="": コンテナの ID をファイルに書き出す

イメージ[@ダイジェスト値]

v2 以降のイメージ・フォーマットのイメージを使うと、その中にダイジェスト値(digest)と呼ばれる識別子が、内容に対して割り当てられています。入力に使われたイメージファイルに対する変更がなければ、ダイジェスト値とは予想されうる値であり、参照可能なものです。

PID 設定(–pid)

--pid=""  : コンテナに対する PID (プロセス)名前空間モードを指定
       'host':コンテナ内のホストが使う PID 名前空間

デフォルトでは、全てのコンテナは有功な PID 名前空間を持っています。

PID 名前空間はプロセスの分離をもたらします。PID 名前空間はシステム・プロセスを見えないようにし、PID 1 を含むプロセス ID を再利用できるようにします。

コンテナがホスト上の特定のプロセス名前空間を共有する場合は、コンテナ内のプロセスが、システム上の全プロセスを基本的に見られるようにします。例えば、 stracegdb のようなデバッグ用ツールを含むコンテナを構築したとき、コンテナ内のデバッグ用プロセスのみツールを使えるように指定する場合です。

$ docker run --pid=host rhel7 strace -p 1234

これはホスト上の pid 1234 にあるコンテナ内で strace を使うコマンドです。

UTS 設定(–uts)

--uts=""  : UTS 名前空間モードをコンテナに設定する
       'host': コンテナ内でホストの UTS 名前空間を使う

UTS 名前空間とは、プロセスを実行する名前空間上で見えるホスト名とドメイン名を設定するものです。デフォルトでは、全てのコンテナは --uts=host の指定により、自身の UTS 名前空間を持っています。 host には、ホスト名として同じ UTS 名前空間をコンテナで使えるよう設定します。

ホスト上と UTS 名前空間を共有したい場合もあるでしょう。例えば、コンテナを動かすホストがホスト名を変更してしまい、コンテナのホスト名も変更したい場合です。より高度な使い方としては、コンテナからホスト側のホスト名の変更を行うケースです。

注釈

--uts="host" 設定をすると、ホスト上のホスト名の変更に対するフル・アクセスをもたらすため、安全ではないと考えられます。

IPC 設定(–ipc)

--ipc=""  : コンテナに IPC モードを設定する
             'container:<名前|id>': 他のコンテナの IPC 名前空間を再利用
             'host': ホストの IPC 名前空間をコンテナの中で使用

デフォルトでは、全てのコンテナが有効な IPC 名前空間を持っています。

IPC (POSIX/SysV IPC) 名前空間は、共有メモリ・セグメント、セマフォ、メッセージ・キューとよばれる分離を提供します。

プロセス間通信は共有メモリ・セグメントはメモリの速度まで(ネットワーク・スタックをパイプするか通過するよりも速く)加速します。共有メモリとは、一般的にデータベースや、科学計算や緊急サービス産業向けの高性能アプリケーション向けカスタム・ビルド(典型的なのは、C/OpenMPI、C++ の高速化ライブラリ)に用いられます。この種のアプリケーションが複数のコンテナに分割される場合は、コンテナの IPC 機構を使って共有する必要があるでしょう。

ネットワーク設定

--dns=[]         : Set custom dns servers for the container
--net="bridge"   : Connects a container to a network
                    'bridge': creates a new network stack for the container on the docker bridge
                    'none': no networking for this container
                    'container:<name|id>': reuses another container network stack
                    'host': use the host network stack inside the container
                    'NETWORK': connects the container to user-created network using `docker network create` command
--net-alias=[]   : Add network-scoped alias for the container
--add-host=""    : Add a line to /etc/hosts (host:IP)
--mac-address="" : Sets the container's Ethernet device's MAC address
--ip=""          : Sets the container's Ethernet device's IPv4 address
--ip6=""         : Sets the container's Ethernet device's IPv6 address

デフォルトでは、全てのコンテナはネットワーク機能を持っており、外部に対する接続を可能とします。オペレータはネットワークを無効化したいのであれば docker run --net=none を指定することで、内側と外側の両方のネットワーク機能を無効化します。このような指定をすると、 I/O 処理はファイルに対してか、 STDINSTDOUT のみになります。

公開用のポートを他のコンテナとリンクできるのは、デフォルト(ブリッジ)のみです。リンク機能はレガシー(過去の)機能です。リンク機能を使うよりも、常に Docker ネットワーク機能を使うべきです。

コンテナは、デフォルトではホストと同じ DNS サーバを使いますが、 --dns で上書きできます。

デフォルトでは、コンテナに割り当てられる IP アドレスを使って、Mac アドレスが生成されます。コンテナの Mac アドレスの指定は、 --mac-address パラメータ(書式: 12:34:56:78:9a:bc )を使い MAC アドレスを指定できます。

サポートしているネットワーク:

ネットワーク 説明
none コンテナにネットワーク機能を持たせません。
bridge (デフォルト) コンテナを各インターフェースに接続します。
host コンテナ内でホスト側のネットワーク・スタックを使います。
container: <名前|id> 他のコンテナ名か ID を指定し、そのネットワーク・スタックを使います。
NETWORK ユーザが作成したネットワーク( docker network create コマンドを使用 )にコンテナを接続します。

ネットワーク:none

コンテナのネットワークを none に指定すると、外部の経路に対してアクセスできなくなくなります。それでもコンテナは loopback (ループバック)インターフェースが有効ですが、外部のトラフィックに対する経路がなくなります。

ネットワーク:bridge

コンテナのネットワークを bridge に指定すると、コンテナは Docker のデフォルト・ネットワーク機能をセットアップします。ブリッジはホスト上で設定されるもので、通常は docker0 と名前が付けられます。そして、 veth インターフェースのペアがコンテナ用に作成されます。 veth ペアの片方はホスト側にアタッチされたままとなります。もう一方は、コンテナの名前空間の中で loopback インターフェースに加えて追加されます。ブリッジ・ネットワーク上で IP アドレスがコンテナに割り当てられ、コンテナに対するトラフィックはこのブリッジを経由します。

デフォルトでは、コンテナは各々の IP アドレスを経由して通信できます。コンテナ名で通信するには、リンクする必要があります。

ネットワーク:host

host ネットワークをコンテナに設定すると、ホスト側のネットワーク・スタックと、全てのホスト上のインターフェースがコンテナ上でも共有できます。コンテナのホスト名はホストシステム上のホスト名と一致します。 host ネットワーク・モードでは、 --add-host--hostname--dns--dns-search--dns-opt--mac-address が無効になるのでご注意ください。

デフォルトの bridge モードと比較すると、 host モードは 著しく ネットワーク性能が良いです。これは、bridge の場合は docker デーモンの仮想化レベルを通過しているのに対して、host の場合はネイティブなネットワーク・スタックを用いるからです。例えば、プロダクションのロードバランサや高性能のウェブサーバのような、ネットワーク性能がクリティカルな環境では、このモードでのコンテナ動作を推奨します。

注釈

--net="host" を指定すると、コンテナは D-bus のようなローカル・システム・サービスに対してフルアクセスできるので、安全ではないと考えられます。

ネットワーク:container

container ネットワークをコンテナにセットすると、他のコンテナのネットワーク・スタックを共有します。他のコンテナ名は --net container:<名前|id> の書式で指定する必要があります。 container ネットワーク・モードでは、 --add-host--hostname--dns--dns-search--dns-opt--mac-address が無効になるだけでなく、 --publish--publish-all--expose も無効になるのでご注意ください。

例として、Redis コンテナで Redis が localhost をバインドしているとき、 localhost インターフェースを通して Redis サーバに redis-cli コマンドを実行して接続します。

$ docker run -d --name redis example/redis --bind 127.0.0.1
$ # redis コンテナのネットワーク・スタックにある localhost にアクセスします
$ docker run --rm -it --net container:redis example/redis-cli -h 127.0.0.1

ユーザ定義ネットワーク

ネットワークを作成するには、Docker ネットワーク・ドライバか外部のネットワーク・ドライバ・プラグインを使います。同じネットワークに対して、複数のコンテナが接続できます。ユーザ定義ネットワークに接続すると、コンテナはコンテナの名前や IP アドレスを使い、簡単に通信できるようになります。

overlay ネットワークやカスタム・プラグインは、複数のホストへの接続性をサポートしています。コンテナが同一のマルチホスト・ネットワークに接続していれば、別々のエンジンで起動していても、このネットワークを通して通信可能です。

以下の例は、内蔵の bridge ネットワーク・ドライバを使ってネットワークを作成し、作成したネットワーク上でコンテナを実行します。

$ docker network create -d bridge my-net
$ docker run --net=my-net -itd --name=container3 busybox

/etc/hosts の管理

/etc/hosts には localhost や一般的な項目と同じように、自分が定義したコンテナのホスト名が追加されます。 --add-host フラグを使うことで、 /etc/hosts に行を追加できます。

$ docker run -it --add-host db-static:86.75.30.9 ubuntu cat /etc/hosts
172.17.0.22     09d03f76bf2c
fe00::0         ip6-localnet
ff00::0         ip6-mcastprefix
ff02::1         ip6-allnodes
ff02::2         ip6-allrouters
127.0.0.1       localhost
::1             localhost ip6-localhost ip6-loopback
86.75.30.9      db-static

コンテナがデフォルト・ブリッジ・ネットワークに接続し、他のコンテナと link (リンク)すると、コンテナの /etc/hosts ファイルが更新され、リンクされたコンテナ名が書き込まれます。

もしもコンテナがユーザ定義ネットワークに接続した場合は、コンテナの /etc/hosts ファイルが更新され、ユーザ定義ネットワーク上の他のコンテナ名が書き込まれます。

注釈

Docker がコンテナの /etc/hosts ファイルをリアルタイムに更新するかもしれません。そのため、コンテナ内のプロセスが /etc/hosts ファイルを読み込もうとしても空だったり、あるいは最後まで読み込めなかったりする場合が有り得ます。ほとんどの場合、再度読み込もうとすることで、問題を解決するでしょう。

再起動ポリシー(–restart)

Docker で実行時に --restart フラグを使うことで、再起動ポリシーを指定できます。再起動ポリシーとは、コンテナが終了したときに再起動すべきかどうかを定義します。

コンテナの再起動ポリシーが有効な場合、 docker ps でコンテナを見ると、常に UpRestarting のどちらかです。また、再起動ポリシーが有効かどうかを確認するため、 docker events を使うのも便利です。

Docker は以下の再起動ポリシーをサポートしています。

ポリシー 結果
no (なし) コンテナが終了しても、自動的には再起動しません。これがデフォルトです。
on-failure [:最大リトライ数] コンテナが 0 以外の終了コードで停止したら再起動します。オプションで Docker デーモンが何度再起動を試みるかを指定できます。
always (常に) コンテナの終了コードに拘わらず、常にコンテナの再起動を試みます。Docker デーモンは無制限に再起動を試みます。また、デーモンの起動時にも、コンテナの状況に拘わらず常に起動を試みます。
unless-stopped (停止していない場合) コンテナの終了コードに拘わらず、常にコンテナの再起動を試みます。しかし、直近のコンテナが停止状態であったのであれば、デーモンの起動時にコンテナを開始しません。

サーバが溢れかえるのを防ぐため、再起動の前に遅延時間が追加されます(遅延は100ミリ秒から開始し、直前の値の2倍になります)。つまり、デーモンは100ミリ秒待った後は、200ミリ秒、400、800、1600…と on-failure 上限に到達するか、あるいは、コンテナを docker stop で停止するか、 docker rm -f で強制削除するまで続けます。

コンテナの再起動が成功すると(コンテナは少なくとも10秒以内で起動します)、遅延時間の値は再び 100 ミリ秒にリセットされます。

on-failure ポリシーを使うことで、Docker がコンテナの再起動を試みる最大回数を指定できます。デフォルトでは、Docker はコンテナを永久に再起動し続けます。コンテナの再起動(を試みる)回数は docker inspect で確認可能です。たとえば、コンテナ「my-container」の再起動数を取得するには、次のようにします。

$ docker inspect -f "{{ .RestartCount }}" my-container
# 2

あるいは、コンテナが(再)起動した時刻を知るには、次のようにします。

$ docker inspect -f "{{ .State.StartedAt }}" my-container
# 2015-03-04T23:47:07.691840179Z

再起動ポリシーと クリーンアップ は同時に指定できません。 --restart--rm を同時に指定してもエラーになります。

$ docker run --restart=always redis

こちらの例は、 常に (always) 再起動するポリシーで redis コンテナを実行しているので、停止すると Docker は再起動します。

$ docker run --restart=on-failure:10 redis

こちらの例は、 失敗したら (on-failure) 10回カウントするまで再起動を行うポリシーで redis コンテナを起動しています。もし redis コンテナが 0 以外の状態で終了すると、Docker はコンテナの再起動を10回続けて試みます。再起動の上限を設定できるのは、 on-failure ポリシーを有効にした場合のみです。

クリーンアップ(–rm)

デフォルトではコンテナを終了しても、コンテナのファイルシステム(の内容)を保持し続けます。これにより、多くのデバッグをより簡単にし(最後の状態を確認できるので)、そして、全てのデータを維持し続けるのがデフォルトです。しかし、短い期間だけ フォアグラウンド で動かしたとしても、これらのコンテナのファイルシステムが溜まり続けます。そうではなく、 コンテナが終了した時に、自動的にコンテナをクリーンアップし、ファイルシステムを削除する には --rm フラグを追加します。

--rm=false: Automatically remove the container when it exits (incompatible with -d)

注釈

--rm フラグを設定すると、コンテナの削除時、関連するボリュームも削除されます。これは docker rm -v my-container を実行するのと同様です。ただし、名前を指定しなかったボリュームのみが削除されます。例えば docker run --rm -v /foo -v awesome:/bar busybox top の場合、 /foo ボリュームは削除されます。しかし、 /bar は削除されません。 --volume-form で継承しているボリュームが削除されないのと同じ仕組みです。このように、オリジナルのボリュームに名前が指定されていれば、そこは削除 されません

セキュリティ設定

--security-opt="label:user:USER"   : Set the label user for the container
--security-opt="label:role:ROLE"   : Set the label role for the container
--security-opt="label:type:TYPE"   : Set the label type for the container
--security-opt="label:level:LEVEL" : Set the label level for the container
--security-opt="label:disable"     : Turn off label confinement for the container
--security-opt="apparmor:PROFILE"  : Set the apparmor profile to be applied
                                     to the container

各コンテナに対するデフォルトのラベリング・スキーマ(labeling scheme)は --security-opt フラグを指定することで上書き可能です。たとえば、MCS/MLS レベルを指定するには MLS システムが必要です。コンテナ間で同じ内容を共有できるようにレベルを指定するには、次のようにコマンドを実行します。

$ docker run --security-opt label:level:s0:c100,c200 -i -t fedora bash

MLS であれば、次のような例になります。

$ docker run --security-opt label:level:TopSecret -i -t rhel7 bash

コンテナに対するセキュリティ・ラベリングを無効化するには、 --permissive フラグを使い、次のように指定します。

$ docker run --security-opt label:disable -i -t fedora bash

コンテナ内のプロセスに対して、何らかのセキュリティ・ポリシーを適用するには、コンテナに対して何らかのタイプを指定します。コンテナを実行する時、Apache のポートのみがリッスンできるようにするには、次のように実行します。

注釈

ここでは svirt_apache_t タイプ に対する書き込みポリシーがあるものと想定しています。

カスタム cgroups の指定

--cgroup-parent フラグを使うことで、コンテナを特定の cgroup で実行できるようにします。これにより自分自身で cgroup の作成や管理が可能になります。各 cgroup に対してカスタム・リソースを定義でき、コンテナを共通の親グループ下に置くこともできます。

実行時のリソース制限

オペレータはコンテナのパフォーマンス・パラメータも調整できます。

オプション 説明
-m , --memory="" メモリの上限(書式: <数値> [<単位>] 、単位は b 、k、m、g のいずれか)
--memory-swap="" 合計メモリの上限(メモリ+スワップ、書式: <数値> [<単位>] 、単位は b 、k、m、g のいずれか)
--memory-reservation="" メモリのソフト・リミット(書式: <数値> [<単位>] 、単位は b 、k、m、g のいずれか)
--kernel-memory="" カーネル・メモリの上限(書式: <数値> [<単位>] 、単位は b 、k、m、g のいずれか)
-c , --cpu-shares=0 CPU 共有(CPU shares)を相対値で指定
--cpu-period=0 CPU CFS (Completely Fair Scheduler) ピリオドの上限(訳者注:cgroup による CPU リソースへのアクセスを再割り当てする間隔)
--cpuset-cpus="" 実行する CPU の割り当て(0-3, 0,1)
--cpuset-mems="" 実行するメモリ・ノード(MEM)の割り当て(0-3, 0,1)。NUMA システムのみで動作
--cpu-quota=0 CPU CFS (Completely Fair Scheduler) のクォータを設定
--blkio-weight=0 ブロック I/O ウェイト(相対値)を 10 ~ 1000 までの値でウエイトを設定
--oom-kill-disable=false コンテナを OOM killer による停止を無効化するかどうか指定
--memory-swappiness="" コンテナがメモリのスワップ度合いを調整。整数値の 0 ~ 100 で指定

ユーザ・メモリの制限

ユーザのメモリ使用を制限するには、4つの方法があります。

オプション 結果
memory=inf, memory-swap=inf (デフォルト) コンテナに対する上限を設けない。コンテナは必要な分のメモリを使える
memory=L<inf, memory-swap=inf (memory を指定し、memory-swap を -1 にする)コンテナは L バイト以上のメモリ使用が許されないが、必要があればスワップを使える(ホスト側がスワップ・メモリをサポートしている場合)
memory=L<inf, memory-swap=2*L (memory を指定するが memory-swap は指定しない)コンテナは L バイト以上のメモリ使用は許されないが、指定した値の2倍の「追加」スワップ・メモリが使える
memory=L<inf, memory-swap=S<inf, L<=S (memory も memory-swap も指定する)コンテナは L バイト以上のメモリ使用が許されないが、「追加」スワップ・メモリは S バイトまで使える

例:

$ docker run -ti ubuntu:14.04 /bin/bash

メモリを設定していません。これはコンテナ内のプロセスは必要な分だけメモリが使えます。それだけでなく、スワップ・メモリも同様の必要なだけ使えます。

$ docker run -ti -m 300M --memory-swap -1 ubuntu:14.04 /bin/bash

メモリ上限を指定し、スワップ・メモリの制限を無効化しました。これはコンテナ内のプロセスは 300M のメモリを使えます。それだけでなく、スワップ・メモリは必要なだけ使えます(ホスト側がスワップ・メモリをサポートしている場合)。

$ docker run -ti -m 300M ubuntu:14.04 /bin/bash

メモリの上限のみ設定しました。これはコンテナが 300M のメモリと 300M のスワップ・メモリを使えます。合計の仮想メモリサイズ(total virtual memory size、 –memory-swap で指定)はメモリの2倍に設定されます。今回の例では、メモリ+スワップは 2×300M なので、プロセスは 300M のスワップ・メモリを利用できます。

$ docker run -ti -m 300M --memory-swap 1G ubuntu:14.04 /bin/bash

メモリとスワップ・メモリを指定したので、コンテナ内のプロセスは 300M のメモリと 700M のスワップ・メモリを使えます。

メモリ予約(memory reservation)は、メモリに対するある種のソフト・リミットであり、共有メモリを大きくします。通常の状況下であれば、コンテナは必要とするだけ多くのメモリを使うことができます。そして、 -m--memory オプションがあるときのみ、コンテナに対してハード・リミットが設定されます。メモリ予約が設定されると、Docker はメモリのコンテンション(競合)や少ないメモリを検出し、コンテナが予約した上限まで使えるようにします。

メモリ予約の値は、常にハード・リミット以下に設定しなければ、ハード・リミットが先に処理されてしまいます。予約値を 0 に設定するのは、予約しないのと同じです。デフォルトでは(予約をセットしない場合)、メモリ予約とはメモリのハード・リミットと同じです。

メモリ予約とはソフト・リミット機能であり、制限を超過しないことを保証しません。その代わりに、かなりメモリが競合する場合、予約のヒント/設定に基づいてメモリの割り当てを試みる機能があります。

次の例はメモリの上限( -m )を 500M に制限し、メモリ予約を 200M に設定します。

$ docker run -ti -m 500M --memory-reservation 200M ubuntu:14.04 /bin/bash

この設定の下では、コンテナはメモリを 200MB 以上 ~ 500MB 以下まで使えます。次のシステム・メモリはコンテナのメモリが 200MB 以下になるよう縮小を試みます。

次の例はメモリのハード・リミットを設定せず、メモリ予約を 1G に設定します。

$ docker run -ti --memory-reservation 1G ubuntu:14.04 /bin/bash

コンテナはメモリを必要なだけ使えます。メモリ予約設定により、コンテナが長時間多くのメモリを消費しなくなります。これはコンテナがメモリを消費したとしても、予約分を使えるようにメモリの使用を縮小しようとするからです。

デフォルトでは、アウト・オブ・メモリ(OOM; out of memory)エラーが発生すると、カーネルはコンテナ内のプロセスを停止(kill)します。この振る舞いを変更するには、 --oom-kill-disable オプションを使います。また、 -m/--memory オプションを指定した時のみ、コンテナに対する OOM が無効化できます。もし -m フラグがセットされなければ、ホスト側でアウト・オブ・メモリ処理が発生します。また、ホスト側のシステム・プロセスが空きメモリを必要とするため、対象のプロセスを停止(kill)します。

次の例はメモリの上限を 100M とし、対象となるコンテナに対する OOM killer (アウト・オブ・メモリ処理による強制停止)を無効化します。

$ docker run -ti -m 100M --oom-kill-disable ubuntu:14.04 /bin/bash

次の例では、危険なフラグの使い方を説明します。

$ docker run -ti --oom-kill-disable ubuntu:14.04 /bin/bash

コンテナは無制限にメモリを使えるため、ホスト上のメモリを使い果たしたら、空きメモリ確保のために、システム・プロセスを停止する必要が出てきます。

カーネル・メモリ制限

カーネル・メモリはスワップ・アウトできないため、ユーザ・メモリとは根本的に異なります。このスワップができないことにより、システム・サービスがカーネル・メモリを多く使えないように妨害する可能性があります。カーネル・メモリとは、次のものを差します。

  • stack pages
  • slab pages
  • sockets memory pressure
  • tcp memory pressure

これらのメモリを制限するため、カーネル・メモリの上限を設定できます。たとえば、各プロセスが同じスタック・ページ(stack page)を使うようにする場合です。カーネル・メモリの制限により、カーネル・メモリの使用量が大きいとき、新しいプロセスの作成を妨げます。

カーネル・メモリはユーザ・メモリとは完全に独立しています。その代わり、ユーザ・メモリを制限すると同時に、カーネル・メモリの制限も必要です。上限の設定には3つの方法があります。ここでは、「U」はユーザ・メモリの上限で、「K」はカーネルの上限とみなしています。

オプション 結果
U != 0, K = inf (デフォルト) カーネル・メモリが使う前に、標準的なメモリ制限を設ける仕組み。カーネル・メモリは完全に無視される。
U != 0, K < U カーネル・メモリをユーザ・メモリのサブセットとする。この設定は cgroup ごとに大きな合計メモリ容量をオーバーコミットで割り当て、デプロイする場合に使いy水。カーネル・メモリ制限のオーバコミットは、全くもって推奨されていない。範囲が再利用できないメモリ領域の場合が有り得るため。この例では、 K を設定したので、全グループの合計は、全メモリ容量を超えられない。そして、システム・サービスの品質のために U を任意に設定できる。
U != 0, K > U カーネルのメモリを使用するため、コンテナ向けに両方のメモリが、ユーザ・カウンタと再利用トリガに影響を与えます。

例:

$ docker run -ti -m 500M –kernel-memory 50M ubuntu:14.04 /bin/bash

メモリとカーネルメモリを設定しました。これにより、コンテナ内のプロセスは合計 500M まで使えます。この 500M のメモリのうち、トップに 50M のカーネル・メモリがあります。

$ docker run -ti --kernel-memory 50M ubuntu:14.04 /bin/bash

-m オプションを指定せずカーネル・メモリを指定しました。そのため、コンテナ内のプロセスは必要なだけ多くのメモリを利用可能ですが、そこに最低限 50M のカーネル・メモリを使います。

スワップ回避(swappiness)制限

デフォルトでは、コンテナのカーネルは、アノニマス・ページ・メモリ上の何パーセントかをスワップ・アウトします。コンテナ向けのこのパーセントを指定するには --memory-swappiness で 0 ~ 100 までの値を設定します。この値が 0 であればアノニマス・ページのスワッピング(anonymous page swapping)を無効にします。値を 100 にすると全てのページがスワップ可能となります。デフォルトでは、 --memory-swappiness を指定しなければ、メモリのスワップ回避(swappiness)は親の値を継承します。

例:

$ docker run -ti --memory-swappiness=0 ubuntu:14.04 /bin/bash

--memory-swappiness オプションが訳に立つのは、コンテナの作業セットを維持し、スワップによるパフォーマンスのペナルティを避ける場合です。

CPU 共有制限

デフォルトでは、全てのコンテナは同じ CPU サイクルの割合を持っています。この割合は変更可能なものであり、コンテナの CPU 共有ウェイトを、実行中の全てのコンテナに対する相対的な値として変更できます。

割合をデフォルトの 1024 から変更するには、 -c--cpu-shares フラグでウェイトを 2 以上の値で設定します。もし 0 を設定しても、システムは値を無視してデフォルトの 1024 を使います。

割合が適用されるのは CPU に対する処理が集中するときのみです。あるコンテナのタスクがアイドル(何もしていない待機状態)であれば、他のコンテナは CPU 時間の余剰を利用できます。実際に割り当てられる CPU 時間の量は、システム上で実行するコンテナの下図に非常に依存します。

例えば、3つのコンテナがあるとしましょう。1つめの CPU 共有は 1024 で、残り2つの CPU 共有は 512 とします。もし3つのコンテナが CPU を 100% 使用している状態になれば、1つめのコンテナが合計 CPU 時間の 50% を扱えます。4つめのコンテナを CPU 共有 1024 として追加すると、1つめのコンテナが得られるのは CPU の 33% になります。そして、残りの2つめ以降のコンテナが得られる CPU 時間は、それぞれ 16.5%(2つめ)、16.5%(3つめ)、33% (4つめ)となります。

複数のコアを持つ(マルチ・コア)システム上では、すべての CPU コアに分散してCPU 時間が共有されます。コンテナが CPU 時間の 100% より低く制限していても、個々の CPU コアでは 100% 利用できます。

例えば、システムが3つ以上のコアを持っていると想定してみましょう。1つめのコンテナ {C0} では -c=512 を指定し、1つのプロセスを実行するものとします。そして、他のコンテナ {C1}-c=1024 を指定し、2つのプロセスを実行するとします。この結果、CPU 共有は個々のコアに分散されます。

PID    container    CPU CPU share
100    {C0}     0   100% of CPU0
101    {C1}     1   100% of CPU1
102    {C1}     2   100% of CPU2

CPU 周期(period)制約

デフォルトの CPU CFS(Completely Fair Scheduler)周期は 100 ミリ秒です。コンテナの CPU 使用率を制限するには、 --cpu-period で CPU の周期を制限します。そして、通常は --cpu-period--cpu-quota と一緒に使われるでしょう。

例:

$ docker run -ti --cpu-period=50000 --cpu-quota=25000 ubuntu:14.04 /bin/bash

もし1 CPU であれば、コンテナは 50 ミリ秒ごとに CPU の 50% を利用できます(訳者注:–cpu-quota のクォータ値が、 –cpu-period の周期の半分のため)。

より詳しい情報については、CFS ドキュメントの帯域制限について(英語) をご覧ください。

CPU セット制限

どの CPU でコンテナを実行するか指定できます。

例:

$ docker run -ti --cpuset-cpus="1,3" ubuntu:14.04 /bin/bash

これはコンテナ内のプロセスを cpu 1 と cpu 3 で実行します。

$ docker run -ti --cpuset-cpus="0-2" ubuntu:14.04 /bin/bash

こちらはコンテナ内のプロセスを cpu 0 、cpu 1 、 cpu 2 で実行します。

NUMA system 上でのみ、どのコンテナをメモリ上で実行するか設定できます。

$ docker run -ti --cpuset-mems="1,3" ubuntu:14.04 /bin/bash

この例ではコンテナ内でのプロセスを、メモリ・ノード 1 と 3 上のメモリのみに使用を制限します。

$ docker run -ti --cpuset-mems="0-2" ubuntu:14.04 /bin/bash

この例ではコンテナ内でのプロセスを、メモリ・ノード 0と1と2 上のメモリのみに使用を制限します。

CPU クォータ制限

--cpu-quota フラグはコンテナの CPU 使用を制限します。デフォルト値 0 の場合、コンテナは CPU リソース( 1 CPU )の 100% を扱えます。CFS (Completely Fair Scheduler) がプロセス実行時のリソース割り当てを扱っており、これがカーネルによってデフォルトの Linux スケジューラとして使われています。この値を 50000 に指定すると、コンテナは CPU リソースの 50% までの使用に制限されます。複数の CPU の場合は、 --cpu-quota の調整が必要です。より詳しい情報については、CFS ドキュメントの帯域制限について(英語) をご覧ください。

ブロック IO 帯域(blkio)制限

デフォルトでは、全てのコンテナはブロック IO 帯域(blkio)を同じ割合で取得します。デフォルトの割合は 500 です。割合を変更するには --blkio-weight フラグを使い、実行中の全てのコンテナに対する装置亜的な blkio ウェイトを指定します。

--blkio-weight フラグは、 10 ~ 1000 までのウェイト値を設定できます。例えば、次のコマンドは2つのコンテナに対し、別々の blkio ウェイトと設定しています。

$ docker run -ti --name c1 --blkio-weight 300 ubuntu:14.04 /bin/bash
$ docker run -ti --name c2 --blkio-weight 600 ubuntu:14.04 /bin/bash

例えば、次のようにして2つのコンテナで同時にブロック IO を確認できます。

$ time dd if=/mnt/zerofile of=test.out bs=1M count=1024 oflag=direct

2つのコンテナ間の blkio ウェイトの割合により、処理にかかる時間の割合が変わるのが分かるでしょう。

注釈

blkio ウェイトの設定は直接 IO (direct IO) のみです。現時点ではバッファ IO (buffered IO) をサポートしていません。

グループの追加

--group-add: Add Linux capabilities

Docker コンテナのプロセスを実行できるのは、デフォルトでは、補助的なグループに所属しているユーザのみです(訳者注:docker グループに所属するユーザ)。グループを更に追加したい場合は、このフラグを使います。

$ docker run --rm --group-add audio --group-add nogroup --group-add 777 busybox id
uid=0(root) gid=0(root) groups=10(wheel),29(audio),99(nogroup),777

実行時の権限、Linux 機能、LXC 設定

--cap-add: Add Linux capabilities
--cap-drop: Drop Linux capabilities
--privileged=false: Give extended privileges to this container
--device=[]: Allows you to run devices inside the container without the --privileged flag.
--lxc-conf=[]: Add custom lxc options

注釈

Docker 1.10 以降では、デフォルトの seccomp プロフィールでは、コンテナに対して --cap-add を指定しても、システムコールをブロックします。このような場合に私たちが推奨するのは、私たちの デフォルト プロフィールを元に書き換える方法です。あるいはデフォルトの seccomp プロファイルを使いたくないのであれば、実行時に --security-opt=seccomp:unconfined を指定できます。

デフォルトでは、Docker コンテナは「unprivileged」(権限がない)ため、Docker コンテナの中で Docker デーモンを動かす等ができません。これは、デフォルトのコンテナはあらゆるデバイスに対して接続できないためであり、「privileged」(特権)コンテナのみが全てのコンテナに接続できます( lxc-template.gocgroups devices のドキュメントをご覧ください )

オペレータが docker run --privileged を実行すると、Docker はホスト上の全てのデバイスに対して接続可能になります。この時、 AppArmor や SELinux の設定があれば、ホスト上のコンテナ外のプロセスと同じように、ホスト上の同じアクセス権限が与えられた状態で利用可能になります。 --privileged の実行に関する追加情報については、 Docker ブログの投稿(英語) をご覧ください。

特定のデバイスに対する許可だけ加えたいときは、 --device フラグが使えます。これを指定すると、1つまたは複数のデバイスがコンテナ内から接続できるようになります。

$ docker run --device=/dev/snd:/dev/snd ...

デフォルトでは、コンテナはデバイスに対して readwritemknod 可能です。それぞれの --device フラグは、 :rwm という3つのオプション・セットで上書きできます。

$ docker run --device=/dev/sda:/dev/xvdc --rm -it ubuntu fdisk  /dev/xvdc

Command (m for help): q
$ docker run --device=/dev/sda:/dev/xvdc:r --rm -it ubuntu fdisk  /dev/xvdc
You will not be able to write the partition table.

Command (m for help): q

$ docker run --device=/dev/sda:/dev/xvdc:w --rm -it ubuntu fdisk  /dev/xvdc
    crash....

$ docker run --device=/dev/sda:/dev/xvdc:m --rm -it ubuntu fdisk  /dev/xvdc
fdisk: unable to open /dev/xvdc: Operation not permitted

--privileged に加え、オペレータは --cap-add--cap-drop を使うことで、機能に対する詳細な制御が可能になります。デフォルトでは、Docker はデフォルト機能の一覧を保持しています。次の表は、追加・削除可能な Linux 機能オプションの一覧です。

機能のキー(capability key) 機能説明
SETPCAP プロセスの機能を変更
SYS_MODULE カーネル・モジュールのロード(load)・アンロード(unload)
SYSRAWIO ランダム I/O ポート操作 (iopl(2) と ioperm(2)).
SYS_PACCT acct(2) を用いたプロセスのスイッチ回数のカウント有無
SYS_ADMIN システム管理オペレーションの処理範囲
SYS_NICE プロセスの nice 値 (nice(2), setpriority(2)) を上げるのと、任意プロセスに対する nice 値を設定
SYS_RESOURCE リソース上限の上書き
SYS_TIME システム・クロック (settimeofday(2), stime(2), adjtimex(2)) の設定
SYS_TTY_CONFIG vhangup(2) を使用。仮想ターミナル上で ioctl(2) オペレーションの関連権限
MKNOD mknod(2) で特別ファイルを作成
AUDIT_WRITE カーネル監査( auditing )ログに記録
AUDIT_CONTROL カーネルの監査( auditing )を有効化。監査フィルタルールの変更や、監査状態やフィルタリング・ルールの読み出し
MAC_OVERRIDE MAC 設定や状態の変更。Smack LSM 用の実装
MAC_ADMIN Mandatory アクセス・コントロール(MAC)の上書き。Smack Linux Security Module (LSM) 用の実装
NET_ADMIN 様々なネットワーク関連処理の実施
SYSLOG 特権 syslog(2) 処理の実施
CHOWN ファイルの UID と GID 属性を変更( chown(2) を参照)
NET_RAW RAW と PACKET ソケットを使用
DAC_OVERRIDE ファイル音読み書き実行時に迂回し、権限を確認
FOWNER 操作権限の確認時に迂回し、ファイルの UID がシステム上で必要とする UID と一致するか確認
DAC_READ_SEARCH ファイル読み込み権限の確認を迂回し、ディレクトリの読み込み・実行権限を確認
FSETID ファイル変更時にユーザ ID とグループ ID を変更しない
KILL シグナル送信時の権限確認をバイパス
SETGID プロセス GID を GID 一覧にある任意のものに変更
SETUID プロセス UID を任意のものに変更
LINUX_IMMUTABLE FS_APPEND_FL と FS_IMMUTABLE_FL i-node フラグを設定
NET_BIND_SERVICE ソケットをインターネット・ドメイン権限用のポート(ポート番号は 1024 以下)に割り当て
NET_BROADCAST ソケットをブロードキャストし、マルチキャストをリッスンする
IPC_LOCK メモリのロック(mlock(2), mlockall(2), mmap(2), shmctl(2))
IPC_OWNER System V IPC オブジェクト操作用の権限確認
SYS_CHROOT chroot(2) を使い、ルート・ディレクトリを変更
SYS_PTRACE ptrace(2) を使い、任意のプロセスをトレース
SYS_BOOT reboot(2) と kexec_load(2) を使い、後の処理用にリブートと新しいカーネルを読み込み
LEASE 任意のファイルのリースを確立(詳細は fcntl(2) )
SETFCAP ファイルの機能を設定
WAKE_ALARM システムを起動する何らかのトリガ
BLOCK_SUSPEND ブロック・システムをサスペンドする機能

よし詳細なリファレンス情報は Linux man ページの capabilities(7) をご覧ください。

オペレータは全ての機能を有効化するため ALL の値を使えますが 、 MKNOD だけ除外したい時は次のようにします。

$ docker run --cap-add=ALL --cap-drop=MKNOD ...

ネットワーク・スタックとやりとりするには、 --privileged を使う替わりに、ネットワーク・インターフェースの変更には --cap-add=NET_ADMIN を使うべきでしょう。

$ docker run -t -i --rm  ubuntu:14.04 ip link add dummy0 type dummy
RTNETLINK answers: Operation not permitted
$ docker run -t -i --rm --cap-add=NET_ADMIN ubuntu:14.04 ip link add dummy0 type dummy

FUSE を基盤とするファイルシステムをマウントするには、 --cap-add--device の両方を使う必要があります。

$ docker run --rm -it --cap-add SYS_ADMIN sshfs sshfs sven@10.10.10.20:/home/sven /mnt
fuse: failed to open /dev/fuse: Operation not permitted
$ docker run --rm -it --device /dev/fuse sshfs sshfs sven@10.10.10.20:/home/sven /mnt
fusermount: mount failed: Operation not permitted
$ docker run --rm -it --cap-add SYS_ADMIN --device /dev/fuse sshfs
# sshfs sven@10.10.10.20:/home/sven /mnt
The authenticity of host '10.10.10.20 (10.10.10.20)' can't be established.
ECDSA key fingerprint is 25:34:85:75:25:b0:17:46:05:19:04:93:b5:dd:5f:c6.
Are you sure you want to continue connecting (yes/no)? yes
sven@10.10.10.20's password:
root@30aa0cfaf1b5:/# ls -la /mnt/src/docker
total 1516
drwxrwxr-x 1 1000 1000   4096 Dec  4 06:08 .
drwxrwxr-x 1 1000 1000   4096 Dec  4 11:46 ..
-rw-rw-r-- 1 1000 1000     16 Oct  8 00:09 .dockerignore
-rwxrwxr-x 1 1000 1000    464 Oct  8 00:09 .drone.yml
drwxrwxr-x 1 1000 1000   4096 Dec  4 06:11 .git
-rw-rw-r-- 1 1000 1000    461 Dec  4 06:08 .gitignore
....

Docker デーモンを lxc 実行ドライバを使って起動する時( docker daemon --exec-driver=lxc )、オペレータは1つまたは複数の LXC オプションを --lxc-conf パラメータで指定できます。これにより、 lxc-template.go にある新しいパラメータの追加や既存のパラメータ上書きが可能です。将来的には、Docker ホストによっては LXC が使えなくなるかもしれないので、注意が必要です。そのため、特定の実装に関する設定操作をするため、LXC を直接操作するのに慣れておいた方が良いでしょう。

注釈

Docker デーモンに管理されているコンテナに対して、---lxc-conf を使いコンテナの設定を変更可能です。しかし Docker デーモンは変更が施されたことを把握できないため、自分自身で管理上の不一致を解決する必要があります。例えば、 --lxc-conf でコンテナの IP アドレスを設定しても、コンテナ内の /etc/hosts ファイルには反映されません。

ログ記録ドライバ(–log-driver)

Docker デーモンはコンテナごとに異なったログ記録ドライバを指定できます。コンテナのログ記録ドライバを指定するには、 docker run コマンドで --log-driver=VALUE を指定します。以下のオプションがサポートされています。

none コンテナのログ記録ドライバを無効化します。このドライバでは docker logs が機能しません。
json-file Docker に対応するデフォルトのログ記録ドライバです。ファイルに JSON メッセージを書き込みます。このドライバに対するオプションはありません。
syslog Docker に対応する Syslog ログ記録ドライバです。ログのメッセージを syslog に書き込みます。
journald Docker に対応する Journald ログ記録ドライバです。ログのメッセージを journald に書き込みます。
fluentd Docker に対応する Fluentd ログ記録ドライバです。ログ・メッセージを fluentd に書き込みます(forward input)。
awslogs Docker に対応する Amazon CloudWatch Logs ロギング・ドライバです。ログ・メッセージを Amazon CloudWatch Logs に書き込みます。

docker logs コマンドが使えるのは json-filejournald ログ記録ドライバのみです。ログ記録ドライバの詳細な情報については ログ記録ドライバの設定 をご覧ください。

Dockerfile イメージのデフォルトより優先

開発者が Dockerfile を使ってイメージ構築時やコミット時に、対象のイメージを使ってコンテナを起動するときに有効になる各種パラメータを、開発者自身が設定できます。

実行時に4つのコマンド FROMMAINTAINERRUNADD は上書きできません。それ以外のコマンド全ては docker run で上書きできます。開発者が Dockerfile で個々の命令を設定していたとしても、オペレータはその設定を上書きして操作できます。

CMD(デフォルトのコマンドかオプション)

Docker コマンドラインでのオプション コマンド を取り消します。

$ docker run [オプション] イメージ[:タグ|@DIGEST] [コマンド] [引数...]

このコマンドはオプションの指定です。 イメージ の作者が Dockerfile の CMD 命令を使い、デフォルトの コマンド を既に設定している場合があるためです。オペレータ(イメージからコンテナを十個売る人のこと)によって、 CMD 命令を上書きして新しい コマンド を実行します。

イメージに ENTRYPOINT も指定されていれば、 CMDコマンドENTRYPOINT に対する引数となります。

ENTRYPOINT(実行時に処理するデフォルトのコマンド)

--entrypoint="": Overwrite the default entrypoint set by the image

イメージの ENTRYPOINTコマンド と似ています。これはコンテナを開始する時に実行するコマンドを指定しているためです。しかし、こちらは(意図的に)上書きを難しくしています。 ENTRYPOINT が提供するのは、コンテナ自身が持つデフォルトの特性や振る舞いです。そのため ENTRYPOINT を指定しておくと、コンテナ実行時、あたかもコンテナ自身をバイナリのようにして実行することができるようにします。その場合は、デフォルトのオプションを持っているでしょうし、あるいは自分で コマンド を指定してオプションを指定することも可能です。しかし、時々オペレータはコンテナの中で何らかのコマンドを実行したい場合もあるでしょう。例えば、デフォルトの ENTRYPOINT のかわりに、自分で ENTRYPOINT を新たに指定したい場合です。次の例はコンテナ上でシェルを実行するものであり、同様に何らかのもの( /usr/bin/redis-server のように )を自動的に起動できます。

$ docker run -i -t --entrypoint /bin/bash example/redis

あるいは、次の2つの例は ENTRYPOINT に更にパラメータを渡すものです。

$ docker run -i -t --entrypoint /bin/bash example/redis -c ls -l
$ docker run -i -t --entrypoint /usr/bin/redis-cli example/redis --help

EXPOSE (受信用のポート)

run コマンドには、コンテナのネットワーク対応のために以下のオプションがあります。

--expose=[]: Expose a port or a range of ports inside the container.
             These are additional to those exposed by the `EXPOSE` instruction
-P=false   : Publish all exposed ports to the host interfaces
-p=[]      : Publish a container᾿s port or a range of ports to the host
               format: ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort | containerPort
               Both hostPort and containerPort can be specified as a
               range of ports. When specifying ranges for both, the
               number of container ports in the range must match the
               number of host ports in the range, for example:
                   -p 1234-1236:1234-1236/tcp

               When specifying a range for hostPort only, the
               containerPort must not be a range.  In this case the
               container port is published somewhere within the
               specified hostPort range. (e.g., `-p 1234-1236:1234/tcp`)

               (use 'docker port' to see the actual mapping)

--link=""  : Add link to another container (<name or id>:alias or <name or id>)

イメージの開発者は、EXPOSE 命令以外のネットワーク機能に関する管理は行えません。 EXPOSE 命令が定義するのは、サービスが初期化時に提供する受信用ポートです。このポートはコンテナの中のプロセスが利用可能にします。オペレータは --expose オプションを使うことで、公開用ポートを追加できます。

コンテナの内部ポートを公開(expose)するには、オペレータはコンテナ実行時に -P-p フラグを使えます。公開用のポートはホスト上でアクセス可能であり、そのポートはホストに到達可能なクライアントであれば誰でも利用できます。

-P オプションはホスト・インターフェース上に全てのポートを公開します。Docker は公開されたポートを、ホスト側のポートに対してランダムに拘束(bind)します。このポートの範囲を エフェメラル・ポート範囲(ephemeral port range) と呼び、 /proc/sys/net/ipv4/ip_local_port_range によって定義されています。 -p フラグを使うと、特定のポートやポートの範囲を割り当てます。

コンテナ内のポート番号(サービスがリッスンしているポート番号)は、コンテナの外に露出するポート番号(クライアントが接続する番号)と一致させる必要がありません。たとえば、コンテナ内の HTTP サービスがポート 80 をリッスンしているとします(そして、イメージ開発者は Dockerfile で EXPOSE 80 を指定しているでしょう )。実行する時に、ホスト側のポート 42800 以上が使われます。公開用ポートがホスト側のどのポートに割り当てられたかを確認するには、 docker port コマンドを使います。

デフォルトのブリッジ・ネットワークにおいて、新しいクライアント・コンテナの起動時にオペレータが --link を指定すると、クライアント・コンテナはプライベートなネットワーク・インターフェースを経由して公開ポートにアクセスできます。 Docker ネットワーク概要 にあるユーザ定義ネットワーク上で --link を指定すると、コンテナをリンクするためのエイリアス名を作成します。

ENV(環境変数)

新しいコンテナの作成時、Docker は以下の環境変数を自動的に設定します。

変数
HOME USER の値をベースにセット
HOSTNAME コンテナに関連づけられるホスト名
PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin のような一般的なディレクトリを含む
TERM コンテナが疑似ターミナル(pseudo-TTY)を割り当てるときは xterm

さらに、オペレータはコンテナに対して 環境変数の組み合わせ-e フラグで追加出来ます。先ほど言及した環境変数や、開発者が Dockerfile の中で ENV で定義済みの環境変数を上書きできます。

$ docker run -e "deep=purple" --rm ubuntu /bin/bash -c export
declare -x HOME="/"
declare -x HOSTNAME="85bc26a0e200"
declare -x OLDPWD
declare -x PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
declare -x PWD="/"
declare -x SHLVL="1"
declare -x container="lxc"
declare -x deep="purple"

似たようなものとして、オペレータは -hhostname (ホスト名) も定義できます。

TMPFS (tmfps ファイルシステムのマウント)

--tmpfs=[]: Create a tmpfs mount with: container-dir[:<options>],
            where the options are identical to the Linux
            'mount -t tmpfs -o' command.

この例では、オプションで rwnoexecnosuidsize=65536k 、コンテナに対して空の tmpfs をマウントしています。

$ docker run -d --tmpfs /run:rw,noexec,nosuid,size=65536k my_image

VOLUME(共有ファイルシステム)

-v=[]: Create a bind mount with: [host-dir:]container-dir[:<options>], where
options are comma delimited and selected from [rw|ro] and [z|Z].
       If 'host-dir' is missing, then docker creates a new volume.
       If neither 'rw' or 'ro' is specified then the volume is mounted
       in read-write mode.
--volumes-from="": Mount all volumes from the given container(s)

注釈

ホスト側のパスを自動作成する機能は 廃止 されました。

注釈

Docker デーモンの開始・停止を systemd で管理する場合は、 Docker デーモン自身がマウント・プロパゲーション(mount propagation)を管理できるよう、systemd の unit ファイル上で MountFlags というオプションを設定します。このマウントポイントが変更されても、Docker はマウント・プロパゲーションの変更を把握できません。例えば、値を slave としているのであれば、ボリュームのプロパゲーション値に sharedrshared を指定すべきではないでしょう。

ボリューム関連コマンドは コンテナでデータを管理する セクション自身のドキュメントでも複雑なものです。開発者は1つまたは複数の VOLUME を作成し、イメージと関連づけることが可能です。しかし、オペレータができるのは、あるコンテナから別のコンテナに対してのみです(あるいは、コンテナからホスト側のボリュームにマウントする場合)。

コンテナ側ディレクトリ/src/docs のように常に絶対パスの必要があります。 ホスト側ディレクトリ は絶対パスか 名前 の値を指定できます。 ホスト側ディレクトリ に絶対パスを指定する場合は、 Docker は指定したパスを拘束マウント(bind-mounts)します。 名前 を指定する場合は、Docker は 名前 を持つボリュームを作成します。

名前 は英数字で始まる必要があり、以降は a-z0-9_ (アンダースコア)、 . (ピリオド)、 - (ハイフン)が使えます。絶対パスは / (フォアワード・スラッシュ)で始める必要があります。

例えば、 ホスト側ディレクトリ の値に /foofoo を指定したとします。 /foo 値を指定した場合は、Docker はホスト上に拘束マウントを作成します。 foo を指定すると、Docker は指定された名前でボリュームを作成します。

USER

開発者は Dockerfile の USER 命令を使い、1つめのプロセスを実行する時のユーザを定義できます。コンテナが起動するとき、 -u オプションを使うと USER 命令を上書きできます。

-u="", --user="": Sets the username or UID used and optionally the groupname or GID for the specified command.

以下の例は無効です。

--user=[ user | user:group | uid | uid:gid | user:gid | uid:group ]

注釈

数値で UID を指定する場合は、0 ~ 2147483647 の範囲内の必要があります。

WORKDIR

コンテナ内でバイナリを実行する時、デフォルトの作業用ディレクトリはルート( / ) ディレクトリです。しかし開発者は Dockerfile の WORKDIR コマンドを使い、デフォルトの作業用ディレクトリを変更できます。オペレータが更に設定を上書きするには、次のようにします。

-w="": Working directory inside the container

参考

Docker run reference
https://docs.docker.com/engine/reference/run/