零停机发布需滚动更新策略、就绪探针和PreStop钩子协同:maxUnavailable设为0确保旧Pod不先下线,readinessProbe避免流量打入未就绪Pod,preStop执行nginx -s quit优雅终止。

要实现 Nginx 在 Kubernetes 中的零停机发布,关键不是“只改镜像”,而是让新旧 Pod 交替上线与下线的过程被系统精准控制、业务流量平滑过渡。核心在于滚动更新策略 + 探针 + 钩子三者协同,缺一不可。
配置合理的滚动更新参数
默认 RollingUpdate 策略虽可用,但不设限就容易引发抖动或中断。需显式定义 maxSurge 和 maxUnavailable:
-
maxSurge: 1 或 25%:控制最多能多跑几个新 Pod。设为
1表示每次只新增 1 个新版本 Pod,避免资源突增和初始化压力集中。 -
maxUnavailable: 0 或 1:确保更新中至少有全部副本数在服务。设为
0意味着“一个旧 Pod 都不能先下线”,必须等新 Pod 就绪后才删旧 Pod——这是真正零中断的前提。
示例片段:
strategy:type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
必须配好就绪探针(readinessProbe)
Pod 状态变成 Running ≠ 能收流量。Nginx 容器启动快,但若依赖配置重载、上游服务连接或静态资源加载,可能几秒内仍无法响应请求。没有 readinessProbe,Kubernetes 会立即将新 Pod 加入 Service 的 Endpoints,导致 404 或 502。
建议对 Nginx 配置一个轻量 HTTP 就绪检查:
httpGet:
path: /healthz
port: 80
initialDelaySeconds: 5
periodSeconds: 10
timeoutSeconds: 3
同时,在 Nginx 配置中添加对应 location,返回 200 即可(如用 stub_status 或简单 return 200)。
加 PreStop 钩子保老 Pod 善终
删除旧 Pod 时,Kubernetes 默认发 SIGTERM 后等待 terminationGracePeriodSeconds(默认 30s),然后强杀。但若此时仍有长连接、正在处理的请求或 upstream 连接未优雅关闭,就会丢请求。
用 preStop 给 Nginx 一个“缓口气”的机会:
preStop:
exec:
command: ["/bin/sh", "-c", "nginx -s quit; sleep 5"]
这行命令会触发 Nginx 优雅退出(处理完现有连接再关),再留 5 秒缓冲,确保 SLB/Ingress 已将其从后端摘除,避免最后几毫秒的请求失败。
执行与验证流程要闭环
更新不是 kubectl set image 一敲就完事,得确认每步真实生效:
- 用
kubectl set image deploy/nginx-deployment nginx=nginx:1.21.6触发更新; - 立刻跑
kubectl rollout status deploy/nginx-deployment监控进度,直到显示successfully rolled out; - 查
kubectl get endpoints nginx-service,确认新旧 Pod IP 是逐步切换,且始终有足够数量在线; - 模拟真实请求压测(如用 curl 或 hey),观察全程无 5xx 或连接拒绝。


















