storage-operator组件提供了云盘类型有状态应用(StatefulSet)跨可用区迁移和多地域打散的功能,实现了跨可用区迁移的自动化。迁移过程出现异常时,storage-operator组件可以通过预检查和回滚机制在原可用区恢复应用,保证业务的可用性。本文介绍如何实现云盘类型的有状态应用跨可用区迁移。
适用场景
当遇到规划变更、应用规模扩大从而需要在多可用区部署,或当前可用区资源不足时,您都需要将已部署的有状态应用迁移至其他的可用区。
NAS、OSS存储底层支持跨可用区、多挂载使用。但云盘本身无多可用区漂移的能力,无法复用存储声明和存储卷,此时,需要将使用云盘存储卷的有状态应用迁移至新的可用区。
能接受业务中断的应用。对于多副本的有状态应用,为保证数据的一致性,在迁移前会缩容至0副本,云盘迁移完成后再一次性恢复至原副本数,而非滚动迁移。
重要有状态应用的跨可用区迁移过程中会产生业务的中断,中断时长与副本数量、容器启动速度、所使用云盘容量等因素相关。
实现原理及迁移流程
云盘实现应用的跨可用区迁移,依赖云盘快照功能,并且支持设定新建的快照保留时间。关于云盘快照的更多信息,请参见快照介绍。关于快照计费请参见快照计费。
storage-operator组件提供的云盘类型有状态应用迁移流程如下。
相关预检查,例如,待迁移应用运行是否正常、是否有需要迁移的云盘等。若检查失败,则不会进行迁移。
将云盘类型有状态应用缩容至0副本,此时应用处于暂停状态。
为待迁移的有状态应用挂载的云盘制作快照,快照支持跨可用区。
确认快照可用后,使用快照在目标可用区制作新云盘,新云盘与原云盘的数据一致。
重建同名的存储声明及其对应的新存储卷,绑定新云盘。
云盘类型有状态应用副本恢复至原副本数量,并自动关联重建的存储声明,实际挂载新云盘。
重要预检查完成并开始迁移后,每个步骤均对应了不同的失败回滚策略。为确保回滚后的应用能挂载原云盘,避免数据丢失,请确认迁移后的有状态应用运行正常后,再删除云盘。
(可选)确认有状态应用运行正常后,删除原存储卷和相应的云盘。关于云盘计费,请参见块存储计费。
注意事项
待迁移的有状态应用使用的所有存储均为ESSD云盘。
为了提升快照制作时间,本功能在迁移时选用极速快照,具体操作请参见快照极速可用能力。目前极速快照仅支持ESSD云盘,若您的应用使用非ESSD类型云盘,可通过以下方式处理。
将云盘类型变更为ESSD类型后再进行迁移,具体请参见变更云盘类型。
手动为单个云盘存储卷创建快照进行云盘的跨可用区重建。
目标可用区支持ESSD云盘,且集群中已有在目标可用区支持ESSD云盘的节点可供调度。
前提条件
集群的版本为1.20及以上,并且使用CSI存储插件。
如需升级集群,请参见手动升级集群。
集群中已安装storage-operator组件,且版本不低于v1.26.2-1de13b6-aliyun。更多信息,请参见管理storage-operator组件。
集群中已安装csi-plugin和csi-provisioner组件,且安装的csi-provisioner为非托管版。
说明如果当前安装的是csi-provisioner托管版组件,卸载托管版后可以重新安装非托管版。切换CSI组件后,请执行
kubectl delete pod -n kube-system <storage-controller-pod-name>
重启storage controller。如果您的集群是ACK专有集群,需确保集群的WorkerRole和MasterRole具备ModifyDiskSpec权限。具体操作,请参见创建自定义权限策略。
ACK托管集群无需进行此授权。
使用方式
修改集群中ConfigMap的配置。
kubectl patch configmap/storage-operator \ -n kube-system \ --type merge \ -p '{"data":{"storage-controller":"{\"imageRep\":\"acs/storage-controller\",\"imageTag\":\"\",\"install\":\"true\",\"template\":\"/acs/templates/storage-controller/install.yaml\",\"type\":\"deployment\"}"}}'
在集群中创建有状态应用迁移任务。
cat <<EOF | kubectl apply -f - apiVersion: storage.alibabacloud.com/v1beta1 kind: ContainerStorageOperator metadata: name: default spec: operationType: APPMIGRATE operationParams: stsName: web stsNamespace: default stsType: kube targetZone: cn-beijing-h,cn-beijing-j checkWaitingMinutes: "1" healthDurationMinutes: "1" snapshotRetentionDays: "2" retainSourcePV: "true" EOF
参数
是否必选
说明
operationType
必选
取值为
APPMIGRATE
,表明当前的操作是有状态应用迁移。stsName
必选
有状态应用名称,当前仅支持填写单个有状态应用。
说明部署多个有状态应用的迁移任务时,组件将以部署时间顺序依次迁移。
stsNamespace
必选
有状态应用所在命名空间。
targetZone
必选
迁移的目标可用区列表。当存在多个目标可用区时,可用区之间用英文半角逗号(,)隔开。例如
cn-beijing-h,cn-beijing-j
。当应用挂载的某个云盘已在列表中时,应用将不进行迁移。
当目标可用区大于1时,剩余云盘将按列表中可用区的排列顺序依次迁移至各个目标可用区。
stsType
可选
指定的有状态应用的类型,默认为kube。取值:
kube:原生StatefulSet。
kruise:OpenKruise组件提供的Advanced StatefulSet。
checkWaitingMinutes
可选
有状态应用在迁移后的可用区启动时,其状态检查的轮询间隔时间,单位为分钟。
默认为
"1"
,即每分钟检查一次,直至可用副本数与预期一致,或多次检查失败重试后回滚,回迁至原可用区。重要对于副本数较多、镜像拉取时间长、业务本身启动耗时较长的应用,需要适当增加轮询间隔时间,避免重试次数过多后应用回滚。
healthDurationMinutes
可选
二次检查的间隔时间,单位为分钟。二次检查即当有状态应用迁移完成,可用副本数与预期一致后,等待指定时间进行二次检查,以增强数据敏感业务的迁移可靠性。
默认为
"0"
,即不进行二次检查。snapshotRetentionDays
可选
迁移过程中,新建极速快照的保留时间,单位为天。取值:
"1"
:默认值,保留一天。"-1"
:将永久保留极速快照。
retainSourcePV
可选
是否保留原云盘及其在集群中对应的存储卷资源。取值:
"false"
:默认值,不保留。"true"
:保留,您可以登录ECS管理控制台找到原云盘实例,且集群内对应的存储卷资源也不会被删除,存储卷处于Released状态。
使用示例
测试集群为ACK托管集群Pro版,包含不同可用区的多个节点,示例如下:
可用区B:cn-shanghai.192.168.5.245
可用区G:cn-shanghai.192.168.2.214
可用区M:cn-shanghai.192.168.3.236、cn-shanghai.192.168.3.237
步骤一:创建使用ESSD云盘的有状态应用
在集群中创建一个使用ESSD云盘的StatefulSet用于后续测试。如果已有相关测试资源,可跳过该步骤。
创建StatefulSet并挂载ESSD云盘。
确认StatefulSet中Pod的部署情况。
kubectl get pod -o wide -l app=nginx
返回示例如下,根据
Node
字段确认2个Pod均被调度到了可用区M。说明实际可用区部署情况由调度器决定。
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES web-0 1/1 Running 0 2m 192.168.3.243 cn-shanghai.192.168.3.237 <none> <none> web-1 1/1 Running 0 2m 192.168.3.246 cn-shanghai.192.168.3.236 <none> <none>
步骤二:创建有状态应用迁移任务
示例1:跨可用区迁移
创建有状态应用迁移任务。
以下迁移任务示例中,将StatefulSet的2个Pod全部迁移至cn-shanghai-b可用区。
重要迁移前,请确认该节点有足够的资源,且可用区和节点规格均支持ESSD云盘。
cat <<EOF | kubectl apply -f - apiVersion: storage.alibabacloud.com/v1beta1 kind: ContainerStorageOperator metadata: name: migrate-to-b spec: operationType: APPMIGRATE operationParams: stsName: web stsNamespace: default stsType: kube targetZone: cn-shanghai-b # 迁移到的目标可用区。 healthDurationMinutes: "1" # 迁移完成后隔1分钟确认应用运行正常。 snapshotRetentionDays: "-1" # 新建的快照长期保留,直至在控制台删除。 retainSourcePV: "true" # 保留原可用区的云盘和对应PV。 EOF
查询迁移任务的状态。
kubectl describe cso migrate-to-b | grep Status
预期返回如下,如果返回
SUCCESS
表明迁移任务状态正常。Status: Status: SUCCESS
说明如果返回
FAILED
,则表明迁移任务失败,请参考常见问题处理。查询迁移后StatefulSet中2个Pod的部署情况。
kubectl get pod -o wide -l app=nginx
返回示例如下,可以看到2个Pod均已迁移到
cn-shanghai.192.168.5.245
节点,对应可用区B。NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES web-0 1/1 Running 0 2m36s 192.168.5.250 cn-shanghai.192.168.5.245 <none> <none> web-1 1/1 Running 0 2m14s 192.168.5.2 cn-shanghai.192.168.5.245 <none> <none>
在ECS管理控制台确认迁移任务符合预期。
在快照页面,确认已新建2个快照,且快照永久保留。
在块存储页面,确认在迁移后的可用区B已新建2个云盘,迁移前的可用区M的2个云盘未被删除(因为迁移任务中
retainSourcePV
的配置为true
)。
示例2:多可用区打散
为提高应用的可用性,需要将Pod及云盘打散部署到不同的可用区中。
创建有状态应用迁移任务。
以下迁移任务示例中,将StatefulSet的2个Pod打散部署到可用区B和可用区G。
cat <<EOF | kubectl apply -f - apiVersion: storage.alibabacloud.com/v1beta1 kind: ContainerStorageOperator metadata: name: migrate spec: operationType: APPMIGRATE operationParams: stsName: web stsNamespace: default stsType: kube targetZone: cn-shanghai-b,cn-shanghai-g # 迁移到的目标可用区。配置多个时,会自动打散。 healthDurationMinutes: "1" # 迁移完成后隔1分钟确认应用运行正常。 snapshotRetentionDays: "-1" # 新建的快照长期保留,直至在控制台删除。 retainSourcePV: "true" # 保留原可用区的云盘和对应PV。 EOF
查询迁移任务的状态。
kubectl describe cso migrate | grep Status
预期返回如下,如果返回
SUCCESS
表明迁移任务状态正常。Status: Status: SUCCESS
说明如果返回
FAILED
,则表明迁移任务失败,请参考常见问题处理。查询迁移后StatefulSet中2个Pod的部署情况。
kubectl get pod -o wide -l app=nginx
返回示例如下,可以看到2个Pod已打散部署到
cn-shanghai.192.168.5.245
节点(可用区B)和cn-shanghai.192.168.2.214
节点(可用区G)。NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES web-0 1/1 Running 0 4m59s 192.168.2.215 cn-shanghai.192.168.2.214 <none> <none> web-1 1/1 Running 0 4m38s 192.168.5.250 cn-shanghai.192.168.5.245 <none> <none>
在ECS管理控制台确认迁移任务符合预期。
在快照页面,确认已新建2个快照,且快照永久保留。
在块存储页面,确认在迁移后的可用区B和可用区G已新建2个云盘,迁移前的可用区M的2个云盘未被删除(因为迁移任务中
retainSourcePV
的配置为true
)。
常见问题
若查询到的迁移任务状态为FAILED,可通过以下命令查询失败原因,根据原因调整后再重试。
kubectl describe cso <ContainerStorageOperator-name> | grep Message -A 1
返回示例如下,表示失败是由于找不到待迁移的存储声明,可能原因为应用并未挂载存储、应用已挂载在目标可用区,无法获取存储声明信息等,请根据实际情况修改后重试。
Message:
Consume: failed to get target pvc, err: no pvc mounted in statefulset or no pvc need to migrated web