Docker run リファレンス¶
Docker はプロセスを隔離(isolated;分離)したコンテナ内(isolated container)で実行します。コンテナとは、ホスト上で動くプロセスです。ホストとはローカルまたはリモート環境です。作業者が docker run
を実行したら、コンテナのプロセスを隔離(分離)して実行します。コンテナは自身のファイルシステムとネットワーク機能を持ち、ホスト上の他のプロセスツリーからは隔離(分離)されています。
このページでは、docker run
コマンドを使い、実行時にコンテナのリソースを定義する方法を説明します。
一般的な形式¶
基本的な docker run
コマンドは、以下の構成です。
$ docker run [オプション] イメージ[:タグ|@ダイジェスト値] [コマンド] [引数...]
docker run
コマンドは、コンテナ作成の元となる イメージ の指定が必要です。イメージの開発者は、イメージに関連するデフォルト値を定義できます。
デタッチド(detached)あるいはフォアグラウンド(foreground)で実行
コンテナの識別
ネットワーク設定
実行時の CPU とメモリを制限
開発者がイメージに指定したデフォルト設定は、作業者は docker run [オプション]
の実行とともに、設定追加や上書きが可能です。そして更に、Docker ランタイム自身に設定されている、ほぼ全てのデフォルト設定も上書きできます。どうして run コマンドには、他の docker
コマンドより多くのオプションがあるかの理由は、作業者がイメージと Docker ランタイムのデフォルト設定を上書きするためです。
様々な種類の [オプション]
を理解するには、 オプションの種類 をご覧ください。
注釈
Docker システムの設定に依存しますが、 docker run
コマンドの前に、 sudo
を付けて実行する必要があるかもしれません。 docker
コマンドで sudo
を使わないようにするには、システム管理者に docker
という名称のグループが作成できるかどうかたずね、あなたのユーザをそのグループに追加するよう依頼してください。この設定に関するより詳しい情報は、各オペレーティングシステム向けの Docker インストール用ドキュメントをご覧ください。
作業者専用のオプション¶
作業者( docker run
の実行者 )のみ、以下のオプションを設定できます。
-
-
実行時の権限、Linux 機能、LXC 設定
デタッチド vs フォアグラウンド¶
Docker コンテナの起動時、最初に決める必要があるのは、コンテナをバックグラウンドで「デタッチド」(detached )モードで実行するか、デフォルトのフォアグラウンド(foreground)モードで実行するかです。
-d=false: デタッチドモードとは、バックグラウンドでコンテナを実行し、新しいコンテナ ID を表示する
デタッチド (-d)¶
デタッチドモードでコンテナを起動するには、 -d=true
か、単に -d
オプションを使います。設計上、デタッチドモードで起動したコンテナは、このコンテナ実行時に使うルートプロセスが終了すると、 --rm
オプションも指定していない限りコンテナを終了します。 -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 のような挙動をするだけでなく(これは、ほとんどのコマンドライン操作が実行できると予測できるため)、シグナルも渡せます。これら全ては調整できます。
-a=[] : 「STDIN」「STDOUT」「STDERR」のいずれか、またはすべてにアタッチ
-t=false : 議事 tty(pseudo-tty)の割り当て
--sig-proxy=true: 受信したシグナルを、すべて対象プロセスに対してプロキシする(TTY モード以外のみ)
-i=false : アタッチしていなくても、STDIN を開き続ける
-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 長い識別子(long identifier) |
"f78375b1c487e03c9438c729345e54db9d20cfa2ac1fc3494b6eb60872e74778" |
UUID 短い識別子(short identifier) |
“f78375b1c487” |
名前 |
“evil_ptolemy” |
UUID 識別子は Docker デーモンから与えられます。コンテナの名前を --name
オプションで割り当てなければ、デーモンはランダムな文字列から名前を生成します。 name
(名前)の定義とは、 コンテナに対する用途を加えるために便利な方法です。 name
の指定があれば、 Docker ネットワーク内でコンテナを参照するために使えます。バックグラウンドとフォアグラウンド、どちらの Docker コンテナでも参照できます。
注釈
コンテナがデフォルトのブリッジネットワーク上にある場合、コンテナ名で通信するにはリンクする必要があります。
PID 相当の機能¶
あとは、自動化に役立つよう、Docker にコンテナ ID を指定したファイルに対して書き出せます。これは、プログラムがプロセス ID をファイルに書き出す方法と似ています(いわゆる PID ファイル)。
--cidfile="": コンテナの ID をファイルに書き出す
イメージ[:タグ]¶
正確には、コンテナ名を識別する手段ではありませんが、コンテナ実行時のコマンドに イメージ[:タグ]
を追加すると、イメージのバージョンを指定してコンテナを起動できます。例えば docker run ubuntu:14.04
と実行します。
イメージ[@ダイジェスト値]¶
イメージ形式 v2 以降のイメージは、内容に対して割り当てられる digest (ダイジェスト値)と呼ぶ識別子(content-addressable identifier)を持っています。イメージ作成に使う入力内容に変更がなければ、ダイジェスト値とは予想されうる値であり、(内容が正しいものかどうか)照会可能なものです。
次の例は、 alpine
イメージのダイジェスト値 sha256:9cacb71397b640eca97488cf08582ae4e4068513101088e9f96c9814bfda95e0
を使い、コンテナを実行する例です。
$ docker run alpine@sha256:9cacb71397b640eca97488cf08582ae4e4068513101088e9f96c9814bfda95e0 date
PID 設定(--pid)¶
--pid="" : コンテナに対する PID (プロセス)名前空間モードを指定
'container:<名前|id>': 他のコンテナの PID 名前空間に参加
'host': コンテナ内でホスト側の PID 名前空間を使う
デフォルトでは、全てのコンテナで PID 名前空間(PID namespace)が有効な状態です。
PID 名前空間はプロセスの分離をもたらします。PID 名前空間はシステム側のプロセス表示を制限し、かつ、pid 1 を含むプロセス ID を再利用できるようにします。
ホスト上のプロセス名前空間をコンテナと共有する場合、コンテナ内のプロセスは、基本的にシステム上の全プロセスを見られるようにします。例えば、 strace
や gdb
のようなデバッグ用ツールを含むコンテナを構築したとして、デバッグ処理時のみ、コンテナ内で各ツールを使えるように指定したい場合です。
例:コンテナ内で htop を実行¶
Dockerfile を作成します:
FROM alpine:latest
RUN apk add --update htop && rm -rf /var/cache/apk/*
CMD ["htop"]
Dockerfile を構築し、イメージに myhtop
とタグ付け:
$ docker build -t myhtop .
コンテナ内で htop
を実行するため、次のコマンドを使う:
$ docker run -it --rm --pid=host myhtop
他コンテナの pid 名前空間への参加は、コンテナのデバッグ用途に役立ちます。
例¶
redis サーバが動くコンテナを起動:
$ docker run --name my-redis -d redis
redis コンテナをデバッグするため、strace が入った別のコンテナを実行。
$ docker run --it --pid=container:my-redis bash
$ strace -p 1
UTS 設定(--uts)¶
--uts="" : コンテナに対して UTS 名前空間モードを設定する
'host': コンテナ内でホストの UTS 名前空間を使用
UTS 名前空間とは、プロセスが実行中の名前空間上で見えるホスト名とドメイン名を設定します。デフォルトでは、全てのコンテナが、自身の UTS 名前空間を持ちます。これには --network=host
の場合も含みます。 host
設定の結果、ホスト上と同じ UTS 名前空間をコンテナで使えます。なお、 host
UTS モードでは、 --hostname
と --domainname
を指定できないため、ご注意ください。
ホスト上と UTS 名前空間を共有したい場合もあるでしょう。例えば、コンテナを動かすホストがホスト名を変更すると、コンテナのホスト名も変更したい場合です。より高度な使い方としては、コンテナからホスト側のホスト名の変更を変更します。
IPC 設定(--ipc)¶
--ipc="" : コンテナに対し、 IPC モードを設定する
次の値を指定できます。
値 |
説明 |
---|---|
"" |
デーモンのデフォルトを使用 |
"none" |
/dev/shm をマウントしない、自身のプライベートな IPC 名前空間 |
"private" |
自身のプライベートな IPC 名前空間 |
"shareable" |
他のコンテナと共有もできる、自身のプライベートな IPC 名前空間 |
"container:<名前かID>" |
他の「共有可能な」コンテナの IPC 名前空間に参加 |
"host" |
ホストシステムの IPC 名前空間を使用 |
指定がなければ、デーモンはデフォルトを使用します。これは、 "private"
か "shareable"
のどちらかであり、デーモンのバージョンと設定に依存します。
IPC (POSIX/SysV IPC) 名前空間は、
プロセス間通信において、パイプを通したりネットワーク・スタックを通すよりも、共有メモリ・セグメントでメモリ速度を向上するために使われていました。共有メモリが一般的に使われるのは、データベースや、科学計算や金融サービス産業向けの高性能アプリケーション用カスタム・ビルド(典型的なのは、C/OpenMPI、C++ の高速化ライブラリ)に用いられます。この種のアプリケーションが複数のコンテナに分割される場合は、コンテナの IPC 機構を使って共有する必要があるでしょう。メインの(例: "donor")コンテナに対して "shareable"
モードを使い、他のコンテナに対しては "container:<donorという名前、あるいはID>"
を使います。
ネットワーク設定¶
--dns=[] : コンテナに対し、任意の DNS サーバを設定
--net="bridge" : コンテナをネットワークに接続
'bridge': デフォルトのDocker ブリッジ上で、コンテナに対する新しいネットワーク・スタックを作成
'none': コンテナにネットワーク機能を付けない
'container:<名前|id>': 他のコンテナ用ネットワーク・スタックを再利用
'host': Docker ホスト側のネットワーク・スタックを使用
'<ネットワーク名>|<ネットワークID>': 「docker network create」コマンドでユーザ作成したネットワークを使用
--net-alias=[] : コンテナにネットワーク内部用のエイリアスを追加
--add-host="" : /etc/hosts に行を追加(ホスト名:IPアドレス)
--mac-address="" : コンテナのイーサネット・デバイス Mac アドレスを指定
--ip="" : コンテナのイーサネット・デバイスに IPv4 アドレスを指定
--ip6="" : コンテナのイーサネット・デバイスに IPv6 アドレスを指定
--link-local-ip=[] : コンテナのイーサネットデバイスに IPv4/IPv6 リンクローカルアドレスを指定
デフォルトでは、全てのコンテナでネットワーク機能が有効なため、外側への通信ができます。作業者がネットワークを無効化したい場合は docker run --net=none
を指定し、内側と外側の両方のネットワーク機能を無効化できます。このように指定すると、 I/O 処理はファイルを通して行うか、あるいは、 STDIN
と STDOUT
を通してのみになります。
ポートの公開や、他のコンテナへの
デフォルトでは、コンテナはホスト側と同じ DNS サーバを使いますが、 --dns
の指定で上書きできます。
デフォルトでは、コンテナに割り当てられる IP アドレスを使い、MAC アドレスを生成します。コンテナに MAC アドレスを指定するには、 --mac-address
パラメータ(書式: 12:34:56:78:9a:bc
)を使って MAC アドレスを指定できます。 Docker は指定された MAC アドレスがユニークかどうか(重複しているかどうか)を確認する仕組みが無いため、(MAC アドレスを手動で指定する場合は、重複しないように)ご注意ください。
サポートしているネットワーク:
ネットワーク |
説明 |
---|---|
none |
コンテナにネットワーク機能を持たせません。 |
bridge (デフォルト) |
コンテナを各インターフェースに接続します。 |
host |
コンテナ内でホスト側のネットワーク・スタックを使います。 |
container: <名前|id> |
他のコンテナ名か ID を指定し、そのネットワーク・スタックを使います。 |
NETWORK |
ユーザが作成したネットワーク( |
ネットワーク:none¶
ネットワークに none
を指定するコンテナは、外部の経路に対してアクセスできません。コンテナ内では loopback
(ループバック)インターフェースが有効ですが、外部のトラフィックに対する経路はありません。
ネットワーク:bridge¶
ネットワークを bridge
に指定すると、コンテナは Docker のデフォルト・ネットワーク機能を使用します。ブリッジはホスト上で設定されるもので、通常は docker0
という名前ですす。そして、個々のコンテナに対して、一組の veth
インターフェースが作成されます。 veth
ペアの片方は、ルールバック・インターフェースに加え、コンテナの名前空間内に置かれます。また、その間、もう一方はブリッジに接続しているホスト上に残り続けます。IP アドレスは、ブリッジ・ネットワーク上のコンテナに対して割り当てられ、コンテナに対するトラフィックはこのブリッジを経由します。
デフォルトでは、コンテナは各々の IP アドレスを経由して通信できます。コンテナ名で通信するには、コンテナ名でリンクする必要があります。
ネットワーク:host¶
ネットワークを host
に設定したコンテナは、ホスト上のネットワーク・スタックを共有し、ホスト上すべてのインターフェースをコンテナ上でも利用可能になります。コンテナのホスト名は、ホストシステム上のホスト名と一致します。 host
ネットワーク・モードでは、 --mac-address
が無効になるのでご注意ください。 たとえ host
ネットワーク・モードだとしても、コンテナは自身の UTS 名前空間をデフォルトで持ちます。そのため、 host
ネットワーク・モードで --hostname
と --domainname
が許可されるのは、コンテナの中でホスト名とドメイン名を変えるだけです。 --hostname
同様に、 --add-host
、 --dns
、 --dns-search
、 --dns-opt
オプションは host
ネットワーク・モードで利用可能です。これらのオプションはコンテナ内の /etc/hosts
や /etc/resolv.conf
を更新するだけです。ホスト側の /etc/hosts
や /etc/resolv.conf
は変更しません。
デフォルトの bridge
モードと比べ、 host
モードはホスト側のネイティブなネットワーク・スタックを使用するため、ネットワーク性能が 著しく 向上する一方、ブリッジでは docker デーモンを通して一段階の仮想化をする必要があります。プロダクションのロードバランサや高性能なウェブサーバのような、ネットワーク性能が重要な環境では、このモードでのコンテナ実行を推奨します。
注釈
--net="host"
の指定時は、コンテナは D-bus のようなローカル・システム・サービスに対してフルアクセス可能なため、安全ではないと考えられます。
ネットワーク:container¶
コンテナに対して container
(コンテナ)ネットワークを指定しますと、他のコンテナとネットワーク・スタックを共有します。他のコンテナ名は --network 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 ネットワーク・ドライバか外部のネットワーク・ドライバ・プラグインを使います。同じネットワークに対して、複数のコンテナが接続できます。
overlay
ネットワークや、複数のホストへの接続性をサポートしているカスタム・プラグインでは、同じマルチホスト・ネットワークに接続していれば、別々のエンジンで起動したコンテナだとしても、このネットワークを通して通信可能です。
以下の例は、組み込みの bridge
ネットワーク・ドライバを使ってネットワークを作成し、作成したネットワーク内でコンテナを実行します。
$ docker network create -d bridge my-net
$ docker run --net=my-net -itd --name=container3 busybox
/etc/hosts の管理¶
コンテナの /etc/hosts
には、コンテナ自体のホスト名や、 localhost
、その他一般的な項目があります。 /etc/hosts
に行を追加するには --add-host
フラグを使います。
$ 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 (停止していない場合) |
Docker デーモンの停止前にコンテナが停止上状態になっていた場合を除き、デーモンの起動時も含め、コンテナの終了ステータスに関係なく、常にコンテナの再起動を試みます。 |
サーバが溢れかえるのを防ぐため、再起動の前に遅延時間が追加されます(遅延は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
を同時に指定すると、エラーになります。コンテナの再起動時、アタッチしているクライアントは切断されます。 ``--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 ポリシーに対してのみ有効です。
終了ステータス(Exit Status)¶
docker run
の終了コードから得られる情報は、なぜコンテナが実行に失敗したかや、なぜ終了したかです。 docker run
がゼロ以外のコードで終了する時、終了コードは chroot
標準に従います。
125 は Docker デーモン 自身 のエラー発生です。
$ docker run --foo busybox; echo $?
flag provided but not defined: --foo
See 'docker run --help'.
125
( 定義されていない --foo フラグを指定したため、エラー )
126 は コンテナ内のコマンド が実行できない場合のエラーです。
$ docker run busybox /etc; echo $?
docker: Error response from daemon: Container command '/etc' could not be invoked.
126
( 「/etc」には実行権限がない、というエラー)
127 は コンテナ内のコマンド が見つからない場合です。
$ docker run busybox foo; echo $?
docker: Error response from daemon: Container command 'foo' not found or does not exist.
127
(環境変数 $PATH の中に "foo" 実行ファイルが見つかりません、というエラー)
コンテナ内におけるコマンド の 終了コード は上書きできます。
$ docker run busybox /bin/sh -c 'exit 3'; echo $?
3
クリーンアップ(--rm)¶
デフォルトではコンテナを終了しても、コンテナのファイルシステム(の内容)を保持し続けます。そのため、デバッグはとても簡単になり(最後の状態を確認できるため)、デフォルトで全てのデータが保持されます。しかし、プロセスを短い期間だけ フォアグラウンド で動かしたとしても、これらのコンテナのファイルシステムが溜まり続ける場合があります。そうではなく、 コンテナの終了時に、自動的にコンテナをクリーンアップし、ファイルシステムを削除する には --rm
フラグを追加します。
--rm=false: Automatically remove the container when it exits
注釈
--rm
フラグを設定したら、コンテナの削除時、関連する docker rm -v my-container
の実行と同じです。ただし、名前を指定しなかったボリュームのみ削除します。例えば、次のコマンドを実行したとします。
docker run --rm -v /foo -v awesome:/bar busybox top
/foo
ボリュームは削除されますが、 /bar
は削除されません。 --volume-form
で継承しているボリュームが削除されるのと同じ仕組みです。このように、元のボリュームに名前が指定されていれば、そこは削除 されません 。
セキュリティ設定¶
|
コンテナの user ラベルを指定 |
---|---|
|
コンテナの role ラベルを指定 |
|
コンテナの type ラベルを指定 |
|
コンテナの level ラベルを指定 |
|
コンテナのラベル割り当てを無効化 |
|
コンテナに適用する apparmor profile を指定 |
|
コンテナが新しい特権権限を得るのを無効化 |
|
コンテナに対する seccomp 制限を無効化 |
|
sccomp フィルタで使うホワイトリスト syscall seccomp JSON ファイルを指定 |
各コンテナに対するデフォルトの --security-opt
フラグの指定で上書き可能です。コンテナ間で同じ内容を共有できるようレベルを指定するには、次のようにコマンドを実行します。
$ docker run --security-opt label=level:s0:c100,c200 -it fedora bash
注釈
MLS ラベルの自動変換は、現在サポートしていません。
コンテナに対するセキュリティ・ラベリングを無効化するには、 --permissive
フラグを使うのではなく、次のように指定します。
$ docker run --security-opt label=disable -i -t fedora bash
コンテナ内のプロセスに対して、より厳密なセキュリティ・ポリシーを適用するには、コンテナに対して何らかのタイプを指定します。次のコマンドを実行すると、Apache のポートだけがリスニングが許可されたコンテナを実行できます。
$ docker run --security-opt label=type:svirt_apache_t -it centos bash
注釈
ここでは svirt_apache_t
タイプ に対する書き込みポリシーが定義されていると想定しています。
コンテナのプロセスが、特権を追加できないようにするには、次のコマンドを実行します。
$ docker run --security-opt no-new-privileges -it centos bash
この指定により、 su
や sudo
のような権限昇格コマンドを機能しなくします。また、特権を落とした後に、あらゆる seccomp フィルタが適用されますので、フィルタ設定がより厳格に適用されるのを意味します。より詳しい情報は、 カーネルのドキュメント をご覧ください。
init プロセスの指定¶
--init
プラグを使うと、コンテナ内で PID 1 として使われるべき init プロセスを指定できます。init プロセスの指定とは、ゾンビプロセスの回収のような処理を作成したコンテナ内で行い、init システムにおける通常の処理を確実に担います。
デフォルトの init プロセスには、Docker デーモンプロセスのシステムパス上で、最初に実行可能な docker-init
を使います。この docker-init
バイナリは、デフォルトのインストールに含まれており、 tiny の支援を受けています。
カスタム cgroups の指定¶
--cgroup-parent
フラグを使うことで、コンテナを特定の cgroup で実行できるようにします。これにより自分自身で cgroup の作成や管理をできます。各 cgroup に対してカスタム・リソースを定義でき、コンテナを共通する親グループ下に配置できます。
実行時のリソース制限¶
作業者はコンテナのパフォーマンス・パラメータも調整できます。
|
メモリの上限(書式: |
---|---|
|
合計メモリの上限(メモリ+スワップ、書式: |
|
メモリのソフト・リミット(書式: |
|
カーネル・メモリの上限(書式: |
|
CPU 共有(CPU shares)を相対値で指定 |
|
CPU 数です。数値は小数です。0.000 は無制限を意味します。 |
|
CPU CFS (Completely Fair Scheduler) ピリオドの上限(訳者注:cgroup による CPU リソースへのアクセスを再割り当てする間隔) |
|
実行する CPU の割り当て(0-3, 0,1) |
|
実行するメモリ・ノード(MEM)の割り当て(0-3, 0,1)。NUMA システムのみで動作 |
|
CPU CFS (Completely Fair Scheduler) のクォータを設定 |
|
CPU real-time period を設定。マイクロ秒で指定。設定には親 cgroups が必要で、親を越えられない。また、rtprio ulimits も確認する。 |
|
CPU real-time runtime を設定。マイクロ秒で指定。設定には親 cgroups が必要で、親を越えられない。また、rtprio ulimits も確認する。 |
|
ブロック I/O ウエイト(相対値)を 10 ~ 1000 までの値でウエイトを設定 |
|
ブロック I/O ウエイト(相対デバイス値、書式: |
|
デバイスからの読み込みレートを制限(書式: |
|
デバイスからの書き込みレートを制限(書式: |
|
デバイスからの読み込みレート(1秒あたりの IO)を制限(書式: |
|
デバイスからの書き込みレート(1秒あたりの IO)を制限(書式: |
|
コンテナを OOM killer による停止を無効化するかどうか指定 |
|
コンテナの OOM 設定を調整( -1000 から 1000 ) |
|
コンテナがメモリのスワップ度合いを調整。整数値の 0 ~ 100 で指定 |
|
|
ユーザ・メモリの制限¶
ユーザのメモリ使用量を指定するには、4つの方法があります。
オプション |
結果 |
---|---|
memory=inf, memory-swap=inf (デフォルト) |
コンテナに対する上限を設けない。コンテナは必要な分のメモリを使える |
memory=L<inf, memory-swap=inf |
(memory を指定し、memory-swap を |
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 のスワップ・メモリを使えます。
-m
か --memory
オプションがある時のみ、コンテナに対して
メモリ予約の値は、常にハード・リミット以下に設定しなければ、ハード・リミットが先に処理されてしまいます。予約値を 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-kill-disable
オプションを使います。また、 -m/--memory
オプションを指定した時のみ、コンテナに対する OOM キラーを無効化できます。もし -m
フラグがセットされなければ、ホスト側でアウト・オブ・メモリ処理が発生します。また、ホスト側のシステム・プロセスが空きメモリを必要とするため、対象のプロセスを
次の例はメモリの上限を 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
コンテナは無制限にメモリを使えるため、ホスト上のメモリを使い果たしたら、空きメモリ確保のために、システム・プロセスを停止する必要が出てきます。 --oom-score-adj
パラメータを指定すると、システムのメモリが不足した場合、コンテナを強制終了する優先順位を選択できるます。負のスコアであれば強制終了される可能性は低くなり、対して、正のスコアの場合は高くなります。
カーネル・メモリ制限 ¶
カーネル・メモリはユーザ・メモリとは根本的に異なり、
stack pages
slab pages
sockets memory pressure
tcp memory pressure
これらのメモリを制限するため、カーネル・メモリの上限を設定できます。例えば、各プロセスが同じ
カーネル・メモリはユーザ・メモリとは完全に独立しています。その代わり、ユーザ・メモリを制限すると同時に、カーネル・メモリの制限も必要です。上限の設定には3つの方法があります。ここでは、「U」はユーザ・メモリの上限で、「K」はカーネルの上限とみなしています。
オプション |
結果 |
---|---|
U != 0, K = inf (デフォルト) |
カーネル・メモリが使う前に、標準的なメモリ制限を設ける仕組み。カーネル・メモリは完全に無視される。 |
U != 0, K < U |
カーネル・メモリをユーザ・メモリのサブセットとする。この設定は cgroup ごとに大きな合計メモリ容量をオーバーコミットで割り当て、デプロイする場合に使いやすい。範囲が再利用できないメモリ領域の場合が有り得るため、カーネル・メモリ制限のオーバーコミットは、全く推奨されていない。この例では、 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 のカーネル・メモリを使います。
スワップ回避制限 ¶
デフォルトでは、コンテナのカーネルは、 --memory-swappiness
で 0 ~ 100 までの値で指定します。この値が 0 であれば --memory-swappiness
を指定しなければ、メモリの
たとえば、次のように指定できます。
$ docker run -ti --memory-swappiness=0 ubuntu:14.04 /bin/bash
--memory-swappiness
オプションは、コンテナの
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 周期の半分のため)。
--cpu-period
および --cpu-quota
を使用して CPU 周期の制限を設定するほかに、 --cpus
を小数値で指定しても、同じ目的を達成できます。例えば、CPU が1つの場合、 --cpus=0.5
の指定とは、 --cpu-period=50000
および --cpu-quota=25000
(CPU の 50%)と同じ結果です。
--cpu
のデフォルト値は 0.000
であり、これは無制限です。
より詳しい情報については、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 システム上でのみ、どのコンテナをメモリ上で実行するか設定できます。
例:
$ 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 ウエイトを指定します。
注釈
blkid ウェイトは
--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-weight-device="デバイス名:ウェイト"
は、特定のデバイスに対するウェイトを指定します。 デバイス名:ウェイト
の文字列には、コロン記号を使って、デバイス名とウェイトを区切ります。例えば、 /dev/sda
に対するウェイトを 200
にするには、次のようにします。
$ docker run -it \
--blkio-weight-device "/dev/sda:200" \
ubuntu
--blkio-weight
と --blkio-weight-device
の両方を指定すると、 Docker は --blkio-weigh
をデフォルトのウェイトとして扱い、 --blkio-weight-device
は、指定したデバイスに対し、新しいデフォルト値として上書きします。以下の例はデフォルトのウェイトとして 300
を指定し、 /dev/sda
に対するデフォルトのウェイトは 200
に指定します。
$ docker run -it \
--blkio-weight 300 \
--blkio-weight-device "/dev/sda:200" \
ubuntu
--device-read-bps
フラグは、デバイスからの読み込みレート(バイト/秒)を制限します。たとえば、このコマンドはコンテナを作成し、 /dev/sda
からの読み込みレートを秒間 1mb
とします。
$ docker run -it --device-read-bps /dev/sda:1mb ubuntu
--device-write-bps
フラグは、デバイスからの書き込みレート(バイト/秒)を制限します。たとえば、このコマンドはコンテナを作成し、 /dev/sda
からの書き込みレートを秒間 1mb
とします。
$ docker run -it --device-write-bps /dev/sda:1mb ubuntu
<デバイスのパス>:<制限>[単位]
の書式で、フラグと制限の両方を設定できます。読み込みと書き込みレートは、正の整数の必要があります。レートは kb
(キロバイト)、 mb
(メガバイト)、 gb
(ギガバイト)のいずれかを指定できます。
--device-read-iops
フラグは、デバイスからの読み込みレート(IO/秒)を制限します。たとえば、このコマンドはコンテナを作成し、 /dev/sda
からの読み込みレートを秒間 1000
IO とします。
$ docker run -ti --device-read-iops /dev/sda:1000 ubuntu
--device-write-iops
フラグは、デバイスからの書き込みレート(IO/秒)を制限します。たとえば、このコマンドはコンテナを作成し、 /dev/sda
からの書き込みレートを秒間 1000
IO とします。
$ docker run -ti --device-write-iops /dev/sda:1000 ubuntu
<デバイスのパス>:<制限>
の書式で、フラグと制限の両方を設定できます。読み込みと書き込みレートは、正の整数の必要があります。
グループの追加 ¶
--group-add: 実行時のグループを追加
デフォルトでは、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 ケーパビリティ ¶
オプション |
説明 |
---|---|
|
Linux ケーパビリティの追加 |
|
Linux ケーパビリティの |
|
コンテナに |
|
--privileged(特権)フラグが無いコンテナ内でも、デバイスの実行を許可 |
デフォルトでは、Docker コンテナは「unprivileged」(権限が無い)ため、例えば、Docker コンテナの中で Docker デーモンを実行できません。これは、デフォルトのコンテナは、どのデバイスに対しても接続できないためであり、「privileged」(特権)コンテナのみが全てのデバイスに接続できるからです( 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 ケーパビリティのオプション一覧です。
ケーパビリティの説明 |
|
---|---|
AUDIT_WRITE |
カーネル監査( auditing )ログに記録 |
CHOWN |
ファイルの UID と GID 属性を変更( chown(2) を参照) |
DAC_OVERRIDE |
ファイル音読み書き実行時に迂回し、権限を確認 |
FOWNER |
操作権限の確認時に迂回し、ファイルの UID がシステム上で必要とする UID と一致するか確認 |
FSETID |
ファイル変更時にユーザ ID とグループ ID を変更しない |
KILL |
シグナル送信時の権限確認をバイパス |
MKNOD |
mknod(2) で特別ファイルを作成 |
NET_BIND_SERVICE |
ソケットをインターネット・ドメイン権限用のポート(ポート番号は 1024 以下)に割り当て |
NET_RAW |
RAW と PACKET ソケットを使用 |
SETFCAP |
ファイルのケーパビリティを設定 |
SETGID |
プロセス GID を GID 一覧にある任意のものに変更 |
SETPCAP |
プロセスのケーパビリティを変更 |
SETUID |
プロセス UID を任意のものに変更 |
SYS_CHROOT |
chroot(2) を使い、ルート・ディレクトリを変更 |
次の表は、デフォルトでは許可されていないものおん、追加可能なケーパビリティの一覧です。
ケーパビリティの説明 |
|
---|---|
AUDIT_CONTROL |
Enable and disable kernel auditing; change auditing filter rules; retrieve auditing status and filtering rules. |
AUDIT_READ |
Allow reading the audit log via multicast netlink socket. |
BLOCK_SUSPEND |
Allow preventing system suspends. |
BPF |
Allow creating BPF maps, loading BPF Type Format (BTF) data, retrieve JITed code of BPF programs, and more. |
CHECKPOINT_RESTORE |
Allow checkpoint/restore related operations. Introduced in kernel 5.9. |
DAC_READ_SEARCH |
Bypass file read permission checks and directory read and execute permission checks. |
IPC_LOCK |
Lock memory (mlock(2), mlockall(2), mmap(2), shmctl(2)). |
IPC_OWNER |
Bypass permission checks for operations on System V IPC objects. |
LEASE |
Establish leases on arbitrary files (see fcntl(2)). |
LINUX_IMMUTABLE |
Set the FS_APPEND_FL and FS_IMMUTABLE_FL i-node flags. |
MAC_ADMIN |
Allow MAC configuration or state changes. Implemented for the Smack LSM. |
MAC_OVERRIDE |
Override Mandatory Access Control (MAC). Implemented for the Smack Linux Security Module (LSM). |
NET_ADMIN |
Perform various network-related operations. |
NET_BROADCAST |
Make socket broadcasts, and listen to multicasts. |
PERFMON |
Allow system performance and observability privileged operations using perf_events, i915_perf and other kernel subsystems |
SYS_ADMIN |
Perform a range of system administration operations. |
SYS_BOOT |
Use reboot(2) and kexec_load(2), reboot and load a new kernel for later execution. |
SYS_MODULE |
Load and unload kernel modules. |
SYS_NICE |
Raise process nice value (nice(2), setpriority(2)) and change the nice value for arbitrary processes. |
SYS_PACCT |
Use acct(2), switch process accounting on or off. |
SYS_PTRACE |
Trace arbitrary processes using ptrace(2). |
SYS_RAWIO |
Perform I/O port operations (iopl(2) and ioperm(2)). |
SYS_RESOURCE |
Override resource Limits. |
SYS_TIME |
Set system clock (settimeofday(2), stime(2), adjtimex(2)); set real-time (hardware) clock. |
SYS_TTY_CONFIG |
Use vhangup(2); employ various privileged ioctl(2) operations on virtual terminals. |
SYSLOG |
Perform privileged syslog(2) operations. |
WAKE_ALARM |
Trigger something that will wake up the system. |
より詳細なリファレンス情報は Linux man ページの capabilities(7) と、 Linux カーネルのソースコード をご覧ください。
作業者は全ての機能を有効化するために ALL
値を使えますが 、 MKNOD
だけ除外したい時は次のようにします。
$ docker run --cap-add=ALL --cap-drop=MKNOD ...
--cap-add
と --cap-drop
フラグは CAP_
プレフィックスのケーパビリティを指定を許容します。つまり、以下の例はどちらも同じです。
$ docker run --cap-add=SYS_ADMIN ...
$ docker run --cap-add=CAP_SYS_ADMIN ...
ネットワーク・スタックとやりとりするには、 --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
....
デフォルトの seccomp profile は特定のケーパビリティでファシリティを使えるようになりました。
ログ記録ドライバ (--log-driver)¶
コンテナは Docker デーモンと異なる docker run
コマンドで --log-driver=VALUE
を指定します。以下のオプションがサポートされています。
|
コンテナのログ記録ドライバを無効化します。このドライバでは |
|
Docker に対応するデフォルトのログ記録ドライバです。ファイルに JSON メッセージを書き込みます。このドライバに対するオプションはありません。 |
|
Docker に対応する Syslog ログ記録ドライバです。ログのメッセージを syslog に書き込みます。 |
|
Docker に対応する Journald ログ記録ドライバです。ログのメッセージを |
|
Docker に対応する Graylog Extended Log Format (GELF) ログ記録ドライバです。ログのメッセージを Graylog や Logstash のような GELF エンドポイントに書き込みます。 |
|
Docker に対応する Fluentd ログ記録ドライバです。ログ・メッセージを |
|
Docker に対応する Amazon CloudWatch Logs ロギング・ドライバです。ログ・メッセージを Amazon CloudWatch Logs に書き込みます。 |
|
Docker に対応する Splunk ロギング・ドライバです。ログ・メッセージを |
docker logs
コマンドが使えるのは json-file
と journald
ログ記録ドライバのみです。ログ記録ドライバの詳細な情報については ログ記録ドライバの設定 をご覧ください。
Dockerfile イメージのデフォルトを上書き¶
開発者は Dockerfile を使うイメージ構築やコミットの時点で、そのイメージを使うコンテナが起動する時に有効となる各種パラメータを、開発者自身で設定できます。
Dockerfile の4つのコマンド FROM
、 MAINTAINER
、 RUN
、 ADD
は、実行時に上書きできません。それ以外のコマンドは、すべて docker run
で上書きできます。開発者が Dockerfile で個々の命令を設定していても、その設定を作業者が上書き操作する方法を説明します。
CMD(デフォルトのコマンド、またはオプション)¶
Docker コマンド入力時の、オプションで指定する コマンド
を思い出してください。
$ docker run [オプション] イメージ[:タグ|@DIGEST] [コマンド] [引数...]
このコマンドはオプションです。 イメージ
の作者が Dockerfile の CMD
命令を使い、デフォルトの コマンド
を既に設定している場合があるためです。作業者(イメージを使い、コンテナを実行する人)は、新たに コマンド
を指定するだけで、 CMD
命令を上書きできます。
イメージに ENTRYPOINT
も指定されていれば、 ENTRYPOINT
に対する引数として CMD
や コマンド
が追加されます。
ENTRYPOINT(実行時に処理するデフォルトのコマンド)¶
--entrypoint="": イメージで設定済みのデフォルト entrypoint を上書き
イメージの 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
次の例のように、空の文字列を渡して、コンテナのエントリーポイントを無効化できます。
$ docker run -it --entrypoint="" mysql bash
注釈
--entrypoint
を指定すると、イメージ上のあらゆるデフォルト命令群が削除されます(たとえば、イメージ構築時に使った Dockerfile の CMD 命令は削除されます)。
EXPOSE ( 入力ポート )¶
run
コマンドには、コンテナのネットワークに対応する以下のオプションがあります。
--expose=[]: コンテナ内のポートまたはポート範囲を出力(expose)する
これらは「EXPOSE」命令の出力ポートに追加する
-P : 全ての出力ポートをホスト側インターフェースに公開する
-p=[] : コンテナのポートまたはポート範囲をホスト側に公開する
書式: ip:ホスト側ポート:コンテナ側ポート | ip::コンテナ側ポート | ホスト側ポート:コンテナ側ポート | コンテナ側ポート
ホスト側ポートとコンテナ側のポートは、どちらもポート範囲を指定可能です。
両方で範囲を指定した時は、コンテナ側のポート範囲とホスト側のポート範囲が
一致する必要があります。例:
-p 1234-1236:1234-1236/tcp
(実際の割り当てを確認するには ``docker port`` を使う)
--link="" : 他のコンテナに対するリンクを追加 (<名前 or id>:エイリアス or <名前 or id>)
イメージの開発者は、EXPOSE
命令をのぞき、ネットワーク機能をほぼ管理できません。 EXPOSE
命令が定義するのは、サービスを提供するにあたって、初期の --expose
オプションを使い、公開用ポートに追加できます。
コンテナの内部ポートを -P
か -p
フラグを指定します。公開したポートはホスト上でアクセス可能であり、そのポートはホストに到達可能なすべてのクライアントが利用できます。
-P
オプションはホスト・インターフェース上に全てのポートを /proc/sys/net/ipv4/ip_local_port_range
によって定義された ruby:エフェメラル・ポート範囲 <ephemeral port range> です。 -p
フラグを使うと、特定のポートやポートの範囲を明示的に割り当てます。
コンテナ内のポート番号(サービスがリッスンしているポート番号)は、コンテナの外(クライアントの接続場所)に公開するポート番号と一致する必要がありません。例えば、コンテナ内の HTTP サービスがポート 80 をリッスンしているとします(つまり、イメージ開発者は Dockerfile で EXPOSE 80
を指定しています )。実行時には、ホスト側のポート 42800 以上をバインドしている場合があります。公開用ポートがホスト側のどのポートに割り当てられているかを確認するには、 docker port
コマンドを使います。
デフォルトのブリッジ・ネットワークにおいて、新しいクライアント・コンテナの起動時に、作業者が --link
を指定したら、クライアント・コンテナはプライベートなネットワーク・インターフェースを経由して --link
を指定すると、コンテナをリンクするためのエイリアス名を作成します。
ENV( 環境変数 )¶
Docker は Linux コンテナの作成時に、複数の環境変数を自動的に設定します。Windows コンテナの作成時には、Docker は環境変数を設定しません。
以下の環境変数が Linux コンテナに対して設定します。
変数 |
値 |
---|---|
|
|
|
コンテナに関連づけるホスト名 |
|
|
|
コンテナが疑似ターミナル(pseudo-TTY)を割り当てるときは |
さらに、作業者は1つまたは複数の -e フラグを使用して、コンテナ内の任意の環境変数を設定できます。このフラグを使えば、開発者が Dockerfile の ENV
で定義済みの環境変数を上書きできます。作業者が環境変数の名前のみ定義し、値を与えない場合は、現在の
$ export today=Wednesday
$ docker run -e "deep=purple" -e today --rm alpine env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=d2219b854598
deep=purple
today=Wednesday
HOME=/root
PS C:\> docker run --rm -e "foo=bar" microsoft/nanoserver cmd /s /c set
ALLUSERSPROFILE=C:\ProgramData
APPDATA=C:\Users\ContainerAdministrator\AppData\Roaming
CommonProgramFiles=C:\Program Files\Common Files
CommonProgramFiles(x86)=C:\Program Files (x86)\Common Files
CommonProgramW6432=C:\Program Files\Common Files
COMPUTERNAME=C2FAEFCC8253
ComSpec=C:\Windows\system32\cmd.exe
foo=bar
LOCALAPPDATA=C:\Users\ContainerAdministrator\AppData\Local
NUMBER_OF_PROCESSORS=8
OS=Windows_NT
Path=C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Users\ContainerAdministrator\AppData\Local\Microsoft\WindowsApps
PATHEXT=.COM;.EXE;.BAT;.CMD
PROCESSOR_ARCHITECTURE=AMD64
PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 62 Stepping 4, GenuineIntel
PROCESSOR_LEVEL=6
PROCESSOR_REVISION=3e04
ProgramData=C:\ProgramData
ProgramFiles=C:\Program Files
ProgramFiles(x86)=C:\Program Files (x86)
ProgramW6432=C:\Program Files
PROMPT=$P$G
PUBLIC=C:\Users\Public
SystemDrive=C:
SystemRoot=C:\Windows
TEMP=C:\Users\ContainerAdministrator\AppData\Local\Temp
TMP=C:\Users\ContainerAdministrator\AppData\Local\Temp
USERDOMAIN=User Manager
USERNAME=ContainerAdministrator
USERPROFILE=C:\Users\ContainerAdministrator
windir=C:\Windows
同様に、作業者は -h
で hostname (Linux) や COMPUTERNAME (Windows) を定義できます。
HEALTHCHECK ¶
--health-cmd ヘルスチェックのために実行するコマンド
--health-interval チェックを実行する感覚
--health-retries 障害を報告するまでに必要な連続失敗回数
--health-timeout チェックを実行できる最長時間
--health-start-period Start period for the container to initialize before starting health-retries countdown
--no-healthcheck コンテナで指定されている HEALTHCHECK を無効化
例:
$ docker run --name=test -d \
--health-cmd='stat /etc/passwd || exit 1' \
--health-interval=2s \
busybox sleep 1d
$ sleep 2; docker inspect --format='{{.State.Health.Status}}' test
healthy
$ docker exec test rm /etc/passwd
$ sleep 2; docker inspect --format='{{json .State.Health}}' test
{
"Status": "unhealthy",
"FailingStreak": 3,
"Log": [
{
"Start": "2016-05-25T17:22:04.635478668Z",
"End": "2016-05-25T17:22:04.7272552Z",
"ExitCode": 0,
"Output": " File: /etc/passwd\n Size: 334 \tBlocks: 8 IO Block: 4096 regular file\nDevice: 32h/50d\tInode: 12 Links: 1\nAccess: (0664/-rw-rw-r--) Uid: ( 0/ root) Gid: ( 0/ root)\nAccess: 2015-12-05 22:05:32.000000000\nModify: 2015..."
},
{
"Start": "2016-05-25T17:22:06.732900633Z",
"End": "2016-05-25T17:22:06.822168935Z",
"ExitCode": 0,
"Output": " File: /etc/passwd\n Size: 334 \tBlocks: 8 IO Block: 4096 regular file\nDevice: 32h/50d\tInode: 12 Links: 1\nAccess: (0664/-rw-rw-r--) Uid: ( 0/ root) Gid: ( 0/ root)\nAccess: 2015-12-05 22:05:32.000000000\nModify: 2015..."
},
{
"Start": "2016-05-25T17:22:08.823956535Z",
"End": "2016-05-25T17:22:08.897359124Z",
"ExitCode": 1,
"Output": "stat: can't stat '/etc/passwd': No such file or directory\n"
},
{
"Start": "2016-05-25T17:22:10.898802931Z",
"End": "2016-05-25T17:22:10.969631866Z",
"ExitCode": 1,
"Output": "stat: can't stat '/etc/passwd': No such file or directory\n"
},
{
"Start": "2016-05-25T17:22:12.971033523Z",
"End": "2016-05-25T17:22:13.082015516Z",
"ExitCode": 1,
"Output": "stat: can't stat '/etc/passwd': No such file or directory\n"
}
]
}
docker ps
の出力からもヘルス・ステータスを表示できます。
TMPFS ( tmfps ファイルシステムのマウント )¶
--tmpfs=[]: tmpfs マウントを作成: コンテナ側ディレクトリ[:<オプション>],
オプションは Linux コマンドの 'mount -t tmpfs -o' オプションと同一形式
この例では、空の tmpfs を rw
、 noexec
、 nosuid
、 size=65536k
オプションを指定し、コンテナにマウントします。
$ docker run -d --tmpfs /run:rw,noexec,nosuid,size=65536k my_image
VOLUME ( 共有ファイルシステム )¶
-v, --volume=[ホスト側ディレクトリ:]コンテナ側ディレクトリ[:<オプション>]: ボリュームのバインド・マウント
オプションはカンマ区切りで [rw|ro] または [z|Z]、[[r]shared|[r]slave|[r]private]、そして [nocopy] から選択
「ホスト側ディレクトリ」は絶対パスもしくは名前を値にします。
「rw」 (読み書き)または 「ro」 (読み込み専用)の指定が無ければ、
読み書き可能なモードでマウントします。
「nocopy」 モードを指定すると、コンテナ内に要求したボリューム・パスに対して、
ボリュームの保存している場所に自動コピーを無効にします。
名前付きボリュームの場合は、「copy」がデフォルトのモードです。
copy モードは、バインド・マウントしたボリュームではサポートされていません。
--volumes-from="": 指定したコンテナから、すべてのボリュームをマウントします。
注釈
systemd で Docker デーモンの開始と停止を管理する場合は、 Docker デーモン自身の MountFlags
というオプション設定があります。この設定により、マウントポイントで行われたマウント伝播の変更を、Docker が認識しない可能性があります。例えば、値を slave
としているのであれば、ボリュームのプロパゲーション値に shared
や rshared
ボリューム関連コマンドは非常に複雑なため、 /storage/volumes セクションに独自のドキュメントがあります。開発者は1つまたは複数の VOLUME
を作成し、イメージと関連づけることが可能です。しかし、あるコンテナから別のコンテナ(あるいは、コンテナ側からホスト上にマウントされたボリューム)へのアクセスを許可できるのは、作業者のみです。
コンテナ側ディレクトリ
は /src/docs
のように常に絶対パスの必要があります。 ホスト側ディレクトリ
は絶対パスか 名前
を値に指定できます。 ホスト側ディレクトリ
に絶対パスを指定すると、 Docker は指定したパスを 名前
を指定する場合は、Docker は、その 名前
を持つボリュームを作成します。
名前
は英数字で始まる必要があり、以降は a-z0-9
、_
(アンダースコア)、 .
(ピリオド)、 -
(ハイフン)が使えます。絶対パスは /
(フォアワード・スラッシュ)で始める必要があります。
例えば、 ホスト側ディレクトリ
の値に /foo
か foo
を指定したとします。 /foo
値を指定した場合は、Docker はホスト上にバインドマウントを作成します。 foo
を指定したら、Docker は指定された名前でボリュームを作成します。
USER¶
開発者は Dockerfile の USER
命令を使い、1つめのプロセスを実行するデフォルトのユーザを定義できます。コンテナ起動時に -u
オプションを使うと USER
命令を上書きできます。
-u="", --user="": ユーザ名または UID を指定する命令。オプションでグループ名や GUID を指定
以下は有効な例です。
--user=[ user | user:group | uid | uid:gid | user:gid | uid:group ]
注釈
数値で UID を指定する場合は、0 ~ 2147483647 の範囲内の必要があります。
WORKDIR¶
コンテナ内でバイナリを実行するためにある、デフォルトの /
) ディレクトリです。 Dockerfile の WORKDIR
コマンドで、デフォルトの作業用ディレクトリが指定されているかもしれません。作業者はこの設定を上書きできます。
-w="": コンテナ内の作業用(ワーキング)ディレクトリ
参考
- Docker run reference