使用CDK创建ELB(含EC2/Fargate)时部署进程永久停滞
AWS CDK部署ECS ELB服务停滞问题排查与解决
问题详情
尝试通过AWS CDK创建ELB(支持Fargate或EC2类型),但所有部署操作均陷入永久停滞状态。
示例代码
const vpc = new ec2.Vpc(this, 'backoffice-vpc', { cidr: '10.0.0.0/16', natGateways: 0, maxAzs: 3, subnetConfiguration: [ { name: 'public-subnet-1', subnetType: ec2.SubnetType.PUBLIC, cidrMask: 24, }, { name: 'isolated-subnet-1', subnetType: ec2.SubnetType.PRIVATE_ISOLATED, cidrMask: 28, }, ], }); // 创建EC2实例安全组 const ec2InstanceSG = new ec2.SecurityGroup(this, 'ec2-backoffice-sg', { vpc, }); ec2InstanceSG.addIngressRule( ec2.Peer.anyIpv4(), ec2.Port.tcp(22), '允许任意IP通过SSH连接', ); const repository = ecr.Repository.fromRepositoryName(this, "tq-backoffice-repo", "tq-backoffice-repo") const cluster = new ecs.Cluster(this, "backoffice-cluster", { vpc, clusterName: 'backoffice-cluster', }); cluster.addCapacity('DefaultAutoScalingGroupCapacity', { instanceType: ec2.InstanceType.of( ec2.InstanceClass.T2, ec2.InstanceSize.LARGE, ), }); // 拉取示例容器镜像 const image = ecs.ContainerImage.fromRegistry('amazon/amazon-ecs-sample'); const taskDefinition = new TaskDefinition(this, 'Task', { compatibility: Compatibility.EC2, memoryMiB: '512', cpu: '256', }); taskDefinition .addContainer('cms-img', { image: image, memoryLimitMiB:256, cpu: 256, }) .addPortMappings({ containerPort: 1337 }); cluster.addCapacity('app-scaling-group', { instanceType: new ec2.InstanceType('t2.micro'), desiredCapacity: 1, maxCapacity: 4, minCapacity: 1 }); new ecs_patterns.ApplicationLoadBalancedEc2Service( this, 'app-service', { cluster, cpu: 256, desiredCount: 1, minHealthyPercent: 50, maxHealthyPercent: 300, serviceName: 'cmsservice', taskDefinition: taskDefinition, publicLoadBalancer: true, }, );
部署输出
执行cdk deploy后,控制台持续输出:
[20:15:50] Stack BackOfficeDeployStack has an ongoing operation in progress and is not stable (UPDATE_IN_PROGRESS) [20:15:56] Stack BackOfficeDeployStack has an ongoing operation in progress and is not stable (UPDATE_IN_PROGRESS) [20:16:01] Stack BackOfficeDeployStack has an ongoing operation in progress and is not stable (UPDATE_IN_PROGRESS)
CloudFormation停滞资源
CloudFormation显示停滞的目标资源为:
arn:aws:ecs:us-east-1:273080356284:service/backoffice-cluster/cmsservice
问题根源
- VPC网络配置缺失:设置
natGateways: 0,且ECS实例部署在PRIVATE_ISOLATED子网,实例无出站访问能力,无法拉取容器镜像、与ECS控制平面通信。 - 重复集群容量配置:代码中两次调用
cluster.addCapacity(),创建两个Auto Scaling Group,引发资源调度冲突。 - 安全组规则不足:仅开放SSH端口,未允许ELB访问容器端口,也未开放实例出站流量,导致服务无法正常注册。
修复方案
1. 调整VPC配置
将私有子网改为PRIVATE_WITH_EGRESS类型,并启用NAT网关,确保ECS实例有出站访问能力:
const vpc = new ec2.Vpc(this, 'backoffice-vpc', { cidr: '10.0.0.0/16', natGateways: 1, maxAzs: 3, subnetConfiguration: [ { name: 'public-subnet-1', subnetType: ec2.SubnetType.PUBLIC, cidrMask: 24, }, { name: 'private-subnet-1', subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS, cidrMask: 24, }, ], });
2. 移除重复的集群容量配置
删除其中一组cluster.addCapacity()调用,保留一组即可,例如移除:
// cluster.addCapacity('DefaultAutoScalingGroupCapacity', { // instanceType: ec2.InstanceType.of( // ec2.InstanceClass.T2, // ec2.InstanceSize.LARGE, // ), // });
3. 完善安全组规则
为ECS实例安全组添加必要的入站和出站规则:
const ec2InstanceSG = new ec2.SecurityGroup(this, 'ec2-backoffice-sg', { vpc, allowAllOutbound: true, // 允许出站流量用于镜像拉取和控制平面通信 }); // 允许ELB访问容器端口(生产环境建议限制为ELB安全组) ec2InstanceSG.addIngressRule( ec2.Peer.anyIpv4(), ec2.Port.tcp(1337), '允许ELB访问容器端口' ); // 保留SSH访问规则 ec2InstanceSG.addIngressRule( ec2.Peer.anyIpv4(), ec2.Port.tcp(22), '允许任意IP通过SSH连接' );
4. 验证部署状态
修复后重新执行cdk deploy,并通过以下方式验证:
- 进入ECS控制台,查看集群的ECS实例状态是否为
ACTIVE; - 检查ECS服务的任务是否正常启动;
- 查看CloudWatch日志,确认无镜像拉取失败或通信错误。
内容的提问来源于stack exchange,提问作者vtukhtarov
相关产品推荐
相关产品推荐

