服务器与大带宽专家 · 持牌IDC/CDN/ISP服务商
简米科技官网JIANMI TECH
资讯 2026-08-19 简米科技 5,349 字 13 分钟阅读

K8s滚动更新如何不停机发布,滚动更新原理是什么

导读Kubernetes 滚动更新通过在更新过程中逐步替换旧版本 Pod,结合就绪探针(Readiness Probe)和 PodDisruptionBudget(PDB)等机制,确保始终有足够数量的实例处理请求,从而实现真正意义上的不停机发布新版本,滚动更新如何保持服务不中断:核心机制解析滚动更新的本质是让新版本……

Kubernetes 滚动更新通过在更新过程中逐步替换旧版本 Pod,结合就绪探针(Readiness Probe)和 PodDisruptionBudget(PDB)等机制,确保始终有足够数量的实例处理请求,从而实现真正意义上的不停机发布新版本。

滚动更新如何保持服务不中断:核心机制解析

滚动更新的本质是让新版本 Pod 像波浪一样依次替换旧版本,整个过程对用户请求完全透明,要做到这一点,需要几个关键组件协同工作。

ReplicaSet 与 Pod 的逐步替换

每个 Deployment 背后管理着一个或多个 ReplicaSet,当你发起滚动更新时,控制器会创建一个新版本的 ReplicaSet,然后逐步增加新 Pod 副本数,同时减少旧 ReplicaSet 的副本数,这个节奏由 maxSurgemaxUnavailable 两个参数控制,业内专家指出,默认情况下这两个参数都设置为 25%,意味着更新过程中最多允许超出期望副本数 25%,同时最多允许 25% 的 Pod 不可用,这种配置在大多数场景下能平衡速度与稳定性。

就绪探针与存活探针的协作

滚动更新依赖的就绪探针(Readiness Probe)是真正决定流量切换的关键,新 Pod 启动后,只有通过就绪探针检测,才会被加入 Service 的 Endpoint 列表接收流量,旧 Pod 在终止前也会等待一段时间,确保正在处理的请求完成,存活探针(Liveness Probe)则负责检测 Pod 是否正常运行,如果探测失败,控制器会重启 Pod,避免因代码问题导致整个更新卡住。

PodDisruptionBudget 保证最小可用副本数

PodDisruptionBudget(PDB)是滚动更新时的保护层,它定义了一个集合中最小可用或最大不可用的 Pod 数量,你可以设置 minAvailable: 3,确保在任何时刻至少有三个 Pod 处于运行状态,当滚动更新配合 PDB 时,控制器会主动放慢退出旧 Pod 的速度,避免因一次性终止过多 Pod 导致服务降级,据统计,在生产环境中配置 PDB 的团队,更新失败率显著低于未配置的团队。

生产环境滚动更新配置:从参数到最佳实践

理解了机制后,我们直接看如何配置一个安全高效的滚动更新策略,很多新手容易忽略参数间的相互影响,导致更新时出现短暂中断。

maxSurge 与 maxUnavailable 参数详解

这两个参数决定滚动更新的速度与资源占用。

  • maxSurge:更新时允许超出期望副本数的最大 Pod 数,可以是绝对数字或百分比,25%2,如果设置过大,可能瞬间创建过多 Pod,加大集群资源压力。
  • maxUnavailable:更新时允许同时不可用的最大 Pod 数,同样支持百分比,设置过小会导致更新过程拖长,但能保证更稳定的服务容量。

常见实践是将 maxSurgemaxUnavailable 都设置为 1,尤其对于有状态服务或关键业务,这样可以确保每次只更新一个 Pod,最大限度降低风险,对于无状态、弹性好的服务,可以适当提高比例以加快发布速度。

K8s滚动更新如何不停机发布,滚动更新原理是什么

滚动更新操作的完整命令示例

假设你有一个名为 nginx-web 的 Deployment,想将镜像版本从 19 升级到 21

# 触发滚动更新
kubectl set image deployment/nginx-web nginx=nginx:1.21
# 实时查看更新状态
kubectl rollout status deployment/nginx-web
# 如果更新出现问题,立即暂停
kubectl rollout pause deployment/nginx-web
# 问题解决后恢复
kubectl rollout resume deployment/nginx-web
# 查看历史修订版本
kubectl rollout history deployment/nginx-web
# 回滚到上一个版本
kubectl rollout undo deployment/nginx-web

在执行 set image 后,Deployment 会自动开始滚动更新,无需手动操作 Pod 创建或删除。

如何验证滚动更新是否成功

验证不仅仅是看 Pod 状态,还需要确认流量是否正常切换到新版本。

  • 检查 Pod 状态kubectl get pods -w 观察新旧 Pod 的创建和终止过程。
  • 检查 Endpoint 变化kubectl get endpoints <service-name> 确保新 Pod 的 IP 被正确加入,旧 Pod 的 IP 逐步移除。
  • 模拟请求测试:用 curl 或压测工具访问 Service,观察响应是否正常,以及版本号是否更新。
  • 查看日志kubectl logs -l app=<app-name> --tail=50 对比新旧 Pod 的日志输出,确认新版本代码没有报错。

滚动更新与蓝绿部署:场景化选择指南

在选型时,不少团队会在滚动更新和蓝绿部署之间犹豫,两者各有优劣,适合不同场景。

两种部署策略的核心差异

  • 滚动更新:逐步替换,新旧版本共存一段时间,资源消耗平稳,但无法保证所有流量瞬间切换到新版本。
  • 蓝绿部署:维护两套完整环境,切换时一次性将流量从旧环境(蓝)导向新环境(绿),切换瞬间完成,但需要双倍资源。

适用场景对比:流量特征与资源成本

维度 滚动更新 蓝绿部署
资源成本 低,仅需额外 25% 左右资源 高,需要两套完整集群
回滚速度 较慢,需逐步回退 极快,直接切换回旧环境
流量切换粒度 逐个 Pod 迁移 一次性全量切换
适合业务 无状态、对延迟不敏感 有状态、需要全量验证

对于大多数 Web 应用和微服务,滚动更新是更经济的选择,而一旦涉及数据库 Schema 变更或需要灰度观察,蓝绿部署或结合流量路由的滚动更新会更合适。

混合使用:滚动更新+蓝绿部署的进阶方案

K8s滚动更新如何不停机发布,滚动更新原理是什么

部分团队会在 Kubernetes 中通过 Ingress 或 Service Mesh 实现混合策略,利用 Istio 的流量权重管理,先创建新版本的全部 Pod,但只切分 10% 流量到新版本,类似蓝绿部署的缓慢切换,这种方式既保留了滚动更新的资源效率,又获得了蓝绿部署的灰度能力,这需要额外引入服务网格组件,复杂度较高。

滚动更新常见问题与回滚策略:如何应对更新失败

不管你准备得多充分,更新失败的可能性始终存在,掌握快速诊断和回滚的方法,是生产环境运维的必备技能。

更新卡住或 Pod 无法启动的处理

滚动更新卡住通常由以下原因导致:

  • 就绪探针配置错误:新 Pod 始终无法通过检测,导致 ReplicaSet 一直等待,此时可以检查探针的路径、端口和超时时间。
  • 资源不足:集群无法调度新 Pod,更新停滞。kubectl describe pod <pod-name> 可以查看调度失败原因。
  • 镜像拉取失败:新镜像不存在或不可访问,检查镜像仓库地址和凭据。
  • PDB 限制:PDB 设置过紧,旧 Pod 无法被删除,新 Pod 无法创建,可以临时调整 PDB 或暂停更新。

遇到卡住时,最安全的方式是先用 kubectl rollout pause 暂停更新,然后逐一排查原因,修复后再恢复。

回滚操作的标准流程

回滚是发布失败的兜底手段,Kubernetes 默认保留最近 10 个修订版本,你可以随时回退到任意版本。

# 查看历史版本
kubectl rollout history deployment/nginx-web
# 回滚到上一个版本
kubectl rollout undo deployment/nginx-web
# 回滚到指定版本
kubectl rollout undo deployment/nginx-web --to-revision=2

执行 undo 后,Deployment 会重新创建一个旧的 ReplicaSet,并开始反向滚动更新,整个过程与正向更新类似,同样受到 maxSurgemaxUnavailable 约束,因此回滚也是平滑的。

利用 kubectl rollout 命令管理发布历史

除了 historyundorollout 子命令组还提供了 statusrestart 等实用功能。

  • kubectl rollout status:持续输出更新进度,直到成功或失败。
  • kubectl rollout restart:不更新镜像,直接重启所有 Pod,常用于重载配置或清理异常状态。
  • kubectl rollout history --revision=<n>:查看某个版本的详细信息,包括镜像版本和配置。

建议在 CI/CD 流水线中集成 rollout status 的等待逻辑,确保发布流程在自动化场景下也能感知更新结果。

不同云环境下的滚动更新实践差异

虽然 Kubernetes 本身是标准化的,但各大云服务商在托管集群中的实现细节有所不同,需要根据实际环境调整配置。

简米云 ACK:自动注入 sidecar 与滚动更新

K8s滚动更新如何不停机发布,滚动更新原理是什么

简米云容器服务(ACK)默认开启了集群自动注入 Sidecar 的功能,例如日志采集、监控 Agent 等,这些 Sidecar 容器会影响滚动更新的启动速度,因为就绪探针需要等待所有容器就绪,建议在 Deployment 中显式定义 readinessProbeinitialDelaySecondsperiodSeconds,为 Sidecar 初始化留出足够时间。

AWS EKS:使用 Node Group 与滚动更新的配合

在 AWS EKS 中,如果节点组需要升级,推荐先更新节点组再触发应用滚动更新,否则可能出现 Pod 被调度到新节点但旧节点还未下线的问题,EKS 的 VPC CNI 插件对 Pod 的 IP 分配有较大延迟,滚动更新时应注意 maxSurge 不要设置过大,避免 IP 耗尽导致 Pod 启动失败。

自建 Kubernetes 集群的滚动更新注意事项

自建集群通常不会自动处理负载均衡器或 DNS 的更新,你需要确保滚动更新过程中,Service 的 Endpoint 更新与后端负载均衡器、DNS 记录同步,当使用 MetalLB 暴露服务时,滚动更新后可能需要手动清理旧 Pod 的 ARP 缓存,建议在滚动更新脚本中加入 kubectl get endpoints 的等待逻辑,直到所有旧 Pod 的 IP 移除、新 Pod 的 IP 稳定后,再认为更新完成。

Kubernetes滚动更新常见问题解答

滚动更新期间如何处理长连接?

滚动更新默认不会强制中断已有连接,但旧 Pod 终止时会进入 Terminating 状态,等待 preStop 钩子执行完毕,如果你的应用处理 WebSocket 或 gRPC 长连接,建议在容器中设置 preStop 钩子,优雅关闭连接池,比如发送一个关闭信号并等待几秒,在 Service 层面使用 externalTrafficPolicy: Local 避免流量经过不健康的节点,但注意这会损失负载均衡的均匀性。

滚动更新速率如何控制?

滚动更新速率由 maxSurgemaxUnavailable 共同决定,但更精细的控制可以通过 progressDeadlineSeconds 实现,该参数定义在更新进度停滞多久后标记为失败,默认是 600 秒,如果你希望更新更保守,可以加大这个数值,并结合 minReadySeconds 确保新 Pod 稳定运行一段时间后才被视为就绪,设置 minReadySeconds: 30 会让新 Pod 在就绪探针成功后等待 30 秒才被用于替换旧 Pod,有效规避瞬态问题。

滚动更新与 HPA 冲突怎么办?

滚动更新时,Pod 的 CPU 和内存使用率可能短暂升高,导致 HPA 误判需要扩容,而扩容又会与滚动更新争夺资源,解决方法是确保 HPA 的 behavior 配置中 scaleDown 部分有 stabilizationWindowSeconds,避免频繁缩容,在滚动更新期间可以临时暂停 HPA 降级,或者使用 kubectl rollout pause 先暂停更新,等 HPA 稳定后再恢复,对于深度结合的 CI/CD 系统,建议在发布流水线中先暂停 HPA 自动缩放,发布完成后恢复。

分享本文
本文为 简米科技官网 原创,已由运维技术专家审核。转载请注明来源:原文链接
售前咨询 服务热线 售后 邮箱