Todos os produtos
Search
Central de documentação

Container Service for Kubernetes:Migrar volumes NAS provisionados estaticamente do FlexVolume para CSI

Última atualização: Jun 27, 2026

O plug-in FlexVolume foi descontinuado e não tem mais suporte em novos clusters do Container Service for Kubernetes (ACK). Migre seus volumes persistentes (PVs) e solicitações de volume persistente (PVCs) do File Storage NAS (NAS), provisionados estaticamente, do FlexVolume para a Container Storage Interface (CSI) para manter o suporte ao plug-in e acessar novos recursos de armazenamento.

Se o cluster também tiver volumes de disco gerenciados pelo FlexVolume, use o csi-compatible-controller.

Impactos

  • A migração recria os PVCs, o que causa a reinicialização dos pods.

  • A reinicialização dos pods interrompe as cargas de trabalho em execução. Execute a migração fora dos horários de pico.

Comparação entre FlexVolume e CSI

Atributo

CSI

FlexVolume

Componentes

CSI-Provisioner (Deployment): criação automática de volumes e snapshots, armazenamento CNFS e restauração de dados após exclusão acidental. CSI-Plugin (DaemonSet): montagem e desmontagem automática de volumes. Suporta volumes de disco, NAS e OSS por padrão.

Disk-Controller (Deployment): criação automática de volumes. FlexVolume (DaemonSet): montagem e desmontagem de volumes. Suporta volumes de disco, NAS e OSS por padrão.

Parâmetro do kubelet

Defina enable-controller-attach-detach como true em cada nó.

Defina enable-controller-attach-detach como true em cada nó.

Referências

Armazenamento

Visão geral do FlexVolume

Pré-requisitos

Instale o plug-in CSI no cluster antes de começar.

  1. Crie os arquivos csi-plugin.yaml e csi-provisioner.yaml.

    Visualizar o arquivo csi-plugin.yaml

       ---
       apiVersion: v1
       kind: ServiceAccount
       metadata:
         name: csi-admin
         namespace: kube-system
       ---
       kind: ClusterRole
       apiVersion: rbac.authorization.k8s.io/v1
       metadata:
         name: alicloud-csi-plugin
       rules:
         - apiGroups: [""]
           resources: ["secrets"]
           verbs: ["get", "create", "list"]
         - apiGroups: [""]
           resources: ["persistentvolumes"]
           verbs: ["get", "list", "watch", "update", "create", "delete", "patch"]
         - apiGroups: [""]
           resources: ["persistentvolumeclaims"]
           verbs: ["get", "list", "watch", "update"]
         - apiGroups: [""]
           resources: ["persistentvolumeclaims/status"]
           verbs: ["get", "list", "watch", "update", "patch"]
         - apiGroups: ["storage.k8s.io"]
           resources: ["storageclasses"]
           verbs: ["get", "list", "watch"]
         - apiGroups: ["storage.k8s.io"]
           resources: ["csinodes"]
           verbs: ["get", "list", "watch"]
         - apiGroups: [""]
           resources: ["events"]
           verbs: ["get", "list", "watch", "create", "update", "patch"]
         - apiGroups: [""]
           resources: ["endpoints"]
           verbs: ["get", "watch", "list", "delete", "update", "create"]
         - apiGroups: [""]
           resources: ["configmaps"]
           verbs: ["get", "watch", "list", "delete", "update", "create"]
         - apiGroups: [""]
           resources: ["nodes"]
           verbs: ["get", "list", "watch", "update"]
         - apiGroups: ["csi.storage.k8s.io"]
           resources: ["csinodeinfos"]
           verbs: ["get", "list", "watch"]
         - apiGroups: ["storage.k8s.io"]
           resources: ["volumeattachments"]
           verbs: ["get", "list", "watch", "update", "patch"]
         - apiGroups: ["snapshot.storage.k8s.io"]
           resources: ["volumesnapshotclasses"]
           verbs: ["get", "list", "watch", "create"]
         - apiGroups: ["snapshot.storage.k8s.io"]
           resources: ["volumesnapshotcontents"]
           verbs: ["create", "get", "list", "watch", "update", "delete"]
         - apiGroups: ["snapshot.storage.k8s.io"]
           resources: ["volumesnapshots"]
           verbs: ["get", "list", "watch", "update", "create"]
         - apiGroups: ["apiextensions.k8s.io"]
           resources: ["customresourcedefinitions"]
           verbs: ["create", "list", "watch", "delete", "get", "update", "patch"]
         - apiGroups: ["coordination.k8s.io"]
           resources: ["leases"]
           verbs: ["get", "create", "list", "watch", "delete", "update"]
         - apiGroups: ["snapshot.storage.k8s.io"]
           resources: ["volumesnapshotcontents/status"]
           verbs: ["update"]
         - apiGroups: ["storage.k8s.io"]
           resources: ["volumeattachments/status"]
           verbs: ["patch"]
         - apiGroups: ["snapshot.storage.k8s.io"]
           resources: ["volumesnapshots/status"]
           verbs: ["update"]
         - apiGroups: ["storage.k8s.io"]
           resources: ["storageclasses"]
           verbs: ["get", "list", "watch"]
         - apiGroups: [""]
           resources: ["namespaces"]
           verbs: ["get", "list"]
         - apiGroups: [""]
           resources: ["pods","pods/exec"]
           verbs: ["create", "delete", "get", "post", "list", "watch", "patch", "update"]
         - apiGroups: ["storage.alibabacloud.com"]
           resources: ["rules"]
           verbs: ["get"]
         - apiGroups: ["storage.alibabacloud.com"]
           resources: ["containernetworkfilesystems"]
           verbs: ["get","list", "watch"]
       ---
       kind: ClusterRoleBinding
       apiVersion: rbac.authorization.k8s.io/v1
       metadata:
         name: alicloud-csi-plugin
       subjects:
         - kind: ServiceAccount
           name: csi-admin
           namespace: kube-system
       roleRef:
         kind: ClusterRole
         name: alicloud-csi-plugin
         apiGroup: rbac.authorization.k8s.io
       ---
       apiVersion: storage.k8s.io/v1
       kind: CSIDriver
       metadata:
         name: diskplugin.csi.alibabacloud.com
       spec:
         attachRequired: true
         podInfoOnMount: true
       ---
       apiVersion: storage.k8s.io/v1
       kind: CSIDriver
       metadata:
         name: nasplugin.csi.alibabacloud.com
       spec:
         attachRequired: false
         podInfoOnMount: true
       ---
       apiVersion: storage.k8s.io/v1
       kind: CSIDriver
       metadata:
         name: ossplugin.csi.alibabacloud.com
       spec:
         attachRequired: false
         podInfoOnMount: true
       ---
       kind: DaemonSet
       apiVersion: apps/v1
       metadata:
         name: csi-plugin
         namespace: kube-system
       spec:
         selector:
           matchLabels:
             app: csi-plugin
         template:
           metadata:
             labels:
               app: csi-plugin
           spec:
             tolerations:
               - operator: Exists
             affinity:
               nodeAffinity:
                 requiredDuringSchedulingIgnoredDuringExecution:
                   nodeSelectorTerms:
                   - matchExpressions:
                     - key: type
                       operator: NotIn
                       values:
                       - virtual-kubelet
             nodeSelector:
               kubernetes.io/os: linux
             serviceAccount: csi-admin
             priorityClassName: system-node-critical
             hostNetwork: true
             hostPID: true
             dnsPolicy: ClusterFirst
             containers:
               - name: disk-driver-registrar
                 image: registry.cn-hangzhou.aliyuncs.com/acs/csi-node-driver-registrar:v2.3.1-038aeb6-aliyun
                 resources:
                   requests:
                     cpu: 10m
                     memory: 16Mi
                   limits:
                     cpu: 500m
                     memory: 1024Mi
                 args:
                   - "--v=5"
                   - "--csi-address=/var/lib/kubelet/csi-plugins/diskplugin.csi.alibabacloud.com/csi.sock"
                   - "--kubelet-registration-path=/var/lib/kubelet/csi-plugins/diskplugin.csi.alibabacloud.com/csi.sock"
                 volumeMounts:
                   - name: kubelet-dir
                     mountPath: /var/lib/kubelet
                   - name: registration-dir
                     mountPath: /registration
               - name: nas-driver-registrar
                 image: registry.cn-hangzhou.aliyuncs.com/acs/csi-node-driver-registrar:v2.3.1-038aeb6-aliyun
                 resources:
                   requests:
                     cpu: 10m
                     memory: 16Mi
                   limits:
                     cpu: 500m
                     memory: 1024Mi
                 args:
                   - "--v=5"
                   - "--csi-address=/var/lib/kubelet/csi-plugins/nasplugin.csi.alibabacloud.com/csi.sock"
                   - "--kubelet-registration-path=/var/lib/kubelet/csi-plugins/nasplugin.csi.alibabacloud.com/csi.sock"
                 volumeMounts:
                   - name: kubelet-dir
                     mountPath: /var/lib/kubelet/
                   - name: registration-dir
                     mountPath: /registration
               - name: oss-driver-registrar
                 image: registry.cn-hangzhou.aliyuncs.com/acs/csi-node-driver-registrar:v2.3.1-038aeb6-aliyun
                 resources:
                   requests:
                     cpu: 10m
                     memory: 16Mi
                   limits:
                     cpu: 500m
                     memory: 1024Mi
                 args:
                   - "--v=5"
                   - "--csi-address=/var/lib/kubelet/csi-plugins/ossplugin.csi.alibabacloud.com/csi.sock"
                   - "--kubelet-registration-path=/var/lib/kubelet/csi-plugins/ossplugin.csi.alibabacloud.com/csi.sock"
                 volumeMounts:
                   - name: kubelet-dir
                     mountPath: /var/lib/kubelet/
                   - name: registration-dir
                     mountPath: /registration
               - name: csi-plugin
                 securityContext:
                   privileged: true
                   allowPrivilegeEscalation: true
                 image: registry.cn-hangzhou.aliyuncs.com/acs/csi-plugin:v1.24.6-55c95dd-aliyun
                 args:
                   - "--endpoint=$(CSI_ENDPOINT)"
                   - "--v=2"
                   - "--driver=oss,nas,disk"
                 env:
                   - name: KUBE_NODE_NAME
                     valueFrom:
                       fieldRef:
                         apiVersion: v1
                         fieldPath: spec.nodeName
                   - name: CSI_ENDPOINT
                     value: unix://var/lib/kubelet/csi-plugins/driverplugin.csi.alibabacloud.com-replace/csi.sock
                   - name: MAX_VOLUMES_PERNODE
                     value: "15"
                   - name: SERVICE_TYPE
                     value: "plugin"
                 resources:
                   requests:
                     cpu: 100m
                     memory: 128Mi
                   limits:
                     cpu: 500m
                     memory: 1024Mi
                 livenessProbe:
                   httpGet:
                     path: /healthz
                     port: healthz
                     scheme: HTTP
                   initialDelaySeconds: 10
                   periodSeconds: 30
                   timeoutSeconds: 5
                   failureThreshold: 5
                 readinessProbe:
                   httpGet:
                     path: /healthz
                     port: healthz
                   initialDelaySeconds: 10
                   periodSeconds: 30
                   timeoutSeconds: 5
                   failureThreshold: 5
                 ports:
                   - name: healthz
                     containerPort: 11260
                 volumeMounts:
                   - name: kubelet-dir
                     mountPath: /var/lib/kubelet/
                     mountPropagation: "Bidirectional"
                   - name: etc
                     mountPath: /host/etc
                   - name: host-log
                     mountPath: /var/log/
                   - name: ossconnectordir
                     mountPath: /host/usr/
                   - name: container-dir
                     mountPath: /var/lib/container
                     mountPropagation: "Bidirectional"
                   - name: host-dev
                     mountPath: /dev
                     mountPropagation: "HostToContainer"
                   - mountPath: /var/addon
                     name: addon-token
                     readOnly: true
                   - mountPath: /host/var/run/
                     name: fuse-metrics-dir
             volumes:
               - name: fuse-metrics-dir
                 hostPath:
                   path: /var/run/
                   type: DirectoryOrCreate
               - name: registration-dir
                 hostPath:
                   path: /var/lib/kubelet/plugins_registry
                   type: DirectoryOrCreate
               - name: container-dir
                 hostPath:
                   path: /var/lib/container
                   type: DirectoryOrCreate
               - name: kubelet-dir
                 hostPath:
                   path: /var/lib/kubelet
                   type: Directory
               - name: host-dev
                 hostPath:
                   path: /dev
               - name: host-log
                 hostPath:
                   path: /var/log/
               - name: etc
                 hostPath:
                   path: /etc
               - name: ossconnectordir
                 hostPath:
                   path: /usr/
               - name: addon-token
                 secret:
                   defaultMode: 420
                   optional: true
                   items:
                   - key: addon.token.config
                     path: token-config
                   secretName: addon.csi.token
         updateStrategy:
           rollingUpdate:
             maxUnavailable: 30%
           type: RollingUpdate

    Visualizar o arquivo csi-provisioner.yaml

       ---
       kind: Deployment
       apiVersion: apps/v1
       metadata:
         name: csi-provisioner
         namespace: kube-system
       spec:
         selector:
           matchLabels:
             app: csi-provisioner
         strategy:
           rollingUpdate:
             maxSurge: 0
             maxUnavailable: 1
           type: RollingUpdate
         replicas: 2
         template:
           metadata:
             labels:
               app: csi-provisioner
           spec:
             affinity:
               nodeAffinity:
                 preferredDuringSchedulingIgnoredDuringExecution:
                 - weight: 1
                   preference:
                     matchExpressions:
                     - key: node-role.kubernetes.io/master
                       operator: Exists
                 requiredDuringSchedulingIgnoredDuringExecution:
                   nodeSelectorTerms:
                   - matchExpressions:
                     - key: type
                       operator: NotIn
                       values:
                       - virtual-kubelet
               podAntiAffinity:
                 preferredDuringSchedulingIgnoredDuringExecution:
                 - weight: 100
                   podAffinityTerm:
                     labelSelector:
                       matchExpressions:
                       - key: app
                         operator: In
                         values:
                         - csi-provisioner
                     topologyKey: kubernetes.io/hostname
             tolerations:
             - effect: NoSchedule
               operator: Exists
               key: node-role.kubernetes.io/master
             - effect: NoSchedule
               operator: Exists
               key: node.cloudprovider.kubernetes.io/uninitialized
             serviceAccount: csi-admin
             hostPID: true
             priorityClassName: system-node-critical
             containers:
               - name: external-disk-provisioner
                 image: registry.cn-hangzhou.aliyuncs.com/acs/csi-provisioner:v3.0.0-080f01e64-aliyun
                 resources:
                   requests:
                     cpu: 10m
                     memory: 16Mi
                   limits:
                     cpu: 500m
                     memory: 1024Mi
                 args:
                   - "--csi-address=$(ADDRESS)"
                   - "--feature-gates=Topology=True"
                   - "--volume-name-prefix=disk"
                   - "--strict-topology=true"
                   - "--timeout=150s"
                   - "--leader-election=true"
                   - "--retry-interval-start=500ms"
                   - "--extra-create-metadata=true"
                   - "--default-fstype=ext4"
                   - "--v=5"
                 env:
                   - name: ADDRESS
                     value: /var/lib/kubelet/csi-provisioner/diskplugin.csi.alibabacloud.com/csi.sock
                 volumeMounts:
                   - name: disk-provisioner-dir
                     mountPath: /var/lib/kubelet/csi-provisioner/diskplugin.csi.alibabacloud.com
               - name: external-disk-attacher
                 image: registry.cn-hangzhou.aliyuncs.com/acs/csi-attacher:v3.3-72dd428b-aliyun
                 resources:
                   requests:
                     cpu: 10m
                     memory: 16Mi
                   limits:
                     cpu: 500m
                     memory: 1024Mi
                 args:
                   - "--v=5"
                   - "--csi-address=$(ADDRESS)"
                   - "--leader-election=true"
                 env:
                   - name: ADDRESS
                     value: /var/lib/kubelet/csi-provisioner/diskplugin.csi.alibabacloud.com/csi.sock
                 volumeMounts:
                   - name: disk-provisioner-dir
                     mountPath: /var/lib/kubelet/csi-provisioner/diskplugin.csi.alibabacloud.com
               - name: external-disk-resizer
                 image: registry.cn-hangzhou.aliyuncs.com/acs/csi-resizer:v1.3-ca84e84-aliyun
                 resources:
                   requests:
                     cpu: 10m
                     memory: 16Mi
                   limits:
                     cpu: 500m
                     memory: 8Gi
                 args:
                   - "--v=5"
                   - "--csi-address=$(ADDRESS)"
                   - "--leader-election"
                 env:
                   - name: ADDRESS
                     value: /var/lib/kubelet/csi-provisioner/diskplugin.csi.alibabacloud.com/csi.sock
                 volumeMounts:
                   - name: disk-provisioner-dir
                     mountPath: /var/lib/kubelet/csi-provisioner/diskplugin.csi.alibabacloud.com
               - name: external-nas-provisioner
                 image: registry.cn-hangzhou.aliyuncs.com/acs/csi-provisioner:v3.0.0-080f01e64-aliyun
                 resources:
                   requests:
                     cpu: 10m
                     memory: 16Mi
                   limits:
                     cpu: 500m
                     memory: 1024Mi
                 args:
                   - "--csi-address=$(ADDRESS)"
                   - "--volume-name-prefix=nas"
                   - "--timeout=150s"
                   - "--leader-election=true"
                   - "--retry-interval-start=500ms"
                   - "--default-fstype=nfs"
                   - "--v=5"
                 env:
                   - name: ADDRESS
                     value: /var/lib/kubelet/csi-provisioner/nasplugin.csi.alibabacloud.com/csi.sock
                 volumeMounts:
                   - name: nas-provisioner-dir
                     mountPath: /var/lib/kubelet/csi-provisioner/nasplugin.csi.alibabacloud.com
               - name: external-nas-resizer
                 image: registry.cn-hangzhou.aliyuncs.com/acs/csi-resizer:v1.3-ca84e84-aliyun
                 resources:
                   requests:
                     cpu: 10m
                     memory: 16Mi
                   limits:
                     cpu: 500m
                     memory: 8Gi
                 args:
                   - "--v=5"
                   - "--csi-address=$(ADDRESS)"
                   - "--leader-election"
                 env:
                   - name: ADDRESS
                     value: /var/lib/kubelet/csi-provisioner/nasplugin.csi.alibabacloud.com/csi.sock
                 volumeMounts:
                   - name: nas-provisioner-dir
                     mountPath: /var/lib/kubelet/csi-provisioner/nasplugin.csi.alibabacloud.com
               - name: external-oss-provisioner
                 args:
                   - --csi-address=$(ADDRESS)
                   - --volume-name-prefix=oss
                   - --timeout=150s
                   - --leader-election=true
                   - --retry-interval-start=500ms
                   - --default-fstype=ossfs
                   - --v=5
                 env:
                 - name: ADDRESS
                   value: /var/lib/kubelet/csi-provisioner/ossplugin.csi.alibabacloud.com/csi.sock
                 image: registry.cn-hangzhou.aliyuncs.com/acs/csi-provisioner:v3.0.0-080f01e64-aliyun
                 resources:
                   limits:
                     cpu: 500m
                     memory: 1Gi
                   requests:
                     cpu: 10m
                     memory: 16Mi
                 volumeMounts:
                 - mountPath: /var/lib/kubelet/csi-provisioner/ossplugin.csi.alibabacloud.com
                   name: oss-provisioner-dir
               - name: external-csi-snapshotter
                 image: registry.cn-hangzhou.aliyuncs.com/acs/csi-snapshotter:v4.0.0-a230d5b3-aliyun
                 resources:
                   requests:
                     cpu: 10m
                     memory: 16Mi
                   limits:
                     cpu: 500m
                     memory: 1024Mi
                 args:
                   - "--v=5"
                   - "--csi-address=$(ADDRESS)"
                   - "--leader-election=true"
                   - "--extra-create-metadata=true"
                 env:
                   - name: ADDRESS
                     value: /csi/csi.sock
                 volumeMounts:
                   - name: disk-provisioner-dir
                     mountPath: /csi
               - name: external-snapshot-controller
                 image: registry.cn-hangzhou.aliyuncs.com/acs/snapshot-controller:v4.0.0-a230d5b3-aliyun
                 resources:
                   requests:
                     cpu: 10m
                     memory: 16Mi
                   limits:
                     cpu: 500m
                     memory: 1024Mi
                 args:
                   - "--v=5"
                   - "--leader-election=true"
               - name: csi-provisioner
                 securityContext:
                   privileged: true
                 image: registry.cn-hangzhou.aliyuncs.com/acs/csi-plugin:v1.24.6-55c95dd-aliyun
                 args:
                   - "--endpoint=$(CSI_ENDPOINT)"
                   - "--v=2"
                   - "--driver=nas,disk,oss"
                 env:
                   - name: CSI_ENDPOINT
                     value: unix://var/lib/kubelet/csi-provisioner/driverplugin.csi.alibabacloud.com-replace/csi.sock
                   - name: MAX_VOLUMES_PERNODE
                     value: "15"
                   - name: SERVICE_TYPE
                     value: "provisioner"
                   - name: "CLUSTER_ID"
                     value: "CLUSTER_ID"
                 livenessProbe:
                   httpGet:
                     path: /healthz
                     port: healthz
                     scheme: HTTP
                   initialDelaySeconds: 10
                   periodSeconds: 30
                   timeoutSeconds: 5
                   failureThreshold: 5
                 readinessProbe:
                   httpGet:
                     path: /healthz
                     port: healthz
                   initialDelaySeconds: 5
                   periodSeconds: 20
                 ports:
                   - name: healthz
                     containerPort: 11270
                 volumeMounts:
                   - name: host-log
                     mountPath: /var/log/
                   - name: disk-provisioner-dir
                     mountPath: /var/lib/kubelet/csi-provisioner/diskplugin.csi.alibabacloud.com
                   - name: nas-provisioner-dir
                     mountPath: /var/lib/kubelet/csi-provisioner/nasplugin.csi.alibabacloud.com
                   - name: oss-provisioner-dir
                     mountPath: /var/lib/kubelet/csi-provisioner/ossplugin.csi.alibabacloud.com
                   - mountPath: /var/addon
                     name: addon-token
                     readOnly: true
                   - mountPath: /mnt
                     mountPropagation: Bidirectional
                     name: host-dev
                   - mountPath: /host/etc
                     name: etc
                 resources:
                   limits:
                     cpu: 500m
                     memory: 1024Mi
                   requests:
                     cpu: 100m
                     memory: 128Mi
             volumes:
               - name: disk-provisioner-dir
                 emptyDir: {}
               - name: nas-provisioner-dir
                 emptyDir: {}
               - name: oss-provisioner-dir
                 emptyDir: {}
               - name: host-log
                 hostPath:
                   path: /var/log/
               - name: etc
                 hostPath:
                   path: /etc
                   type: ""
               - name: host-dev
                 hostPath:
                   path: /mnt
                   type: ""
               - name: addon-token
                 secret:
                   defaultMode: 420
                   optional: true
                   items:
                   - key: addon.token.config
                     path: token-config
                   secretName: addon.csi.token
  2. Implante o csi-plugin e o csi-provisioner no cluster:

       kubectl apply -f csi-plugin.yaml -f csi-provisioner.yaml
  3. Verifique se o CSI está em execução. Saída esperada: Se todos os pods exibirem Running, o CSI estará instalado.

       kubectl get pods -nkube-system | grep csi
       csi-plugin-577mm                              4/4     Running   0          3d20h
       csi-plugin-k9mzt                              4/4     Running   0          41d
       csi-provisioner-6b58f46989-8wwl5              9/9     Running   0          41d
       csi-provisioner-6b58f46989-qzh8l              9/9     Running   0          6d20h

Procedimento

O exemplo a seguir demonstra a migração de uma carga de trabalho StatefulSet. A figura abaixo ilustra o fluxo de trabalho:

nas

Etapa 1: Verificar o status do volume

  1. Consulte o status do pod. Saída esperada:

       kubectl get pod
       NAME           READY   STATUS    RESTARTS   AGE
       nas-static-1   1/1     Running   0          11m
  2. Identifique o nome do PVC usado pelo pod. Saída esperada:

       kubectl describe pod nas-static-1 |grep ClaimName
       ClaimName:  nas-pvc
  3. Verifique o status do PVC. Saída esperada:

       kubectl get pvc
       NAME      STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
       nas-pvc   Bound    nas-pv   512Gi        RWX                         7m23s

Etapa 2: Criar PV e PVC gerenciados por CSI

Crie um novo PV e PVC gerenciados por CSI que apontem para o mesmo sistema de arquivos NAS. Escolha uma das opções a seguir.

Opção A: Conversão automatizada (CLI FlexVolume2CSI)

  1. Use a CLI FlexVolume2CSI para converter as definições de PV e PVC gerenciadas pelo FlexVolume em equivalentes gerenciados por CSI. A ferramenta gera um arquivo chamado nas-pv-pvc-csi.yaml.

  2. Aplique o arquivo gerado:

       kubectl apply -f nas-pv-pvc-csi.yaml
  3. Verifique o status do PVC. Saída esperada:

       kubectl get pvc
       NAME          STATUS   VOLUME       CAPACITY   ACCESS MODES   STORAGECLASS   AGE
       nas-pvc       Bound    nas-pv       512Gi      RWX            nas            30m
       nas-pvc-csi   Bound    nas-pv-csi   512Gi      RWX            nas            2s

Opção B: Conversão manual

  1. Faça backup das definições existentes de PV e PVC do FlexVolume. Salve o PVC. Saída esperada: Salve o PV. Saída esperada:

       kubectl get pvc nas-pvc -oyaml > nas-pvc-flexvolume.yaml
       cat nas-pvc-flexvolume.yaml
       apiVersion: v1
       kind: PersistentVolumeClaim
       metadata:
         name: nas-pvc
         namespace: default
       spec:
         accessModes:
         - ReadWriteMany
         resources:
           requests:
             storage: 512Gi
         selector:
           matchLabels:
             alicloud-pvname: nas-pv
         storageClassName: nas
       kubectl get pv nas-pv -oyaml > nas-pv-flexvolume.yaml
       cat nas-pv-flexvolume.yaml
       apiVersion: v1
       kind: PersistentVolume
       metadata:
         labels:
           alicloud-pvname: nas-pv
         name: nas-pv
       spec:
         accessModes:
         - ReadWriteMany
         capacity:
           storage: 512Gi
         flexVolume:
           driver: alicloud/nas
           options:
             path: /aliyun
             server: ***.***.nas.aliyuncs.com
             vers: "3"
         persistentVolumeReclaimPolicy: Retain
         storageClassName: nas
  2. Crie um PV e PVC gerenciados por CSI. Crie um arquivo chamado nas-pv-pvc-csi.yaml com o seguinte conteúdo. Aplique o arquivo. Verifique o status do PVC. Saída esperada:

       apiVersion: v1
       kind: PersistentVolumeClaim
       metadata:
         name: nas-pvc-csi
         namespace: default
       spec:
         accessModes:
         - ReadWriteMany
         resources:
           requests:
             storage: 512Gi
         selector:
           matchLabels:
             alicloud-pvname: nas-pv-csi
         storageClassName: nas
       ---
       apiVersion: v1
       kind: PersistentVolume
       metadata:
         labels:
           alicloud-pvname: nas-pv-csi
         name: nas-pv-csi
       spec:
         accessModes:
         - ReadWriteMany
         capacity:
           storage: 512Gi
         csi:
           driver: nasplugin.csi.alibabacloud.com
           volumeHandle: nas-pv-csi
           volumeAttributes:
             server: "***.***.nas.aliyuncs.com"
             path: "/aliyun"
         mountOptions:
         - nolock,tcp,noresvport
         - vers=3
         persistentVolumeReclaimPolicy: Retain
         storageClassName: nas
       kubectl apply -f nas-pv-pvc-csi.yaml
       kubectl get pvc
       NAME      STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
       nas-pvc   Bound    nas-pv   512Gi        RWX                         7m23s

Etapa 3: Atualizar a aplicação

  1. Edite a configuração do StatefulSet:

       kubectl edit sts nas-static
  2. Atualize a solicitação de volume para referenciar o PVC gerenciado por CSI:

       volumes:
             - name: pvc-nas
               persistentVolumeClaim:
                 claimName: nas-pvc-csi
  3. Confirme a reinicialização do pod. Saída esperada:

       kubectl get pod
       NAME           READY   STATUS    RESTARTS   AGE
       nas-static-1   1/1     Running   0          70s
  4. Verifique se o volume NAS está montado via CSI. Se a migração for bem-sucedida, a saída exibirá kubernetes.io~csi no caminho de montagem:

       kubectl exec nas-static-1 -- mount |grep nas
       # View the mount information
       ***.***.nas.aliyuncs.com:/aliyun on /var/lib/kubelet/pods/ac02ea3f-125f-4b38-9bcf-9b117f62***/volumes/kubernetes.io~csi/nas-pv-csi/mount type nfs (rw,relatime,vers=3,rsize=1048576,wsize=1048576,namlen=255,hard,nolock,noresvport,proto=tcp,timeo=600,retrans=2,sec=sys,mountaddr=192.168.XX.XX,mountvers=3,mountport=2049,mountproto=tcp,local_lock=all,addr=192.168.XX.XX)

Etapa 4: Desinstalar o FlexVolume

  1. Acesse o console do OpenAPI Explorer e chame a operação UnInstallClusterAddons para desinstalar o plug-in FlexVolume. Para mais informações, consulte Desinstalar componentes de um cluster.

    • ClusterId: ID do cluster. Encontre-o na aba Basic Information da página de detalhes do cluster.

    • name: Defina como flexvolume.

  2. Exclua os componentes alicloud-disk-controller e alicloud-nas-controller:

       kubectl delete deploy -n kube-system alicloud-disk-controller alicloud-nas-controller
  3. Verifique se o FlexVolume foi totalmente desinstalado. Se nenhuma saída for retornada, o FlexVolume terá sido completamente removido.

       kubectl get pods -n kube-system | grep 'flexvolume\|alicloud-disk-controller\|alicloud-nas-controller'
  4. Exclua as StorageClasses do FlexVolume (provisioner: alicloud/disk). Saída esperada:

       kubectl delete storageclass alicloud-disk-available alicloud-disk-efficiency alicloud-disk-essd alicloud-disk-ssd
       storageclass.storage.k8s.io "alicloud-disk-available" deleted
       storageclass.storage.k8s.io "alicloud-disk-efficiency" deleted
       storageclass.storage.k8s.io "alicloud-disk-essd" deleted
       storageclass.storage.k8s.io "alicloud-disk-ssd" deleted

Etapa 5: Instalar o CSI via API

  1. Acesse o console do OpenAPI Explorer e chame a operação InstallClusterAddons para instalar o CSI. Para mais informações, consulte Instalar um componente em um cluster ACK.

    • ClusterId: ID do cluster.

    • name: Defina como csi-provisioner.

    • version: A versão mais recente é especificada automaticamente. Para detalhes sobre versões, consulte csi-provisioner.

  2. Verifique se o CSI está em execução. Saída esperada: Se todos os pods exibirem Running, o CSI estará instalado.

       kubectl get pods -nkube-system | grep csi
       csi-plugin-577mm                              4/4     Running   0          3d20h
       csi-plugin-k9mzt                              4/4     Running   0          41d
       csi-provisioner-6b58f46989-8wwl5              9/9     Running   0          41d
       csi-provisioner-6b58f46989-qzh8l              9/9     Running   0          6d20h

Etapa 6: Atualizar configurações de nós

Implante um DaemonSet para definir o parâmetro do kubelet --enable-controller-attach-detach como true em todos os nós existentes. Exclua o DaemonSet após a conclusão da atualização.

Importante

Este DaemonSet reinicia o kubelet em cada nó. Avalie o impacto nas aplicações em execução antes de prosseguir.

Crie um arquivo com o seguinte conteúdo e aplique-o com kubectl apply -f <filename>.yaml:

kind: DaemonSet
apiVersion: apps/v1
metadata:
  name: kubelet-set
spec:
  selector:
    matchLabels:
      app: kubelet-set
  template:
    metadata:
      labels:
        app: kubelet-set
    spec:
      tolerations:
        - operator: "Exists"
      hostNetwork: true
      hostPID: true
      containers:
        - name: kubelet-set
          securityContext:
            privileged: true
            capabilities:
              add: ["SYS_ADMIN"]
            allowPrivilegeEscalation: true
          image: registry.cn-hangzhou.aliyuncs.com/acs/csi-plugin:v1.26.5-56d1e30-aliyun
          imagePullPolicy: "Always"
          env:
          - name: enableADController
            value: "true"
          command: ["sh", "-c"]
          args:
          - echo "Starting kubelet flag set to $enableADController";
            ifFlagTrueNum=`cat /host/etc/systemd/system/kubelet.service.d/10-kubeadm.conf | grep enable-controller-attach-detach=$enableADController | grep -v grep | wc -l`;
            echo "ifFlagTrueNum is $ifFlagTrueNum";
            if [ "$ifFlagTrueNum" = "0" ]; then
                curValue="true";
                if [ "$enableADController" = "true" ]; then
                    curValue="false";
                fi;
                sed -i "s/enable-controller-attach-detach=$curValue/enable-controller-attach-detach=$enableADController/" /host/etc/systemd/system/kubelet.service.d/10-kubeadm.conf;
                restartKubelet="true";
                echo "current value is $curValue, change to expect "$enableADController;
            fi;
            if [ "$restartKubelet" = "true" ]; then
                /nsenter --mount=/proc/1/ns/mnt systemctl daemon-reload;
                /nsenter --mount=/proc/1/ns/mnt service kubelet restart;
                echo "restart kubelet";
            fi;
            while true;
            do
                sleep 5;
            done;
          volumeMounts:
          - name: etc
            mountPath: /host/etc
      volumes:
        - name: etc
          hostPath:
            path: /etc

Referências