
# 1.15集群如何从Flexvolume存储类型迁移到CSI Everest存储类型
在v1.15.11-r1之后版本的集群中，CSI Everest插件已接管fuxi Flexvolume（即storage-driver插件）容器存储的所有功能，建议将对fuxi Flexvolume的使用切换CSI Everest上。
迁移的主要原理是通过创建静态PV的形式关联原有底层存储，并创建新的PVC关联该新建的静态PV，之后应用升级挂载这个新的PVC到原有挂载路径，实现存储卷迁移。
![](https://support.huaweicloud.com/usermanual-cce/public_sys-resources/warning_3.0-zh-cn.png)
迁移时会造成服务断服，请合理规划迁移时间，并做好相关备份。
#### 操作步骤
1. 数据备份（可选，主要防止异常情况下数据丢失）。
2. 根据FlexVolume格式的PV，准备CSI格式的PV的yaml文件关联已有存储。
   
   执行如下命令，配置名为"pv-example.yaml"的创建PV的yaml文件。
   **touch pv-example.yaml**
   **vi pv-example.yaml**
   **云硬盘存储卷PV** 的配置示例如下：
   ```
   apiVersion: v1
   kind: PersistentVolume
   metadata:
     labels:
       failure-domain.beta.kubernetes.io/region: cn-north-4
       failure-domain.beta.kubernetes.io/zone: <zone name>
     annotations:
       pv.kubernetes.io/provisioned-by: everest-csi-provisioner
     name: pv-evs-example
   spec:
     accessModes:
     - ReadWriteOnce
     capacity:
       storage: 10Gi
     csi:
       driver: disk.csi.everest.io
       fsType: ext4
       volumeAttributes:
         everest.io/disk-mode: SCSI
         everest.io/disk-volume-type: SAS
         storage.kubernetes.io/csiProvisionerIdentity: everest-csi-provisioner
       volumeHandle: 0992dbda-6340-470e-a74e-4f0db288ed82
     persistentVolumeReclaimPolicy: Delete
     storageClassName: csi-disk
   ```
   
   加粗标红字段需要重点关注，其中参数说明如下：
   表1云硬盘存储卷PV配置参数说明 
   | 参数                                       | 描述                                                                                                                 |
   |:---|:---|
   | failure-domain.beta.kubernetes.io/region | 云硬盘所在region，可参考FlexVolume PV的相同字段。                                                                                 |
   | failure-domain.beta.kubernetes.io/zone   | 云硬盘所在可用区，可参考FlexVolume PV的相同字段。                                                                                    |
   | name                                     | PV资源的名称，集群下唯一。                                                                                                     |
   | storage                                  | 云硬盘的容量，单位为Gi。可参考FlexVolume PV的spec.capacity.storage。                                                               |
   | driver                                   | 挂载依赖的存储驱动，EVS云硬盘配置为"disk.csi.everest.io"。                                                                          |
   | volumeHandle                             | 云硬盘的volumeID，可参考FlexVolume PV的spec.flexVolume.options.volumeID。                                                    |
   | everest.io/disk-mode                     | 云硬盘磁盘模式，可参考FlexVolume PV的spec.flexVolume.options.disk-mode。                                                        |
   | everest.io/disk-volume-type              | 云硬盘类型，当前支持高I/O（SAS）、超高I/O（SSD）。可参考FlexVolume PV的spec.storageClassName对应的sc中的parameters."kubernetes.io/volumetype"。 |
   | storageClassName                         | 存储卷动态供应关联的K8s storage class名称；云硬盘需使用"csi-disk"。                                                                    |
      
   **文件存储卷** **PV**配置示例如下：
   ```
   apiVersion: v1
   kind: PersistentVolume
   metadata:
     name: pv-sfs-example
     annotations:
       pv.kubernetes.io/provisioned-by: everest-csi-provisioner
   spec:
     accessModes:
     - ReadWriteMany
     capacity:
       storage: 10Gi
     csi:
       driver: nas.csi.everest.io
       fsType: nfs
       volumeAttributes:
         everest.io/share-export-location: sfs-nas01.cn-south-1.myhuaweicloud.com:/share-436304e8 
         storage.kubernetes.io/csiProvisionerIdentity: everest-csi-provisioner
       volumeHandle: 682f00bb-ace0-41d8-9b3e-913c9aa6b695
     persistentVolumeReclaimPolicy: Delete
     storageClassName: csi-nas
   ```
   
   加粗标红字段需要重点关注，其中参数说明如下：
   表2文件存储卷PV配置参数说明 
   | 参数                               | 描述                                                                  |
   |:---|:---|
   | name                             | PV资源的名称，集群下唯一。                                                      |
   | storage                          | 文件存储的大小，单位为Gi。可参考FlexVolume PV的spec.capacity.storage。               |
   | driver                           | 挂载依赖的存储驱动，文件存储配置为"nas.csi.everest.io"。                              |
   | everest.io/share-export-location | 文件存储的共享路径。可参考FlexVolume PV的spec.flexVolume.options.deviceMountPath。 |
   | volumeHandle                     | 文件存储的ID。可参考FlexVolume PV的spec.flexVolume.options.volumeID。          |
   | storageClassName                 | K8s storage class名称；需配置为"csi-nas"。                                  |
      
   **对象存储卷PV**配置示例如下：
   ```
   apiVersion: v1
   kind: PersistentVolume
   metadata:
     name: pv-obs-example
     annotations:
       pv.kubernetes.io/provisioned-by: everest-csi-provisioner
   spec:
     accessModes:
     - ReadWriteMany
     capacity:
       storage: 1Gi
     csi:
       driver: obs.csi.everest.io
       fsType: s3fs
       volumeAttributes:
         everest.io/obs-volume-type: STANDARD
         everest.io/region: cn-north-4
         storage.kubernetes.io/csiProvisionerIdentity: everest-csi-provisioner
       volumeHandle: obs-normal-static-pv
     persistentVolumeReclaimPolicy: Delete
     storageClassName: csi-obs
   ```
   
   加粗标红字段需要重点关注，其中参数说明如下：
   表3对象存储卷PV配置参数说明 
   | 参数                         | 描述                                                                                                                                                                    |
   |:---|:---|
   | name                       | PV资源的名称，集群下唯一。                                                                                                                                                        |
   | storage                    | 存储容量，单位为Gi。此处配置为固定值1Gi。                                                                                                                                               |
   | driver                     | 挂载依赖的存储驱动，对象存储配置为"obs.csi.everest.io"。                                                                                                                                |
   | fsType                     | 文件类型，支持"obsfs"与"s3fs"，取值为s3fs时创建是obs对象桶，配套使用s3fs挂载；取值为obsfs时创建的是obs并行文件系统，配套使用obsfs挂载。可参考FlexVolume PV的spec.flexVolume.options.posix的对应关系：true（obsfs）、false/空值（s3fs）。 |
   | everest.io/obs-volume-type | 存储类型，包括STANDARD（标准桶）、WARM（低频访问桶）。可参考FlexVolume PV的spec.flexVolume.options.storage_class的对应关系：standard（标准桶）、standard_ia（低频访问桶）。                                        |
   | everest.io/region          | 对象存储所在的region。可参考FlexVolume PV的spec.flexVolume.options.region。                                                                                                        |
   | volumeHandle               | 对象存储的桶名称。可参考FlexVolume PV的spec.flexVolume.options.volumeID。                                                                                                           |
   | storageClassName           | K8s storage class名称；需配置为"csi-obs"。                                                                                                                                    |
      
   **极速文件存储卷PV**配置示例如下：
   ```
   apiVersion: v1
   kind: PersistentVolume
   metadata:
     name: pv-efs-example
     annotations:
       pv.kubernetes.io/provisioned-by: everest-csi-provisioner
   spec:
     accessModes:
     - ReadWriteMany
     capacity:
       storage: 10Gi
     csi:
       driver: sfsturbo.csi.everest.io
       fsType: nfs
       volumeAttributes:
         everest.io/share-export-location: 192.168.0.169:/
         storage.kubernetes.io/csiProvisionerIdentity: everest-csi-provisioner
       volumeHandle: 8962a2a2-a583-4b7f-bb74-fe76712d8414
     persistentVolumeReclaimPolicy: Delete
     storageClassName: csi-sfsturbo
   ```
   
   加粗标红字段需要重点关注，其中参数说明如下：
   表4极速文件存储卷PV配置参数说明 
   | 参数                               | 描述                                                                    |
   |:---|:---|
   | name                             | PV资源的名称，集群下唯一。                                                        |
   | storage                          | 文件存储的大小。可参考FlexVolume PV的spec.capacity.storage。                       |
   | driver                           | 挂载依赖的存储驱动，极速文件存储配置为"sfsturbo.csi.everest.io"。                         |
   | everest.io/share-export-location | 极速文件存储的共享路径。可参考FlexVolume PV的spec.flexVolume.options.deviceMountPath。 |
   | volumeHandle                     | 极速文件存储的ID。可参考FlexVolume PV的spec.flexVolume.options.volumeID。          |
   | storageClassName                 | 指定K8s storage class名称；极速文件存储卷需配置为"csi-sfsturbo"。                      |
      
   
   
3. 根据FlexVolume格式的PVC，准备CSI格式的PVC的yaml文件关联上述步骤准备的静态PV。
   
   执行如下命令，配置名为"pvc-example.yaml"的创建PVC的yaml文件。
   **touch pvc-example.yaml**
   **vi pvc-example.yaml**
   **云硬盘存储卷PVC**的配置示例如下：
   ```
   apiVersion: v1  
   kind: PersistentVolumeClaim
   metadata:
     labels:
       failure-domain.beta.kubernetes.io/region: cn-north-4
       failure-domain.beta.kubernetes.io/zone: <zone name>
     annotations:
       everest.io/disk-volume-type: SAS
       volume.beta.kubernetes.io/storage-provisioner: everest-csi-provisioner
     name: pvc-evs-example
     namespace: default
   spec:
     accessModes:
     - ReadWriteOnce
     resources:
       requests:
         storage: 10Gi
     volumeName:  pv-evs-example
     storageClassName: csi-disk
   ```
   
   加粗标红字段需要重点关注，其中参数说明如下：
   表5云硬盘存储卷PVC配置参数说明 
   | 参数                                       | 描述                                                                                   |
   |:---|:---|
   | failure-domain.beta.kubernetes.io/region | 集群所在region。可参考FlexVolume PVC的相同字段。                                                   |
   | failure-domain.beta.kubernetes.io/zone   | EVS云硬盘所在可用区。可参考FlexVolume PVC的相同字段。                                                  |
   | everest.io/disk-volume-type              | 云硬盘存储类型，支持SAS、SSD。和上述步骤的PV保持一致。                                                      |
   | name                                     | PVC资源名称，同namespace下唯一。保证在namespace下唯一即可。（若PVC是由有状态应用动态创建，则保持和FlexVolume PVC的name一致）。 |
   | namespace                                | PVC资源命名空间。可参考FlexVolume PVC的相同字段。                                                    |
   | storage                                  | PVC申请容量，必须和已有PV的storage大小保持一致。                                                       |
   | volumeName                               | PV的名称。使用上述步骤的静态PV的名称。                                                                |
   | storageClassName                         | 指定K8s storage class名称；云硬盘需使用"csi-disk"。                                              |
      
   **文件存储卷PVC**配置示例如下：
   ```
   apiVersion: v1
   kind: PersistentVolumeClaim
   metadata:
     annotations:
       volume.beta.kubernetes.io/storage-provisioner: everest-csi-provisioner
     name: pvc-sfs-example
     namespace: default
   spec:
     accessModes:
     - ReadWriteMany
     resources:
       requests:
         storage: 10Gi
     storageClassName: csi-nas
     volumeName: pv-sfs-example
   ```
   
   加粗标红字段需要重点关注，其中参数说明如下：
   表6文件存储卷PVC配置参数说明 
   | 参数               | 描述                                                                                   |
   |:---|:---|
   | name             | PVC资源名称，同namespace下唯一。保证在namespace下唯一即可。（若PVC是由有状态应用动态创建，则保持和FlexVolume PVC的name一致）。 |
   | namespace        | PVC资源命名空间。可参考FlexVolume PVC的相同字段。                                                    |
   | storage          | 存储容量，单位Gi，必须和已有pv的storage大小保持一致。                                                     |
   | storageClassName | 需配置为"csi-nas"。                                                                       |
   | volumeName       | PV的名称。参考上述步骤的静态PV的名称。                                                                |
      
   **对象存储卷PVC**配置示例如下：
   ```
   apiVersion: v1
   kind: PersistentVolumeClaim
   metadata:
     annotations:
       volume.beta.kubernetes.io/storage-provisioner: everest-csi-provisioner
       everest.io/obs-volume-type: STANDARD
       csi.storage.k8s.io/fstype: s3fs
     name: pvc-obs-example
     namespace: default
   spec:
     accessModes:
     - ReadWriteMany
     resources:
       requests:
         storage: 1Gi
     storageClassName: csi-obs
     volumeName: pv-obs-example
   ```
   
   加粗标红字段需要重点关注，其中参数说明如下：
   表7对象存储卷PVC配置参数说明 
   | 参数                         | 描述                                                                                   |
   |:---|:---|
   | everest.io/obs-volume-type | obs存储类型；当前支持标准（STANDARD）和低频（WARM）两种存储类型。和上述步骤的PV保持一致。                                |
   | csi.storage.k8s.io/fstype  | 指定文件类型，支持"obsfs"与"s3fs"。与上述步骤中静态obs存储的PV的fsType保持一致。                                 |
   | name                       | PVC资源名称，同namespace下唯一。保证在namespace下唯一即可。（若PVC是由有状态应用动态创建，则保持和FlexVolume PVC的name一致）。 |
   | namespace                  | PVC资源命名空间。可参考FlexVolume PVC的相同字段。                                                    |
   | storage                    | 存储容量，单位为Gi。此处配置为固定值1Gi。                                                              |
   | storageClassName           | K8s storage class名称；需配置为"csi-obs"。                                                   |
   | volumeName                 | PV的名称。参考上述步骤创建的静态PV的名称。                                                              |
      
   **极速文件存储卷PVC**配置示例如下：
   ```
   apiVersion: v1
   kind: PersistentVolumeClaim
   metadata:
     annotations:
       volume.beta.kubernetes.io/storage-provisioner: everest-csi-provisioner
     name: pvc-efs-example
     namespace: default
   spec:
     accessModes:
     - ReadWriteMany
     resources:
       requests:
         storage: 10Gi
     storageClassName: csi-sfsturbo
     volumeName: pv-efs-example
   ```
   
   加粗标红字段需要重点关注，其中参数说明如下：
   表8极速文件存储卷PVC配置参数说明 
   | 参数               | 描述                                                                                   |
   |:---|:---|
   | name             | PVC资源名称，同namespace下唯一。保证在namespace下唯一即可。（若PVC是由有状态应用动态创建，则保持和FlexVolume PVC的name一致）。 |
   | namespace        | PVC资源命名空间。可参考FlexVolume PVC的相同字段。                                                    |
   | storageClassName | 指定K8s storage class名称；需配置为"csi-sfsturbo"。                                            |
   | storage          | 存储容量，单位Gi，必须和已有pv的storage大小保持一致。                                                     |
   | volumeName       | PV的名称。参考上述步骤创建的静态PV的名称。                                                              |
      
   
   
4. 应用升级替换成新的PVC。
   
   **无状态应用**
   1. 通过kubectl create -f的形式创建pv和pvc。 **kubectl create -f pv-example.yaml**
      **kubectl create -f pvc-example.yaml**
      ![](https://support.huaweicloud.com/usermanual-cce/public_sys-resources/note_3.0-zh-cn.png)
      命令中的yaml名称是示例，请以实际步骤[2]和步骤[3]创建的pv和pvc的yaml名字为准。
      
   
   2. 进入应用更新升级界面：更新升级 - 高级设置 - 数据存储 - 云存储。 ![](https://support.huaweicloud.com/usermanual-cce/zh-cn_image_0000001088946827.png "点击放大")
      
   
   3. 卸载老存储，同时添加CSI格式的PVC的云存储，容器内挂载路径和以前保持一致，实现存储迁移。
   
   4. 单击提交，确认后升级生效。
   
   5. 等待pod running。
    
   **升级使用已有存储的有状态应用**
   1. 通过kubectl create -f的形式创建pv和pvc **kubectl create -f pv-example.yaml**
      **kubectl create -f pvc-example.yaml**
      ![](https://support.huaweicloud.com/usermanual-cce/public_sys-resources/note_3.0-zh-cn.png)
      命令中的yaml名称是示例，请以实际步骤[2]和步骤[3]创建的pv和pvc的yaml名字为准。
      
   
   2. 通过kubectl edit的方式修改有状态应使用新建的PVC。 **kubectl edit sts sts-example -n** xxx
      ![](https://support.huaweicloud.com/usermanual-cce/zh-cn_image_0000001097062729.png "点击放大")
      ![](https://support.huaweicloud.com/usermanual-cce/public_sys-resources/note_3.0-zh-cn.png)
      命令中的sts-example为待升级的有状态应用的名称，请以实际为准。xxx指代有状态应用所在的命名空间。
      
   
   3. 等待pod running。
   
   
   ![](https://support.huaweicloud.com/usermanual-cce/public_sys-resources/note_3.0-zh-cn.png)
   当前界面暂未提供有状态应用添加新的云存储，因此升级替换成新PVC需要通过后台kubectl命令实现。
   **升级使用动态分配存储的有状态应用**
   1. 备份当前有状态应用使用的flexVolume格式的PV和PVC。 **kubectl get pvc xxx -n {namespaces} -oyaml \> pvc-backup.yaml**
      **kubectl get pv xxx -n {namespaces} -oyaml \> pv-backup.yaml**
      
   
   2. 将应用的实例数修改成0。
   
   3. 在存储界面解关联有状态应用使用的flexVolume格式的PVC。
   
   4. 通过kubectl create -f的形式创建pv和pvc。 **kubectl create -f pv-example.yaml**
      **kubectl create -f pvc-example.yaml**
      ![](https://support.huaweicloud.com/usermanual-cce/public_sys-resources/note_3.0-zh-cn.png)
      命令中的yaml名称是示例，请以实际步骤[2]和步骤[3]创建的pv和pvc的yaml名字为准。
      
   
   5. 将应用的实例数恢复，等待pod running。
   
   
   ![](https://support.huaweicloud.com/usermanual-cce/public_sys-resources/note_3.0-zh-cn.png)
   有状态应用动态创建存储是通过volumeClaimTemplates机制实现，而该字段K8s无法修改，因此无法通过更换新PVC的方式实现数据迁移。
   volumeClaimTemplates的PVC命名格式是固定的，当符合命名格式的PVC已经存在的时候则直接使用该PVC。
   因此需要先将原有PVC解除关联之后，创建同名的CSI格式的PVC来实现存储迁移。
   6. 迁移完成，但是如果不重建有状态应用，扩容时仍是FlexVolume格式的PVC（按需操作）。
   - 获取当前有状态应用yaml：
   
   
   **kubectl get sts xxx -n {namespaces} -oyaml \> sts.yaml**
   - 备份当前有状态应用yaml：
   
   
   **cp sts.yaml sts-backup.yaml**
   - 修改有状态应用yaml中volumeClaimTemplates的定义：
   
   
   **vi sts.yaml**
   **云硬盘存储卷volumeClaimTemplates**的配置示例如下：
   ```
   volumeClaimTemplates:
       - metadata:
           name: pvc-161070049798261342
           namespace: default
           creationTimestamp: null
           annotations:
             everest.io/disk-volume-type: SAS
         spec:
           accessModes:
             - ReadWriteOnce
           resources:
             requests:
               storage: 10Gi
           storageClassName: csi-disk
   ```
   其中参数和上述步骤创建的云硬盘存储卷的PVC保持一致。
   **文件存储卷volumeClaimTemplates**配置示例如下：
   ```
   volumeClaimTemplates:
       - metadata:
           name: pvc-161063441560279697
           namespace: default
           creationTimestamp: null
         spec:
           accessModes:
             - ReadWriteMany
           resources:
             requests:
               storage: 10Gi
           storageClassName: csi-nas
   ```
   其中参数和上述步骤创建的文件存储卷PVC保持一致。
   **对象存储卷PVC**配置示例如下：
   ```
   volumeClaimTemplates:
       - metadata:
           name: pvc-161070100417416148
           namespace: default
           creationTimestamp: null
           annotations:
             csi.storage.k8s.io/fstype: s3fs
             everest.io/obs-volume-type: STANDARD
         spec:
           accessModes:
             - ReadWriteMany
           resources:
             requests:
               storage: 1Gi
           storageClassName: csi-obs
   ```
   其中参数和上述步骤创建的对象存储卷PVC保持一致。
   - 删除原有状态应用：
   
   
   **kubectl delete sts xxx -n** {namespaces}
   - 创建新的有状态应用
   
   
   **kubectl create -f sts.yaml**
   
   
5. 检查业务功能。 
   1. 检查业务功能是否正常。
   
   2. 检查数据是否丢失。
   
   
   ![](https://support.huaweicloud.com/usermanual-cce/public_sys-resources/note_3.0-zh-cn.png)
   若功能或数据检查异常需要回退，请执行步骤[4]，选择FlexVolume格式的PVC并单击提交升级。
   
   
6. 卸载FlexVolume格式的PVC。 
   检查正常，存储管理界面执行解关联操作。
   也可以后台通过kubectl指令删除Flexvolume格式的PVC和PV。
   ![](https://support.huaweicloud.com/usermanual-cce/public_sys-resources/caution_3.0-zh-cn.png)
   在删除之前需要修改PV的回收策略persistentVolumeReclaimPolicy为Retain，否则底层存储会被回收。
   在存储迁移执行前已完成集群升级可能会导致无法删除PV，可以去除PV的保护字段finalizers来实现PV删除
   kubectl patch pv {pv_name} -p '{"metadata":{"finalizers":null}}'
   
   
 
