
# 集群内资源迁移（Velero）
#### 操作场景
本文使用Wordpress应用为例，将自建Kubernetes集群中应用整体迁移到CCE集群。Wordpress应用包含Wordpress和MySQL两个组件，均为容器化实例，分别绑定了两个Local类型的本地存储卷，并通过NodePort服务对外提供访问。
迁移前通过浏览器访问Wordpress站点，创建站点名称为"Migrate to CCE"，并发布一篇文章用于验证迁移后PV数据的完整性。Wordpress中发布的文章会被存储在MySQL数据库的"wp_posts"表中，若迁移成功，数据库中的内容也将会被全量搬迁至新集群，可依此进行PV数据迁移校验。
#### 前提条件
- 请在迁移前提前清理原集群中异常的Pod资源。当Pod状态异常但是又挂载了PVC的资源时，在集群迁移后，PVC状态会处于pending状态。
- 请确保CCE侧集群中没有与被迁移集群侧相同的资源，因为Velero工具在检测到相同资源时，默认不进行恢复。
- 为确保集群迁移后容器镜像资源可以正常拉取，请将镜像资源迁移至容器镜像服务（SWR）。
- CCE**不支持ReadWriteMany**的云硬盘存储，在原集群中存在该类型资源时，需要先修改为ReadWriteOnce。
- Velero对存储卷进行备份还原时**不支持HostPath类型** 的存储卷，详情请参见[文件系统备份限制](https://velero.io/docs/v1.13/file-system-backup/#limitations)。若您需备份该类型的存储卷，请参考[无法备份HostPath类型存储卷](https://support.huaweicloud.com/bestpractice-cce/cce_bestpractice_0314.html#cce_bestpractice_0314__section11197194820367)将HostPath类型替换为Local类型。当备份任务中存在HostPath类型的存储，该类型存储卷将会被自动跳过并产生Warning信息，并不会导致备份失败。
 
 #### 原集群应用备份
1. （可选）如果需要对Pod中指定的存储卷数据进行备份，需对Pod添加annotation，标记模板如下：
   
   ```
   kubectl -n <namespace> annotate <pod/pod_name> backup.velero.io/backup-volumes=<volume_name_1>,<volume_name_2>,...
   ```
   - \<namespace\>：Pod所在的namespace。
   
   - \<pod_name\>：Pod名称。
   
   - \<volume_name\>：Pod挂载的持久卷名称。可通过describe语句查询Pod信息，Volume字段下即为该Pod挂载的所有持久卷名称。
   
   
   对Wordpress和MySQL的Pod添加annotation，pod名称分别为wordpress-758fbf6fc7-s7fsr和mysql-5ffdfbc498-c45lh。由于Pod在默认命名空间default下，-n \<NAMESPACE\>参数可省略：
   ```
   kubectl annotate pod/wordpress-758fbf6fc7-s7fsr backup.velero.io/backup-volumes=wp-storage
   kubectl annotate pod/mysql-5ffdfbc498-c45lh backup.velero.io/backup-volumes=mysql-storage
   ```
   
   
2. 对应用进行备份。备份时可以根据参数指定资源，若不添加任何参数，则默认对整个集群资源进行备份，详细参数请参考[Resource filtering](https://velero.io/docs/v1.13/resource-filtering/)。
   
   - **--default-volumes-to-fs-backup：** 表示使用PV备份工具对Pod挂载的所有存储卷进行备份，**不支持HostPath类型** 的存储卷。如不指定该参数，将默认对[1]中annotation指定的存储卷进行备份。此参数仅在[安装Velero时](https://support.huaweicloud.com/bestpractice-cce/cce_bestpractice_0310.html#cce_bestpractice_0310__li1722825643415)指定"--use-node-agent"后可用。
     ```
     velero backup create <backup-name> --default-volumes-to-fs-backup
     ```
     ![](https://support.huaweicloud.com/bestpractice-cce/public_sys-resources/note_3.0-zh-cn.png)
     由于备份工具仅支持使用路径格式的桶域名（请参见[issue](https://github.com/velero-io/velero/issues/8739)），当前OBS部分局点已禁用路径格式的域名访问，在这些局点中不支持备份PV数据。
     
   
   - **--include-namespaces：** 用于指定namespace下的资源进行备份。
     ```
     velero backup create <backup-name> --include-namespaces <namespace>
     ```
     
   
   - **--include-resources：** 用于指定资源进行备份。
     ```
     velero backup create <backup-name> --include-resources deployments
     ```
     
   
   - **--selector：** 用于指定与selector相匹配的资源备份。
     ```
     velero backup create <backup-name> --selector <key>=<value>
     ```
     
   
   - **--exclude-resources：** 用于指定需要排除的Kubernetes资源类型，支持同时指定多种资源类型，用英文逗号分隔。不能与 --include-cluster-scoped-resources、--exclude-cluster-scoped-resources、--include-namespace-scoped-resources、 --exclude-namespace-scoped-resources一起使用。
     ```
     velero backup create <backup-name> --exclude-resources persistentvolumes,secrets
     ```
     
   
   
   本文指定default命名空间下的资源进行备份，wordpress-backup为备份名称，进行应用恢复时也需指定相同的备份名称。示例如下：
   ```
   velero backup create wordpress-backup --include-namespaces default --default-volumes-to-fs-backup
   ```
   回显如下，表示成功创建备份任务：
   ```
   Backup request "wordpress-backup" submitted successfully. 
   Run `velero backup describe wordpress-backup` or `velero backup logs wordpress-backup` for more details.
   ```
   
   
3. 查看备份情况。 
   ```
   velero backup get
   ```
   回显如下：
   ```
   NAME               STATUS      ERRORS   WARNINGS   CREATED                         EXPIRES   STORAGE LOCATION   SELECTOR
   wordpress-backup   Completed   0        0          2021-10-14 15:32:07 +0800 CST   29d       default            <none>
   ```
   同时可前往对象桶中查看备份的文件，其中backups路径为应用资源备份，另一路径为PV数据备份。
   
   
 
 #### 目标集群应用恢复
如果待迁移的Pod中挂载了存储卷，由于原集群的存储接口CSI和存储基础设施与CCE不同，集群迁移到CCE后无法继续使用原类型的存储，会遇到Pod无法挂载PV的问题。您可以参考以下情况进行适配：
- 原集群中的存储卷已使用StorageClass动态创建：在进行迁移时需要对新集群中的StorageClass进行适配，在创建工作负载时可以忽略两个集群之间底层存储接口的差异，自动申请支持的存储资源。该适配工作需要在**目标集群** 中于**恢复应用前** 完成，否则可能出现PV数据资源无法恢复的情况。相关操作请参考[StorageClass更新适配](https://support.huaweicloud.com/bestpractice-cce/cce_bestpractice_0312.html#cce_bestpractice_0312__section746195321414)。
- 原集群中的存储卷未使用StorageClass：建议您在目标集群中提前创建同名的PV，然后再使用Velero进行应用迁移。
 
若您使用外部迁移工具对数据进行迁移，如使用对象存储迁移服务OMS完成存储迁移，您可手动创建同名的PV，并将其挂载到迁移后的工作负载，请参考[对接已有对象存储](https://support.huaweicloud.com/usermanual-cce/cce_10_0379.html)。
本例中原集群的StorageClass名为local，存储类型为本地磁盘。本地磁盘存储完全依赖节点可用性，数据容灾性能差，节点不可用时将直接影响已有存储数据。因此CCE集群中的存储资源选用云硬盘存储卷，后端存储介质使用SAS存储。
1. 通过kubectl连接CCE集群。
2. 创建ConfigMap映射，将原集群使用的StorageClass映射到CCE集群默认的StorageClass。 
   ```
   apiVersion: v1
   kind: ConfigMap
   metadata:
     name: change-storageclass-plugin-config
     namespace: velero
     labels:
       app.kubernetes.io/name: velero
       velero.io/plugin-config: "true"
       velero.io/change-storage-class: RestoreItemAction
   data:
     local: csi-disk
   ```
   将原集群中的StorageClass **local** 替换为CCE云硬盘对应的StorageClass **csi-disk**。
   ![](https://support.huaweicloud.com/bestpractice-cce/public_sys-resources/note_3.0-zh-cn.png)
   - 包含PV数据的应用在CCE集群中进行恢复时，定义的StorageClass将会根据PVC动态创建相应的存储资源（如云硬盘）并挂载，将会产生云存储费用，请您知悉。
   
   - 此处集群的存储资源映射关系可以根据需求进行更改，并非仅限于云硬盘存储卷。若需要挂载其他类型的存储，如文件存储、对象存储，请添加或修改相应的StorageClass名称进行适配，详情请参考[StorageClass更新适配](https://support.huaweicloud.com/bestpractice-cce/cce_bestpractice_0312.html#cce_bestpractice_0312__section746195321414)。
    
   
   
3. 执行以下命令，应用上述的ConfigMap配置。 
   ```
   kubectl create -f change-storage-class.yaml
   ```
   回显如下：
   ```
   configmap/change-storageclass-plugin-config created
   ```
   
   
4. 使用Velero工具创建restore，指定名称为wordpress-backup的备份，将Wordpress应用恢复至CCE集群。 
   ```
   velero restore create --from-backup wordpress-backup
   ```
   可通过**velero restore get**语句查看应用恢复情况。
   
   
5. 恢复完成后查看应用实例是否正常运行，可能存在其他的更新适配问题，请参考[资源更新适配](https://support.huaweicloud.com/bestpractice-cce/cce_bestpractice_0312.html)中的步骤排查解决。
 
