Docker 容器平滑重启如何做

作者:袖梨 2026-09-03

Docker容器“平滑重启”需同时保障daemon重启时容器保活(启用live-restore+KillMode=process)和异常退出后自愈(配置unless-stopped等restart策略+HEALTHCHECK),缺一不可。

Docker 容器“平滑重启”不是指单个容器的 restart 命令,而是指在**不中断业务的前提下,让容器持续运行或无缝恢复**——常见于两种场景:一是宿主机或 Docker daemon 重启时容器不退出;二是容器自身异常退出后自动、可控地恢复。真正实现“平滑”,需同时处理**守护进程稳定性**和**容器自愈能力**两层问题。

一、保障 daemon 重启时容器不退出(保活)

默认情况下,systemctl restart docker 会杀死所有容器——因为容器进程由 dockerd 管理,daemon 停止即失去父进程,内核回收子进程。

要打破这种强绑定,必须启用最新支持的 live-restore 机制:

  1. /etc/docker/daemon.json 中添加:{"live-restore": true}
  2. 执行 systemctl daemon-reload && systemctl restart docker 生效
  3. 验证:停掉 dockerd(如 kill -15 $(pidof dockerd)),再运行 ps aux | grep your-app,进程仍在;docker ps 会报错,但不影响业务

注意:仅启用 live-restore 不够,还需调整 systemd 配置,否则 systemd 仍可能清空 cgroup:

  1. 编辑 /lib/systemd/system/docker.service/etc/systemd/system/docker.service.d/override.conf
  2. 确保包含:KillMode=process(禁用默认的 control-group
  3. 移除或注释掉 RestartSec= 类延迟配置,避免干扰恢复节奏

二、容器自身异常退出后自动恢复(自愈)

即使 daemon 一直在线,应用崩溃、OOM、代码 panic 也会导致容器退出。这时靠 restart 策略 实现自动拉起:

  1. --restart=unless-stopped:生产环境最常用——容器随 daemon 启动而启动,手动 docker stop 后不再自动拉起,便于维护
  2. --restart=on-failure:3:适合批处理或有明确成功/失败语义的服务,最多重试 3 次,防无限重启
  3. 避免用 always:它连 docker stop 后也会重启,容易干扰运维操作

配合健康检查可提升判断精度(不只是进程存活):

  1. 在 Dockerfile 中加:HEALTHCHECK --interval=30s --timeout=5s --retries=3 CMD curl -f http://localhost/health || exit 1
  2. Docker Compose 中可进一步结合 deploy.restart_policy(Swarm 模式)或依赖健康状态触发编排动作

三、避免“伪平滑”陷阱

有些做法看似平滑,实则埋雷:

  1. docker restart 手动重启容器:本质是 stop + start,必然中断连接,不适用于高可用服务
  2. 依赖 systemctl restart docker 当“热更新”:仍是 stop-start 流程,没开 live-restore 就等于停服
  3. 只设 restart 策略却不设资源限制:容器 OOM 被 kill 后反复重启,形成“重启风暴”
  4. 日志驱动用 journald + live-restore:daemon 停期间日志可能丢失,关键服务建议用 json-file 或外送

四、验证是否真平滑

别只看 docker ps,要测真实业务连续性:

  1. 在容器内跑一个长期监听的 HTTP 服务,用 curl -v 持续请求,同时触发 daemon 重启
  2. 观察连接是否断开(TCP reset)、响应是否超时、是否有 502/503
  3. docker inspect 容器名 | grep -A 5 Status 确认 RestartCount 是否增加(自愈生效)
  4. journalctl -u docker -n 50 确认无 killexit 相关错误

相关文章

精彩推荐