Docker デーモンの設定とトラブルシュート

Docker のインストールに成功したら、 dockerd デーモンはデフォルトの設定で動いています。このトピックで扱うのは、どのようにして設定を変更するか、手動でデーモンを起動する方法、トラブルシュート、実行に問題があればデーモンのデバッグの仕方です。

オペレーティングシステムのユーティリティでデーモンを起動

Docker デーモンを典型的にインストールすると、Docker デーモンの起動はユーザが手動で行うのではなく、システム・ユーティリティによって起動されます。これにより、マシンの再起動時に、自動的に Docker を起動するのが簡単になります。

Docker の起動コマンドは、利用しているオペレーティングシステムに依存します。 Docker インストール 以下にある適切なページをご覧ください。システム起動時の Docker 自動起動に関する調整は、 ブート時に Docker を起動する設定 をご覧ください。

デーモンを手動で起動

システム・ユーティリティを使わずに Docker デーモンを管理したい場合や、純粋にテストだけを行いたい場合に、 dockerd コマンドを使って手動で実行できます。場合によっては sudo が必要になるかもしれませんが、お使いのオペレーティングシステムの設定に依存します。

Docker をこの方法で起動すると、Docker はフォアグラウンドで実行され、自身のログはターミナル上に直接送ります。

$ dockerd

INFO[0000] +job init_networkdriver()
INFO[0000] +job serveapi(unix:///var/run/docker.sock)
INFO[0000] Listening for HTTP on unix (/var/run/docker.sock)

手動で起動した Docker を停止するには、ターミナル上で Ctrl+C を実行します。

Docker デーモンの設定

Docker デーモンの設定を変更するには、2つの方法があります。

  • JSON 設定ファイルを使う方法。全ての設定情報を1ヵ所にまとめているため、望ましいオプション
  • dockerd で起動時にフラグを付ける方法

フラグと JSON ファイルで同じオプションを指定しなければ、両方の選択肢を同時に利用できます。その際、 Docker デーモンが起動できなければ、エラーメッセージを表示します。

Docker デーモンを JSON ファイルで設定するには、Linux システム上では /etc/docker/daemon.json にファイルを作成するか、Windows 上では C:\ProgramData\docker\config\daemon.json を作成します。Mac OS ではタスクバーの鯨アイコンから Preferences > Daemon > Advanced を選択します。

設定ファイルとは、以下のような形式です。

{
  "debug": true,
  "tls": true,
  "tlscert": "/var/docker/server.pem",
  "tlskey": "/var/docker/serverkey.pem",
  "hosts": ["tcp://192.168.59.3:2376"]
}

この設定を使って Docker デーモンを起動すると、デバッグモードで起動し、TLS を使い、 192.168.59.3 のポート 2376 へリッスンしているトラフィックを転送します。設定情報のオプションに関する情報は dockerd リファレンス・ドキュメント をご覧ください。

また、Docker デーモンを手動かつフラグを設定して起動することもできます。これは問題のトラブルシューティングに役立ちます。

以下の例は、Docker デーモンを手動で起動し、先ほどの設定と同じオプションを指定しています。

dockerd --debug \
  --tls=true \
  --tlscert=/var/docker/server.pem \
  --tlskey=/var/docker/serverkey.pem \
  --host tcp://192.168.59.3:2376

どのような設定オプションが利用可能かどうかを知るには、 dockerd リファレンス・ドキュメント か、次のように実行します。

dockerd --help

Docker ドキュメント上で、様々な設定オプションが話題に上がっています。次にご覧ください。

  • /config/containers/start-containers-automatically
  • /config/containers/resource_constraints
  • /storage/storagedriver/select-storage-driver
  • /engine/security

Docker デーモンのディレクトリ

Docker デーモンは全てのデータを1つのディレクトリ内に保存します。この場所に Docker に関連する全てがおかれており、コンテナ、イメージ、ボリューム、サービス定義、シークレットがあります。

このディレクトリはデフォルトで、以下の通りです。

  • Linux 上では /var/lib/docker
  • Windows 上では C:\ProgramData\docker

Docker デーモンの設定により、オプションで data-root を設定すると 、ここで利用するディレクトリを変更できます。

Docker デーモンはこのディレクトリ上で状態を保持するため、各デーモンがそれぞれ専用のディレクトリを使う必要があります。例えば NFS 共有のようなディレクトリで、もしも2つのデーモンが同じディレクトリを共有すると、問題解決が困難なエラーに直面することになるでしょう。

デーモンのトラブルシュート

デーモンに対するデバッギングを有効化すると、デーモンのランタイム動作に関して知ることができるようになり、トラブルシューティングに役立ちます。もし、デーモンが完全に無応答であれば、Docker デーモンに対して SIGUSR シグナルを送信し、全てのスレッドに対してデーモンのログを追加出来るよう、 スタック・トレースの強制によるログ記録 も行えます。

daemon.json とスタートアップ・スクリプト間で競合した時のトラブルシュート

daemon.json ファイルの利用と、 dockerd コマンドに対して手動もしくはスタートアップ・スクリプトでオプション指定の利用を同時に利用すると、お互いのオプションが競合するとき、Docker は起動できず、次のようなエラーを出力します。

unable to configure the Docker daemon with file /etc/docker/daemon.json:
the following directives are specified both as a flag and in the configuration
file: hosts: (from flag: [unix:///var/run/docker.sock], from file: [tcp://127.0.0.1:2376])

もしも、フラグを付けてデーモンを手動で起動するときと似たようなエラーであれば、フラグの設定を調整するか、衝突を避けるために daemon.json を削除します。

注釈

これが何らかの具体的なエラーであれば、 次のセクション を参照して回避してください。

オペレーティングシステムの init スクリプトで Docker を起動しようとしている場合は、特定のオペレーティングシステムを対象としたデフォルトのスタートアップ・スクリプトで上書きする必要があるかもしれません。

systemd で daemon.json にホストキーを使う

設定が競合する有名な例として、デーモンをデフォルトとは異なる場所へ指定しようとする時は、トラブルシュートが大変です。Docker はデフォルトでソケットを通してリッスンしようとします。Debian と Ubuntu のシステム上では systemd を使います。つまり、 dockerd の起動時に、常にホストフラグ -H を使うのを意味します。もしも daemon.jsonhosts エントリを指定しても、これによって(前述の)設定ファイルの競合を引き起こし、Docker は起動に失敗します。

この問題に対処するには、以下の内容の新しいファイル /etc/systemd/system/docker.service.d/docker.conf を作成し、デフォルトでデーモン起動時に -H 引数を使わないよう削除します。

[Service]
ExecStart=
ExecStart=/usr/bin/dockerd

他にも、 HTTP や HTTPS プロキシの設定 のように、Docker で systemd の設定が必要になる場合があるでしょう。

注釈

Docker を手動で起動するとき、 このオプションを上書きし、 daemon.jsonhosts エントリや -H フラグの指定が無ければ、Docker は起動に失敗します。

Docker を起動しようとする前に、 sudo systemctl daemon-reload を実行します。Docker が起動に成功すると、ソケットではなく、 daemon.jsonhosts キーで指定した IP アドレスでリッスンします。

重要

daemon.json での hosts 設定は、 Docker Desktop for Windows や Docker Desktop for Mac ではサポートされていません。

Out Of Memory Exception (OOME)

システムで利用可能なメモリよりも、多くのメモリ利用をコンテナが試みようとすると、Out Of Memory Exception (OOME) が発生し、 Docker あるいは Docker デーモンがカーネル OOM killer によって強制停止されるでしょう。この挙動を防ぐためには、ホスト上で実行するアプリケーションに対し、十分なメモリを割り当ててから実行します。詳細は Out of Memory を引き起こすリスクの理解 をご覧ください

ログを読む

デーモンのログは問題の解析に役立つでしょう。ログは1ヵ所に保存されますが、オペレーティングシステムの設定と、サブシステムが使っているログ記録システムに依存します。

  • オペレーティングシステム * 場所
  • RHEL, Oracle Linux
    • /var/log/messages
  • Debian
    • /var/log/daemon.log
  • Ubuntu 16.04+, CentOS
    • コマンド journalctl -u docker.service を使用
  • Ubuntu 14.10-
    • /var/log/upstart/docker.log
  • macOS (Docker 18.01+)
    • ~/Library/Containers/com.docker.docker/Data/vms/0/console-ring
  • macOS (Docker <18.01)
    • ~/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/console-ring
  • Windows
    • AppData\Local

デバッギングの有効化

デバッグを有効化するには2つの方法があります。推奨する方法は、 daemon.json ファイル中で debug キーを true に設定するものです。この手法は全ての Docker プラットフォームで動作します。

  1. daemon.json ファイルを編集します。通常は /etc/docker にあります。ファイルが存在していなければ、このファイルを作る必要があります。macOS や Windows であれば、このディレクトリは編集しないで、かわりに Preferences > Daemon > Advanced で設定します。
  1. ファイルが空っぽであれば、次の様に追加します。
{
  "debug": true
}

既に JSON ファイルが存在していれば、 "debug": true のキーのみ追加します。このとき、この記述がカッコ(ブランケット)を閉じる直前の行でなければ、行末にカンマ記号を追加する必要がありますので注意してください。また、もしも log-level キーを設定している場合、そこでは infodebug が指定されているか確認します。 info はデフォルトであり、変更可能な値は debuginfowarnerrorfatal です。

  1. 設定情報を再読込するため、デーモンに対して HUB シグナルを送信します。 Linux ホスト上では以下のコマンドを使います。
$ sudo kill -SIGHUP $(pidof dockerd)

Windows ホスト上では Docker を再起動します。

以上の手順のほかに、Docker デーモンを停止し、手動で Docker デーモンを起動する時にデバッグ用のフラグ -D を付ける方法もあります。しかしながら、通常ホスト側のスタートアップ・スクリプトによって作成する Docker 環境とは、異なる環境が起動してしまう場合もあります。そして、そうなればデバッグが困難になるでしょう。

スタック・トレースのログ記録を強制

デーモンの反応がなくなった場合、 SIGUSR1 をデーモンに送ると、 完全なスタック・トレースの強制によってログを記録できます。

  • Linux :

    $ sudo kill -SIGUSR1 $(pidof dockerd)
    
  • Windows Server:

    • docker-signal のダウンロード
    • Get-Process dockerd で dockerd の ID を取得
    • --pid=<デーモンのPID> を付けて実行

このスタック・トレースの強制は、デーモンを停止せずにログを記録します。デーモンのログは、スタック・トレース上、あるいは、ファイルにスタック・トレースを記録する設定をしている場合は、そのパスにあるファイルに記録します。

SIGUSR1 シグナルを受けてもデーモンは操作を実行し、スタック・トレースのログを送り続けます。スタック・トレースによって、全ての goroutine の状態や、デーモンないのスレッド状況が分かるでしょう。

スタックトレースの表示

Docker デーモンのログ表示は、以下の方法どちらかを使って行えます。

  • Linux システム上では systemctl を使い、 journalctl -u docker.service を実行します。
  • 以前の Linux システム上では /var/log/messages/var/log/daemon.log/var/log/docker.log を読みます。

注釈

Docker Desktop for Mac や Docker Desktop for Windows 上では、スタック・トレースを手動で生成することができません。ですが、問題が発生した時は、 Docker タスクバーアイコンをクリックし、 Diagnose and feedbak を選択し、Docker に対して情報を送信できます。

Docker のログに表示される文字列は、以下のようなものです。

...goroutine stacks written to /var/run/docker/goroutine-stacks-2017-06-02T193336z.log
...daemon datastructure dump written to /var/run/docker/daemon-data-2017-06-02T193336z.log

Docker がこれらスタック・トレースおよびダンプ情報をどこに記録するかは、利用しているオペレーティングシステムと設定に依存します。スタック・トレースとダンプから直接解析した情報が、役に立つ場合があるでしょう。あるいは、問題の解析のために、Docker への送信が役立つ場合もあるでしょう。

どこにある Docker が動作しているか確認

Docker がどこで動作しているかはオペレーティングシステムによって別々ですが、確認するには docker info コマンドを実行します。

また、オペレーティングシステムのユーティリティも利用できます。 sudo systemctl is-active dockersudo status dockersudo service docker status や、Windows ユーティリティを使ったサービスを確認できます。

あとは、 dockerd プロセスのプロセスリストを確認するには、 pstop のようなコマンドを使います。

参考

Configuring and running Docker on various distributions
https://docs.docker.com/config/daemon/