docker swarm 服务容错依赖健康检查驱动的任务替换,而非容器级 --restart;需在 deploy.restart_policy 中配置 condition: on-failure 等参数,并配合 healthcheck、start_period、window 等协同生效。
--restart-condition 是 docker 容器级重启策略的参数,但它不适用于 docker swarm 服务——这是关键前提。swarm 服务使用的是 deploy.restart_policy,而非容器启动时的 --restart 选项。混淆这两者会导致配置失效、容错机制完全不触发。
要真正提升 Swarm 容器的容错率,必须在服务部署层(而非单容器层)正确配置健康驱动的重启策略,并与服务状态机深度协同。
✅ 正确配置 Swarm 服务的自动恢复策略
Swarm 的容错不是靠“容器挂了就重启”,而是靠:
健康检查失败 → 服务任务状态标记为 unhealthy → 调度器主动终止旧任务 + 在健康节点上调度新任务。
整个过程由 Swarm Manager 的 Health-Driven Reconciliation Loop 主动驱动。
你需要在 docker-compose.yml 或 docker service create 中明确声明:
services:
web:
image: nginx:alpine
deploy:
restart_policy:
condition: on-failure # 或 any / none;on-failure 最常用
delay: 5s
max_attempts: 3
window: 120s # 检查窗口期,避免误判瞬时抖动
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/"]
interval: 30s
timeout: 5s
retries: 3
start_period: 40s # 容器启动后预留缓冲期,避免健康检查过早失败
⚠️ 注意:
condition: on-failure仅在容器退出码非 0 时触发;而condition: any才会在任意退出(包括正常 exit 0)后重启——这通常不符合生产逻辑,易引发误重启。
? 关键细节决定容错是否生效
- healthcheck 必须启用且稳定:没有健康检查,Swarm 不会感知应用级故障,只会依赖进程是否存活(OS 层面),无法发现“进程活着但 HTTP 接口卡死”的典型问题。
- start_period 要足够长:尤其对 Java、Node.js 等冷启动慢的服务,建议设为 60–120s,否则健康检查在应用未就绪时失败,直接触发无效重启。
-
window 和 retries 需匹配业务节奏:例如支付接口要求强一致性,可设
retries: 2+window: 60s;后台任务可放宽至retries: 5+window: 300s。 -
max_attempts 是全局限制:达到后任务将进入
failed状态,不再自动重试——此时需靠 Swarm 的 task replacement 机制(由replicas或mode: global驱动)拉起新任务,而非反复重启同一个实例。
? 配合集群级容错机制才能闭环
单靠服务级重启策略不够,还需叠加:
- 多 Manager 节点(3 或 5 个):保障 Raft 协议下控制平面高可用,避免管理节点宕机导致整个集群失管。
-
跨节点部署约束:用
placement.constraints避免同服务多副本挤在单台 Worker 上,例如:deploy: placement: constraints: - "node.role == worker" -
Volume 健康监控(Docker 27+):若服务依赖持久化存储,启用
volume的 auto-remount fallback 可防止因 NFS 挂载中断导致任务卡死。
?️ 验证配置是否生效
运行以下命令观察健康事件流和任务行为:
# 实时监听健康状态变更
docker system events --filter event=health_status --format '{{json .}}'
# 查看某服务的任务状态(重点关注 STATUS 列)
docker service ps myapp_web
# 强制触发一次健康失败(需进容器执行)
echo "down" > /tmp/health.status
若看到任务状态从 Running → Preparing → Running(新 ID),说明健康驱动的替换流程已通。
Swarm 的容错本质是“声明期望状态 + 自动收敛偏差”,不是堆砌重启指令。配对健康检查与 deploy.restart_policy,再叠加集群架构冗余,容错才真正落地。











