16.3.4 ReplicaSet与Deployment滚动更新

4. ReplicaSet与Deployment滚动更新#

ReplicaSet核心概念#

ReplicaSet(RS)用于维持指定数量的Pod副本,通常由Deployment间接管理。RS关键点:
- 通过spec.replicas控制副本数
- 通过spec.selectortemplate.metadata.labels匹配Pod
- 当Pod异常退出或节点故障时,自动补齐副本

原理草图

文章图片

常用命令与解释

# 查看ReplicaSet列表与副本数
kubectl get rs

# 查看RS详细信息(选择器、事件、期望/当前副本)
kubectl describe rs web-deploy-7d9f7f6f6b

# 扩容到5副本(解释:修改spec.replicas)
kubectl scale rs web-deploy-7d9f7f6f6b --replicas=5

# 验证Pod数量
kubectl get pods -l app=web

实践建议:避免手动创建RS,优先使用Deployment统一管理更新与回滚。


Deployment滚动更新机制#

Deployment为无状态应用提供声明式更新,默认采用RollingUpdate策略。

关键字段
- spec.strategy.type: RollingUpdate
- spec.strategy.rollingUpdate.maxSurge:更新时可额外创建的Pod数量(可为百分比)
- spec.strategy.rollingUpdate.maxUnavailable:更新期间允许不可用的Pod数量
- spec.revisionHistoryLimit:保留历史RS数量,默认10

滚动更新流程图

文章图片

滚动更新完整示例#

1)创建Deployment

# 文件:/opt/k8s/web-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-deploy
  labels:
    app: web
spec:
  replicas: 4
  revisionHistoryLimit: 5
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: web
        image: nginx:1.25
        ports:
        - containerPort: 80
# 应用资源
kubectl apply -f /opt/k8s/web-deploy.yaml

# 查看Deployment与RS
kubectl get deploy,rs -l app=web

2)触发更新

# 将镜像更新为nginx:1.26(解释:修改Pod模板触发新RS)
kubectl set image deploy/web-deploy web=nginx:1.26

# 查看滚动更新状态(解释:观察升级进度)
kubectl rollout status deploy/web-deploy

3)观察更新过程

# 观察RS与Pod变化
kubectl get rs -l app=web
kubectl get pods -l app=web -w

回滚管理与版本控制#

# 查看版本历史(解释:每次更新生成一个revision)
kubectl rollout history deploy/web-deploy

# 回滚到上一版本
kubectl rollout undo deploy/web-deploy

# 回滚到指定版本
kubectl rollout undo deploy/web-deploy --to-revision=2

常见问题与排错#

1)更新卡住
- 可能原因:探针失败、镜像拉取失败、资源不足、maxUnavailable过小

# 查看Pod状态与事件
kubectl get pods -l app=web
kubectl describe pod <pod-name>

# 检查滚动更新阻塞原因
kubectl describe deploy web-deploy

2)镜像拉取失败

# 事件中常见错误:ImagePullBackOff
kubectl describe pod <pod-name>

# 临时验证镜像可用性(集群节点上)
crictl pull nginx:1.26

3)选择器冲突

# selector与template.labels不一致会导致RS无法管理Pod
kubectl get deploy web-deploy -o jsonpath='{.spec.selector.matchLabels}'
kubectl get deploy web-deploy -o jsonpath='{.spec.template.metadata.labels}'

练习与实操任务#

  1. 创建一个副本数为2的Deployment,使用nginx:1.25。
  2. 设置maxSurge=1maxUnavailable=0,观察升级时Pod数量变化。
  3. 将镜像升级到nginx:1.26,记录滚动更新耗时。
  4. 故意设置一个不存在的镜像版本,观察Pod状态并修复。
  5. 回滚到上一个可用版本并确认Pod恢复。

最佳实践#

  • 无状态服务用Deployment统一管理,避免手动创建RS
  • 使用探针与就绪门控,确保新Pod可用后切流量
  • 合理设置maxSurgemaxUnavailable,兼顾稳定与速度
  • 生产环境保留足够历史版本并启用回滚策略