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つの標準ストリーム( STDIN
、 STDOUT
、 STDERR
)のうち、特定のものに対してのみ接続も可能です。
$ 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 から特別に扱われます。デフォルトの操作では、あらゆるシグナルを無視します。そのため、プロセスは SIGINT
か SIGTERM
で停止するようにコードを書かない限り、停止できません。
コンテナの識別¶
名前(–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 を再利用できるようにします。
コンテナがホスト上の特定のプロセス名前空間を共有する場合は、コンテナ内のプロセスが、システム上の全プロセスを基本的に見られるようにします。例えば、 strace
や gdb
のようなデバッグ用ツールを含むコンテナを構築したとき、コンテナ内のデバッグ用プロセスのみツールを使えるように指定する場合です。
$ 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 処理はファイルに対してか、 STDIN
と STDOUT
のみになります。
公開用のポートを他のコンテナとリンクできるのは、デフォルト(ブリッジ)のみです。リンク機能はレガシー(過去の)機能です。リンク機能を使うよりも、常に 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
でコンテナを見ると、常に Up
か Restarting
のどちらかです。また、再起動ポリシーが有効かどうかを確認するため、 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.go と cgroups devices のドキュメントをご覧ください )
オペレータが docker run --privileged
を実行すると、Docker はホスト上の全てのデバイスに対して接続可能になります。この時、 AppArmor や SELinux の設定があれば、ホスト上のコンテナ外のプロセスと同じように、ホスト上の同じアクセス権限が与えられた状態で利用可能になります。 --privileged
の実行に関する追加情報については、 Docker ブログの投稿(英語) をご覧ください。
特定のデバイスに対する許可だけ加えたいときは、 --device
フラグが使えます。これを指定すると、1つまたは複数のデバイスがコンテナ内から接続できるようになります。
$ docker run --device=/dev/snd:/dev/snd ...
デフォルトでは、コンテナはデバイスに対して read
、 write
、 mknod
可能です。それぞれの --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-file
と journald
ログ記録ドライバのみです。ログ記録ドライバの詳細な情報については ログ記録ドライバの設定 をご覧ください。
Dockerfile イメージのデフォルトより優先¶
開発者が Dockerfile を使ってイメージ構築時やコミット時に、対象のイメージを使ってコンテナを起動するときに有効になる各種パラメータを、開発者自身が設定できます。
実行時に4つのコマンド FROM
、 MAINTAINER
、 RUN
、 ADD
は上書きできません。それ以外のコマンド全ては docker run
で上書きできます。開発者が Dockerfile で個々の命令を設定していたとしても、オペレータはその設定を上書きして操作できます。
- CMD(デフォルトのコマンドかオプション)
- ENTRYPOINT(実行時に処理するデフォルトのコマンド)
- EXPOSE (受信用のポート)
- ENV(環境変数)
- VOLUME(共有ファイルシステム)
- USER
- WORKDIR
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"
似たようなものとして、オペレータは -h
で hostname (ホスト名) も定義できます。
TMPFS (tmfps ファイルシステムのマウント)¶
--tmpfs=[]: Create a tmpfs mount with: container-dir[:<options>],
where the options are identical to the Linux
'mount -t tmpfs -o' command.
この例では、オプションで rw
、 noexec
、 nosuid
、 size=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
としているのであれば、ボリュームのプロパゲーション値に shared
や rshared
を指定すべきではないでしょう。
ボリューム関連コマンドは コンテナでデータを管理する セクション自身のドキュメントでも複雑なものです。開発者は1つまたは複数の VOLUME
を作成し、イメージと関連づけることが可能です。しかし、オペレータができるのは、あるコンテナから別のコンテナに対してのみです(あるいは、コンテナからホスト側のボリュームにマウントする場合)。
コンテナ側ディレクトリ
は /src/docs
のように常に絶対パスの必要があります。 ホスト側ディレクトリ
は絶対パスか 名前
の値を指定できます。 ホスト側ディレクトリ
に絶対パスを指定する場合は、 Docker は指定したパスを拘束マウント(bind-mounts)します。 名前
を指定する場合は、Docker は 名前
を持つボリュームを作成します。
名前
は英数字で始まる必要があり、以降は a-z0-9
、_
(アンダースコア)、 .
(ピリオド)、 -
(ハイフン)が使えます。絶対パスは /
(フォアワード・スラッシュ)で始める必要があります。
例えば、 ホスト側ディレクトリ
の値に /foo
か foo
を指定したとします。 /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/