找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

342

积分

0

好友

46

主题
发表于 前天 23:53 | 查看: 5| 回复: 0

在 Kubernetes 中,Deployment 是我们最常接触的资源之一。你用它部署服务、扩容应用、发布新版、回滚版本……

但 Deployment 背后的控制器到底在做什么?为什么更新镜像后 Pod 会“一个一个”被替换?滚动升级又是怎样确保业务不中断的?

这篇文章将带你深入理解核心控制器的工作流程与 Deployment 的滚动升级策略。

01 Deployment 只是“声明”,真正干活的是控制器

当你定义了一个 Deployment YAML 文件时,你其实是在向 Kubernetes 声明你的期望状态:“我希望有 X 个副本运行这个 Pod 模板。”

Deployment 资源本身并不直接创建或管理 Pod,它的核心工作是创建一个 ReplicaSet,然后由这个 ReplicaSet 来负责确保 Pod 的副本数量始终符合预期。

其完整工作流程如下:

  1. 你通过 kubectl apply 创建或更新一个 Deployment。
  2. Deployment Controller 监听到变化,读取 .spec.template 中的 Pod 模板定义。
  3. 根据模板,控制器创建一个对应的 ReplicaSet 资源。
  4. 随后,这个新创建的 ReplicaSet 接手工作,负责创建和管理具体的 Pod 实例。

简单来说,这三者的关系可以概括为:Deployment 管理应用版本,ReplicaSet 管理 Pod 副本数量,而 Pod 则负责运行业务代码。

当你更新 Deployment(例如更改容器镜像版本)时,Deployment Controller 的工作流程是:

  • 根据新的 Pod 模板,创建一个新的 ReplicaSet。
  • 逐步缩减旧 ReplicaSet 的副本数至零。
  • 同步逐步扩容新 ReplicaSet 的副本数至目标值。

这个过程,正是 滚动升级(Rolling Update) 的底层实现机制。

02 滚动升级:可控、渐进、不影响业务

✓ 默认策略:RollingUpdate

Kubernetes 默认使用滚动升级策略,这意味着新旧 Pod 的替换是逐步进行的,而非一次性全部重启,这对于维持服务的可用性至关重要。

RollingUpdate 策略有两个核心参数控制着升级的节奏:

  • maxUnavailable:在升级过程中,允许“最多有多少个”Pod 处于不可用状态。这可以是一个绝对数(如1)或相对于总副本数的百分比(如25%)。
  • maxSurge:在升级过程中,允许“最多临时超出”期望副本数的 Pod 数量。同样可以是绝对数或百分比。

举例说明: 假设你的 Deployment 定义了 5 个副本(replicas: 5),并设置 maxUnavailable: 1maxSurge: 1

滚动升级示意图

升级过程将按以下步骤进行:

  1. 由于 maxSurge: 1,可以临时多创建一个 Pod,因此会先启动 1个新版本 Pod。此时总 Pod 数为 6(5旧+1新)。
  2. 由于 maxUnavailable: 1,可以允许 1 个 Pod 不可用,因此会删除 1个旧版本 Pod。此时总 Pod 数回到 5(4旧+1新)。
  3. 重复步骤 1 和 2,直到所有 5 个 Pod 都被替换为新版本。

在整个过程中,可用的 Pod 数量始终不少于 4 个(5 - 1),从而保证了业务流量不会中断。这种精密的控制正是现代 容器编排 系统的优势所在。

03 Readiness Probe:滚动升级安全的守护者

许多开发者会忽略 readinessProbe(就绪探针)的配置,但它在滚动升级过程中扮演着至关重要的角色。

当新版本的 Pod 被创建并启动后:

  • 如果 readinessProbe 检查失败,Pod 状态为“未就绪(Not Ready)”。此时,Deployment Controller 不会继续终止下一个旧 Pod
  • 只有当新 Pod 的 readinessProbe 检查成功,状态变为“就绪(Ready)”后,控制器才会继续缩减一个旧 Pod,并启动下一个新 Pod。

如果你没有配置 readinessProbe,Kubernetes 会默认认为 Pod 一旦启动(Running)就能立即处理请求。这可能导致新 Pod 还在初始化(如加载缓存、连接数据库)时就被接入流量,从而引发短暂的业务错误或性能抖动。在复杂的 微服务架构 中,这种问题会被放大。

04 回滚机制:发布失败的保险丝

Deployment 内置了版本历史记录功能。每次更新(rollout)都会记录一个版本(revision)。一旦发布出现问题,你可以快速一键回滚到上一个稳定版本。

kubectl rollout undo deployment/your-app

此外,如果因为新版本镜像问题导致 readinessProbe 持续失败,新 Pod 将一直无法进入就绪状态。在这种情况下,滚动升级过程会自动暂停,而不会无休止地尝试替换和重启,这为运维人员提供了介入和排查的时间窗口。

05 RollingUpdate vs Recreate:谨慎选择后者

Deployment 还支持另一种升级策略:Recreate

它的行为与 RollingUpdate 截然不同:

  • 第一阶段:立即删除所有旧版本的 Pod,导致服务在此时完全中断。
  • 第二阶段:等待所有旧 Pod 清理完毕后,再一次性创建所有新版本的 Pod。

这种策略非常危险,会导致服务在升级期间出现一段不可用时间。除非你的应用有严格的依赖关系(例如数据库迁移,必须停止旧实例才能启动新实例),或者在开发测试环境,否则在生产环境中应尽量避免使用 Recreate 策略。

06 总结:Deployment,应用发布的稳定基石

通过本文,我们深入理解了 Deployment 的三个核心要点:

① 控制器模式是核心

Deployment Controller 是真正的“调度大脑”,它通过创建和管理多个 ReplicaSet 来实现应用的多版本控制与平滑过渡。

② 滚动升级是精密的过程

通过 maxUnavailablemaxSurge 两个关键参数,你可以精确控制升级的激进程度与可用性底线,实现安全、可控的发布。

③ 就绪探针是安全的保障

正确配置 readinessProbe 是确保滚动升级期间业务连续性的关键,它确保了流量只会被导向真正准备好的 Pod 实例。

掌握这些机制,你就能更好地驾驭 Kubernetes 的应用部署与发布流程,构建更稳健的 DevOps 流水线。




上一篇:LinuxFP性能评估:虚拟网络与K8s场景下的透明加速对比分析
下一篇:布隆过滤器与布谷鸟过滤器原理详解:大数据去重与缓存穿透实战指南
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区(YunPan.Plus) ( 苏ICP备2022046150号-2 )

GMT+8, 2025-12-7 00:24 , Processed in 0.095315 second(s), 38 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 CloudStack.

快速回复 返回顶部 返回列表