You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改GKE上Strimzi Kafka集群的PV存储类并保留数据

问题描述

我是Strimzi新手,想寻求相关建议。我们在GKE上通过Strimzi部署了Kafka集群,覆盖了包括生产环境在内的所有环境。当前Kafka的PVC配置如下:

kafka:
    template:
      pod:
    .....
    storage:
      type: jbod
      volumes:
      - id: 0
        type: persistent-claim
        size: {{ .Values.kafka.storageSize | quote }}
        deleteClaim: true

ZooKeeper的存储配置如下:

zookeeper:
...
    storage:
      type: persistent-claim
      size: {{ .Values.zookeeper.storageSize | quote }}
      deleteClaim: true

当前配置生成的PV使用默认存储类,其ReclaimPolicy为Delete,我需要将其改为ReclaimPolicy为Retain的自定义存储类,同时保留所有主题数据。我的问题是:应该执行哪些操作以及操作顺序是怎样的?因为直接通过.spec.storage.class修改存储类会导致PVC被释放、PV被删除。


操作步骤与顺序

由于直接修改Strimzi配置中的存储类会触发PVC重建(进而导致PV被删除、数据丢失),必须通过先保护现有数据、再迁移到新存储类的安全流程操作,具体步骤如下:

一、提前创建自定义存储类

先在GKE上创建ReclaimPolicy为Retain的自定义存储类,示例配置如下:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: retain-sc
provisioner: kubernetes.io/gce-pd
parameters:
  type: pd-standard
reclaimPolicy: Retain
volumeBindingMode: Immediate

执行创建并确认状态:

kubectl apply -f retain-sc.yaml
kubectl get storageclasses

二、临时保护现有PV

把当前默认存储类生成的所有Kafka、ZooKeeper相关PV的ReclaimPolicy改为Retain,防止后续操作中意外删除数据:

  1. 列出集群内所有相关PVC:
kubectl get pvc -n <你的命名空间>
  1. 对每个PVC对应的PV,执行补丁修改:
# 替换<pv-name>为实际PV名称
kubectl patch pv <pv-name> -p '{"spec":{"persistentVolumeReclaimPolicy":"Retain"}}'

三、备份集群数据(生产环境必做)

1. ZooKeeper元数据备份

进入ZooKeeper pod执行备份:

# 停止单个ZooKeeper节点
kubectl exec -it <zookeeper-pod-name> -n <你的命名空间> -- zkServer.sh stop
# 打包数据
kubectl exec -it <zookeeper-pod-name> -n <你的命名空间> -- tar -czf /tmp/zk-backup.tar.gz /var/lib/zookeeper/data
# 复制到本地
kubectl cp <zookeeper-pod-name>:/tmp/zk-backup.tar.gz ./zk-backup.tar.gz -n <你的命名空间>
# 重启节点
kubectl exec -it <zookeeper-pod-name> -n <你的命名空间> -- zkServer.sh start

2. Kafka主题数据备份(可选但推荐)

使用kafka-dump-log.sh工具备份关键主题,或通过Strimzi MirrorMaker创建临时镜像集群做数据冗余。

四、创建新PVC(绑定自定义存储类)

为每个Kafka broker和ZooKeeper节点创建新PVC,指定自定义存储类retain-sc:

Kafka JBOD PVC示例(每个broker对应一个):

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: kafka-0-retain-sc
  namespace: <你的命名空间>
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: retain-sc
  resources:
    requests:
      storage: <原存储大小>

ZooKeeper PVC示例(每个节点对应一个):

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: zookeeper-0-retain-sc
  namespace: <你的命名空间>
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: retain-sc
  resources:
    requests:
      storage: <原存储大小>

创建后确认PVC绑定成功:

kubectl get pvc -n <你的命名空间>

五、迁移数据到新PVC

逐个处理Kafka broker和ZooKeeper节点,确保数据完整迁移:

  1. 停止目标节点的pod:
# 以Kafka broker 0为例,缩容到0副本
kubectl patch statefulset <kafka-statefulset-name> -p '{"spec":{"replicas":0}}' -n <你的命名空间>
  1. 创建临时pod同时挂载原PVC和新PVC,复制数据:
# 创建临时休眠pod
kubectl run data-copy-pod --image=busybox -n <你的命名空间> --command -- sleep 3600
# 挂载新旧PVC到临时pod
kubectl patch pod data-copy-pod -n <你的命名空间> -p '{"spec":{"volumes":[{"name":"old-pvc","persistentVolumeClaim":{"claimName":"<原PVC名称>"}},{"name":"new-pvc","persistentVolumeClaim":{"claimName":"<新PVC名称>"}}],"containers":[{"name":"busybox","volumeMounts":[{"name":"old-pvc","mountPath":"/old"},{"name":"new-pvc","mountPath":"/new"}]}]}}'
# 复制数据并校验完整性
kubectl exec -it data-copy-pod -n <你的命名空间> -- cp -r /old/. /new/
kubectl exec -it data-copy-pod -n <你的命名空间> -- diff -r /old /new
# 删除临时pod
kubectl delete pod data-copy-pod -n <你的命名空间>
  1. 启动该节点pod,确认运行正常后,再处理下一个节点。

六、更新Strimzi集群配置

修改Kafka和ZooKeeper的存储配置,指定自定义存储类,并恢复Operator的自动同步(如果之前暂停过):

Kafka配置更新:

kafka:
    template:
      pod:
    .....
    storage:
      type: jbod
      volumes:
      - id: 0
        type: persistent-claim
        size: {{ .Values.kafka.storageSize | quote }}
        deleteClaim: true
        class: retain-sc  # 添加自定义存储类

ZooKeeper配置更新:

zookeeper:
...
    storage:
      type: persistent-claim
      size: {{ .Values.zookeeper.storageSize | quote }}
      deleteClaim: true
      class: retain-sc  # 添加自定义存储类

应用配置变更:

kubectl apply -f <你的Kafka集群配置文件>

七、清理旧资源(可选)

确认集群完全稳定运行、数据无异常后,再删除旧的PVC和PV:

# 删除旧PVC
kubectl delete pvc <旧PVC名称> -n <你的命名空间>
# 删除旧PV(因已设为Retain,需手动删除)
kubectl delete pv <旧PV名称>

内容的提问来源于stack exchange,提问作者Никита Петров

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 10:08:16