<p style="text-align:center"><img src="https://platform-outputs.agnes-ai.space/images/t2i/task_OwTmvAdGu85VU8hgbYLlJlgyqOz4xT2J/output_8287cdf720394a198e12bdcc34e06f28.png" alt="封面图" style="max-width:100%;height:auto" /></p>
K8s 滚动部署失效?maxUnavailable 参数没搞透
生产环境一发布就报 502,用户投诉电话被打爆,这种坑我踩过不止一次。很多时候不是代码问题,而是 K8s 滚动部署策略配置太随意。很多新手以为配置了 RollingUpdate 就是零停机,结果流量照样断。今天不聊虚的,直接上干货,教你如何配置才能实现真正的零停机,避免背锅。
核心参数别乱填
很多人`maxUnavailable`直接设 50%,以为快就是好。其实这参数决定了更新期间最多允许多少个 Pod 不可用。假设你 replica 是 3,设 50% 就是允许 1.5 个(向下取整 1 个)Pod 挂掉。如果新 Pod 启动慢,旧 Pod 又被杀了,流量瞬间打空。底层原理上,Controller 会先创建新 Pod,再删除旧 Pod,但顺序受这两个参数严格约束。此外,Pod 终止宽限期(terminationGracePeriodSeconds)也关键,默认 30 秒,给应用处理完现有请求的时间。
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
输出说明:maxUnavailable 设 0 最稳妥,确保旧 Pod 存活到新 Pod 就绪。maxSurge 设 1 允许临时多跑一个 Pod 加速更新,避免资源死锁。
探针才是命门
参数配对了,为什么还是断流?因为`readinessProbe`没配好。K8s 只有探针检测通过,才会把流量切过去。如果接口启动需要 5 秒,探针初始延迟却设 2 秒,流量进来必挂。这里涉及 K8s Service Endpoint 的更新机制,只有 Ready 状态的 Pod 才会被加入 iptables 规则,同步有延迟,探针必须覆盖这段空白期。
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
failureThreshold: 3
输出说明:initialDelaySeconds 必须大于应用启动耗时。failureThreshold 给足重试机会,避免网络抖动导致误杀。切记别用 livenessProbe 代替 readiness,前者挂了会重启,后者挂了只切流量。
验证与回滚实战
发布不是丢完 yaml 就完事,得盯着状态。别只用`get pod`,要看 rollout 状态。一旦发现问题,秒级回滚是底线。很多故障扩大化就是因为犹豫不决,不敢回滚。底层是 Controller 记录了 ReplicaSet 的历史版本,回滚本质是切换版本标签,速度极快。
kubectl rollout status deployment/my-app
kubectl rollout undo deployment/my-app
输出说明:第一条命令实时查看更新进度,卡住立刻第二条回滚。生产环境严禁盲目等待,超时即回滚。配合 CI/CD 脚本自动化判断状态更佳,设置 5 分钟超时阈值。
老运维避坑清单
-
`maxUnavailable`生产环境建议为 0,别贪快,稳定压倒一切。
-
探针路径必须是真实业务依赖检查,别只 ping 通,要查数据库连接。
-
更新前确认资源配额,新 Pod 可能因 quota Pending 导致旧 Pod 被杀。
-
灰度发布比全量滚动更安全,有条件的上 Istio 或 ingress Canary。
-
监控告警要覆盖部署期间,别等用户投诉,关注 5xx 突增。
-
应用启动脚本要处理好信号量,支持平滑关闭,避免请求被截断。
-
确保节点资源充足,避免新 Pod 因资源不足无法调度,导致更新卡死。
你生产环境滚动部署遇到过最奇葩的问题是什么?评论区聊聊。