目标组实例不健康:Auto Scaling Group关联ALB后实例被终止排查
问题排查与修正方案
核心问题分析
你遇到的实例被终止问题,根源大概率是NAT网关的路由配置错误,导致实例无法访问公网下载httpd,进而引发ALB健康检查失败,触发ASG终止实例。此外用户数据脚本也存在潜在问题,可能导致httpd服务无法正常启动。
关键问题点
NAT网关子网路由错误
当前模板中,NAT网关部署在MySubnet02,但该子网和MySubnet01共用同一张路由表,默认路由指向NAT网关。这会导致NAT网关自身无法访问互联网(形成路由环路),实例通过NAT网关访问公网的请求全部失败。用户数据脚本缺陷
- 执行
systemctl start httpd.service未加sudo,在Amazon Linux 2中可能因权限不足失败 ifconfig命令默认未安装(Amazon Linux 2需手动安装net-tools包),会导致脚本中断,后续步骤无法执行- 未设置httpd开机自启,实例重启后服务会停止
- 执行
健康检查宽限期不足
虽然设置了HealthCheckGracePeriod: 120,但httpd安装、配置加上实例初始化的时间可能超过这个值,导致健康检查提前触发,判定实例不健康。
修正后的CloudFormation模板
AWSTemplateFormatVersion: 2010-09-09 Description: ec2-instance Parameters: AMIs: Description: 镜像类型 Type: String Default: Linux AllowedValues: - Linux - Windows InstanceCount: Description: 实例数量 Type: Number Default: 1 Environment: Description: 部署环境 Type: String Default: Dev AllowedValues: - Dev - Prod Subnet01: Description: 私有子网1 CIDR Type: String Default: 10.0.1.0/24 Subnet02: Description: 公有子网(NAT网关用)CIDR Type: String Default: 10.0.2.0/24 LaunchTemplateVersionNumber: Default: 1 Type: String Mappings: FreeTier: Linux: HVM64: ami-0d9f286195031c3d9 Windows: HVM64: ami-09cf24ffd6d332930 Conditions: SelectImage: !Equals [!Ref AMIs, Linux] SelectEnv: !Equals [ !Ref Environment, Dev] Resources: # 应用负载均衡 ApplicationLB: Type: AWS::ElasticLoadBalancingV2::LoadBalancer Properties: Type: application IpAddressType: "ipv4" Scheme: internet-facing Subnets: - !Ref MySubnet01 - !Ref MySubnet02 Name: WebAppLB LoadBalancerAttributes: - Key: load_balancing.cross_zone.enabled Value: true SecurityGroups: - !Ref SecurityALB - !Ref enbalessh ALBListner: Type: AWS::ElasticLoadBalancingV2::Listener Properties: LoadBalancerArn: !Ref ApplicationLB DefaultActions: - Type: forward TargetGroupArn: !Ref MyTargetGroup Port: 80 Protocol: "HTTP" # 目标组 MyTargetGroup: Type: AWS::ElasticLoadBalancingV2::TargetGroup Properties: HealthCheckEnabled: true HealthCheckIntervalSeconds: 30 HealthCheckPath: /index.html HealthCheckPort: "traffic-port" UnhealthyThresholdCount: 3 HealthCheckTimeoutSeconds: 10 HealthCheckProtocol: "HTTP" Port: 80 Protocol: HTTP VpcId: !Ref MyVpc TargetType: "instance" Matcher: HttpCode: "200" TargetGroupAttributes: - Key: load_balancing.algorithm.type Value: round_robin - Key: "deregistration_delay.timeout_seconds" Value: "300" # VPC MyVpc: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/16 EnableDnsHostnames: true EnableDnsSupport: true # 私有子网1(实例部署用) MySubnet01: Type: AWS::EC2::Subnet Properties: AvailabilityZone: Fn::Select: - 0 - Fn::GetAZs: Ref: AWS::Region CidrBlock: !Ref Subnet01 VpcId: !Ref MyVpc # 公有子网(NAT网关部署用) MySubnet02: Type: AWS::EC2::Subnet Properties: AvailabilityZone: Fn::Select: - 1 - Fn::GetAZs: Ref: AWS::Region CidrBlock: !Ref Subnet02 VpcId: !Ref MyVpc MapPublicIpOnLaunch: true # 公有子网自动分配公网IP # 私有子网路由表(指向NAT网关) PrivateRouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref MyVpc # 公有子网路由表(指向IGW) PublicRouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref MyVpc MyIgw: Type: AWS::EC2::InternetGateway # 私有子网关联私有路由表 Subnet01RouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref MySubnet01 RouteTableId: !Ref PrivateRouteTable # 公有子网关联公有路由表 Subnet02RouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref MySubnet02 RouteTableId: !Ref PublicRouteTable VPCGatewayAttachment: Type: AWS::EC2::VPCGatewayAttachment Properties: InternetGatewayId: !Ref MyIgw VpcId: !Ref MyVpc MyEIP: Type: AWS::EC2::EIP DependsOn: VPCGatewayAttachment MyNAT: Type: AWS::EC2::NatGateway Properties: AllocationId: !GetAtt MyEIP.AllocationId SubnetId: !Ref MySubnet02 # 公有路由表添加指向IGW的默认路由 RouteToIGW: Type: AWS::EC2::Route DependsOn: VPCGatewayAttachment Properties: RouteTableId: !Ref PublicRouteTable DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref MyIgw # 私有路由表添加指向NAT网关的默认路由 RouteToNat: Type: AWS::EC2::Route DependsOn: MyNAT Properties: RouteTableId: !Ref PrivateRouteTable DestinationCidrBlock: 0.0.0.0/0 NatGatewayId: !Ref MyNAT # 启动模板 Launchtemplate: Type: AWS::EC2::LaunchTemplate Properties: LaunchTemplateData: ImageId: !If [SelectImage, !FindInMap [ FreeTier, Linux, HVM64 ], !FindInMap [ FreeTier, Windows, HVM64 ]] InstanceType: t2.micro KeyName: cfn-putty UserData: Fn::Base64: | #!/bin/bash # 安装httpd和net-tools(提供ifconfig命令) sudo yum -y install httpd net-tools # 创建测试页面 sudo touch /var/www/html/index.html echo "webserver v1" > /var/www/html/index.html sudo hostname >> /var/www/html/index.html sudo ifconfig >> /var/www/html/index.html # 启动httpd并设置开机自启 sudo systemctl start httpd.service sudo systemctl enable httpd.service SecurityGroupIds: - !GetAtt enbalessh.GroupId - !GetAtt SecurityALB.GroupId # 自动扩缩容组 LauncConfig: Type: AWS::AutoScaling::AutoScalingGroup DependsOn: - RouteToNat - RouteToIGW Properties: DefaultInstanceWarmup: 120 HealthCheckGracePeriod: 300 # 延长宽限期,给足初始化时间 HealthCheckType: ELB VPCZoneIdentifier: - !Ref MySubnet01 # 实例只部署在私有子网 MaxSize: 3 MinSize: 1 TargetGroupARNs: - !Ref MyTargetGroup DesiredCapacity: !Ref InstanceCount LaunchTemplate: LaunchTemplateId: !Ref Launchtemplate Version: !Ref LaunchTemplateVersionNumber Tags: - Key: "Environment" PropagateAtLaunch: true Value: !If [SelectEnv,Dev,Prod] - Key: "Name" PropagateAtLaunch: true Value: !Sub - "web-${os}-${env}" - os: !Ref AMIs env: !Ref Environment # 实例安全组 enbalessh: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: 允许SSH和HTTP访问 SecurityGroupIngress: - IpProtocol: tcp FromPort: '22' ToPort: '22' CidrIp: "0.0.0.0/0" - IpProtocol: tcp FromPort: 80 ToPort: 80 SourceSecurityGroupId: !Ref SecurityALB # 只允许ALB访问实例80端口 VpcId: !Ref MyVpc # ALB安全组 SecurityALB: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: 允许HTTP访问ALB SecurityGroupIngress: - IpProtocol: tcp FromPort: '80' ToPort: '80' CidrIp: "0.0.0.0/0" VpcId: !Ref MyVpc
修正说明
- 拆分路由表:新增公有/私有两张路由表,NAT所在的公有子网路由指向IGW,实例所在的私有子网路由指向NAT网关,解决NAT网关自身无法访问公网的问题。
- 优化用户数据脚本:
- 添加
sudo确保权限 - 安装
net-tools提供ifconfig命令 - 设置
systemctl enable httpd.service保证服务开机自启
- 添加
- 调整健康检查配置:
- 缩短健康检查间隔至30秒,减少等待时间
- 延长健康检查宽限期至300秒,给足实例初始化时间
- 安全组优化:实例的80端口只允许ALB安全组访问,提升安全性
- 公有子网配置:开启
MapPublicIpOnLaunch,确保NAT网关所在子网的资源能正常访问公网
内容的提问来源于stack exchange,提问作者Markus
相关产品推荐
相关产品推荐

