You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ECS on EC2集群CDK栈:如何优雅无停机更新实例AMI?

问题:EC2集群ECS栈无停机轮换实例至最新AMI的CDK/CFN方案

在EC2类型的ECS集群中,需要实现无停机轮换实例到最新AMI,但CDK+CloudFormation的组合在更新Auto Scaling Group(ASG)的AMI时遇到问题:

直接更新ASG的AMI配置(代码如下),CDK可以正常合成模板,但CloudFormation变更集会失败——能创建新的启动配置,却无法完成ASG的更新。

InstanceType: awsec2.NewInstanceType(jsii.String(envProps.AsgInstanceType)),
MachineImage: awsec2.MachineImage_GenericLinux(&imageMap, &awsec2.GenericLinuxImageProps{}),
//DesiredCapacity: jsii.Number(envAsgSize), //Don't set for prod and probably others
Vpc:      vpc,
Role: instanceRole,

尝试过手动流程:编辑启动配置(但CDK会生成带随机名称的新配置,无法覆盖)→ 执行ASG更新替换实例→ 同步CDK/CFN状态,但流程繁琐,希望找到更优的适配CDK的方案,不希望用Lambda这类过于复杂的实现。


可行方案

方案1:利用ASG实例刷新+CDK自动生成启动配置

CDK每次更新AMI时必然会创建新的启动配置(这是设计特性,无法修改),但可以通过配置ASG的实例刷新能力,让CloudFormation在创建新启动配置后自动触发实例替换:

  • 在CDK中给ASG添加实例刷新配置:
const asg = new autoscaling.AutoScalingGroup(this, 'EcsAsg', {
  // 原有配置...
  instanceType: awsec2.InstanceType.of(awsec2.InstanceClass.T2, awsec2.InstanceSize.MEDIUM),
  machineImage: awsec2.MachineImage.genericLinux(imageMap),
  vpc,
  role: instanceRole,
  // 添加实例刷新配置
  instanceRefresh: {
    strategy: autoscaling.InstanceRefreshStrategy.ROLLING,
    minHealthyPercentage: 70, // 根据集群容量调整,保证业务无停机
    instanceWarmup: Duration.minutes(5), // 匹配ECS实例注册到集群的预热时间
  },
});
  • 当通过CDK更新AMI并部署时,CloudFormation会创建新启动配置,然后触发ASG的实例刷新,逐步替换旧实例为新AMI的实例,全程无停机。
  • 注意:需要确保ASG的minCapacity和desiredCapacity设置合理,避免刷新过程中容量不足;同时ECS服务的部署策略要设置为ROLLING_UPDATE,保证容器在实例替换时平滑迁移。

方案2:用Launch Template替代Launch Configuration

Launch Template是Launch Configuration的升级版,CloudFormation对ASG使用Launch Template的更新支持更友好:

  • 将原有的启动配置替换为Launch Template:
const launchTemplate = new ec2.LaunchTemplate(this, 'EcsLaunchTemplate', {
  instanceType: awsec2.InstanceType.of(awsec2.InstanceClass.T2, awsec2.InstanceSize.MEDIUM),
  machineImage: awsec2.MachineImage.genericLinux(imageMap),
  role: instanceRole,
  // 其他配置如安全组、用户数据等
});

const asg = new autoscaling.AutoScalingGroup(this, 'EcsAsg', {
  vpc,
  launchTemplate: launchTemplate,
  minCapacity: 2,
  maxCapacity: 5,
  // 同样配置实例刷新
  instanceRefresh: {
    strategy: autoscaling.InstanceRefreshStrategy.ROLLING,
    minHealthyPercentage: 70,
  },
});
  • 更新AMI时,CDK会创建Launch Template的新版本,CloudFormation会自动关联ASG到新版本,再通过实例刷新完成实例替换。相比Launch Configuration,Launch Template支持版本化管理,更适配CDK的声明式更新模型。

方案3:手动触发ASG实例刷新(适配已有CDK栈)

如果不想修改现有CDK代码结构,可以按以下步骤操作:

  • 通过CDK更新AMI并部署,此时CloudFormation会创建新的启动配置但不会更新ASG
  • 进入AWS控制台,找到目标ASG,手动触发实例刷新,选择使用最新的启动配置
  • 等待实例刷新完成后,CDK的状态会自动同步(因为新启动配置已经被CDK创建并记录在模板中)

这种方式不需要修改代码,适合临时的AMI更新场景,但长期来看还是推荐方案1或2的自动化方式。


内容的提问来源于stack exchange,提问作者Trevor Griffiths

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 01:03:10