容器重启策略 restart
面试题
Docker 容器的重启策略(restart policy)有哪些?分别适用于什么场景?
标准答案
重启策略决定容器退出后 Docker 的行为——是自动重启、记录失败还是完全不管。合理配置重启策略是高可用部署的基础。
四大重启策略
| 策略 | 行为 | 示例 |
|---|---|---|
no |
不自动重启(默认值) | --restart no |
always |
总是重启,无论退出码是什么 | --restart always |
on-failure |
仅退出码非 0 时重启 | --restart on-failure:5 |
unless-stopped |
总是重启,除非手动停止 | --restart unless-stopped |
详细说明
no(默认策略)
# 默认行为:容器退出后什么都不做
docker run --name test alpine echo hello
docker ps -a # 容器状态为 Exited,不会重启
always——总是重启
docker run -d --restart always --name web nginx
# 即使容器 exit 0,也会被立即重启
# 手动 docker stop 后呢?
docker stop web
# 注意:手动 stop 后,Docker 不会主动重启
# 但是!如果 Docker Daemon 重启了,容器也会随 daemon 一起重启
特点:
– 退出码无论是否为 0,都重启
– 手动 docker stop 后不重启
– Docker Daemon 重启时自动拉起
– 重启间隔:初始约 100ms,失败时逐渐增加到最多 1 分钟
on-failure——失败时重启
# 仅非零退出码时重启
docker run -d --restart on-failure --name worker myapp
# 限制最大重启次数
docker run -d --restart on-failure:3 --name worker myapp
# 最多重启 3 次,之后不再尝试
适用场景:
– 脚本任务:异常退出时重试,正常退出则不打扰
– 启动依赖:应用因数据库未就绪而退出,等待后自动重试
– 限制重试次数:避免无限重启浪费资源
unless-stopped——除非手动停止
docker run -d --restart unless-stopped --name db postgres:15
docker stop db # 手动停止后,即使 daemon 重启也不会自动启动
与 always 的区别:
– 两者在自动退出时都会重启
– 关键区别在于 Daemon 重启后的行为:
– always:即使之前手动 stop 过,Daemon 重启后也会拉起来
– unless-stopped:如果之前手动 stop 过,Daemon 重启后不会拉起来
重启策略的实际表现
# 场景:模拟应用崩溃
docker run -d --restart always alpine sh -c "exit 1"
docker ps # 你会看到容器一直在"running"→"restarting"循环
# 重启间隔逐步从 100ms 增加到 1 分钟
# 查看重启次数
docker inspect --format '{{ .RestartCount }}' my-container
# 查看最近一次重启时间
docker inspect --format '{{ .State.StartedAt }}' my-container
与 docker-compose 结合
version: '3'
services:
web:
image: nginx:alpine
restart: always # compose 中推荐 always
worker:
image: myworker:latest
restart: on-failure:5 # 最多重试 5 次
cron:
image: mycron:latest
restart: unless-stopped # 手动停才不重启
disposable:
image: onetask:latest
restart: no # 一次性任务
常见面试追问
问:–restart always 和 –restart unless-stopped 怎么选?
答:如果容器属于”基础设施组件”(Nginx、数据库等),用 always;如果容器是”用户业务服务”且运维人员可能需要手动停止进行维护,用 unless-stopped 更安全。
问:docker stop 后 always 策略的容器会被拉起吗?
答:docker stop 发出的 SIGTERM 会被 Docker 识别为主动停止,不会触发重启。但如果之后 Docker Daemon 重启了,always 策略的容器会重新启动。
问:重启策略支持哪些退出码组合?
答:on-failure 只看退出码是否为 0。非 0 即失败,0 即成功。可以配合应用的退出码约定使用,如 0=正常结束,1=通用错误,2=配置错误等。
问:如何查看容器的重启历史?
# 重启次数
docker inspect -f '{{.RestartCount}}' myapp
# 完整状态信息
docker inspect myapp | jq '.[0].State'
生产环境推荐
# 无状态应用(Web API、微服务)
docker run -d --restart always myapp
# 有状态服务(数据库、缓存)
docker run -d --restart unless-stopped mysql:8
# 后台任务/Worker
docker run -d --restart on-failure:5 worker-image
# 一次性任务/Cron Job
docker run --restart no job-image
总结
重启策略是保障容器可用性的基础。核心记住:
– always:服务类应用的最佳选择
– unless-stopped:需要手动维护的有状态服务
– on-failure:N:批量任务、启动依赖场景
– no:一次性任务的默认值
不需要记复杂的参数,只需理解每个策略的”主观意图”——你想让容器有多”顽强”。


暂无评论内容