Время ожидания соединения балансировщика нагрузки со службой ecs, выполняющей fargate (оба в одной частной подсети), истекло - PullRequest
1 голос
/ 24 апреля 2019

У меня есть VPC с 4 подсетями, две общедоступные и две частные (по одной частной и общедоступной в каждой AZ). Я запускаю службу ecs с задачами fargate в частных подсетях и назначаю задачу ecs группе безопасности, которая разрешает входящий трафик из группы безопасности балансировщика нагрузки приложения. Балансировщик нагрузки имеет внутренний тип и запускается в той же частной подсети. Мой файл облачной информации выглядит так:

---
AWSTemplateFormatVersion: 2010-09-09
Description: ECS task some server

Parameters:
  VpcId:
    Type: String
  VpcCidr:
    Type: String
  SubnetIds:
    Type: CommaDelimitedList # private subnets
  Cluster:
    Type: String
  ServiceName:
    Type: String
  ContainerPort:
    Type: String

  # ENVIRONMENT VARS
  Image:
    Type: String
  DBUrl: 
    Type: String
  DBUser:
    Type: String
  DBPassword:
    Type: String
    NoEcho: true

Resources:
  LogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub /ecs/${ServiceName}
      RetentionInDays: '1827' # 5 years

  ExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub ${ServiceName}-ExecutionRole
      AssumeRolePolicyDocument:
        Statement:
        - Effect: Allow
          Principal:
            Service:
              - ecs-tasks.amazonaws.com
          Action:
            - sts:AssumeRole
      Path: /
      Policies:
        - PolicyName: ECSTaskExecutionRolePolicy
          PolicyDocument:
            Statement:
            - Effect: Allow
              Action:
                # download images from ECR
                - ecr:GetAuthorizationToken
                - ecr:BatchCheckLayerAvailability
                - ecr:GetDownloadUrlForLayer
                - ecr:BatchGetImage

                # upload logs to CloudWatch
                - logs:CreateLogStream
                - logs:PutLogEvents
              Resource: '*'

  TaskRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub ${ServiceName}-TaskRole
      AssumeRolePolicyDocument:
        Statement:
        - Effect: Allow
          Principal:
            Service:
              - ecs-tasks.amazonaws.com
          Action:
            - sts:AssumeRole
      Path: /
      Policies:
        - PolicyName: ECSTaskRolePolicy
          PolicyDocument:
            Statement:
            - Effect: Allow
              Action:
                - appsync:GraphQL
              Resource:
                - '*'

  TaskDefinition: 
    Type: AWS::ECS::TaskDefinition
    DependsOn: 
      - LogGroup
    Properties:
      Family: !Ref ServiceName
      NetworkMode: awsvpc
      RequiresCompatibilities:
        - FARGATE

      Cpu: 1024 # .25 vCPU (256/512/1024/2048/4096)
      Memory: 8GB # (0.5GB/1GB/2GB/.../30GB)

      ExecutionRoleArn: !Ref ExecutionRole
      TaskRoleArn: !Ref TaskRole

      ContainerDefinitions:
        - Name: !Ref ServiceName
          Image: !Ref Image
          PortMappings:
          - ContainerPort: !Ref ContainerPort
          Environment:
          - Name: LOG_LEVEL
            Value: debug
          - Name: DBURL
            Value: !Sub jdbc:mysql://${DBUrl}:3306/db
          - Name: DBUSER
            Value: !Ref DBUser
          - Name: DBPASSWORD
            Value: !Ref DBPassword
          LogConfiguration:
            LogDriver: awslogs
            Options:
              awslogs-region: !Ref AWS::Region
              awslogs-group: !Ref LogGroup
              awslogs-stream-prefix: !Ref ServiceName

  LoadBalancerSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: !Sub ${ServiceName}-loadbalancer
      VpcId: !Ref VpcId
      SecurityGroupIngress:
      - IpProtocol: tcp
        FromPort: !Ref ContainerPort
        ToPort: !Ref ContainerPort
        CidrIp: !Ref VpcCidr

  ContainerSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: !Sub ${ServiceName}-container
      VpcId: !Ref VpcId
      SecurityGroupIngress:
      - IpProtocol: tcp
        SourceSecurityGroupId: !Ref LoadBalancerSecurityGroup
        FromPort: 0
        ToPort: 65535

  TargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      TargetType: ip
      Name: !Ref ServiceName
      Port: !Ref ContainerPort
      Protocol: HTTP
      VpcId: !Ref VpcId
      HealthCheckPath: /healthcheck
      HealthCheckProtocol: HTTP

  LoadBalancer:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Type: application
      IpAddressType: ipv4
      Scheme: internal
      Subnets: !Ref SubnetIds
      SecurityGroups: 
        - !Ref LoadBalancerSecurityGroup

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

  Service:
    Type: AWS::ECS::Service
    DependsOn: Listener
    Properties:
      ServiceName: !Ref ServiceName
      Cluster: !Ref Cluster
      TaskDefinition: !Ref TaskDefinition
      DesiredCount: 1
      LaunchType: FARGATE
      NetworkConfiguration:
        AwsvpcConfiguration:
          Subnets: !Ref SubnetIds
          SecurityGroups:
            - !Ref ContainerSecurityGroup
      LoadBalancers:
        - ContainerName: !Ref ServiceName
          ContainerPort: !Ref ContainerPort
          TargetGroupArn: !Ref TargetGroup

Outputs:
  LoadBalancerArn:
    Value: !Ref LoadBalancer
  LoadBalancerDNS:
    Value: !GetAtt LoadBalancer.DNSName
  LoadbalancerName:
    Value: !GetAtt LoadBalancer.LoadBalancerName

URL-адрес Healthcheck, безусловно, правильный, он находится на том же порту, что и контейнер, и возвращает код состояния 200. Но по какой-то причине время балансировки нагрузки истекает, возможно, я что-то здесь упускаю. Любая помощь будет принята с благодарностью!

...