容器重启策略 restart

容器重启策略 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:一次性任务的默认值

不需要记复杂的参数,只需理解每个策略的”主观意图”——你想让容器有多”顽强”。

© 版权声明
THE END
喜欢就支持一下吧
点赞15 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容