live-restore 实测:Docker 重启时容器不断,但这几种情况它救不了
为什么要动 Docker 守护进程
单机 Docker 环境里有个绕不开的场景:改 daemon.json(换镜像加速、调日志轮转、开 live-restore)之后要重启守护进程。很多人在这一步犹豫——systemctl restart docker 会不会把上面跑的容器全干掉?如果是深夜升级 Docker 版本,业务是不是也得跟着停?
Docker 提供的答案是 live-restore:让守护进程和容器运行时解耦,daemon 重启期间容器继续运行。这个配置在我一台 1.7G 内存、跑着若干常驻容器的 Ubuntu 22.04 云主机上开了很久,下面把实测结果和它的能力边界一次说清。
开启与验证
配置只有一行,写入 /etc/docker/daemon.json(如果文件里已有其他配置项,注意 JSON 逗号,别覆盖已有内容):
{
"live-restore": true,
"log-driver": "json-file",
"log-opts": {
"max-size": "50m",
"max-file": "3"
}
}
然后让 daemon 重新加载配置。这里有个细节:开启 live-restore 本身这一次,建议用 reload 而不是 restart——SIGHUP 可以让 daemon 在不退出进程的情况下应用部分配置,对已在运行的容器最友好:
sudo systemctl reload docker
# 验证是否生效
docker info | grep -i 'live restore'
# 期望输出:Live Restore Enabled: true
如果 docker info 里显示 false,先检查 JSON 是否合法(python3 -m json.tool /etc/docker/daemon.json),再看 journalctl -u docker --since "5 min ago" 里有没有配置解析报错。live-restore 需要 Docker 1.12 以上,现在的版本基本都满足;但注意它和 swarm 模式不兼容,开了 swarm 的机器不要开这个选项。
实测:三种场景下容器到底怎么样
在我的 22.04 机器上(Docker 29.x + containerd)跑了三个测试,测试容器用 docker run -d --name t1 nginx:alpine 起一个常驻服务即可。
场景一:systemctl restart docker。 daemon 停止期间 docker ps 会报 Cannot connect to the Docker daemon,但 ps aux | grep nginx 能看到容器进程还在跑,端口也还在监听。daemon 起来后 docker ps 恢复正常,容器的 STATUS 列显示的启动时间是重启前的,没有重建。结论:无缝。
场景二:升级 Docker 版本触发的 daemon 重启。 表现和场景一一致。这正是 live-restore 的设计目标——升级 daemon 不再要求先停全部容器。升级后建议 docker ps 确认容器还在、docker logs 能正常取日志,再进行下一步操作。
场景三:宿主机重启。 容器照样停。live-restore 只管 daemon 与容器的解耦,机器重启时内核都没了,容器不可能活着。恢复依赖容器的 --restart 策略(always 或 unless-stopped),两者建议配合使用,别把 live-restore 当成开机自启方案。
还有一个容易误判的场景:手动 kill containerd。dockerd 拉起的容器实际由 containerd 托管,live-restore 只在 dockerd 退出时保容器;如果 systemctl restart containerd 或 containerd 崩溃,容器一样会退出。想验证的话,kill -9 掉 dockerd 主进程,容器依然存活,这就是和"关掉 live-restore 再 kill"最直观的差别。
它救不了什么
- 宿主机重启、内核 OOM、containerd 故障:容器照停,靠 restart 策略和监控兜底。
- dockerd 长时间不回来:容器虽然活着,但期间无法通过 docker API 操作(不能 exec、logs、inspect),等于"业务通、管理断"。
- 网络插件层面的变更:如果重启涉及自定义网络重建或防火墙规则刷新,跨主机连通性问题不在 live-restore 的保护范围内。
容器意外退出的排查对照表
| 报错/现象 | 可能原因 | 处理 |
|---|---|---|
docker ps -a 显示 Exited (137) |
OOM 或被人 kill -9 | dmesg | grep -i oom 看内核记录,限制容器内存或加 swap |
| Exited (139),偶发 | 段错误,多为应用 bug | docker logs 看退出前日志,升级镜像版本 |
| restart 后容器不见了 | 未设 restart 策略 | docker update --restart unless-stopped 容器名 |
restart docker 后 exec 报 container is not running |
live-restore 未生效,容器被一并重启 | 检查 daemon.json 与 docker info 确认配置 |
Cannot connect to the Docker daemon 但业务端口通 |
live-restore 生效中,daemon 正在重启 | 等 daemon 起来,不要此时盲目 docker start |
小结
live-restore 是个"配一次就忘"的低成本保险:一行配置,换来的是改配置、升级 daemon 时容器不中断。但要记住它的保护面只在 dockerd 这一层,宿主机和 containerd 出问题它无能为力。在 22.04 上以上行为均实测验证;其他发行版或更老的 Docker 版本,建议先用一台测试机跑一遍场景一再上生产。
- 点赞
- 收藏
- 关注作者
评论(0)