通过备份中心,您可以将Flexvolume集群中的应用迁移至CSI集群中,也可以将低版本的Kubernetes集群应用迁移至新版本集群中。备份中心解决了跨存储插件、跨版本集群间应用迁移的一些问题,例如,需要备份未被应用使用到的Cluster级别资源、API Version自动切换至恢复集群支持的版本等。本文以1.16版本Flexvolume集群的应用迁移至1.28版本的CSI集群为例,介绍如何使用备份中心进行集群应用迁移。
注意事项
备份集群与恢复集群需处于同一地域,且备份集群为1.16或以上版本。考虑到apiVersion兼容问题,不建议您通过备份中心将高版本集群中的应用迁移至低版本的集群中。
备份应用时,正在删除的资源不会被备份。
如需恢复为容器网络文件系统管理的NAS类型(即恢复时转换为存储类列选择为alibabacloud-cnfs-nas),您需要先创建StorageClass。具体操作,请参见通过CNFS管理NAS文件系统(推荐)。
恢复应用时,资源将优先按照恢复集群版本推荐的apiVersion进行恢复。若某资源在两个版本中无同时支持的apiVersion版本,恢复时您需要手动部署。例如:
1.16版本集群Deployment支持
extensions/v1beta1
、apps/v1beta1
、apps/v1beta2
以及apps/v1
,恢复至1.28集群时将全部恢复至apps/v1
。1.16版本集群Ingress支持
extensions/v1beta1
、networking.k8s.io/v1beta1
,无法将其直接恢复至1.22及以上版本集群。
更多集群版本API变更信息,请参见ACK版本发布说明、Deprecated API Migration Guide。
重要在1.16版本集群中,
apps
、rbac.authorization.k8s.io
等groups已支持v1,升级至1.28版本集群时,您需要手动恢复Ingress、CronJob等资源。
适用场景
跨存储插件应用部署
新建1.20及以后版本的ACK集群已不再支持Flexvolume存储插件,您可以通过备份中心将Flexvolume集群中运行的有状态应用迁移到CSI集群中。
说明使用Flexvolume和CSI存储插件的集群均支持迁移,新的恢复集群仅支持使用CSI存储插件。
Kubernetes版本跨度较大的集群切换
某些场景下,您可能需要将低版本(不低于1.16版本)集群中的业务迁移至新集群。例如,网络插件从Flannel切换至Terway等。备份中心可实现版本跨度较大的集群应用迁移,同时自适应修正Kubernetes版本升级后的应用模板API Version等基本配置。
前提条件
已开通云备份(Cloud Backup)服务。对NAS、OSS、本地盘类型存储卷进行备份时,以及在混合云场景中,备份中心需要使用云备份进行文件备份。具体操作,请参见云备份。
已创建恢复集群,为确保能正常使用ECS快照恢复云盘数据,建议恢复集群为v1.18及以上版本。具体操作,请参见创建ACK托管集群、创建ACK专有集群或创建注册集群并接入本地数据中心集群。
重要恢复集群必须使用CSI存储插件,使用Flexvolume存储插件或通过csi-compatible-controller组件同时使用CSI Flexvolume存储插件的集群不支持恢复。
备份中心关注业务应用的备份和恢复。在恢复任务之前,您需要在恢复集群中预先安装并配置好所需的系统组件。例如:
ACR免密组件:您需要为恢复集群重新授权并配置acr-configuration。
ALB Ingress组件:您需要预先配置ALBConfig等。
已安装备份服务组件并完成对应权限的配置。具体操作,请参见安装migrate-controller备份服务组件并配置权限。
如需使用云盘快照备份数据卷,需要安装v1.1.0或以上版本的CSI插件。关于如何安装CSI插件,请参见安装与升级CSI组件。
迁移流程
备份集群使用的存储插件类型不同,迁移流程略有不同,具体流程如下所示。
备份集群无存储应用
备份集群使用Flexvolume存储插件
备份集群使用CSI存储插件
迁移步骤
本文以1.16版本的ACK Flexvolume集群为例,分别以数据换源以及数据不换源方式展示如何将集群中的应用及配置项等资源,以及将存储卷数据迁移至1.28版本的ACK CSI集群。对于无存储的应用迁移,或者备份集群使用CSI存储插件的场景,可以简化其中可选部分的步骤。
使用数据不换源方式时,需要将备份集群的PV的回收策略改为Retain,避免删除存储卷时触发数据清理。
kubectl patch pv/<pv-name> --type='json' -p '[{"op":"replace","path":"/spec/persistentVolumeReclaimPolicy","value":"Retain"}]'
类别 | 概念 | 适用场景 |
数据换源 | 在备份集群中备份存储卷中的数据,同步一份新数据给恢复集群的应用使用,即最终有两套完全独立的存储。数据恢复流程使用动态挂载,可以通过转换存储类实现存储类型的变更,例如,将NAS存储转变为云盘存储。 |
|
数据不换源 | 不换源方式将根据备份的存储声明、存储卷在恢复流程中使用静态挂载,因此使用的是原数据源,例如云盘ID、OSS Bucket等。如果您正在进行Flexvolume集群到CSI集群的应用迁移,由于YAML不通用,您需要手动创建静态存储声明、存储卷。 | 业务在备份恢复期间无法暂停写入,并且业务有强数据一致性的需求。 |
环境准备
类别 | 备份集群 | 恢复集群 |
集群版本 | 1.16.9-aliyun.1 | 1.28.3-aliyun.1 |
运行时版本 | Docker 19.03.5 | containerd 1.6.20 |
存储组件版本 | Flexvolume:v1.14.8.109-649dc5a-aliyun | CSI:v1.26.5-56d1e30-aliyun |
其他 |
| 已安装csi-plugin和csi-provisioner存储组件。更多信息,请参见管理组件。 |
步骤一:部署测试应用
执行以下命令,部署云盘动态存储卷。
其中
alicloud-disk-topology
请替换为您集群中Flexvolume存储插件默认安装的云盘存储类名称。cat << EOF | kubectl apply -f - kind: PersistentVolumeClaim apiVersion: v1 metadata: name: disk-essd spec: accessModes: - ReadWriteOnce storageClassName: alicloud-disk-topology resources: requests: storage: 20Gi EOF
执行以下命令,部署NAS静态存储卷。
其中
server
需要替换为账号下NAS文件系统的挂载点。cat << EOF | kubectl apply -f - apiVersion: v1 kind: PersistentVolume metadata: name: pv-nas spec: capacity: storage: 5Gi storageClassName: nas accessModes: - ReadWriteMany flexVolume: driver: "alicloud/nas" options: server: "1758axxxxx-xxxxx.cn-beijing.nas.aliyuncs.com" vers: "3" options: "nolock,tcp,noresvport" --- kind: PersistentVolumeClaim apiVersion: v1 metadata: name: pvc-nas spec: accessModes: - ReadWriteMany storageClassName: nas resources: requests: storage: 5Gi EOF
执行以下命令,部署应用,该应用同时挂载上述云盘和NAS存储卷。
以下代码中的
apiVersion
使用了extensions/v1beta1,该apiVersion
在1.28集群已被废弃。cat << EOF | kubectl apply -f - apiVersion: extensions/v1beta1 kind: Deployment metadata: name: nginx labels: app: nginx spec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx ports: - containerPort: 80 volumeMounts: - name: nas mountPath: /cold - name: disk mountPath: /hot volumes: - name: nas persistentVolumeClaim: claimName: pvc-nas - name: disk persistentVolumeClaim: claimName: disk-essd EOF
执行以下命令,确认部署的应用已正常启动。
kubectl get pod -l app=nginx
预期输出:
NAME READY STATUS RESTARTS AGE nginx-5ffbc895b-xxxxx 1/1 Running 0 2m28s
步骤二:在备份集群中安装备份中心
在备份集群安装备份服务组件。具体操作,请参见安装migrate-controller备份服务组件。
说明1.16版本以上的集群,可以直接在组件中心安装备份服务组件,且组件为v1.7.6及以上版本。
若您的备份集群为ACK专有版集群或注册集群,或使用的存储插件非CSI(例如Flexvolume),则需要额外的权限配置。具体操作,请参见注册集群。
(可选)若您的集群为Flexvolume集群,则执行以下命令,确认已经配置好相关权限。
kubectl -n csdr get secret alibaba-addon-secret
(可选)若您的集群为Flexvolume集群,则执行以下命令,增加kube-system命名空间下部署migrate-controller的
USE_FLEXVOLUME
环境变量。重要在Flexvolume集群中,migrate-controller备份服务组件安装完成后,migrate-controller的Pod将异常退出,打开集群应用备份页面将出现404报错。此时,您需要编辑组件的YAML,增加USE_FLEXVOLUME环境变量。
kubectl -n kube-system patch deployment migrate-controller --type json -p '[{"op":"add","path":"/spec/template/spec/containers/0/env/-","value":{"name":"USE_FLEXVOLUME","value":"true"}}]'
执行以下命令,确认备份服务组件已经正常运行。
kubectl -n kube-system get pod -l app=migrate-controller kubectl -n csdr get pod
预期输出:
NAME READY STATUS RESTARTS AGE migrate-controller-6c8b9c6cbf-967x7 1/1 Running 0 3m55s NAME READY STATUS RESTARTS AGE csdr-controller-69787f6dc8-f886h 1/1 Running 0 3m39s csdr-velero-58494f6bf4-52mv6 1/1 Running 0 3m37s
步骤三:在备份集群中创建备份
在与备份集群相同的地域创建以
cnfs-oss-*
格式命名的OSS Bucket,用于存放备份。具体操作,请参见创建存储空间。说明ACK托管集群默认拥有
cnfs-oss-*
开头的OSS Bucket权限,若您的Bucket命名格式不符合要求,同样需要额外的权限配置。具体操作,请参见通过控制台安装组件并配置权限。创建备份仓库。具体操作,请参见创建备份仓库。
执行以下命令,创建立即备份任务。
关于通过控制台设置备份相关配置项,请参见集群内备份和恢复应用。本步骤根据示例场景,提供建议的配置信息,您可以根据实际场景进行相应调整。
cat << EOF | kubectl apply -f - apiVersion: csdr.alibabacloud.com/v1beta1 kind: ApplicationBackup metadata: annotations: csdr.alibabacloud.com/backuplocations: '{"name":"<备份仓库名称>","region":"<regionID如cn-beijing>","bucket":"<备份仓库关联的OSSBucket名称>","provider":"alibabacloud"}' labels: csdr/schedule-name: fake-name name: <备份名称> namespace: csdr spec: excludedNamespaces: - csdr - kube-system - kube-public - kube-node-lease excludedResources: - storageclasses - clusterroles - clusterrolebindings - events - persistentvolumeclaims - persistentvolumes includeClusterResources: true pvBackup: defaultPvBackup: true storageLocation: <备份仓库名称> ttl: 720h0m0s EOF
参数
说明
excludedNamespaces
备份过程中排除的命名空间。建议排除以下命名空间:
csdr
:备份中心的工作命名空间。备份中心有集群间的同步逻辑,无需手动备份csdr命名空间下的备份、恢复等任务。否则可能导致非预期行为。kube-system
、kube-public
、kube-node-lease
:ACK集群默认存在的命名空间,因集群参数、配置等不同,无法在集群之间简单恢复。
excludedResources
排除资源。可根据业务需求设置。
includeClusterResources
是否备份Cluster级别的资源,例如StorageClass、CRD、Webhook等。
true
:备份所有Cluster级别资源。false
:仅备份被选择的命名空间中的Namespace级别资源引用的Cluster级别资源。例如,备份Pod时,引用的ServiceAccount授权了某ClusterRole,该ClusterRole将被自动备份;备份CR时,CRD将被自动备份。
说明通过容器服务管理控制台创建的备份任务,默认
IncludeClusterResources
字段为false
。defaultPvBackup
是否备份存储卷数据。
true
:备份应用以及Running Pod使用的存储卷数据。false
:仅备份应用。
重要对于Kubernetes版本及CSI版本均为1.18及以上版本的集群,默认使用ECS快照备份云盘数据;对于其他存储类型的数据,或大于等于1.16且小于1.18版本集群的云盘数据,均使用云备份备份。
对于未被Running Pod使用的存储卷,仅支持通过数据不换源的方式在新的集群中手动创建静态存储卷、存储声明,并指定原存储源,如云盘ID、OSS Bucket等。
若业务有数据强一致性需求,请您在备份期间暂停业务的数据写入。或者您可以选择数据不换源方式,在备份时仅备份应用。
执行以下命令,查询备份任务状态。
kubectl -ncsdr describe applicationbackup <备份名称>
预期输出中
Status
的Phase
变为Completed
,表明备份任务创建成功。执行以下命令,确认此次备份的资源列表Resource List。
kubectl -ncsdr get pod | grep csdr-velero kubectl -ncsdr exec -it <csdr-velero的pod名称> -- /velero describe backup <备份名称> --details
您可以查看列表中未被备份的资源,通过调整备份配置项及时重新备份。
Resource List: apiextensions.k8s.io/v1/CustomResourceDefinition: - volumesnapshots.snapshot.storage.k8s.io v1/Endpoints: - default/kubernetes v1/Namespace: - default v1/PersistentVolume: - d-2ze88915lz1il01v1yeq - pv-nas v1/PersistentVolumeClaim: - default/disk-essd - default/pvc-nas v1/Secret: - default/default-token-n7jss - default/oss-secret - default/osssecret v1/Service: - default/kubernetes v1/ServiceAccount: - default/default ...
步骤四:在恢复集群中安装备份中心
在恢复集群中安装备份中心。具体操作,请参见步骤二:在备份集群中安装备份中心。
将上述备份仓库关联到恢复集群。
登录容器服务管理控制台。
在集群列表页面,单击目标集群名称,然后在左侧导航栏,选择 。
在应用备份页面,单击立即恢复。
选择备份使用的备份仓库,单击初始化仓库,并等待备份同步至本集群。
(可选)步骤五:手动在恢复集群中创建存储声明及存储卷
多数场景中,您只需要根据以下步骤六直接在恢复集群中创建恢复任务,由备份中心组件根据备份自动生成存储声明及存储卷。
备份中心执行恢复任务时,为保护已有数据,遇到同名的存储声明及存储卷将跳过恢复,即不重建也不覆盖存储卷内的数据。因此,遇到以下场景,您可以在恢复任务之前预先创建存储声明及存储卷,以实现更灵活的恢复。
备份时备份了存储卷,但部分存储卷中存储了日志等无需迁移的数据,可以预先创建空的存储卷。
备份时备份了存储卷,但备份集群中未被Running Pod使用的存储卷同样需要迁移至恢复集群。
备份时未备份存储卷,且excludedResources里包含persistentvolumeclaims与persistentvolumes,或涉及Flexvolume集群至CSI集群的应用迁移。
具体操作步骤如下:
(可选)若您的备份集群为Flexvolume集群,由于Flexvolume与CSI的存储卷、存储声明的YAML不同,您可以使用命令行工具批量切换YAML。具体操作,请参见使用Flexvolume2CSI命令行工具批量转换YAML。
执行以下命令,部署通过Flexvolume2CSI获取的CSI YAML文件。
其中
outputfile.txt
为使用命令行工具切换YAML的输出。kubectl apply -f outputfile.txt
执行以下命令,确认存储声明在恢复集群中已处于Bound状态。
kubectl get pvc
预期输出:
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE disk-essd Bound d-2ze88915lz1il0xxxxxx 20Gi RWO alicloud-disk-essd 29m pvc-nas Bound pv-nas 5Gi RWX nas 29m
步骤六:在恢复集群中创建恢复任务
若恢复集群中已存在同名的资源,则恢复任务将跳过该资源。
备份中心关注业务应用的备份和恢复。在恢复任务之前,您需要在恢复集群中预先安装并配置好所需的系统组件。例如:
ACR免密组件:您需要为恢复集群重新授权并配置acr-configuration。
ALB Ingress组件:您需要预先配置ALBConfig等。
Service资源恢复时,根据Service类型的不同将进行如下适配:
NodePort类型的Service:跨集群恢复时,默认保留端口号。
LoadBalancer类型的Service:ExternalTrafficPolicy为Local时,HealthCheckNodePort默认使用随机端口号。若您需要保留端口号,请在创建恢复任务时,设置
spec.preserveNodePorts: true
。在备份集群中由指定已有SLB的Service,恢复时将使用原有的SLB并默认关闭强制监听,您需要前往SLB控制台配置监听。
在备份集群中由CCM管理SLB的Service,恢复时将由CCM创建新的SLB实例,更多信息,请参见Service的负载均衡配置注意事项。
若您创建备份时备份了存储卷,即使用数据换源的方式备份恢复。您可以通过存储类转换(convertedarg)实现存储类型的变更。例如,将NAS存储变为云盘存储。您可以根据业务需求,选择转换的目标存储类。
本示例中,由于备份集群是1.16的Flexvolume集群,云盘存储卷备份使用了云备份,因此可以为存储声明disk-essd选择目标存储类alicloud-disk(即转换为CSI云盘类,默认为alicloud-disk-topology-alltype)。若您的备份集群为v1.18及以上的CSI集群,则无需对云盘存储卷做相关配置。
本示例中,还将Flexvolume NAS存储卷转换为CNFS管理的NAS隔离存储卷,即为存储声明pvc-nas选择目标存储类alibabacloud-cnfs-nas。若您的集群不存在alibabacloud-cnfs-nas存储类,请参见通过CNFS管理NAS文件系统(推荐)。
具体操作步骤如下:
执行以下命令,创建恢复任务。
关于通过控制台设置恢复任务的相关配置项,请参见恢复应用和数据卷。本步骤根据示例场景提供了建议的配置信息,您可以根据实际场景进行相应调整。
cat << EOF | kubectl apply -f - apiVersion: csdr.alibabacloud.com/v1beta1 kind: ApplicationRestore metadata: csdr.alibabacloud.com/backuplocations: >- '{"name":"<备份仓库名称>","region":"<regionID如cn-beijing>","bucket":"<备份仓库关联的OSSbucket名称>","provider":"alibabacloud"}' name: <恢复名称> namespace: csdr spec: backupName: <备份名称> excludedNamespaces: - arms-prom excludedResources: - secrets appRestoreOnly: false convertedarg: - convertToStorageClassType: alicloud-disk-topology-alltype namespace: default persistentVolumeClaim: alicloud-disk - convertToStorageClassType: alibabacloud-cnfs-nas namespace: default persistentVolumeClaim: pvc-nas namespaceMapping: <backupNamespace>: <restoreNamespace> EOF
参数
说明
excludedNamespaces
排除命名空间。对备份资源列表中不需要的命名空间进行排除。
excludedResources
排除资源。对备份资源列表中不需要的资源类型进行排除。
appRestoreOnly
对于已备份存储卷的备份,是否恢复存储卷。
true
:恢复时创建动态存储卷、存储声明,指向新的数据源。控制台创建的备份任务默认为true。false
:不创建,需要预先手动部署静态卷。
说明一般情况下,数据换源方式此处需设置为
true
,数据不换源方式此处需设置为false
。convertedarg
转换存储类列表。备份中的FileSystem数据类型的存储卷(OSS、NAS、CPFS、本地存储等)的存储声明,在当前集群中恢复为目标存储类,实现例如NAS存储至云盘存储的转换。
convertToStorageClassType:目标存储类,需要在当前集群已存在。当前版本仅支持选择云盘或NAS类型的存储类。
namespace:存储声明所在的命名空间。
persistentVolumeClaim:存储声明名称。
您可以通过
kubectl -ncsdr describe <backup-name>
查询备份的存储声明信息,在输出的status.resourceList.dataResource.pvcBackupInfo
列表中dataType字段为数据类型,分为FileSystem与Snapshot,nameSpace与pvcName分别为存储声明所在的命名空间与存储声明名称。执行以下命令,查询恢复任务的状态。
kubectl -ncsdr describe applicationrestore <备份名称>
预期输出中
Status
的Phase
变为Completed
,表明任务恢复成功。执行以下命令,确认是否有恢复失败的资源及失败的原因。
kubectl -ncsdr get pod | grep csdr-velero kubectl -ncsdr exec -it <csdr-velero的pod名称> -- /velero describe restore <恢复名称> --details
预期输出:
Warnings: Velero: <none> Cluster: could not restore, ClusterRoleBinding "kubernetes-proxy" already exists. Warning: the in-cluster version is different than the backed-up version. Namespaces: demo-ns: could not restore, ConfigMap "kube-root-ca.crt" already exists. Warning: the in-cluster version is different than the backed-up version. could not restore, Endpoints "kubernetes" already exists. Warning: the in-cluster version is different than the backed-up version. could not restore, Service "kubernetes" already exists. Warning: the in-cluster version is different than the backed-up version. Errors: Velero: <none> Cluster: <none> Namespaces: demo-ns: error restoring endpoints/xxxxxx/kubernetes: Endpoints "kubernetes" is invalid: subsets[0].addresses[0].ip: Invalid value: "169.254.128.9": may not be in the link-local range (169.xxx.0.0/16, fe80::/10) error restoring endpointslices.discovery.k8s.io/demo-ns/kubernetes: EndpointSlice.discovery.k8s.io "kubernetes" is invalid: endpoints[0].addresses[0]: Invalid value: "169.xxx.128.9": may not be in the link-local range (169.xxx.0.0/16, fe80::/10) error restoring services/xxxxxx/kubernetes-extranet: Service "kubernetes-extranet" is invalid: spec.ports[0].nodePort: Invalid value: 31882: provided port is already allocated
通过以上预期输出,您可以查看恢复集群中是否有未被恢复的资源,例如,Warnings中有资源已存在的问题,且资源已被跳过。Errors中有NodePort复用的问题,跨集群恢复时会保留原有端口。
确认恢复的应用是否正常运行。
确认应用恢复后,是否存在由于业务限制、容器运行异常或其他原因导致资源处于异常状态,如有,请进行手动修复。
验证恢复后,Nginx应用的
apiVersion
已默认调整至1.28版本的集群推荐使用的apps/v1。