目标组没有关联的负载均衡器

Posted

技术标签:

【中文标题】目标组没有关联的负载均衡器【英文标题】:The target group does not have an associated load balancer 【发布时间】:2019-05-27 01:36:00 【问题描述】:

我想从 Cloud Formation Script 创建 ECS 服务。该服务需要通过 Application Load Balancer 暴露给外部

我创建了 Elastic Load Balancer、Listener 和 ListnerRule

 Resources:
  Vpc:
    Type: 'AWS::EC2::VPC'
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsSupport: 'true'
      EnableDnsHostnames: 'true'
    Metadata:
      'AWS::CloudFormation::Designer':
        id: 0e3933ae-23c2-44e1-a0d9-82fcfba93511
  PubSubnetAz1:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId: !Ref Vpc
      CidrBlock: 10.0.1.0/24
      AvailabilityZone: 'ap-southeast-1a'
      MapPublicIpOnLaunch: true
    Metadata:
      'AWS::CloudFormation::Designer':
        id: 6c7ca021-4114-4ec8-acf8-4f103ff7011f
  PubSubnetAz2:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId: !Ref Vpc
      CidrBlock: 10.0.2.0/24
      AvailabilityZone: 'ap-southeast-1b'
      MapPublicIpOnLaunch: true
    Metadata:
      'AWS::CloudFormation::Designer':
        id: cfe07e5c-e00f-4918-b877-f567fa08c802
  InternetGateway:
    Type: 'AWS::EC2::InternetGateway'
    Metadata:
      'AWS::CloudFormation::Designer':
        id: 46bddd21-3027-4ccb-9e5d-ebf887429453
  AttachGateway:
    Type: 'AWS::EC2::VPCGatewayAttachment'
    Properties:
      VpcId: !Ref Vpc
      InternetGatewayId: !Ref InternetGateway
    Metadata:
      'AWS::CloudFormation::Designer':
        id: 11b7e802-d5ba-437a-8695-4bd5406d4db7
  RouteViaIgw:
    Type: 'AWS::EC2::RouteTable'
    Properties:
      VpcId: !Ref Vpc
    Metadata:
      'AWS::CloudFormation::Designer':
        id: 1a2f2b53-09d3-4c2c-8286-295870b8c602
  PublicRouteViaIgw:
    Type: 'AWS::EC2::Route'
    DependsOn:
      - AttachGateway
    Properties:
      RouteTableId: !Ref RouteViaIgw
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway
    Metadata:
      'AWS::CloudFormation::Designer':
        id: 4b7c941a-8498-4e70-886b-9339018cc18a
  PubSubnet1RouteTableAssociation:
    Type: 'AWS::EC2::SubnetRouteTableAssociation'
    Properties:
      SubnetId: !Ref PubSubnetAz1
      RouteTableId: !Ref RouteViaIgw
    Metadata:
      'AWS::CloudFormation::Designer':
        id: cea0d60a-6d91-4922-90ea-f6db9f4378a9


  PubSubnet2RouteTableAssociation:
    Type: 'AWS::EC2::SubnetRouteTableAssociation'
    Properties:
      SubnetId: !Ref PubSubnetAz2
      RouteTableId: !Ref RouteViaIgw
    Metadata:
      'AWS::CloudFormation::Designer':
        id: c3b3c8e1-a9c8-47c6-8d26-b6f272bcd9e1

  EcsSecurityGroup:
    Condition: CreateNewSecurityGroup
    Type: 'AWS::EC2::SecurityGroup'
    Properties:
      GroupDescription: ECS Allowed Ports
      SecurityGroupIngress:
        IpProtocol: tcp
        FromPort: 30
        ToPort: 150
        CidrIp: 0.0.0.0/0
    Metadata:
      'AWS::CloudFormation::Designer':
        id: 493fdb30-54ce-4e4e-9cd6-c9faa6e3f93b

  LoadBalancerSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      VpcId: !Ref Vpc
      GroupDescription: Access to the load balancer that sits in front of ECS
      SecurityGroupIngress:
        # Allow access from anywhere to our ECS services
        - CidrIp: 0.0.0.0/0
          IpProtocol: -1


  ECSCluster:
    Type: AWS::ECS::Cluster
    Properties:
      ClusterName: 'my-cluster'

  EcsInstanceAsg:
    DependsOn: ECSCluster
    Type: 'AWS::AutoScaling::AutoScalingGroup'
    Properties:
      LaunchConfigurationName: !Ref EcsInstanceLc
      AvailabilityZones:
        - ap-southeast-1a
        - ap-southeast-1b
      MinSize: '2'
      MaxSize: '3'
      DesiredCapacity: '2'

      Tags:
        - Key: Name
          Value: !Sub 'ECS Instance stack'
          PropagateAtLaunch: 'true'
        - Key: Description
          Value: >-
            This instance is the part of the Auto Scaling group which was
            created through ECS Console
          PropagateAtLaunch: 'true'
    Metadata:
      'AWS::CloudFormation::Designer':
        id: 80731e0b-a9e5-461c-9049-e215aed2ad3d

  EcsInstanceLc:
      # DependsOn
      Type: 'AWS::AutoScaling::LaunchConfiguration'
      Properties:
        ImageId: 'ami-050865a806e0dae53'
        InstanceType: 't2.large'
        # AssociatePublicIpAddress: false
        SecurityGroups:
          - !Ref EcsSecurityGroup

      Metadata:
        'AWS::CloudFormation::Designer':
          id: 0e8e3b5a-7b14-4ffc-92af-ef9be7e51689

  LoadBalancer:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Name: 'my-load-balancer'
      Subnets:
        - !Ref PubSubnetAz1
        - !Ref PubSubnetAz2
      Listeners:
        InstancePort: 80
        InstanceProtocol: HTTP
        LoadBalancerPort: 80
        Protocol: HTTP
      HealthCheck:
        HealthyThreshold: '10'
        Interval: '5'
        Target: '10'
        Timeout: '15'
        UnhealthyThreshold: '20'
      SecurityGroups: !Ref LoadBalancerSecurityGroup  



      Tags:
        - Key: Name
          Value: !Ref EcsClusterNam

  TargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      VpcId: !Ref Vpc
      Port: 80
      Protocol: HTTP
      HealthCheckIntervalSeconds: 10
      HealthCheckPort: 80
      HealthCheckPath: '/actuator/health'
      HealthCheckProtocol: HTTP
      HealthCheckTimeoutSeconds: 5
      HealthyThresholdCount: 3
      TargetType: instance
      Matcher:
        HttpCode: '200'

  Listener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      DefaultActions:
      - Type: forward
        TargetGroupArn: !Ref TargetGroup
      LoadBalancerArn: !Ref LoadBalancer
      Port: '80'
      Protocol: HTTP


  ListenerRule:
    Type: AWS::ElasticLoadBalancingV2::ListenerRule
    Properties:
      Actions:
       - Type: forward
      TargetGroupArn: !Ref TargetGroup
      LoadBalancerArn: !Ref LoadBalancer
      Port: 80
      Protocol: tcp
      Priority: 1
      Conditions:
      - Field: path-pattern
        Values: "/*"
      ListenerArn: !Ref Listener

  TaskDefinition:
    Type: AWS::ECS::TaskDefinition
    Properties:
      Family: 'product-service'
      Cpu: '256'
      Memory: '512'
      NetworkMode: bridge
      RequiresCompatibilities:
        - EC2
      ExecutionRoleArn: 'ecserviceRole'
      ContainerDefinitions:
        - Name: 'product-service'
          Cpu: '128'
          Memory: '256'
          Image: 'ccmcwolf/microservices:awstest'
          PortMappings:
            - HostPort: '80'
              ContainerPort: '80'
              Protocol: 'tcp'

          # LogConfiguration:
          #   LogDriver: awslogs
          #   Options:
          #     awslogs-group: !Ref CloudWatchLogsGroup
          #     awslogs-region: !Ref AWS::Region


  Service:
    Type: AWS::ECS::Service
    Properties:
      Cluster: !Ref ECSCluster
      Role: 'ecserviceRole'
      DesiredCount: '2'
      TaskDefinition: !Ref TaskDefinition
      LoadBalancers:
        - TargetGroupArn: !Ref TargetGroup
          ContainerPort: 80
          ContainerName: "product-service"

但是当我在 Cloudformation 中运行脚本时,它会引发错误

具有 targetGroupArn 的目标组 arn:aws:elasticloadbalancing:ap-southeast-1:xxxxxxxxxxxx:targetgroup/iy6-TargetG-A6FWY20V6B6P/7e5d12f4cb4758a1 没有关联的负载均衡器

。 整个 AWS 云形成脚本可在 https://notepad.pw/ecsaws

获得

【问题讨论】:

我尝试运行它,但得到:“无法承担角色并验证指定的targetGroupArn。请验证正在传递的ECS服务角色是否具有适当的权限。” 【参考方案1】:

此案例现在在AWS::ECS::Service CloudFormation 页面的“将应用程序负载均衡器与服务关联”下的示例部分中进行了介绍。

Amazon ECS 服务需要明确依赖 Application Load Balancer 侦听器规则和 Application Load Balancer 侦听器。这可以防止服务在侦听器准备好之前启动。

您遇到的最终问题是由于AWS::ECS::Service 在将目标组添加到负载均衡器之前尝试附加到目标组。解决这个问题非常简单:

 Service:
    Type: AWS::ECS::Service
    DependsOn: Listener       # Line Added
    Properties:
      Cluster: !Ref ECSCluster
      Role: 'ecserviceRole'
      DesiredCount: '2'
      TaskDefinition: !Ref TaskDefinition
      LoadBalancers:
        - TargetGroupArn: !Ref TargetGroup
          ContainerPort: 80
          ContainerName: "product-service"

话虽如此,您还必须更新您的LoadBalancer 定义,因为它有很多错误。应该是:

  LoadBalancer:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Name: 'my-load-balancer'
      Subnets:
        - !Ref PubSubnetAz1
        - !Ref PubSubnetAz2
      SecurityGroups: 
        - !Ref LoadBalancerSecurityGroup 

【讨论】:

AWS cfn 文档明确指出:“Amazon ECS 服务需要对 Application Load Balancer 侦听器规则和 Application Load Balancer 侦听器的显式依赖。这会阻止服务在侦听器准备好之前启动。”【参考方案2】:

添加DependsOn 不仅是Listener,还添加ListenerRule,如下所示:

ECSService:
  Type: AWS::ECS::Service
  DependsOn:
    - ListenerHTTPS
    - ListenerRule

【讨论】:

ListenerRule 已经依赖于 Listener 因为 !Ref Listener 行。因此,您不必在此处添加 ListenerRule(最近 AWS 开始建议在存在隐式的情况下反对显式依赖)。

以上是关于目标组没有关联的负载均衡器的主要内容,如果未能解决你的问题,请参考以下文章

网络负载均衡器目标组中的 AWS Auto Scaling 目标

Cloudformation Elasticbeanstalk 指定共享负载均衡器的目标组

网络负载均衡器的AWS EC2安全组权限

如何更改附加到弹性 beantalk 的负载均衡器

应用程序负载均衡器在自动缩放组打开新实例之前不会保留请求

在网络负载均衡器 + 目标组后面运行 SSH 的 AWS ECS 服务使用 CodeDeploy 部署缓慢