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

CDK创建带经典负载均衡器的ASG时EC2访问异常、健康主机数为0

问题根因与修复方案

两个故障现象(经典负载均衡器后端健康主机数为0、EC2公网无法访问Web/Instance Connect连接失败)均由配置缺失导致,核心问题点和修复方式如下:

  • 公网子网实例未分配公网IP:CDK中Auto Scaling Group在公网子网启动实例时,默认不会自动关联公网IP。没有公网IP的实例既无法响应公网发起的HTTP、SSH连接请求,也无法正常访问公网yum源,直接导致写在user data里的httpd安装脚本执行失败,Web服务根本没启动。
  • 安全组默认规则未放通必要流量:CDK自动创建的CLB、EC2安全组默认不会放通CLB健康检查流量、SSH连接流量、公网HTTP访问流量,流量直接被安全组拦截。
  • 代码逻辑顺序与健康检查配置不全:原代码先给CLB添加ASG目标、后配置监听器,顺序错误;同时健康检查仅指定端口,未明确检查路径和协议,容易出现检查异常。

修复后完整代码

Vpc vpc=new Vpc(this,"MyVPC");
// 配置CLB安全组,放通公网80端口入站
SecurityGroup clbSg = SecurityGroup.Builder.create(this,"ClbSg")
        .vpc(vpc)
        .allowAllOutbound(true)
        .build();
clbSg.addIngressRule(Peer.anyIpv4(), Port.tcp(80), "Allow public HTTP access");

// 配置EC2实例安全组
SecurityGroup instanceSg = SecurityGroup.Builder.create(this,"InstanceSg")
        .vpc(vpc)
        .allowAllOutbound(true)
        .build();
// 放通CLB来源的80端口流量,用于健康检查和请求转发
instanceSg.addIngressRule(Peer.securityGroupId(clbSg.getSecurityGroupId()), Port.tcp(80), "Allow HTTP from CLB");
// 放通22端口入站,支持Instance Connect连接
instanceSg.addIngressRule(Peer.anyIpv4(), Port.tcp(22), "Allow SSH for Instance Connect");

AutoScalingGroup asg = AutoScalingGroup.Builder.create(this,"AutoScalingGroup")
        .vpcSubnets(SubnetSelection.builder()
                .subnetType(SubnetType.PUBLIC)
                .build())
        .vpc(vpc)
        .instanceType(InstanceType.of(InstanceClass.BURSTABLE2, InstanceSize.MICRO))
        .machineImage(new AmazonLinuxImage())
        .minCapacity(1)
        .desiredCapacity(5)
        .maxCapacity(10)
        .securityGroup(instanceSg)
        .associatePublicIpAddress(true) // *关键配置*:公网子网实例自动分配公网IP
        .build();

asg.addUserData("#!/bin/bash\n" +
                "# install httpd (Linux 2 version)\n" +
                "yum update -y\n" +
                "yum install -y httpd\n" +
                "systemctl start httpd\n" +
                "systemctl enable httpd\n" +
                "echo \"<h1>Hello World from $(hostname -f)</h1>\" > /var/www/html/index.html");

LoadBalancer loadbalancer=LoadBalancer.Builder.create(this,"ElasticLoadBalancer")
        .vpc(vpc)
        .internetFacing(true)
        .securityGroup(clbSg)
        .healthCheck(software.amazon.awscdk.services.elasticloadbalancing.HealthCheck.builder()
                .port(80)
                .path("/index.html")
                .healthyThresholdCount(2)
                .unhealthyThresholdCount(2)
                .interval(Duration.seconds(30))
                .build())
        .build();
// 先添加监听器,再绑定后端目标
loadbalancer.addListener(LoadBalancerListener.builder().externalPort(80).build());
loadbalancer.addTarget(asg);

部署后验证

  1. 部署完成后等待3-5分钟,等待ASG拉起新实例、user data脚本执行完成。建议手动终止旧的异常实例,让ASG自动启动新配置的实例,避免旧实例配置残留影响结果。
  2. 单实例验证:选中任意一台ASG创建的新实例,通过公网IP访问80端口,确认能正常返回Hello World页面;测试Instance Connect功能,确认可以正常连接实例。
  3. CLB验证:查看CLB目标实例健康状态,等待所有5台实例状态变为Healthy后,通过CLB的DNS名称访问,确认请求可以正常分发到后端实例。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 01:42:17