现场是这样的。容器配了 --restart always,systemd 里又写了一个 unit 去 docker start 它,机器重启后两者互相拉,容器在 Up 和 Restarting 之间反复横跳。

中间走过弯路,把「systemd 的 RestartSec 太短,容器刚创建就被再次拉起」当成主因,改完现象没变。

真正麻烦的地方在于,几个原因的现象几乎一样。docker 的 restart 策略和 systemd 的 Restart 同时生效,两套机制抢同一个容器;unit 的 ExecStart 用 docker start,容器不存在时直接失败退出;containerd 还没就绪,docker start 报 Cannot connect to the Docker daemon。

第一件事是看容器重启次数和退出码

docker inspect -f '{{.RestartCount}} {{.State.ExitCode}}' app

接着确认 unit 和 docker 各自的重启配置

systemctl cat docker-app && docker inspect -f '{{.HostConfig.RestartPolicy.Name}}' app

二选一,unit 里去掉重启或容器改 restart no

docker update --restart=no app && systemctl daemon-reload

剩下的就是重启 docker 后观察容器状态

systemctl restart docker && docker ps -a | grep app

报错是间歇性的,我蹲守了半小时才抓到一次完整现场。

别只看报错消失,验证要多做一步。容器 RestartCount 不再增长,状态稳定为 Up,systemd 的 unit 显示 active 且没有反复重启记录。

容器编排交给 docker 或 systemd 其中之一就行,两套都开会在开机阶段互相干扰;用 compose 的项目直接交给 compose 管。拖得越久,排查成本越高,因为现场状态会被后续操作覆盖。

作者 9823189