bigywater.tech
Docker · 34

重启策略:always、on-failure 与退避时间

容器崩了会自动重启吗?always、on-failure、unless-stopped 的区别是什么,重启得多快,什么情况下不会重启?这篇逐项实测,包括容器不停崩溃时间隔如何变长。

6537 ms
总是失败的 always 容器,第 7 个重启间隔(前一个 3310 ms,约 2 倍)
RestartCount=3
on-failure:3 加总是失败的命令:重启 3 次后停止,共执行 4 次
exit 0 也重启
always 和 unless-stopped 对成功退出的容器同样不停重启

四种策略

实测 · 本机执行输出
  --restart no              命令 exit 0:Status=exited     RestartCount=0
  --restart no              命令 exit 1:Status=exited     RestartCount=0
  --restart on-failure:2    命令 exit 0:Status=exited     RestartCount=0
  --restart on-failure:2    命令 exit 1:Status=exited     RestartCount=2
  --restart always          命令 exit 0:Status=restarting RestartCount=6
  --restart always          命令 exit 1:Status=restarting RestartCount=6
  --restart unless-stopped  命令 exit 0:Status=restarting RestartCount=6
  --restart unless-stopped  命令 exit 1:Status=restarting RestartCount=6

no 不重启;on-failure 只在退出码非 0 时重启,可以限制次数(:2 重启 2 次后停止),exit 0 不重启;always 和 unless-stopped 对退出码不挑,连成功退出也重启。后两者的区别(daemon 重启后 unless-stopped 不会拉起手动停止过的容器)需要重启 Docker 守护进程来验证,我没有做。

指数退避

实测 · 本机执行输出
  14 秒内共启动 8 次,RestartCount=8
  相邻两次 start 的间隔(ms):[175, 276, 467, 886, 1679, 3310, 6537]
  每个间隔与前一个的比值:[1.58, 1.69, 1.9, 1.9, 1.97, 1.97]

重启间隔 175、276、467、886、1679、3310、6537 ms,稳定后每次约为前一次的 2 倍。第一个间隔含容器启动和退出本身的耗时,所以不是整整的 100 ms。我只测了 14 秒,没有看到上限(以及容器稳定运行多久会重置退避),没有验证。

手动停止

实测 · 本机执行输出
  docker stop 3 秒后:Status=exited(手动停止的容器不会被重启策略拉起)
  docker start 之后:Status=running
  docker kill 之后 3 秒:Status=exited RestartCount=0(docker kill 之后没有被重新拉起)
  docker update --restart no 之后再 kill:Status=exited;策略现在是 no

docker stop 之后容器保持 exited。docker kill 之后在这个版本里也没有被重新拉起(RestartCount=0)。

次数与 --rm

实测 · 本机执行输出
  on-failure:3 + 总失败:Status=exited RestartCount=3(1 次原始启动加 3 次重启共 4 次执行)
  --rm 与 --restart always 同时用 → 退出码 125;docker: conflicting options: cannot specify both --restart and --rm

on-failure:3 总共执行 4 次(1 次原始启动加 3 次重启)。--rm 和 --restart 不能同时使用,docker run 直接以 125 报错。

分步演示

重启策略
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / Docker Desktop(Engine 29.8.2,容器跑在 Docker Desktop 自带的 Linux 虚拟机里,内核与宿主机的 macOS 不同);镜像为 linux/arm64;需要看虚拟机内部时用特权容器 + nsenter;计时用 time / date +%s%N,数字每次运行会有小幅抖动。策略对比的每种组合起一个容器,等 5 秒取状态;退避间隔取自 docker events 的 start 事件时间戳(TimeNano);其余场景各运行一次;实验后已删除容器
    • 没有验证:Docker 守护进程重启后 always 与 unless-stopped 的差别、退避的上限和重置条件、--restart 与 Swarm / Compose 的 restart、健康检查失败是否触发重启
    京ICP备2026067502号-1京公网安备11010502063487号