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

目标组实例不健康:Auto Scaling Group关联ALB后实例被终止排查

问题排查与修正方案

核心问题分析

你遇到的实例被终止问题,根源大概率是NAT网关的路由配置错误,导致实例无法访问公网下载httpd,进而引发ALB健康检查失败,触发ASG终止实例。此外用户数据脚本也存在潜在问题,可能导致httpd服务无法正常启动。

关键问题点

  1. NAT网关子网路由错误
    当前模板中,NAT网关部署在MySubnet02,但该子网和MySubnet01共用同一张路由表,默认路由指向NAT网关。这会导致NAT网关自身无法访问互联网(形成路由环路),实例通过NAT网关访问公网的请求全部失败。

  2. 用户数据脚本缺陷

    • 执行systemctl start httpd.service未加sudo,在Amazon Linux 2中可能因权限不足失败
    • ifconfig命令默认未安装(Amazon Linux 2需手动安装net-tools包),会导致脚本中断,后续步骤无法执行
    • 未设置httpd开机自启,实例重启后服务会停止
  3. 健康检查宽限期不足
    虽然设置了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  

修正说明

  1. 拆分路由表:新增公有/私有两张路由表,NAT所在的公有子网路由指向IGW,实例所在的私有子网路由指向NAT网关,解决NAT网关自身无法访问公网的问题。
  2. 优化用户数据脚本:
    • 添加sudo确保权限
    • 安装net-tools提供ifconfig命令
    • 设置systemctl enable httpd.service保证服务开机自启
  3. 调整健康检查配置:
    • 缩短健康检查间隔至30秒,减少等待时间
    • 延长健康检查宽限期至300秒,给足实例初始化时间
  4. 安全组优化:实例的80端口只允许ALB安全组访问,提升安全性
  5. 公有子网配置:开启MapPublicIpOnLaunch,确保NAT网关所在子网的资源能正常访问公网

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 02:27:01