AWS EKS环境下无停机将StorageClass从gp2迁移至gp3可行吗?
无停机从gp2转换到gp3的可行性与操作方案
首先明确两个核心限制:
- 直接修改现有StorageClass的
parameters字段(比如把type从gp2改成gp3)不允许,这就是你遇到Forbidden: Updates to parameters are forbidden错误的原因——Kubernetes中StorageClass的parameters是不可变字段。 - 直接修改PVC的
storageClassName字段同样不可行,该字段为创建后不可修改属性,无法像控制台修改普通EBS卷那样直接变更PVC的存储类。
不过无停机转换是完全可行的,结合你的StatefulSet场景,具体操作方案如下:
1. 创建新的gp3类型StorageClass
先基于ebs.csi.aws.com provisioner创建gp3存储类,示例YAML:
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: gp3-sc provisioner: ebs.csi.aws.com parameters: type: gp3 fsType: ext4 reclaimPolicy: Retain volumeBindingMode: WaitForFirstConsumer
执行创建命令:kubectl apply -f gp3-sc.yaml
2. 针对StatefulSet的PVC无停机迁移
StatefulSet会自动绑定对应命名的PVC(比如data-web-0对应web-0 Pod),无法直接通过修改VolumeClaimTemplates替换现有PVC,需要逐个处理每个PVC:
步骤1:数据同步
为每个现有gp2 PVC创建对应的gp3 PVC,同步数据:
- 创建gp3 PVC(以
data-web-0为例):apiVersion: v1 kind: PersistentVolumeClaim metadata: name: data-web-0-gp3 spec: accessModes: - ReadWriteOnce storageClassName: gp3-sc resources: requests: storage: 10Gi # 与原PVC容量保持一致 - 启动临时迁移Pod,同时挂载新旧PVC:
apiVersion: v1 kind: Pod metadata: name: data-migrator-web-0 spec: containers: - name: busybox image: busybox:1.36 command: ["sleep", "3600"] volumeMounts: - name: old-volume mountPath: /old - name: new-volume mountPath: /new volumes: - name: old-volume persistentVolumeClaim: claimName: data-web-0 - name: new-volume persistentVolumeClaim: claimName: data-web-0-gp3 - 进入Pod执行数据同步:
kubectl exec -it data-migrator-web-0 -- rsync -av /old/ /new/ - 验证数据完整性后,删除临时Pod:
kubectl delete pod data-migrator-web-0
步骤2:替换StatefulSet的PVC
单副本场景:
- 临时缩容StatefulSet到0:
kubectl scale statefulset web --replicas=0 - 删除旧gp2 PVC(注意:若StorageClass的
reclaimPolicy为Retain,对应EBS卷不会被删除;若为Delete,请先手动修改EBS卷保留策略):kubectl delete pvc data-web-0 - 修改StatefulSet的
VolumeClaimTemplates,将storageClassName改为gp3-sc - 扩容StatefulSet回1:
kubectl scale statefulset web --replicas=1
新Pod会自动使用同命名的gp3 PVC
- 临时缩容StatefulSet到0:
多副本场景:
逐个处理副本,避免整体停机:- 将目标Pod从服务端点移除:
kubectl patch pod web-0 -p '{"metadata":{"labels":{"app":"web-temp"}}}',让Service不再路由流量到该Pod - 删除该Pod:
kubectl delete pod web-0 - 删除对应旧PVC:
kubectl delete pvc data-web-0 - 等待StatefulSet自动重建Pod,此时会用新gp3 StorageClass创建PVC
- 验证Pod正常后,恢复标签让其重新加入服务,再处理下一个副本
- 将目标Pod从服务端点移除:
3. 可选:直接修改EBS卷类型(更快捷)
若不想迁移数据,可直接在线修改EBS卷类型为gp3,再更新StatefulSet配置:
- 修改EBS卷类型:
aws ec2 modify-volume --volume-id vol-xxxxxx --volume-type gp3 - 等待卷状态变为
optimizing完成后,修改StatefulSet的VolumeClaimTemplates使用新的gp3 StorageClass - 后续新创建的PVC会用gp3,现有PVC对应的卷已转为gp3类型,无需迁移数据
这种方法操作更高效,AWS修改EBS卷类型为在线操作,无停机影响。
内容的提问来源于stack exchange,提问作者Pepper
相关产品推荐
相关产品推荐

