Kubernetes Deployment 详解:声明式发布、滚动更新与版本回滚实践 一、Deployment 是什么Deployment 是 Kubernetes 中用于管理无状态应用发布的控制器。用户通过 YAML 声明应用名称、镜像、副本数、端口、更新策略和探针等信息Deployment 控制器持续比较“期望状态”和“实际状态”并协调底层 ReplicaSet 与 Pod使集群逐步达到目标状态。简单来说Deployment 不直接运行容器而是通过 ReplicaSet 管理 Pod并负责应用版本的创建、更新、扩缩容和回滚。它非常适合 Web 服务、API 服务、后台任务和其他可以横向扩展的无状态应用。二、Deployment、ReplicaSet 与 Pod 的关系三者可以理解为一条管理链Deployment | -- ReplicaSet管理某一个版本的副本数量 | -- Pod真正运行容器的最小调度单元1. DeploymentDeployment 保存应用发布意图例如使用哪个镜像、需要几个副本、采用什么滚动策略。每当 Pod 模板发生变化Deployment 通常会创建新的 ReplicaSet。2. ReplicaSetReplicaSet 的主要任务是保证指定数量的 Pod 存在。如果某个 Pod 因为节点故障或进程异常消失ReplicaSet 会尝试创建新的 Pod。3. PodPod 是 Kubernetes 调度和运行容器的基本单位。一个 Pod 可以包含一个或多个紧密协作的容器但大多数 Web 应用通常采用一个 Pod 运行一个主容器的方式。三、一个基础 Deployment 示例apiVersion:apps/v1kind:Deploymentmetadata:name:web-demonamespace:defaultspec:replicas:3strategy:type:RollingUpdaterollingUpdate:maxUnavailable:1maxSurge:1selector:matchLabels:app:web-demotemplate:metadata:labels:app:web-demospec:containers:-name:webimage:nginx:1.27ports:-containerPort:80readinessProbe:httpGet:path:/port:80initialDelaySeconds:5periodSeconds:5resources:requests:cpu:100mmemory:128Milimits:cpu:500mmemory:512Mi这个配置表达了几个关键事实需要维持 3 个副本。镜像版本为nginx:1.27。使用滚动更新。更新期间最多额外创建 1 个 Pod。更新期间最多允许 1 个副本不可用。只有通过就绪探针的 Pod 才应该接收服务流量。通过 requests 和 limits 为调度和资源隔离提供依据。四、Deployment 如何执行滚动更新当用户把镜像从nginx:1.27修改为nginx:1.28时Deployment 的 Pod 模板发生变化。Kubernetes 会为新模板创建一个新的 ReplicaSet然后逐步增加新版本 Pod逐步减少旧版本 Pod。典型过程如下新建新的 ReplicaSet。创建一个新版本 Pod。等待新 Pod 通过就绪探针。新 Pod 可用后减少一个旧版本 Pod。重复上述过程直到新版本达到目标副本数。旧 ReplicaSet 保留历史记录用于后续回滚。滚动更新的目标是在发布过程中保持服务尽量可用但“零中断”并不是 Deployment 自动保证的。应用启动时间、探针设计、服务连接、数据库兼容性和流量入口都会影响实际结果。五、maxUnavailable 与 maxSurge1. maxUnavailable表示更新期间允许少于期望数量的最大 Pod 数量。例如副本数为 5maxUnavailable: 1表示更新过程中至少保持 4 个可用副本。它可以使用整数也可以使用百分比。设置过大发布速度较快但可用容量下降设置过小发布更稳妥但更新耗时更长。2. maxSurge表示更新期间允许超出期望副本数的最大 Pod 数量。例如副本数为 5maxSurge: 1表示最多可以同时存在 6 个 Pod。适当增加maxSurge可以让新版本更快启动但会增加 CPU、内存和节点资源消耗。如果集群资源紧张过大的maxSurge可能导致新 Pod 长时间处于 Pending 状态。3. 参数如何选择资源充足、发布速度优先可以提高maxSurge。容量紧张、稳定性优先控制maxSurge避免瞬时超卖。不能接受容量明显下降把maxUnavailable设置得较小。启动时间长的应用给探针和progressDeadlineSeconds留出足够时间。六、滚动更新与 Recreate 的区别Deployment 支持两种常见更新策略。RollingUpdate先启动部分新版本再逐步减少旧版本。适合可以新旧版本短时间共存的无状态服务。优点是中断较少缺点是新旧版本并存时必须保证接口、数据库结构和消息格式兼容。Recreate先删除旧版本再创建新版本。适合新旧版本不能同时运行或应用对单实例运行有强约束的场景。它的配置更简单但更新期间通常会出现服务中断必须结合维护窗口或上层降级策略使用。七、为什么探针决定发布是否可靠1. 就绪探针 readinessProbe就绪探针回答的问题是“这个 Pod 现在是否可以接收业务流量”应用虽然进程已经启动但可能还在加载配置、连接数据库、预热缓存或同步数据。没有就绪探针时流量可能过早进入未准备好的 Pod。2. 存活探针 livenessProbe存活探针回答的问题是“这个容器是否已经失去自我恢复能力”探针失败后Kubernetes 可能重启容器。配置过于激进会造成反复重启配置过于宽松又无法及时处理死锁和假活状态。3. 启动探针 startupProbe对于启动时间很长的应用可以用启动探针保护初始化阶段避免存活探针在应用尚未启动完成时提前重启容器。4. 探针接口设计建议探针接口应轻量、稳定、快速返回。不要让每次健康检查都执行复杂数据库查询。就绪检查应尽量反映“是否适合接收流量”。根据应用真实启动时间设置初始延迟和失败阈值。八、如何查看发布状态kubectl get deployment web-demo kubectl rollout status deployment/web-demo kubectl get rs kubectl get pods-lappweb-demo kubectl describe deployment web-demo kubectl get events --sort-by.lastTimestamp重点观察AVAILABLE是否达到期望数量。新旧 ReplicaSet 的副本数量是否在变化。Pod 是否处于Pending、CrashLoopBackOff或ImagePullBackOff。事件中是否出现资源不足、探针失败、调度失败或镜像拉取错误。九、暂停、恢复与回滚1. 暂停发布kubectl rollout pause deployment/web-demo暂停适合在分阶段修改多个字段时使用避免每修改一次配置就触发一次更新。2. 恢复发布kubectl rollout resume deployment/web-demo恢复后Deployment 会继续按照当前期望状态推进。3. 查看历史版本kubectl rollouthistorydeployment/web-demo4. 回滚到上一版本kubectl rollout undo deployment/web-demo也可以指定历史版本kubectl rollout undo deployment/web-demo --to-revision2回滚并不等于数据库回滚。应用镜像可以退回但数据库结构、消息格式和外部副作用可能已经发生变化因此发布前必须考虑向前兼容和数据迁移策略。十、常见发布失败原因1. 新 Pod 无法调度常见原因包括节点资源不足、节点污点、亲和性规则、资源请求过大和存储挂载失败。应检查 Pod 事件和调度器提示。2. 镜像拉取失败可能是镜像地址错误、仓库认证失败、节点无法访问仓库或标签不存在。生产环境建议使用稳定且可追踪的版本标签避免依赖容易变化的latest。3. 就绪探针失败可能是路径、端口、协议、启动时间或依赖服务配置错误。需要区分“应用确实未准备好”和“探针写错了”。4. 新旧版本不兼容接口字段、数据库结构、缓存格式和消息协议不兼容时滚动更新可能导致部分请求失败。应采用兼容性更好的迁移顺序例如先扩展结构再切换代码最后清理旧字段。5. 更新卡住更新可能因为新 Pod 不就绪、资源不足、容器不断重启或progressDeadlineSeconds超时而停止。不要只查看 Deployment 状态应同时查看 ReplicaSet、Pod、事件和应用日志。十一、生产环境实践建议使用不可变或可追踪的镜像版本记录构建提交号。为每个 Deployment 设置 requests 和 limits。同时设计就绪、存活和必要的启动探针。根据应用启动速度设置maxUnavailable、maxSurge和发布超时。使用 PodDisruptionBudget 减少维护操作对可用副本的影响。设置反亲和性或拓扑分布避免副本全部落在同一节点。在新旧版本共存期间保证 API、数据库和消息格式兼容。发布前记录版本发布后观察延迟、错误率、资源和业务指标。为回滚准备操作手册但不要把回滚当成数据迁移方案。对重要服务进行故障演练验证探针、扩容、摘除和恢复流程。十二、Deployment 的局限Deployment 主要面向无状态应用。数据库、分布式存储、需要稳定网络标识或严格启动顺序的服务通常需要结合 StatefulSet、Operator 或专门的云服务。Deployment 也不能自动解决应用层问题。它可以创建 Pod、替换 Pod 和维持副本但无法判断业务逻辑是否正确也不能保证新版本与数据库、缓存、消息队列完全兼容。十三、总结Deployment 的核心价值是把应用发布从人工操作变成声明式控制用户描述期望状态控制器负责创建 ReplicaSetReplicaSet 负责维持 Pod滚动更新负责逐步替换版本历史记录则为回滚提供基础。真正可靠的 Kubernetes 发布需要把 Deployment 配置、探针、资源、服务发现、应用兼容性、监控指标和回滚策略一起设计。只写出一个 YAML 文件不等于完成了生产级发布方案。CSDN 发布时建议先上传k8s-deployment-rolling-update.png再将相对图片路径替换为 CSDN 图片地址。