我在我的 Ubuntu 伺服器上運行了許多 docker 容器。它們由 systemd 控制。
如果我運行容器會正常關閉。 Journalctl的輸出如下(逆時輸出,最新的在上):systemctl stop [email protected]
Nov 05 10:58:11 ubox0 systemd[1]: Stopped Docker container startup for mw/salcom/app.
Nov 05 10:58:11 ubox0 docker[3622]: mw-salcom-app
Nov 05 10:58:09 ubox0 docker[3470]: [Thu Nov 05 10:58:09.921033 2020] [mpm_prefork:notice] [pid 1] AH00169: caught SIGTERM, shutting down
Nov 05 10:58:09 ubox0 systemd[1]: Stopping Docker container startup for mw/salcom/app...
但是,如果我執行shutdown -h now
,我會得到:
Nov 05 10:51:04 ubox0 systemd[1]: Stopped Docker container startup for mw/salcom/app.
Nov 05 10:51:04 ubox0 systemd[1]: [email protected]: Failed with result 'timeout'.
Nov 05 10:51:04 ubox0 systemd[1]: [email protected]: Main process exited, code=killed, status=9/KILL
Nov 05 10:51:04 ubox0 systemd[1]: [email protected]: Killing process 2077 (docker) with signal SIGKILL.
Nov 05 10:51:04 ubox0 systemd[1]: [email protected]: State 'stop-sigterm' timed out. Killing.
Nov 05 10:50:04 ubox0 systemd[1]: [email protected]: Stopping timed out. Terminating.
Nov 05 10:49:04 ubox0 systemd[1]: Stopping Docker container startup for mw/salcom/app...
容器不會停止,流程最終會在 2 分鐘後逾時,容器會中止。
這是什麼原因呢?
我希望我的容器能夠正常關閉,以便停止其中運行的服務而不會丟失資料。
我的服務文件是:
[Unit]
Description=Docker container startup for %I
Requires=docker.service
After=docker.service
[Service]
TimeoutStartSec=40
Restart=always
# wait a while before restarting in case we are doing a restore;
# this includes a 'docker stop' command after we restore the data
RestartSec=60
ExecStartPre=-/usr/bin/docker stop %i
ExecStart=/usr/bin/docker start -a %i
ExecStop=/usr/bin/docker stop %i
TimeoutStopSec=60
[Install]
WantedBy=multi-user.target
更新經過進一步搜索,我發現了那個帖子如何正確地將 Docker 容器當作 systemd 服務處理?描述了同樣的問題,但沒有答案。
答案1
看來 docker 和 systemd 並不總是相處得很好,請參閱:
我在另一台機器(我的備份伺服器)上有完全相同的設置,這裡一切正常。我可以執行 shutdown 命令,所有 docker 容器都會正常關閉。
所以問題可能是依賴問題。也許 systemd 已經關閉了 docker 容器所需的一些服務,以便它們可以正確關閉。
「失敗」的系統上的 docker 版本是18.09.2
,「工作」的系統上的 docker 版本是18.06.1-ce
。
這發行說明對於 docker 版本18.09
狀態:
In Docker versions prior to 18.09, containerd was managed
by the Docker engine daemon. In Docker Engine 18.09,
containerd is managed by systemd.
當我將以下幾行新增到我的單元檔案中:
[Unit]
...
Requires=containerd.service
After=containerd.service
並重新加載單元文件(systemctl daemon-reload
),一切又開始工作了。我的容器在我設定的 1 分鐘超時後沒有終止,而是在幾秒鐘後關閉。
我先嘗試將docker升級到版本20.10.1
,但沒有成功。
當我遇到這個「解決方案」時,我想到了這個「解決方案」:https://github.com/sous-chefs/docker/issues/1062