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 インストール用ドキュメントをご覧ください。

デタッチド 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つの標準ストリーム( 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 長い識別子(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 を再利用できるようにします。

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

例:コンテナ内で 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) 名前空間は、 共有メモリ・セグメント(shared memory segments)セマフォ(semaphores)メッセージ・キュー(message queues) と呼ばれる分離を提供します。

プロセス間通信において、パイプを通したりネットワーク・スタックを通すよりも、共有メモリ・セグメントでメモリ速度を向上するために使われていました。共有メモリが一般的に使われるのは、データベースや、科学計算や金融サービス産業向けの高性能アプリケーション用カスタム・ビルド(典型的なのは、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 処理はファイルを通して行うか、あるいは、 STDINSTDOUT を通してのみになります。

ポートの公開や、他のコンテナへの リンク(link) は、デフォルト( ブリッジ(bridge) )のみです。リンク機能は過去の機能(レガシー機能)です。リンク機能よりも、Docker ネットワーク・ドライバの使用を常に優先する必要があります。

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

デフォルトでは、コンテナに割り当てられる IP アドレスを使い、MAC アドレスを生成します。コンテナに MAC アドレスを指定するには、 --mac-address パラメータ(書式: 12:34:56:78:9a:bc )を使って MAC アドレスを指定できます。 Docker は指定された MAC アドレスがユニークかどうか(重複しているかどうか)を確認する仕組みが無いため、(MAC アドレスを手動で指定する場合は、重複しないように)ご注意ください。

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

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

ネットワーク: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 ネットワーク・ドライバか外部のネットワーク・ドライバ・プラグインを使います。同じネットワークに対して、複数のコンテナが接続できます。 ユーザ定義ネットワーク() に接続したら、コンテナはコンテナの名前や IP アドレスを使い、簡単に通信できるようになります。

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 フラグを使えば、 再起動ポリシー(restart policy) を指定できます。再起動ポリシーとは、コンテナが終了時に再起動すべきかどうかの定義です。

コンテナの再起動ポリシーが有効な場合、 docker ps でコンテナを見たら、常に UpRestarting のどちらかです。また、再起動ポリシーが有効かどうかを確認するには、 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 フラグを設定したら、コンテナの削除時、関連する 匿名ボリューム(anonymous volumes) も削除します。これは docker rm -v my-container の実行と同じです。ただし、名前を指定しなかったボリュームのみ削除します。例えば、次のコマンドを実行したとします。

docker run --rm -v /foo -v awesome:/bar busybox top

/foo ボリュームは削除されますが、 /bar は削除されません。 --volume-form で継承しているボリュームが削除されるのと同じ仕組みです。このように、元のボリュームに名前が指定されていれば、そこは削除 されません

セキュリティ設定

--security-opt="label=user:USER" コンテナの user ラベルを指定
--security-opt="label=role:ROLE" コンテナの role ラベルを指定
--security-opt="label=type:TYPE" コンテナの type ラベルを指定
--security-opt="label=level:LEVEL" コンテナの level ラベルを指定
--security-opt="label=disable" コンテナのラベル割り当てを無効化
--security-opt="apparmor=PROFILE" コンテナに適用する apparmor profile を指定
--security-opt="no-new-privileges:true" コンテナが新しい特権権限を得るのを無効化
--security-opt="seccomp=unconfined" コンテナに対する seccomp 制限を無効化
--security-opt="seccomp=profile.json" sccomp フィルタで使うホワイトリスト syscall seccomp JSON ファイルを指定

各コンテナに対するデフォルトの ラベル付きスキーム(labeling scheme) は、 --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

この指定により、 susudo のような権限昇格コマンドを機能しなくします。また、特権を落とした後に、あらゆる seccomp フィルタが適用されますので、フィルタ設定がより厳格に適用されるのを意味します。より詳しい情報は、 カーネルのドキュメント をご覧ください。

init プロセスの指定

--init プラグを使うと、コンテナ内で PID 1 として使われるべき init プロセスを指定できます。init プロセスの指定とは、ゾンビプロセスの回収のような処理を作成したコンテナ内で行い、init システムにおける通常の処理を確実に担います。

デフォルトの init プロセスには、Docker デーモンプロセスのシステムパス上で、最初に実行可能な docker-init を使います。この docker-init バイナリは、デフォルトのインストールに含まれており、 tiny の支援を受けています。

カスタム cgroups の指定

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

実行時のリソース制限

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

-m , --memory="" メモリの上限(書式: <数値> [<単位>] 、単位は bkmg のいずれか)
--memory-swap="" 合計メモリの上限(メモリ+スワップ、書式: <数値> [<単位>] 、単位は bkmg のいずれか)
--memory-reservation="" メモリのソフト・リミット(書式: <数値> [<単位>] 、単位は bkmg のいずれか)
--kernel-memory="" カーネル・メモリの上限(書式: <数値> [<単位>] 、単位は bkmg のいずれか)
-c , --cpu-shares=0 CPU 共有(CPU shares)を相対値で指定
--cpus=0.000 CPU 数です。数値は小数です。0.000 は無制限を意味します。
--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) のクォータを設定
--cpu-rt-period=0 CPU real-time period を設定。マイクロ秒で指定。設定には親 cgroups が必要で、親を越えられない。また、rtprio ulimits も確認する。
--cpu-rt-runtime=0 CPU real-time runtime を設定。マイクロ秒で指定。設定には親 cgroups が必要で、親を越えられない。また、rtprio ulimits も確認する。
--blkio-weight=0 ブロック I/O ウエイト(相対値)を 10 ~ 1000 までの値でウエイトを設定
--blkio-weight-device="" ブロック I/O ウエイト(相対デバイス値、書式: DEVICE_NAME:WEIGHT
--device-read-bps="" デバイスからの読み込みレートを制限(書式: <デバイスのパス>:<数値> [<単位>] )。数値は正の整数値。単位は kbmbgb のいずれか
--device-write-bps="" デバイスからの書き込みレートを制限(書式: <デバイスのパス>:<数値> [<単位>] )。数値は正の整数値。単位は kbmbgb のいずれか
--device-read-iops="" デバイスからの読み込みレート(1秒あたりの IO)を制限(書式: <デバイスのパス>:<数値>) 。数値は正の整数値。
--device-write-iops="" デバイスからの書き込みレート(1秒あたりの IO)を制限(書式: <デバイスのパス>:<数値>) 。数値は正の整数値。
--oom-kill-disable=false コンテナを OOM killer による停止を無効化するかどうか指定
--oom-score-adj=0 コンテナの OOM 設定を調整( -1000 から 1000 )
--memory-swappiness="" コンテナがメモリのスワップ度合いを調整。整数値の 0 ~ 100 で指定
--shm-size="" /dev/shm の容量。書式は <数値><単位>数値0 より大きい必要がある。単位はオプションで、指定できるのは b (バイト)、 k (キロバイト)、 m (メガバイト)、 g (ギガバイト

ユーザ・メモリの制限

ユーザのメモリ使用量を指定するには、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) は、メモリに対するある種の ソフト・リミット(soft limit) であり、共有メモリを大きくします。通常の状況下であれば、コンテナは必要とするだけ多くのメモリを使うことができます。そして、 -m--memory オプションがある時のみ、コンテナに対して ハード・リミット(hard limit) が設定されます。メモリ予約が設定したら、Docker は メモリの競合(memory contention) やメモリ不足を検出し、コンテナが予約した上限まで使えるようにします。

メモリ予約の値は、常にハード・リミット以下に設定しなければ、ハード・リミットが先に処理されてしまいます。予約値を 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

コンテナは無制限にメモリを使えるため、ホスト上のメモリを使い果たしたら、空きメモリ確保のために、システム・プロセスを停止する必要が出てきます。 --oom-score-adj パラメータを指定すると、システムのメモリが不足した場合、コンテナを強制終了する優先順位を選択できるます。負のスコアであれば強制終了される可能性は低くなり、対して、正のスコアの場合は高くなります。

カーネル・メモリ制限(kernel memory constraints)

カーネル・メモリはユーザ・メモリとは根本的に異なり、 スワップ・アウト(swap out) できません。何らかのコンテナがカーネル・メモリが多く消費したとしても、スワップできないため、システムサービスをブロックする可能性があります。カーネル・メモリとは、次の項目を指します。

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

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

カーネル・メモリはユーザ・メモリとは完全に独立しています。その代わり、ユーザ・メモリを制限すると同時に、カーネル・メモリの制限も必要です。上限の設定には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 のカーネル・メモリを使います。

スワップ回避制限(swappiness constraint)

デフォルトでは、コンテナのカーネルは、 アノニマス・ページ・メモリ(anonymous pages) 上の何パーセントかをスワップ・アウトできます。コンテナに対し、このパーセントを指定するには、 --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 オプションは、コンテナの 作業セット(working set) を維持し、スワップによるパフォーマンスの低下を避けたい場合に役立ちます。

CPU 共有制限(CPU share constraint)

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

割合をデフォルトの 1024 から変更するには、 -c--cpu-shares フラグで 重み付け(waiting) を 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つめ)となります。

複数のコアを持つ(multi-core) システム上では、全ての 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 period constraint)

デフォルトの 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 セット制限(cpuset constraint)

コンテナをどの 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 constraint)

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

ブロック IO 帯域(blkio)制限(Block IO bandwith [Blkio] constraint)

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

注釈

blkid ウェイトは ダイレクト IO(direct IO) に対してのみ設定できます。現在、 バッファ IO(buffered IO) はサポートしていません。

--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

<デバイスのパス>:<制限> の書式で、フラグと制限の両方を設定できます。読み込みと書き込みレートは、正の整数の必要があります。

グループの追加(additional groups)

--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

実行時の権限(runtime privilege)Linux ケーパビリティ(Linux capabilities)

オプション 説明
--cap-add Linux ケーパビリティの追加
--cap-drop Linux ケーパビリティの 削除(drop)
--privileged コンテナに 拡張権限(extended privileges) を与える
--device=[] --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 ...

デフォルトでは、コンテナはデバイスに対して 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) ケーパビリティの説明
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) を使い、ルート・ディレクトリを変更

次の表は、デフォルトでは許可されていないものおん、追加可能なケーパビリティの一覧です。

ケーパビリティのキー(capability key) ケーパビリティの説明
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 は特定のケーパビリティでファシリティを使えるようになりました。

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

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

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

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

Dockerfile イメージのデフォルトを上書き

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

Dockerfile の4つのコマンド FROMMAINTAINERRUNADD は、実行時に上書きできません。それ以外のコマンドは、すべて 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 ( 入力ポート(incoming ports)

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

--expose=[]: コンテナ内のポートまたはポート範囲を出力(expose)する
             これらは「EXPOSE」命令の出力ポートに追加する
-P         : 全ての出力ポートをホスト側インターフェースに公開する
-p=[]      : コンテナのポートまたはポート範囲をホスト側に公開する
               書式: ip:ホスト側ポート:コンテナ側ポート | ip::コンテナ側ポート | ホスト側ポート:コンテナ側ポート | コンテナ側ポート
               ホスト側ポートとコンテナ側のポートは、どちらもポート範囲を指定可能です。
               両方で範囲を指定した時は、コンテナ側のポート範囲とホスト側のポート範囲が
               一致する必要があります。例:
                   -p 1234-1236:1234-1236/tcp

               (実際の割り当てを確認するには ``docker port`` を使う)

--link=""  : 他のコンテナに対するリンクを追加 (<名前 or id>:エイリアス or <名前 or id>)

イメージの開発者は、EXPOSE 命令をのぞき、ネットワーク機能をほぼ管理できません。 EXPOSE 命令が定義するのは、サービスを提供するにあたって、初期の 受信用ポート(incoming ports) です。このポートはコンテナの中のプロセスが利用可能です。作業者は --expose オプションを使い、公開用ポートに追加できます。

コンテナの内部ポートを 公開(expose) するには、作業者はコンテナ実行時に -P-p フラグを指定します。公開したポートはホスト上でアクセス可能であり、そのポートはホストに到達可能なすべてのクライアントが利用できます。

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

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

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

ENV( 環境変数(environment variables)

Docker は Linux コンテナの作成時に、複数の環境変数を自動的に設定します。Windows コンテナの作成時には、Docker は環境変数を設定しません。

以下の環境変数が Linux コンテナに対して設定します。

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

さらに、作業者は1つまたは複数の -e フラグを使用して、コンテナ内の任意の環境変数を設定できます。このフラグを使えば、開発者が Dockerfile の ENV で定義済みの環境変数を上書きできます。作業者が環境変数の名前のみ定義し、値を与えない場合は、現在の 名前付き変数(named variable) の値が、コンテナの環境に 伝わります(propagated)

$ 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

同様に、作業者は -hhostname (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 ファイルシステムのマウント(mount tmpfs filesystems)

--tmpfs=[]: tmpfs マウントを作成: コンテナ側ディレクトリ[:<オプション>],
            オプションは Linux コマンドの 'mount -t tmpfs -o' オプションと同一形式

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

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

VOLUME(ボリューム)共有ファイルシステム(shared filesystems)

-v, --volume=[ホスト側ディレクトリ:]コンテナ側ディレクトリ[:<オプション>]: ボリュームのバインド・マウント
オプションはカンマ区切りで [rw|ro] または [z|Z][[r]shared|[r]slave|[r]private]、そして [nocopy] から選択
「ホスト側ディレクトリ」は絶対パスもしくは名前を値にします。

「rw」 (読み書き)または 「ro」 (読み込み専用)の指定が無ければ、
読み書き可能なモードでマウントします。

「nocopy」 モードを指定すると、コンテナ内に要求したボリューム・パスに対して、
ボリュームの保存している場所に自動コピーを無効にします。
名前付きボリュームの場合は、「copy」がデフォルトのモードです。
copy モードは、バインド・マウントしたボリュームではサポートされていません。

--volumes-from="": 指定したコンテナから、すべてのボリュームをマウントします。

注釈

systemd で Docker デーモンの開始と停止を管理する場合は、 Docker デーモン自身の マウント伝播( mount propagation) を制御するために、systemd の unit ファイル上で MountFlags というオプション設定があります。この設定により、マウントポイントで行われたマウント伝播の変更を、Docker が認識しない可能性があります。例えば、値を slave としているのであれば、ボリュームのプロパゲーション値に sharedrshared 伝播(propagation) を使用できないことがあります。

ボリューム関連コマンドは非常に複雑なため、 /storage/volumes セクションに独自のドキュメントがあります。開発者は1つまたは複数の VOLUME を作成し、イメージと関連づけることが可能です。しかし、あるコンテナから別のコンテナ(あるいは、コンテナ側からホスト上にマウントされたボリューム)へのアクセスを許可できるのは、作業者のみです。

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

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

例えば、 ホスト側ディレクトリ の値に /foofoo を指定したとします。 /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

コンテナ内でバイナリを実行するためにある、デフォルトの 作業用ディレクトリ(working directory) は、ルート( / ) ディレクトリです。 Dockerfile の WORKDIR コマンドで、デフォルトの作業用ディレクトリが指定されているかもしれません。作業者はこの設定を上書きできます。

-w="": コンテナ内の作業用(ワーキング)ディレクトリ

参考

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