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

AWS目标组实例健康检查失败,ELB返回502错误求助

AWS基础设施部署问题排查

问题描述

在Udacity的AWS项目中部署包含弹性负载均衡器、自动扩展组、监听器、监听器规则、安全组和目标组的基础设施后,出现以下问题:

  • 目标组内实例健康检查始终显示不健康
  • 调用负载均衡DNS地址或实例IP均返回502 Bad Gateway
  • 无法通过负载均衡URL看到Apache Tomcat启动页面

部署前已创建VPC栈,以下是对应的CloudFormation代码:

VPC栈代码

Parameters:
    EnvironmentName:
        Description: An environment name that will be prefixed to resource names
        Type: String

    VpcCIDR:
        Description: Please enter the IP range (CIDR notatio) for this VPC
        Type: String
        Default: 10.0.0.0/16

    PublicSubnet1CIDR:
        Description: Please enter the IP range (CIDR notation) for the public subnet in the first Availability Zone
        Type: String
        Default: 10.0.0.0/24

    PublicSubnet2CIDR:
        Description: Please enter the IP range (CIDR notation) for the public subnet in the second Availability Zone
        Type: String
        Default: 10.0.1.0/24

    PrivateSubnet1CIDR:
        Description: Please enter the IP range (CIDR notation) for the private subnet in the first Availability Zone
        Type: String
        Default: 10.0.2.0/24
    PrivateSubnet2CIDR:
        Description: Please enter the IP range (CIDR notation) for the private subnet in the second Availability Zone
        Type: String
        Default: 10.0.3.0/24
Resources:
    VPC:
        Type: AWS::EC2::VPC
        Properties:
            CidrBlock: !Ref VpcCIDR
            EnableDnsHostnames: true
            Tags:
                - Key: Name
                  Value: !Ref EnvironmentName
    InternetGateway:
        Type: AWS::EC2::InternetGateway
        Properties:
            Tags:
                - Key: Name
                  Value: !Ref EnvironmentName
    InternetGatewayAttachment:
        Type: AWS::EC2::VPCGatewayAttachment
        Properties:
            InternetGatewayId: !Ref InternetGateway
            VpcId: !Ref VPC

    PublicSubnet1:
        Type: AWS::EC2::Subnet
        Properties:
            VpcId: !Ref VPC
            AvailabilityZone: !Select [0, !GetAZs ""]
            CidrBlock: !Ref PublicSubnet1CIDR
            MapPublicIpOnLaunch: true
            Tags:
                - Key: Name
                  Value: !Sub ${EnvironmentName} Public Subnet (AZ1)

    PublicSubnet2:
        Type: AWS::EC2::Subnet
        Properties:
            VpcId: !Ref VPC
            AvailabilityZone: !Select [1, !GetAZs ""]
            CidrBlock: !Ref PublicSubnet2CIDR
            MapPublicIpOnLaunch: true
            Tags:
                - Key: Name
                  Value: !Sub ${EnvironmentName} Public Subnet (AZ2)

    PrivateSubnet1:
        Type: AWS::EC2::Subnet
        Properties:
            VpcId: !Ref VPC
            AvailabilityZone: !Select [0, !GetAZs ""]
            CidrBlock: !Ref PrivateSubnet1CIDR
            MapPublicIpOnLaunch: false
            Tags:
                - Key: Name
                  Value: !Sub ${EnvironmentName} Private Subnet (AZ1)

    PrivateSubnet2:
        Type: AWS::EC2::Subnet
        Properties:
            VpcId: !Ref VPC
            AvailabilityZone: !Select [1, !GetAZs ""]
            CidrBlock: !Ref PrivateSubnet2CIDR
            MapPublicIpOnLaunch: false
            Tags:
                - Key: NameAW
                  Value: !Sub ${EnvironmentName} Private Subnet (AZ2)

    NatGateway1EIP:
        Type: AWS::EC2::EIP
        DependsOn: InternetGatewayAttachment
        Properties:
            Domain: vpc

    NatGateway2EIP:
        Type: AWS::EC2::EIP
        DependsOn: InternetGatewayAttachment
        Properties:
            Domain: vpc

    NatGateway1:
        Type: AWS::EC2::NatGateway
        Properties:
            AllocationId: !GetAtt NatGateway1EIP.AllocationId
            SubnetId: !Ref PublicSubnet1

    NatGateway2:
        Type: AWS::EC2::NatGateway
        Properties:
            AllocationId: !GetAtt NatGateway2EIP.AllocationId
            SubnetId: !Ref PublicSubnet2

    PublicRouteTable:
        Type: AWS::EC2::RouteTable
        Properties: 
            VpcId: !Ref VPC
            Tags: 
                - Key: Name 
                  Value: !Sub ${EnvironmentName} Public Routes

    DefaultPublicRoute: 
        Type: AWS::EC2::Route
        DependsOn: InternetGatewayAttachment
        Properties: 
            RouteTableId: !Ref PublicRouteTable
            DestinationCidrBlock: 0.0.0.0/0
            GatewayId: !Ref InternetGateway

    PublicSubnet1RouteTableAssociation:
        Type: AWS::EC2::SubnetRouteTableAssociation
        Properties:
            RouteTableId: !Ref PublicRouteTable
            SubnetId: !Ref PublicSubnet1

    PublicSubnet2RouteTableAssociation:
        Type: AWS::EC2::SubnetRouteTableAssociation
        Properties:
            RouteTableId: !Ref PublicRouteTable
            SubnetId: !Ref PublicSubnet2

    PrivateRouteTable1:
        Type: AWS::EC2::RouteTable
        Properties: 
            VpcId: !Ref VPC
            Tags: 
                - Key: Name 
                  Value: !Sub ${EnvironmentName} Private Routes (AZ1)

    DefaultPrivateRoute1:
        Type: AWS::EC2::Route
        Properties:
            RouteTableId: !Ref PrivateRouteTable1
            DestinationCidrBlock: 0.0.0.0/0
            NatGatewayId: !Ref NatGateway1

    PrivateSubnet1RouteTableAssociation:
        Type: AWS::EC2::SubnetRouteTableAssociation
        Properties:
            RouteTableId: !Ref PrivateRouteTable1
            SubnetId: !Ref PrivateSubnet1

    PrivateRouteTable2:
        Type: AWS::EC2::RouteTable
        Properties: 
            VpcId: !Ref VPC
            Tags: 
                - Key: Name 
                  Value: !Sub ${EnvironmentName} Private Routes (AZ2)

    DefaultPrivateRoute2:
        Type: AWS::EC2::Route
        Properties:
            RouteTableId: !Ref PrivateRouteTable2
            DestinationCidrBlock: 0.0.0.0/0
            NatGatewayId: !Ref NatGateway2

    PrivateSubnet2RouteTableAssociation:
        Type: AWS::EC2::SubnetRouteTableAssociation
        Properties:
            RouteTableId: !Ref PrivateRouteTable2
            SubnetId: !Ref PrivateSubnet2

Outputs:
    VPC:
        Description: A reference to the created VPC
        Value: !Ref VPC
        Export:
            Name: !Sub ${EnvironmentName}-VPCID

    PublicSubnets:
        Description: A list of the public subnets
        Value: !Join [",", [!Ref PublicSubnet1, !Ref PublicSubnet2]]
        Export:
            Name: !Sub ${EnvironmentName}-PUB-NETS

    PrivateSubnets:
        Description: A list of the private subnets
        Value: !Join [",", [!Ref PrivateSubnet1, !Ref PrivateSubnet2]]
        Export:
            Name: !Sub ${EnvironmentName}-PRIV-NETS

    PublicSubnet1:
        Description: A reference to the public subnet in the 1st Availability Zone
        Value: !Ref PublicSubnet1
        Export:
            Name: !Sub ${EnvironmentName}-PUB1-SN

    PublicSubnet2:
        Description: A reference to the public subnet in the 2nd Availability Zone
        Value: !Ref PublicSubnet2
        Export:
            Name: !Sub ${EnvironmentName}-PUB2-SN

    PrivateSubnet1:
        Description: A reference to the private subnet in the 1st Availability Zone
        Value: !Ref PrivateSubnet1
        Export:
            Name: !Sub ${EnvironmentName}-PRI1-SN

    PrivateSubnet2:
        Description: A reference to the private subnet in the 2nd Availability Zone
        Value: !Ref PrivateSubnet2
        Export:
            Name: !Sub ${EnvironmentName}-PRI2-SN

应用层栈代码

Description: >
  xxx / Udacity 2023

Parameters:
  EnvironmentName:
    Description: An environment name that will be prefixed to resource names
    Type: String
  myLaunchTemplateVersionNumber:
    Type: String
    Default: 1

Resources:
  LBSecGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Allow http to our load balancer
      VpcId: 
        Fn::ImportValue:
          !Sub "${EnvironmentName}-VPCID"
      SecurityGroupIngress: 
      - IpProtocol: tcp
        FromPort: 80
        ToPort: 80
        CidrIp: 0.0.0.0/0 
      SecurityGroupEgress:
      - IpProtocol: tcp
        FromPort: 80
        ToPort: 80
        CidrIp: 0.0.0.0/0
  WebServerSecGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Allow http to our hosts and SSH from local only
      VpcId:
        Fn::ImportValue:
          !Sub "${EnvironmentName}-VPCID"
      SecurityGroupIngress:
      - IpProtocol: tcp
        FromPort: 8080
        ToPort: 8080
        CidrIp: 0.0.0.0/0
      - IpProtocol: tcp 
        FromPort: 22
        ToPort: 22
        CidrIp: 0.0.0.0/0
      SecurityGroupEgress:
      - IpProtocol: tcp
        FromPort: 0
        ToPort: 65535
        CidrIp: 0.0.0.0/0
  myWebAppLaunchTemplate:
    Type: AWS::EC2::LaunchTemplate
    Properties:
      LaunchTemplateData:
        UserData:
          Fn::Base64: !Sub |
            #!/bin/bash
            apt-get update -y
            apt-get install apache2 -y
            systemctl start apache2.service
            cd /var/www/html
            echo "Udacity Demo Web Server Up and Running!" > index.html
        ImageId: ami-0a261c0e5f51090b1 
        KeyName: mykey 
        SecurityGroupIds:    
          - sg-01ad772aba0f98d98
        InstanceType: t3.medium
        BlockDeviceMappings:
          - DeviceName: "/dev/sdk"
            Ebs:
              VolumeSize: '10'
  WebAppGroup:
    Type: AWS::AutoScaling::AutoScalingGroup
    Properties:
      VPCZoneIdentifier:
        - Fn::ImportValue: !Sub "${EnvironmentName}-PUB-NETS"
      LaunchTemplate:
        LaunchTemplateId: !Ref myWebAppLaunchTemplate
        Version: !Ref myLaunchTemplateVersionNumber
      MinSize: "3"
      MaxSize: "5"
      TargetGroupARNs: 
      - Ref: WebAppTargetGroup 
  WebAppLB:  
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer 
    Properties:
      Subnets: 
      - Fn::ImportValue: !Sub "${EnvironmentName}-PUB1-SN"
      - Fn::ImportValue: !Sub "${EnvironmentName}-PUB2-SN"
      SecurityGroups:
      - Ref: LBSecGroup
  Listener: 
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      DefaultActions:
      - Type: forward
        TargetGroupArn:
          Ref: WebAppTargetGroup
      LoadBalancerArn:
        Ref: WebAppLB
      Port: '80' 
      Protocol: HTTP
  ALBListenerRule:
    Type: AWS::ElasticLoadBalancingV2::ListenerRule
    Properties:
      Actions:
      - Type: forward
        TargetGroupArn: !Ref 'WebAppTargetGroup'
      Conditions:
      - Field: path-pattern
        Values: [/] 
      ListenerArn: !Ref 'Listener'
      Priority: 1
  WebAppTargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties: 
      HealthCheckIntervalSeconds: 30 
      HealthCheckPath: / 
      HealthCheckProtocol: HTTP 
      HealthCheckTimeoutSeconds: 15
      HealthyThresholdCount: 2 
      UnhealthyThresholdCount: 5 
      Port: 8080 
      Protocol: HTTP
      VpcId:
        Fn::ImportValue:
          Fn::Sub: "${EnvironmentName}-VPCID"

问题排查与修复方案

1. 负载均衡安全组出站规则限制

问题:LBSecGroup的出站规则仅允许TCP 80端口流量,但目标组健康检查和流量转发都使用8080端口,导致负载均衡无法向实例发送健康检查请求,也无法转发用户流量到实例的8080端口。

修复:修改LBSecGroup的SecurityGroupEgress规则,允许所有TCP端口:

SecurityGroupEgress:
- IpProtocol: tcp
  FromPort: 0
  ToPort: 65535
  CidrIp: 0.0.0.0/0

2. 启动模板安全组硬编码

问题:myWebAppLaunchTemplate中的SecurityGroupIds使用了固定的安全组ID,而非引用当前栈中创建的WebServerSecGroup,可能导致实例使用错误的安全组,无法接收负载均衡的流量。

修复:将硬编码的安全组ID替换为引用:

SecurityGroupIds:    
  - !Ref WebServerSecGroup

3. 实例服务端口与目标组端口不匹配

问题:用户数据中安装的是Apache2(默认监听80端口),但目标组配置的是检查和转发到8080端口,导致实例在8080端口无服务运行,健康检查失败;同时用户需求是看到Tomcat启动页面,但当前脚本未安装Tomcat。

修复:选择以下两种方案之一:

  • 方案一:适配Apache2端口:修改目标组的端口为80:
    WebAppTargetGroup:
      Properties: 
        Port: 80 
    
  • 方案二:安装Tomcat服务:修改UserData脚本,安装并启动Tomcat(默认监听8080端口):
    UserData:
      Fn::Base64: !Sub |
        #!/bin/bash
        apt-get update -y
        apt-get install openjdk-11-jdk -y
        wget https://dlcdn.apache.org/tomcat/tomcat-9/v9.0.85/bin/apache-tomcat-9.0.85.tar.gz
        tar xzf apache-tomcat-9.0.85.tar.gz
        mv apache-tomcat-9.0.85 /opt/tomcat
        chmod +x /opt/tomcat/bin/startup.sh
        /opt/tomcat/bin/startup.sh
    

4. VPC栈中子网标签错误(非功能性问题)

问题:PrivateSubnet2的标签Key为NameAW,应为Name,属于配置规范问题。

修复:修改标签Key:

Tags:
  - Key: Name
    Value: !Sub ${EnvironmentName} Private Subnet (AZ2)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 22:37:01