Kubernetes Deployment 滚动更新

2025-07-04 06:14:00
丁国栋
原创 6

Kubernetes Deployment 滚动更新

当使用kubectl rollout restart deploy/myapp命令计划执行滚动更新,结果发现原来的Pod立刻变为Terminating状态,而新的Pod是ContainerCreating状态,但我们期望滚动更新,即只有新的Pod Running后原来的Pod才开始Terminating。

滚动更新可以通过配置 Kubernetes Deployment 的滚动更新策略来实现先启动新 Pod 再终止旧 Pod的行为。具体需要调整以下两个参数:

  1. spec.strategy.rollingUpdate.maxUnavailable:设置为 0,表示在更新期间不允许有任何不可用的 Pod
  2. spec.strategy.rollingUpdate.maxSurge:设置为 1,表示可以临时超出期望副本数 1 个 Pod

修改后的 Deployment 配置示例:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  replicas: 1
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 0  # 更新期间不允许有不可用的Pod
      maxSurge: 1        # 可以临时超出期望副本数1个Pod
  template:
    # Pod模板配置

保存退出后,再次执行滚动更新:

kubectl rollout restart deploy/myapp

此外还需要考虑有状态服务(需要 PVC)的情况。

情况一:无状态服务(不需要 PVC)

如果 myapp 是无状态服务(不依赖持久化存储),此时完全不需要关心 PVC,只需要调整 Deployment 的滚动更新策略maxUnavailable: 0 + maxSurge: 1)即可实现目标。

情况二:有状态服务(需要 PVC)

如果 myapp 依赖 PersistentVolumeClaim (PVC),则需要额外注意以下问题:

1. PVC 的动态绑定限制

  • 默认情况下,PVC 是静态绑定的(一个 PVC 只能被一个 Pod 挂载)。
  • 如果直接滚动更新,新 Pod 可能因 PVC 被旧 Pod 占用而卡在 ContainerCreating 状态(报错 persistentvolumeclaim "xxx" is already mounted)。

因此需要使用共享存储(ReadWriteMany)

  • 检查存储后端是否支持 ReadWriteMany

即检查 StorageClass 是否支持 RWX:

kubectl get storageclass -o yaml | grep -A 5 "allowVolumeExpansion"
  • 如果存储后端支持 ReadWriteMany(如 NFS、CephFS、GlusterFS、Longhorn 等),可以修改 PVC 的 accessModes
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteMany  # 关键修改!
  storageClassName: nfs-client  # 存储类必须支持 RWX
  resources:
    requests:
      storage: 10Gi
  • 这样新旧 Pod 可以同时挂载同一个 PVC,滚动更新会顺利完成。
发表评论
博客分类