现场是这样的。容器配了 --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 管。拖得越久,排查成本越高,因为现场状态会被后续操作覆盖。
