跳转到主内容
极星编程网:以代码为星,赴技术山海!

DockerStop配合负载均衡实现无损滚动更新

docker stop 实现无损滚动更新需应用、容器与LB协同:先摘流再停机。核心是应用响应SIGTERM时关闭监听、等待请求完成并切换/readyz状态为503,LB通过短间隔健康检查(≤3秒)快速剔除节点,最后执行docker stop -t 30确保优雅终止。 使用
docker stop
配合负载均衡实现无损滚动更新,核心在于让容器在真正停止前,先从流量池中优雅摘除,避免新请求被路由到即将关闭的实例。这需要应用层、容器运行时和反向代理三者协同,而非仅靠
docker stop
自身。 理解 docker stop 的默认行为
docker stop
默认发送
SIGTERM
信号给容器主进程,等待 10 秒(可设
--time
)后若未退出则发
SIGKILL
强制终止。但该操作本身不通知上游负载均衡器——如果 LB 仍把请求转发过来,就会导致 502/连接拒绝等错误。 要实现“无损”,必须在发
SIGTERM
前或同时,让 LB 主动剔除该节点。常见做法有: LB 支持健康检查(如 Nginx 的
health_check
、Traefik 的 readiness probe),应用需提供
/healthz
或类似端点,并在收到终止信号后主动返回非健康状态 通过 API 动态下线节点(如 Consul、Nacos 注册中心 + LB 插件) 使用支持服务发现与生命周期钩子的编排工具(如 Docker Swarm 的
update-parallelism
+
update-delay
,或 Kubernetes 的 preStop hook) 关键:应用需支持优雅退出与就绪探针 容器内应用必须能响应
SIGTERM
并执行以下动作: 停止接收新连接(如关闭 HTTP server 的监听 socket) 等待正在处理的请求完成(设置合理的超时,如 30 秒) 同步更新健康检查接口返回值(例如将
/readyz
从
200
变为
503
,触发 LB 快速摘流) 示例(Node.js): 在收到
process.on('SIGTERM', ...)
后,立即调用
server.close()
,并在回调中退出;同时让
/readyz
路由在关闭过程中返回
503
。 负载均衡侧需配合快速感知与摘流 LB 的健康检查间隔和失败阈值直接影响“无损”效果。建议配置: 健康检查间隔 ≤ 3 秒,连续失败次数设为 1~2 次 避免使用长连接保活导致旧连接持续转发(如 Nginx 的
keepalive_timeout
应短于应用优雅停机超时) 若用 DNS 负载均衡(如 CoreDNS + SRV),需确保客户端支持 TTL 刷新并及时重解析 以 Nginx 为例,可结合 upstream 的
max_fails=1 fail_timeout=3s
和应用提供的
/readyz
接口做被动健康检查。 滚动更新流程示意(手动或脚本化) 不依赖 Swarm/K8s 时,可按如下顺序控制单节点更新: 调用 LB API 或修改配置,将目标容器 IP/端口从 upstream 中临时移除(或标记为 down) 等待 1~2 个健康检查周期,确认 LB 不再转发新请求 执行
docker stop -t 30 container_name
,给应用留出处理存量请求的时间 启动新容器,待其
/readyz
返回 200 后,再将其加回 LB upstream 整个过程需幂等、可重试,建议封装为带状态检查的 shell 或 Python 脚本,避免人工误操作。

相关文章