All Products
Search
Document Center

Container Service for Kubernetes:Migrasi volume OSS yang disediakan secara statis dari FlexVolume ke CSI

Last Updated:Jun 18, 2026

Migrasikan volume OSS yang disediakan secara statis dari FlexVolume ke CSI dengan membuat ulang PVC dan PV pada kluster ACK yang sudah ada.

Berlaku hanya untuk kluster dengan volume OSS yang disediakan secara statis menggunakan FlexVolume. Jika kluster Anda juga memiliki volume disk pada FlexVolume, lihat Gunakan csi-compatible-controller untuk migrasi dari FlexVolume ke CSI.

Perbedaan antara CSI dan FlexVolume

Plugin Komponen Parameter kubelet
CSI CSI-Provisioner (Deployment): menangani pembuatan volume, snapshot, penyimpanan Container Network File System (CNFS), dan pemulihan data setelah penghapusan tidak sengaja. CSI-Plugin (DaemonSet): memasang dan melepas volume disk, NAS, dan OSS. Atur enable-controller-attach-detach menjadi true pada setiap node.
FlexVolume Disk-Controller (Deployment): menangani pembuatan volume. FlexVolume (DaemonSet): memasang dan melepas volume disk, NAS, dan OSS. Atur enable-controller-attach-detach menjadi true pada setiap node.

Catatan penggunaan

PVC akan dibuat ulang selama migrasi, yang menyebabkan pod restart dan mengganggu workload. Lakukan migrasi pada jam sepi.

Prasyarat

  • Kluster ACK dengan FlexVolume terinstal dan minimal satu volume OSS yang disediakan secara statis

  • Akses kubectl untuk membuat, mendapatkan, menampilkan daftar, dan menghapus PVC, PV, Deployment, dan DaemonSet di namespace kube-system

  • Akses ke OpenAPI Explorer untuk memanggil UnInstallClusterAddons dan InstallClusterAddons

Migrasi volume OSS yang disediakan secara statis dari FlexVolume ke CSI

Contoh berikut menggunakan workload StatefulSet untuk migrasi volume OSS yang disediakan secara statis dari FlexVolume ke CSI.

oss

Langkah 1: Instal CSI secara manual

Deploy komponen CSI bersama instalasi FlexVolume yang sudah ada.

  1. Buat dua file: csi-plugin.yaml dan csi-provisioner.yaml. csi-plugin.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

    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. Deploy kedua komponen tersebut:

    kubectl apply -f csi-plugin.yaml -f csi-provisioner.yaml
  3. Verifikasi bahwa CSI sedang berjalan:

    kubectl get pod

    Output yang diharapkan:

    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

Langkah 2: Periksa status volume saat ini

Catat status workload saat ini sebelum mengonversi PVC dan PV.

  1. Periksa status pod:

    kubectl get pod

    Output yang diharapkan:

    NAME       READY   STATUS    RESTARTS   AGE
    oss-sts-1  1/1     Running   0          11m
  2. Identifikasi PVC yang digunakan oleh pod:

    kubectl describe pod oss-sts-1 |grep ClaimName

    Output yang diharapkan:

    ClaimName:  oss-pvc
  3. Periksa status PVC:

    kubectl get pvc

    Output yang diharapkan:

    NAME      STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
    oss-pvc   Bound    oss-pv   5Gi        RWX                           7m23s

Langkah 3: Buat PVC dan PV yang dikelola CSI untuk volume OSS

Pilih salah satu metode berikut:

Metode 1: Otomatis (CLI Flexvolume2CSI) Metode 2: Pengeditan YAML manual
Paling cocok untuk Kluster dengan banyak PV yang perlu dikonversi Kluster dengan jumlah PV sedikit atau ketika Anda menginginkan kontrol penuh
Usaha Rendah — CLI menghasilkan YAML CSI Lebih tinggi — edit definisi YAML secara manual
Risiko Rendah — hanya konversi logis; objek PV/PVC asli tetap utuh hingga Anda menghapusnya Rendah — data sama, definisi PV/PVC baru; objek asli tetap ada hingga pembersihan
Downtime Pod restart saat Anda memperbarui referensi aplikasi Pod restart saat Anda memperbarui referensi aplikasi

Metode 1: Konversi otomatis dengan CLI Flexvolume2CSI

  1. Konversi PV dan PVC FlexVolume ke definisi CSI menggunakan CLI Flexvolume2CSI. CLI akan menghasilkan file oss-pv-pvc-csi.yaml.

  2. Terapkan file yang dihasilkan:

    kubectl apply -f oss-pv-pvc-csi.yaml
  3. Verifikasi bahwa PVC lama dan baru sama-sama dalam status bound:

    kubectl get pvc

    Output yang diharapkan:

    NAME          STATUS   VOLUME       CAPACITY   ACCESS MODES   STORAGECLASS   AGE
    oss-pvc-csi   Bound    oss-pv-csi   5Gi        RWO                           7m15s
    oss-pvc       Bound    oss-pv       5Gi        RWX                           52m

Metode 2: Konversi manual dengan mengedit konfigurasi PVC dan PV

  1. Simpan definisi PVC FlexVolume yang ada:

    kubectl get pvc oss-pvc -oyaml > oss-pvc-flexvolume.yaml
    cat oss-pvc-flexvolume.yaml

    Output yang diharapkan:

    apiVersion: v1
    kind: PersistentVolumeClaim
      name: oss-pvc
      namespace: default
    spec:
      accessModes:
      - ReadWriteMany
      resources:
        requests:
          storage: 5Gi
      volumeMode: Filesystem
      volumeName: oss-pv

    Simpan PV:

    kubectl get pv oss-pv -oyaml > oss-pv-flexvolume.yaml
    cat oss-pv-flexvolume.yaml

    Output yang diharapkan:

    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: oss-pv
    spec:
      accessModes:
      - ReadWriteMany
      capacity:
        storage: 5Gi
      claimRef:
        apiVersion: v1
        kind: PersistentVolumeClaim
        name: oss-pvc
        namespace: default
      flexVolume:
        driver: alicloud/oss
        nodePublishSecretRef:
          name: oss-secret
          namespace: default
        options:
          bucket: xxx
          otherOpts: -o max_stat_cache_size=0 -o allow_other
          url: xxx.aliyuncs.com
      persistentVolumeReclaimPolicy: Retain
      volumeMode: Filesystem
  2. Buat file oss-pv-pvc-csi.yaml dengan definisi PVC dan PV berbasis CSI. Ganti *** dengan nama bucket dan endpoint OSS Anda.

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: oss-pvc-csi
    spec:
      accessModes:
      - ReadWriteMany
      resources:
        requests:
          storage: 5Gi
      selector:
        matchLabels:
          alicloud-pvname: oss-pv-csi
    ---
    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: oss-pv-csi
      labels:
        alicloud-pvname: oss-pv-csi
    spec:
      capacity:
        storage: 5Gi
      accessModes:
        - ReadWriteMany
      persistentVolumeReclaimPolicy: Retain
      csi:
        driver: ossplugin.csi.alibabacloud.com
        volumeHandle: oss-pv-csi
        nodePublishSecretRef:
          name: oss-secret
          namespace: default
        volumeAttributes:
          bucket: "***"
          url: "***.aliyuncs.com"
          otherOpts: "-o max_stat_cache_size=0 -o allow_other"
  3. Terapkan file tersebut:

    kubectl apply -f oss-pv-pvc-csi.yaml
  4. Verifikasi bahwa kedua PVC dalam status bound:

    kubectl get pvc

    Output yang diharapkan:

    NAME          STATUS   VOLUME       CAPACITY   ACCESS MODES   STORAGECLASS   AGE
    oss-pvc-csi   Bound    oss-pv-csi   5Gi        RWO                           7m15s
    oss-pvc       Bound    oss-pv       5Gi        RWX                           52m

Langkah 4: Perbarui aplikasi agar menggunakan PVC yang dikelola CSI

  1. Edit konfigurasi StatefulSet:

    kubectl edit sts oss-sts
  2. Perbarui referensi volume ke PVC CSI:

          volumes:
          - name: oss
            persistentVolumeClaim:
              claimName: oss-pvc-csi
  3. Verifikasi bahwa pod telah restart:

    kubectl get pod

    Output yang diharapkan:

    NAME       READY   STATUS    RESTARTS   AGE
    oss-sts-1  1/1     Running   0          70s
  4. Verifikasi bahwa volume menggunakan CSI (ossfs):

    kubectl exec oss-sts-1 -- mount |grep ossfs

    Output yang diharapkan:

    ***:/ on /var/lib/kubelet/pods/ac02ea3f-125f-4b38-9bcf-9b117f62eaf0/volumes/kubernetes.io~csi/oss-pv-csi/mount type ossfs (rw,relatime,max_stat_cache_size=0,allow_other)

    Jalur mount kubernetes.io~csi mengonfirmasi bahwa CSI aktif.

Langkah 5: Uninstal FlexVolume

  1. Panggil UnInstallClusterAddons di OpenAPI Explorer untuk meng-uninstall FlexVolume. Lihat Uninstall komponen dari kluster.

    • ClusterId: ID kluster dari tab Basic Information.

    • name: Atur ke flexvolume.

  2. Hapus komponen controller FlexVolume:

    kubectl delete deploy -n kube-system alicloud-disk-controller alicloud-nas-controller
  3. Verifikasi bahwa FlexVolume telah sepenuhnya dihapus:

    kubectl get pods -n kube-system | grep 'flexvolume\|alicloud-disk-controller\|alicloud-nas-controller'

    Tidak ada output berarti FlexVolume telah sepenuhnya dihapus.

  4. Hapus StorageClass FlexVolume (provisioner: alicloud/disk):

    kubectl delete storageclass alicloud-disk-available alicloud-disk-efficiency alicloud-disk-essd alicloud-disk-ssd

    Output yang diharapkan:

    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

Langkah 6: Instal CSI menggunakan API

Ganti komponen CSI yang dideploy secara manual dengan add-on resmi yang dikelola.

  1. Panggil InstallClusterAddons di OpenAPI Explorer untuk menginstal CSI. Lihat Instal komponen di kluster ACK.

    • ClusterId: ID kluster Anda.

    • name: csi-provisioner

    • version: Diterapkan secara otomatis. Lihat csi-provisioner untuk versi yang tersedia.

  2. Verifikasi bahwa plugin CSI sedang berjalan:

    kubectl get pods -nkube-system | grep csi

    Output yang diharapkan:

    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

Langkah 7: Perbarui parameter kubelet pada node yang ada

CSI memerlukan pengaturan --enable-controller-attach-detach ke true pada setiap node. DaemonSet berikut menerapkan pengaturan ini secara otomatis.

Penting

DaemonSet ini akan merestart kubelet pada setiap node, yang dapat mengganggu penjadwalan pod secara singkat. Drain node satu per satu sebelum melakukan deployment, atau pastikan workload Anda tahan terhadap restart kubelet singkat. Hapus DaemonSet setelah langkah ini selesai.

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

Setelah semua node memiliki enable-controller-attach-detach=true, hapus DaemonSet tersebut:

kubectl delete daemonset kubelet-set

Langkah selanjutnya