背景
可用区(Availability Zone,简称 AZ)是指在同一地域内,电力和网络互相独立的物理区域。例如,华北1(青岛)地域支持2个可用区,包括青岛 可用区B和青岛 可用区C。同一可用区内实例之间的网络延时更小,其用户访问速度更快。将应用部署在多个可用区可以提高应用的可用性,降低故障风险。然而,在实际应用中,有时需要将实例从一个可用区迁移到另一个可用区,以实现故障切换、负载均衡、数据备份与恢复等需求。为了解决这个问题,OOS提供了跨可用区克隆实例的功能,使得您可以轻松地在不同可用区之间克隆实例。
功能介绍
跨可用区克隆实例功能允许用户在不同的可用区之间创建相同的实例,实现以下目标:
-
故障切换 :当一个可用区出现异常或故障时,可以将实例迅速克隆到另一个可用区,以确保业务的高可用性和持续性。
-
负载均衡 :为了实现多个可用区之间的负载均衡,可以在不同的可用区创建相同的实例,分散访问压力,提高系统的稳定性和性能。
-
数据备份与恢复 :在不同的可用区克隆实例可以作为数据的备份,当某个可用区的实例发生数据丢失或损坏时,可以快速恢复到其他可用区的实例。
-
应用扩展 :当业务需求增长,需要增加更多的实例来支持业务时,可以在不同的可用区克隆实例,实现业务的快速扩展。
-
性能测试与优化 :在不同的可用区克隆实例,可以在不影响线上业务的情况下,对实例进行性能测试和优化,确保实例在不同可用区的性能表现一致。
操作步骤
-
登录运维编排管理控制台。
-
单击 公共模板 。
-
在搜索框输入“跨可用区批量克隆ECS实例 ”,可以找到跨可用区批量克隆ECS实例的公共模板,然后单击 创建执行。
-
点击“下一步: 设置参数”
-
填写新实例相关参数
-
选择(支持手动选择、指定实例标签、资源组、上传CSV文件、选择全部、指定配置清单条件几种方式)要操作的源实例后点击“ 确定”。
-
点击 创建
7. 查看执行结果
附录1:公共模版和背后逻辑
跨可用区批量克隆ECS实例公共模板
FormatVersion: OOS-2019-06-01
Description:
en: Cross available zone clone and bulky run ECS instance
zh-cn: 跨可用区批量克隆ECS实例
name-en: ACS-ECS-CloneInstancesAcrossAZ
name-zh-cn: 跨可用区批量克隆ECS实例
categories:
- cross_region
Parameters:
regionId:
Type: String
Label:
en: RegionId
zh-cn: 地域ID
AssociationProperty: RegionId
Default: '{
{ ACS::RegionId }}'
targets:
Label:
en: TargetInstance
zh-cn: 目标实例
Type: Json
AssociationProperty: Targets
AssociationPropertyMetadata:
ResourceType: ALIYUN::ECS::Instance
RegionId: regionId
targetSecurityGroupId:
Label:
en: TargetSecurityGroupId
zh-cn: 新实例的安全组ID
Type: String
AssociationProperty: ALIYUN::ECS::SecurityGroup::SecurityGroupId
AssociationPropertyMetadata:
RegionId: regionId
targetVSwitchId:
Label:
en: TargetVSwitchId
zh-cn: 新实例的交换机ID,填写本参数时将会决定目的可用区
Type: String
AssociationProperty: ALIYUN::VPC::VSwitch::VSwitchId
AssociationPropertyMetadata:
RegionId: regionId
Filters:
- SecurityGroupId: targetSecurityGroupId
targetResourceGroupId:
Label:
en: TargetResourceGroupId
zh-cn: 新实例将加入的目的资源组ID
Type: String
Default: ' '
targetInstanceType:
Label:
en: TargetInstanceType
zh-cn: 新实例的规格
Type: String
AssociationProperty: ALIYUN::ECS::Instance::InstanceType
AssociationPropertyMetadata:
RegionId: regionId
Default: ' '
targetTags:
Label:
en: TargetTags
zh-cn: 新实例的标签
Type: Json
AssociationProperty: Tags
AssociationPropertyMetadata:
ShowSystem: false
targetInstanceChargeType:
Label:
en: TargetInstanceChargeType
zh-cn: 新实例的付费模式,默认按量付费
Type: String
AllowedValues:
- PrePaid
- PostPaid
Default: PostPaid
targetPeriodUnit:
Label:
en: TargetPeriodUnit
zh-cn: 当新实例的付费方式选择包年包月时,请在此处选择时长单位,默认单位是月
Type: String
AllowedValues:
- Week
- Month
- ' '
Default: ' '
targetPeriod:
Label:
en: TargetPeriod
zh-cn: 当新实例的付费方式选择包年包月时,请在此处填写时长数,默认值为1
Type: Number
Default: 1
targetDeploymentSetId:
Label:
en: TargetDeploymentSetId
zh-cn: 新实例的部署集ID
Type: String
Default: ' '
targetInstanceName:
Label:
en: TargetInstanceName
zh-cn: 新实例的名称
Type: String
Default: ' '
targetHostName:
Label:
en: TargetHostName
zh-cn: 新实例的主机名称
Type: String
Default: ' '
rateControl:
Label:
en: RateControl
zh-cn: 循环任务执行的并发率及容错数
Type: Json
AssociationProperty: RateControl
Default:
Mode: Concurrency
MaxErrors: 0
Concurrency: 10
OOSAssumeRole:
Label:
en: OOSAssumeRole
zh-cn: OOS扮演的RAM角色
Type: String
Default: OOSServiceRole
RamRole: '{
{ OOSAssumeRole }}'
Tasks:
- Name: getInstance
Description:
en: Views the ECS instances
zh-cn: 获取ECS实例
Action: ACS::SelectTargets
Properties:
RegionId: '{
{regionId}}'
ResourceType: ALIYUN::ECS::Instance
Filters:
- '{
{ targets }}'
Outputs:
instanceIds:
Type: List
ValueSelector: Instances.Instance[].InstanceId
- Name: cloneInstancesAcrossAZ
Action: ACS::Template
Description:
en: Clone instances
zh-cn: 克隆实例
Properties:
TemplateName: ACS::ECS::CloneInstanceAcrossAZ
Parameters:
imageName: img-{
{ ACS::TaskLoopItem }}-{
{ACS::ExecutionId}}
instanceId: '{
{ ACS::TaskLoopItem }}'
targetSecurityGroupId: '{
{ targetSecurityGroupId }}'
targetResourceGroupId: '{
{ targetResourceGroupId }}'
targetVSwitchId: '{
{ targetVSwitchId }}'
regionId: '{
{ regionId }}'
targetInstanceName: '{
{ targetInstanceName }}'
targetInstanceChargeType: '{
{ targetInstanceChargeType }}'
targetPeriodUnit: '{
{ targetPeriodUnit }}'
targetPeriod: '{
{ targetPeriod }}'
targetInstanceType: '{
{ targetInstanceType }}'
targetHostName: '{
{ targetHostName }}'
targetDeploymentSetId: '{
{ targetDeploymentSetId }}'
tags: '{
{ targetTags }}'
OOSAssumeRole: '{
{OOSAssumeRole}}'
Loop:
Items: '{
{ getInstance.instanceIds }}'
RateControl: '{
{ rateControl }}'
Outputs:
instanceIds:
AggregateType: Fn::ListJoin
AggregateField: instanceId
Outputs:
instanceId:
ValueSelector: instanceId
Type: String
Outputs:
instanceIds:
Value: '{
{ cloneInstancesAcrossAZ.instanceIds }}'
Type: List
Metadata:
ALIYUN::OOS::Interface:
ParameterGroups:
- Parameters:
- targetSecurityGroupId
- targetVSwitchId
- targetInstanceType
- targetTags
- targetInstanceChargeType
- targetPeriodUnit
- targetPeriod
- targetResourceGroupId
- targetDeploymentSetId
- targetInstanceName
- targetHostName
Label:
default:
zh-cn: 设置参数
en: Configure Parameters
- Parameters:
- regionId
- targets
Label:
default:
zh-cn: 选择实例
en: Select Ecs Instances
- Parameters:
- rateControl
- OOSAssumeRole
Label:
default:
zh-cn: 高级选项
en: Control Options
该模板顺序执行以下任务:
-
获取目标实例。
-
跨可用区批量克隆ECS实例。
上述模板使用到的云产品Action: ACS::ECS::CloneInstanceAcrossAZ
FormatVersion: OOS-2019-06-01
Description:
name-en: 'ACS::ECS::CloneInstanceAcrossAZ'
name-zh-cn: 跨可用区域复制并运行ECS实例
en: Cross available zone copy and run ECS instance
zh-cn: 跨可用区域复制并运行ECS实例
Parameters:
instanceId:
Description:
en: The ID of the source ECS instance
zh-cn: 源ECS实例的ID
Type: String
regionId:
Description:
en: The source region ID
zh-cn: 源区域ID
Type: String
Default: '{
{ACS::RegionId}}'
imageName:
Description:
en: The image name for source instance
zh-cn: 源实例的镜像名称
Type: String
targetSecurityGroupId:
Description:
en: The security group id for the new ECS instance
zh-cn: 新ECS实例的安全组ID
Type: String
targetVSwitchId:
Description:
en: The virtual switch ID for the new ECS instance
zh-cn: 新ECS实例的虚拟交换机ID
Type: String
targetDeploymentSetId:
Description:
en: The deploymentset ID for the new ECS instance
zh-cn: 新ECS实例的deploymentsetID
Type: String
targetResourceGroupId:
Description:
en: The target resource group ID that the new ECS instance is to add in
zh-cn: 新ECS实例要添加的目标资源组ID
Type: String
targetInstanceType:
Description:
en: The instance type for the new ECS instance
zh-cn: 新ECS实例的实例类型
Type: String
targetInstanceChargeType:
Description:
en: The charge type for ECS new instance
zh-cn: 新ECS实例的收费类型
Type: String
targetPeriodUnit:
Description:
en: >-
Please select the PeriodUnit when charge type of new instance is
PrePaid,the default is Month
zh-cn: 当“新建实例的计费类型”为“预付”时,请选择“周期单位”,默认为“月”
Type: String
targetPeriod:
Description:
en: Please fill in the Period when charge type of ECS new PrePaid instance
zh-cn: 请填写新ECS实例预付费用类型的期间
Type: Number
tags:
Description:
en: The tags of new ECS instance to add on
zh-cn: 要添加的新ECS实例的标记
Type: Json
AssociationProperty: Tags
targetInstanceName:
Description:
en: The instance name for new ECS instance
zh-cn: 新ECS实例的实例名
Type: String
targetHostName:
Description:
en: The host name for new ECS instance
zh-cn: 新ECS实例的主机名
Type: String
OOSAssumeRole:
Description:
en: The RAM role to be assumed by OOS
zh-cn: OOS扮演的RAM角色
Type: String
Default: OOSServiceRole
RamRole: '{
{ OOSAssumeRole }}'
Tasks:
- Name: queryInstanceInfo
Action: 'ACS::ExecuteAPI'
Description:
en: Views the ECS instance's Info
zh-cn: 查看ECS实例信息
Properties:
Service: ECS
API: DescribeInstances
Parameters:
RegionId: '{
{ regionId }}'
InstanceIds:
- '{
{ instanceId }}'
Outputs:
deploymentSetId:
ValueSelector: 'Instances.Instance[0].DeploymentSetId'
Type: String
instanceName:
ValueSelector: 'Instances.Instance[0].InstanceName'
Type: String
hostName:
ValueSelector: 'Instances.Instance[0].HostName'
Type: String
instanceType:
ValueSelector: 'Instances.Instance[0].InstanceType'
Type: String
resourceGroupId:
ValueSelector: 'Instances.Instance[0].ResourceGroupId'
Type: String
- Name: queryDisks
Action: 'ACS::ExecuteAPI'
Description:
en: Views disk info of the ECS instance
zh-cn: 查看实例的磁盘信息
Properties:
Service: ECS
API: DescribeDisks
Parameters:
RegionId: '{
{ regionId }}'
InstanceId: '{
{ instanceId }}'
Outputs:
dataDisks:
Type: Json
ValueSelector: >-
.Disks.Disk|map( select(.Type == "data"
)|{"Category":(.Category),"Device":
(.Device),"Size":(.Size),"DiskName":(.DiskName),"PerformanceLevel":(.PerformanceLevel)})
systemDisk:
Type: Json
ValueSelector: >-
.Disks.Disk|map( select(.Type == "system"
)|{"Category":(.Category),"Device":
(.Device),"Size":(.Size),"DiskName":(.DiskName),"PerformanceLevel":(.PerformanceLevel)})[]
- Name: queryVSwitchInfo
Action: 'ACS::ExecuteAPI'
Description:
en: Views the VSwitch info
zh-cn: 查看VSwitch信息
Properties:
Service: ECS
API: DescribeVSwitches
Parameters:
RegionId: '{
{ regionId }}'
VSwitchId: '{
{ targetVSwitchId }}'
Outputs:
zoneId:
ValueSelector: 'VSwitches.VSwitch[0].ZoneId'
Type: String
- Name: checkTargetInstanceTypeAvailable
Action: 'ACS::Template'
Description:
en: Check wether the specified target InstanceType is Available
zh-cn: 检查指定的目标实例类型是否可用
Properties:
TemplateName: 'ACS::ECS::CheckAvailableInstanceTypes'
Parameters:
zoneId: '{
{ queryVSwitchInfo.zoneId }}'
regionId: '{
{ regionId }}'
instanceTypes:
- 'Fn::If':
- 'Fn::Equals':
- ' '
- '{
{ targetInstanceType }}'
- '{
{queryInstanceInfo.instanceType}}'
- '{
{ targetInstanceType }}'
- Name: createImage
Action: 'ACS::ExecuteAPI'
OnError: deleteImage
Description:
en: Creates image for source instance
zh-cn: 为源实例创建镜像
Properties:
Service: ECS
API: CreateImage
Parameters:
RegionId: '{
{ regionId }}'
ImageName: '{
{ imageName }}'
InstanceId: '{
{ instanceId }}'
DetectionStrategy: Standard
Outputs:
ImageId:
ValueSelector: ImageId
Type: String
- Name: untilCreateImageReady
Action: 'ACS::WaitFor'
OnError: deleteImage
Description:
en: Waits for created image available
zh-cn: 等待创建的镜像可用
Properties:
Service: ECS
API: DescribeImages
Parameters:
RegionId: '{
{ regionId }}'
ImageId: '{
{ createImage.ImageId }}'
DesiredValues:
- Available
PropertySelector: 'Images.Image[].Status'
Retries: 57
- Name: runInstances
Action: 'ACS::ExecuteAPI'
OnError: deleteImage
Description:
en: Runs instance in new availbable zone
zh-cn: 在新的可用分区中运行instance
Properties:
Service: ECS
API: RunInstances
Parameters:
RegionId: '{
{ regionId }}'
ImageId: '{
{ createImage.ImageId }}'
DataDisks: '{
{queryDisks.dataDisks}}'
SystemDiskCategory:
'Fn::Select':
- Category
- '{
{ queryDisks.systemDisk }}'
SystemDiskSize:
'Fn::Select':
- Size
- '{
{ queryDisks.systemDisk }}'
SystemDiskDiskName:
'Fn::Select':
- DiskName
- '{
{ queryDisks.systemDisk }}'
SystemDiskPerformanceLevel:
'Fn::Select':
- PerformanceLevel
- '{
{ queryDisks.systemDisk }}'
InstanceType:
'Fn::If':
- 'Fn::Equals':
- ' '
- '{
{ targetInstanceType }}'
- '{
{queryInstanceInfo.instanceType}}'
- '{
{ targetInstanceType }}'
SecurityGroupId: '{
{ targetSecurityGroupId }}'
VSwitchId: '{
{ targetVSwitchId }}'
ResourceGroupId:
'Fn::If':
- 'Fn::Equals':
- ' '
- '{
{targetResourceGroupId}}'
- '{
{queryInstanceInfo.resourceGroupId}}'
- '{
{targetResourceGroupId}}'
InstanceChargeType: '{
{targetInstanceChargeType}}'
PeriodUnit:
'Fn::If':
- 'Fn::Equals':
- PrePaid
- '{
{targetInstanceChargeType}}'
- 'Fn::If':
- 'Fn::Equals':
- ' '
- '{
{targetPeriodUnit}}'
- Month
- '{
{targetPeriodUnit}}'
- ''
Period:
'Fn::If':
- 'Fn::Equals':
- PrePaid
- '{
{targetInstanceChargeType}}'
- '{
{targetPeriod}}'
- ''
InstanceName:
'Fn::If':
- 'Fn::Equals':
- ' '
- '{
{targetInstanceName}}'
- '{
{queryInstanceInfo.instanceName}}'
- '{
{targetInstanceName}}'
HostName:
'Fn::If':
- 'Fn::Equals':
- ' '
- '{
{targetHostName}}'
- '{
{queryInstanceInfo.hostName}}'
- '{
{targetHostName}}'
DeploymentSetId:
'Fn::If':
- 'Fn::Equals':
- ' '
- '{
{targetDeploymentSetId}}'
- '{
{queryInstanceInfo.deploymentSetId}}'
- '{
{targetDeploymentSetId}}'
Tags: '{
{ tags }}'
Outputs:
instanceId:
Type: String
ValueSelector: 'InstanceIdSets.InstanceIdSet[]'
- Name: untilInstanceReady
Action: 'ACS::WaitFor'
OnError: deleteImage
Description:
en: Waits for new instance running
zh-cn: 等待新实例运行
Properties:
Service: ECS
API: DescribeInstances
Parameters:
RegionId: '{
{ regionId }}'
InstanceIds:
- '{
{ runInstances.instanceId }}'
DesiredValues:
- Running
PropertySelector: 'Instances.Instance[].Status'
- Name: deleteImage
Action: 'ACS::ExecuteAPI'
Description:
en: Deletes the temporary image
zh-cn: 删除临时镜像
Properties:
Service: ECS
API: DeleteImage
Risk: Normal
Parameters:
RegionId: '{
{ regionId }}'
ImageId: '{
{ createImage.ImageId }}'
Force: true
Outputs:
instanceId:
Type: String
Value: '{
{ runInstances.instanceId }}'
该Action顺序执行以下任务:
-
查看ECS实例信息。
-
查看实例的磁盘信息。
-
查看VSwitch信息
-
检查指定的目标实例类型是否可用
-
为源实例创建镜像。
-
等待创建的镜像达到可用状态。
-
在新的可用分区中运行实例。
-
等待新实例运行。
-
删除临时镜像。