CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
Kubernetes 入门/课时/Deployment 与滚动更新
RawBlame
课时目录12 节

Kubernetes 入门

  1. 01Kubernetes 是什么
  2. 02核心概念与架构
  3. 03本地集群与 kubectl
  4. 04Pod
  5. 05Deployment 与滚动更新
  6. 06Service 与网络
  7. 07ConfigMap 与 Secret
  8. 08存储卷
  9. 09Ingress 入口
  10. 10资源配额与 HPA
  11. 11RBAC 与安全基础
  12. 12综合练习:部署 backend

Deployment 与滚动更新

副本集、滚动发布、回滚。

40 分钟

Deployment 与滚动更新

这一课你将能做到

  1. 写出带 replicas、selector、Pod 模板的 Deployment,并验证「删 Pod 自动补齐」的自愈能力
  2. 用 kubectl set image 或改 YAML 完成一次滚动更新,用 rollout status/history 观察全程
  3. 执行 rollout undo 回滚到上一版本,并说清 maxUnavailable / maxSurge 的含义

为什么要学

无状态 API(本站 backend、platform 前端)在 K8s 里的标准载体是 Deployment:你声明「要 N 个这样的 Pod」,控制器负责维持健康副本,并内置滚动更新与回滚。

对照现网:以前换 jar 要停服、传包、重启,用户感知中断;K8s 的滚动更新是「起新的、验就绪、停旧的」逐步替换,全程服务不断,出问题一条命令回滚。这是 K8s 最打动业务方的能力,也是面试最高频的考点(「滚动更新怎么实现」「发布如何不中断」)。

先建立图像

Deployment(你操作的层)
  └─ ReplicaSet(版本世代:v1 一组、v2 一组)
       └─ Pod × N(同一模板的实例)

发布 v1 → v2 的滚动过程:
  新建 RS(v2) → 逐步加 v2 Pod、减 v1 Pod → 旧 RS 缩到 0(保留以便回滚)

出问题 → rollout undo → 旧 RS 重新扩容、新 RS 缩到 0
你的操作实际发生
apply Deployment创建/更新 ReplicaSet 与 Pod
删一个 Pod控制器立刻补一个
改 template 里的镜像/探针生成新 RS,触发滚动替换
只改 replicas仅扩缩容,不算发版

跟着做

步骤 1:写 Deployment YAML

deploy-backend.yaml(先用 nginx 占位,逻辑与本站 backend 完全一致):

apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend
  labels:
    app: backend
spec:
  replicas: 2
  revisionHistoryLimit: 5        # 保留最近 5 个版本供回滚
  selector:
    matchLabels:
      app: backend               # 必须与 template.labels 匹配
  template:
    metadata:
      labels:
        app: backend
    spec:
      containers:
        - name: api
          image: nginx:1.27-alpine
          ports:
            - containerPort: 80

硬规则:spec.selector.matchLabels 必须与 template.metadata.labels 匹配,且创建后 selector 不可再改——写错直接 apply 失败或抓错 Pod。

步骤 2:apply 并验证自愈

kubectl apply -f deploy-backend.yaml
kubectl get deploy backend
kubectl get rs -l app=backend
kubectl get pods -l app=backend

看到 1 个 Deployment、1 个 ReplicaSet、2 个 Pod(名字形如 backend-7d9f8b6c5-xxxxx)。现在杀掉一个 Pod:

kubectl delete pod <某个pod名>
kubectl get pods -l app=backend -w

几秒内会出现一个新 Pod 接替它——ReplicaSet 控制器发现副本数低于期望,自动重建。这就是「自愈」。

步骤 3:扩缩容

kubectl scale deployment/backend --replicas=4
kubectl get pods -l app=backend

改回 2 也一样。工程习惯:改 YAML 文件里的 replicas 再 apply(声明式、可追溯),scale 命令适合应急。

步骤 4:滚动更新镜像

kubectl set image deployment/backend api=nginx:1.25-alpine
kubectl rollout status deployment/backend

rollout status 会实时打印 Waiting for deployment "backend" rollout to finish... 直到完成。期间另开终端 kubectl get pods -l app=backend -w,能看到新旧 Pod 此消彼长:新 Pod 先起、Ready 后旧 Pod 才退。对本站即:your-registry/backend:1.0.0 → 1.1.0,用户全程无感。

kubectl rollout history deployment/backend

应看到 REVISION 列表——每次模板变更生成一个修订版本。

步骤 5:回滚

kubectl rollout undo deployment/backend
kubectl rollout status deployment/backend
kubectl get rs -l app=backend

应回到上一版本(旧 RS 重新扩容,新 RS 缩到 0)。指定回到某一版:

kubectl rollout undo deployment/backend --to-revision=1

人话:发布前确认能 undo,比「祈祷不出事」可靠一万倍。

步骤 6:理解更新策略参数

在 Deployment 里显式写策略(默认就是 RollingUpdate,默认值 25%/25%):

spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 0     # 滚动期间最多允许几个副本不可用:0 = 不牺牲容量
      maxSurge: 1           # 滚动期间最多允许多起几个临时副本

小集群/低副本数建议 maxUnavailable: 0, maxSurge: 1——先补齐再替换,容量不缩水。注意:必须配合 readiness 探针,否则「新 Pod 起来了」不等于「新 Pod 能接流量」,策略形同虚设。改回文件里的镜像 tag 后 kubectl apply -f deploy-backend.yaml 收尾,保持「文件是真相」。

讲清楚要点

  1. Deployment 管 RS、RS 管 Pod:日常别手搓 ReplicaSet——会和控制器打架;也解释了为什么删 Deployment 才是「真卸载」。
  2. 只有改 Pod 模板才触发滚动:改镜像、环境变量、探针算发版;只改 replicas 是扩缩。版本历史按「模板变更」计。
  3. 滚动更新靠 readiness 保障不中断:新 Pod 未 Ready 就不摘旧 Pod。没配 readiness 的滚动发布 = 「用户打到启动中的实例」,是发布事故最常见根因。
  4. maxUnavailable 与 maxSurge 决定节奏:不可用上限保护容量,超出上限控制资源消耗;两者都以「期望副本数」的百分比或绝对数表示。
  5. 镜像 tag 必须可追溯:本站镜像来自 CI 固定 tag;用 :latest 滚动可能「以为更新了其实没变」(本地缓存旧层),也回滚不了明确版本。
  6. 回滚依赖 revisionHistoryLimit:默认保留 10 个;设 0 会失去回滚能力。频繁无意义的改动会挤掉历史。

你可能会懵的地方

  • spec.selector 能改吗? 创建后不可变。要换标签体系通常得新建 Deployment 迁移——所以命名空间和标签规范要一开始就想好。

  • 滚动更新卡住不动? rollout status 超时常见于:镜像拉不下来(describe 新 Pod 看 Events)、探针一直失败、节点资源不足。处理完根因滚动会自动继续。

  • 和 Compose 换镜像比差在哪? docker compose up -d 常常整容器重建,中间有真空期;K8s 按策略逐步替换并保留回滚点,且由 readiness 保证流量只打健康实例。

  • 有状态应用也用 Deployment? 数据库类优先考虑托管服务或 StatefulSet(第 8 课);Deployment 擅长无状态服务。MySQL 的多个副本绝不该用一个 Deployment 硬凑。

  • k8s 里还有别的发布方式吗? 蓝绿、金丝雀可以在 Deployment 层面做(双 Deployment 切流量),更标准的做法靠 Ingress/服务网格按权重分流(第 9 课铺垫)。本课先把「滚动 + undo」练成肌肉记忆。

错法对照

错法问题正解
手动删 ReplicaSet「清理」破坏版本历史,回滚失效用 rollout undo / 改 Deployment
selector 与 template 标签不一致apply 被拒或 Pod 失管两处严格一致
无 readiness 就滚动流量进未就绪实例探针必配(上一课)
生产直接改集群 live 对象、不入 Git无法复现、无法审计YAML 进仓库,apply 都有据可查
把一次性批处理写成 Deployment任务永不结束或被反复重启用 Job/CronJob(按需自查)

卡点急救

  1. 滚动更新卡住,rollout status 一直等:kubectl describe pod -l app=backend 看新 Pod 的 Events——多数是镜像拉取失败或探针不通过;kubectl rollout undo 可立即止损。
  2. undo 提示没有可回滚版本:revisionHistoryLimit 设成了 0,或这是第一个版本。预防:保留默认 10,别乱设 0。
  3. 副本数与期望不符:kubectl describe deployment backend 看 Conditions;Pod 起不来多因资源不足(Pending,第 10 课)或镜像错误,个别旧 Pod 处于 Terminating 属正常。

面试常问

  • 滚动更新的原理是什么? 修改 Pod 模板后 Deployment 创建新 ReplicaSet,按 maxSurge 逐步扩新 RS、按 maxUnavailable 逐步缩旧 RS,此消彼长直至新 RS 达到期望副本、旧 RS 缩到 0(但保留对象以备回滚)。每个新 Pod 必须 readiness 通过才继续下一步,配合探针实现发布全程服务不中断。rolling update 的每一步都可被 rollout pause/resume 暂停,用于灰度观察。

  • maxUnavailable 和 maxSurge 怎么理解? 都是相对期望副本数的比例或绝对数。maxUnavailable:滚动过程中允许同时有多少个副本「不可用」,控制容量下限;maxSurge:允许超出期望副本数多少个,控制资源上限。例:期望 4、maxUnavailable=0、maxSurge=1,则滚动期间始终 ≥4 个可用副本,最多瞬时 5 个 Pod。要求「容量永不缩水」就设 maxUnavailable: 0。

  • 线上发新版本发现异常,怎么回滚? kubectl rollout undo deployment/<名> 回到上一 revision(或 --to-revision=N 指定版本),随后 rollout status 确认完成。前提:镜像 tag 可追溯、revisionHistoryLimit 未被清零。更完善的方案把「回滚」做成 CI/CD 里的标准动作(重新发布上一个稳定 tag)。

自测三问

  1. 删一个 Pod 和删 Deployment 的后果分别是什么?
  2. 如何确认一次滚动更新真正完成(而不是「看起来完成」)?
  3. 本站 backend 发版时,镜像 tag 与 rollout undo 各扮演什么角色?

小结一句话

Deployment 用「副本维持 + 滚动策略 + 版本历史」把上线变成可观察、可回滚的常规操作——下一课用 Service 给这些随时会变的 Pod 一个稳定访问入口。

延伸

  • Deployments
  • Performing a Rolling Update
  • 下一课预告:Service 与网络——ClusterIP/NodePort/LoadBalancer 三种类型、DNS 服务发现与 Endpoints 排查。
加载本节练习…
← 上一课Pod下一课 →Service 与网络