Dockerのトラブルシューティングがうまくできるようになりたいと思い
- docker daemonの手動起動
- systemdで自動起動しない場合の確認手段
- docker daemonのログ出力
- docker daemonで発生したエラーの確認手段
- docker daemonの強制スタックトレース出力
- daemonの反応がない場合の対応方法
- docker daemonの起動確認
に関して調べてみました。
今回使用したdockerのバージョンは20.10.0です。2020/12/15時点での情報のため、dockerのコマンドや設定ファイルのパス等、今後変更になる可能性があります。
- Dockerエンジンの基本的な構成
- Docker daemonの起動(自動起動)
- Docker daemonの手動起動
- Docker daemonの設定
- デーモンのログのパス/確認方法
- スタックトレースの確認
- Docker deamonの起動確認
- 参考資料
Dockerエンジンの基本的な構成
まず、Dockerエンジンは、以下の図のように主に3つのコンポーネントから構成されています。
- Docker CLI (dockerコマンド): コンテナやイメージ、ネットワーク等の操作をHTTP経由のAPIを介して、Docker daemonと通信するクライアント。
- Dockerエンジン API: CLIやプログラムからのHTTP経由で要求を受け付ける。
- Docker daemon: コンテナの生成、実行、モニタリング等を行い、結果を返す。
今回調べたトラブルシューティング時に追えるようになる情報は、Docker daemonの部分です。
デーモンのログ出力を詳細を見れることでデーモンが起動していない場合でも発生したエラーの内容を見れるので、特に普段dockerコマンド(Docker CLI)しか使わないという場合、トラブル対応時に役に立つかと思います。
なお、Docker CLIの docker logs
はコンテナのログを出力するものなので、デーモンのログとは別のものです。docker logs
にはコンテナ作成時のエラー等は出力されません。
Docker daemonの起動(自動起動)
Dockerをインストールするとシステムユーティリティー(多くのLinuxのディストリの場合Systemd)がOS起動時に自動的にデーモンを起動しています。
試しにdocker.serviceのステータスを確認すると
$ sudo systemctl status docker ● docker.service - Docker Application Container Engine Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled) Active: active (running) since Tue 2020-12-15 16:29:17 JST; 6h ago Docs: https://docs.docker.com Main PID: 1740 (dockerd) Tasks: 80 CGroup: /system.slice/docker.service ├─1740 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock ├─2987 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 15432 -container-ip 172.22.0.3 -container-port 5432 └─3059 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 1080 -container-ip 172.22.0.4 -container-port 80 12月 15 16:29:12 takashi dockerd[1740]: time="2020-12-15T16:29:12.851824229+09:00" level=warning msg="Your kernel does not support swap memory limit"
Main PID: 1740 (dockerd)
という出力があり、デーモンが動いているのが確認できるかと思います。
Docker daemonの手動起動
もし、systemd
の自動起動 or systemd start docker
で デーモンが起動できない場合などに、手動でdockerd
コマンドを実行して起動することもできます。
基本的には1つのdockerホスト内で複数のdocker daemonを起動できないため、systemd
から起動されたデーモンが起動中の場合、新しいデーモンの起動には失敗します。
$ sudo dockerd INFO[2020-12-15T23:03:29.443621640+09:00] Starting up failed to start daemon: pid file found, ensure docker is not running or delete /var/run/docker.pid
一旦 systemd
の docker.service
を停止すると起動でき、起動時のログがコンソールに出力されます。
sudo systemctl stop docker takashi@tamo:/var/lib/docker$ sudo dockerd INFO[2020-12-15T23:05:18.685050913+09:00] Starting up INFO[2020-12-15T23:05:18.685967243+09:00] detected 127.0.0.53 nameserver, assuming systemd-resolved, so using resolv.conf: /run/systemd/resolve/resolv.conf ︙
Docker daemonの設定
自動起動の場合
Linuxの場合 /etc/docker/daemon.json
をデーモンの設定ファイルとして自動的に読み込みます。(Mac, Windowの場合はGUI上のPreferences / Daemon / Advanced
から設定)
設定できるオプションは様々ありますが、トラブルシューティング時に
- デバッグモードを有効にし、デーモンからより詳細な出力を得られるようにする(デフォルトは無効)
- ログレベルをdebugにする(デフォルトはinfo)
という場合は、以下のように記載した設定ファイルを配置します。
{ "debug": true, "log-level": "debug" }
※設定ファイルの他のオプションに関しては、こちらに記載されています。
Linuxの場合、以下のコマンドでデーモンに対して HUP シグナルを送信し、設定を再読み込みさせることができます。
$ sudo kill -SIGHUP $(pidof dockerd)
手動起動の場合
docker daemon
は、設定ファイルを自動的に読み込むようになっていますが、同時に手動起動の場合はオプションも併せて指定することができます。
$ dockerd --debug --log-level debug
設定でオプションを変更したらデーモンが起動しなくなった場合などは、手動起動でどのオプションを変更したら動かなくなるかを確認すると良さそうです。
自動的に読み込まれる設定ファイルとオプションが重複する場合は、以下のようなエラーが発生し、デーモン起動は失敗します。
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])
デーモンのログのパス/確認方法
ログファイルのパス/確認方法はOS毎に異なります。
他のOSのログファイルに関しては、詳細はドキュメント を参照してください。
スタックトレースの確認
デーモンの反応がない場合は、Linuxだと以下のコマンドでスタックトレースを強制的に出力できます。スタックトレースがログに出力されますが、デーモンは停止しません。
$ sudo kill -SIGUSR1 $(pidof dockerd)
Docker deamonの起動確認
いくつかの方法で起動を確認できます。Docker CLIのコマンドを実行して、反応がなかったり、エラーが発生した場合に起動しているか状態を確認すると良さそうです。
- OSに依らない確認方法
- Docker CLIを使う
docker info
- Docker CLIを使う
- OSに依る確認方法
- Systemdを使う
sudo systemctl is-active docker
sudo systemctl status docker
sudo service docker status
- プロセスの状態を確認する
ps
top
- Systemdを使う