docker 容器重启策略RestartPolicy

文章目录

      • [1. no (默认策略)](#1. no (默认策略))
      • [2. on-failure[:max-retries]](#2. on-failure[:max-retries])
      • [3. always](#3. always)
      • [4. unless-stopped](#4. unless-stopped)
      • [📊 策略对比总结表](#📊 策略对比总结表)
      • [🛠️ 如何设置和修改](#🛠️ 如何设置和修改)
        • [1. 创建容器时设置](#1. 创建容器时设置)
        • [2. 更新已存在容器的策略](#2. 更新已存在容器的策略)
        • [3. 在 Docker Compose 中设置](#3. 在 Docker Compose 中设置)
      • [⚠️ 注意事项与最佳实践](#⚠️ 注意事项与最佳实践)
      • [✅ 推荐选择](#✅ 推荐选择)

Docker 容器的重启策略(Restart Policy)决定了当 容器退出(Exit)或 Docker daemon 重启 时,容器应该如何行为。合理配置重启策略对于保证服务的高可用性至关重要。

Docker 提供了 4 种主要的重启策略:

1. no (默认策略)

  • 含义 :容器退出后,不自动重启

  • 适用场景

    • 一次性任务(如数据迁移、批量处理脚本)。
    • 调试阶段,希望容器停止后保留现场以便检查日志。
  • 示例

    bash 复制代码
    $ docker run --restart=no -itd centos:1.0 /bin/bash
    615f9ee50e3fcbf15235d1a9396912f7e51d9da25420073e1d6703fcf429f279
    
    $ docker inspect 615f9ee50e3fcbf | jq '.[0].HostConfig.RestartPolicy'
     {
      "Name": "no",
      "MaximumRetryCount": 0
     }
    # 或者省略,因为这是默认值
    $ docker run  -itd centos:1.0 /bin/bash
    b6b2e24fc9486e0e70d15ce05ace59c438193a53cd495b8590e13edbc458f259
    
    $ docker inspect b6b2e24fc9 | jq '.[0].HostConfig.RestartPolicy'
    {
     "Name": "no",
     "MaximumRetryCount": 0
    }

2. on-failure[:max-retries]

  • 含义 :只有当容器以非零状态码(即发生错误/异常)退出时,才自动重启。如果容器正常退出(状态码为 0),则不会重启。

  • 可选参数:max-retries 指定最大重试次数。超过次数后不再重启。

  • 适用场景

    • 需要容错的服务,但如果是正常结束(如任务完成)则不需要重启。
    • 防止无限重启循环导致资源耗尽。
  • 示例

    bash 复制代码
    # 出错时重启,最多重试 5 次
    $ docker run --restart=on-failure:5  -itd centos:1.0 /bin/bash
    000244f7eb8d2509b68da5ec9c2a0ad8c92ba759aa48458557e0e8bc4701efec
    
    $ docker inspect 000244f7eb8d | jq '.[0].HostConfig.RestartPolicy'
    {
    		"Name": "on-failure",
    		"MaximumRetryCount": 5
    }
    # 出错时无限重试
    $ docker run --restart=on-failure  -itd centos:1.0 /bin/bash
    9bedd20adb5a15019564ff9414e9b318ebaa15c2829b6a27b4350deba3d6d32b
    
    $ docker inspect 9bedd20adb5a | jq '.[0].HostConfig.RestartPolicy'
    {
    		"Name": "on-failure",
    		"MaximumRetryCount": 0
    }

3. always

  • 含义 :无论容器因何种原因退出(无论是错误退出还是正常退出),Docker Daemon 都会尝试重启它。此外,如果 Docker Daemon 本身重启了,该容器也会自动启动。

  • 注意 :如果容器是手动停止的(docker stop),它不会被自动重启,直到你手动启动它或 Docker Daemon 重启。

  • 适用场景

    • 长期运行的后台服务(如 Web 服务器、数据库、API 服务)。
    • 要求高可用性,必须保证容器始终处于运行状态。
  • 示例

    bash 复制代码
    $ docker run --restart=always  -itd centos:1.0 /bin/bash
    f927795ebea74537445c5617c19eee22ccdf0b978835bf8eb042843ac8fa27b4
    
    $ docker inspect f927795ebea7 | jq '.[0].HostConfig.RestartPolicy'
    {
    		"Name": "always",
    		"MaximumRetryCount": 0
    }

4. unless-stopped

  • 含义 :与 always 非常相似,无论容器因何种原因退出都会重启。唯一的区别在于 Docker Daemon 重启时的行为

    • 如果在 Docker Daemon 重启之前 ,容器是被手动停止的(docker stop),那么 Daemon 重启后,该容器保持停止状态,不会自动启动。
    • 如果容器是在运行状态下 Daemon 重启的,它会随 Daemon 一起启动。
  • 适用场景

    • 生产环境中最推荐的策略。
    • 当你维护服务器重启 Docker 服务时,不希望那些你故意停掉进行维护的容器自动跑起来。
  • 示例

    bash 复制代码
    $ docker run --restart=unless-stopped  -itd centos:1.0 /bin/bash
    2b1ad8e1c2de78646e976d6c77b8c0c8f1b04a1a3c0d8704f5e558457f9f78e0
    
    $ docker inspect 2b1ad8e1c2de7 | jq '.[0].HostConfig.RestartPolicy'
    {
    		"Name": "unless-stopped",
    		"MaximumRetryCount": 0
    }

综上,"MaximumRetryCount": 0 并不意味着只重启0次,在重启策略为always/unless-stopped 以及on-failure 不指定次数时含义是无限。


📊 策略对比总结表

策略 容器异常退出 (Error) 容器正常退出 (Exit 0) Docker Daemon 重启后 手动 docker stop 后 Daemon 重启
no ❌ 不重启 ❌ 不重启 ❌ 不启动 ❌ 不启动
on-failure ✅ 重启 ❌ 不重启 ✅ 启动 (若上次是异常退出) ❌ 不启动
always ✅ 重启 ✅ 重启 ✅ 启动 自动启动 ⚠️
unless-stopped ✅ 重启 ✅ 重启 ✅ 启动 保持停止

💡 核心区别alwaysunless-stopped 的主要区别在于手动停止后,Docker 服务重启是否会再次拉起容器 。生产环境通常推荐 unless-stopped,因为它更符合运维直觉(我停了你别动)。


🛠️ 如何设置和修改

1. 创建容器时设置
bash 复制代码
docker run --restart=unless-stopped  -itd centos:1.0 /bin/bash
2. 更新已存在容器的策略

如果容器已经运行,可以使用 update 命令修改策略,无需重建容器:

bash 复制代码
docker update --restart=always my_container_name
3. 在 Docker Compose 中设置

docker-compose.yml文件中:

yaml 复制代码
version: '3'
services:
  web:
    image: nginx
    restart: unless-stopped  # 可选值: no, on-failure, always, unless-stopped
  
  db:
    image: postgres
    restart: on-failure:5    # 出错最多重试5次

⚠️ 注意事项与最佳实践

  1. 避免重启风暴

    如果应用代码有 Bug 导致启动即崩溃,使用 alwayson-failure 会导致容器无限重启,消耗大量 CPU 和日志空间。

    • 建议 :结合健康检查(Healthcheck)或使用监控系统报警。对于开发环境,可以使用 on-failure:3 限制次数。
  2. 启动延迟(Back-off)

    Docker 在重启容器时有一个指数退避机制(Exponential Backoff)。

    • 第一次重启等待 100ms
    • 第二次 200ms
    • 第三次 400ms
    • ...
    • 最长等待时间约为 1 分钟。
      这可以防止容器在短时间内频繁重启拖垮宿主机。
  3. 依赖顺序

    重启策略是独立的。如果容器 A 依赖容器 B,而 B 重启了,A 不会自动感知并重启。如果需要处理依赖关系,建议使用 Docker Compose 的 depends_on 配合健康检查,或使用 Kubernetes 等编排工具。

  4. 日志轮转

    频繁重启会产生大量日志。务必配置 Docker 的日志驱动(logging driver)进行日志轮转(log rotation),防止磁盘写满。

    bash 复制代码
    docker run --log-opt max-size=10m --log-opt max-file=3 ...

✅ 推荐选择

  • 生产环境长期服务unless-stopped
  • 临时任务/批处理no
  • 不稳定但需尝试恢复的服务on-failure:5
相关推荐
IMPYLH1 小时前
Linux 的 tty 命令
linux·运维·服务器·bash
@王先生11 小时前
rancher安装--针对报错API Aggregation not ready
linux·运维·rancher
郝亚军3 小时前
在Ubuntu 2.04上如何按照x86_64架构编译libmodbus库
linux·运维·ubuntu
小黑蛋学java3 小时前
Ubuntu Docker 安装手册
linux·ubuntu·docker
Tim风声(网络工程师)9 小时前
排查内网互联网访问流程
运维·服务器·网络
坚持就完事了10 小时前
Linux中如何添加环境变量
linux·运维·服务器
AC赳赳老秦11 小时前
政企内网落地:OpenClaw 离线环境深度适配方案,无外网场景下本地化模型对接与全功能使用
java·大数据·运维·python·自动化·deepseek·openclaw
l1t11 小时前
mingw和Linux中的gcc和llvm编译器编译的pocketpy执行同一个python脚本的不同效果
linux·运维·python
ITyunwei098711 小时前
团队管理与人才发展:如何打造一支“召之即来,来之能战”的铁军?
大数据·运维·人工智能