Назад | Перейти на главную страницу

Как предоставить несколько портов в одном контейнере в AWS за ALB

Все приложение состоит из двух серверов (RabbitMQ и Tomcat) и БД, работающей за ALB. На данный момент будет только один экземпляр RabbitMQ и один экземпляр Tomcat, однако настройка должна позволять масштабирование. Оба сервера работают в собственных контейнерах Docker. Для этого я использую ECS и CloudFormation.

Проблема с сервером RabbitMQ. Этот сервер должен прослушивать два разных порта - один для соединений WebSocket (порт 15674), а другой - для соединений HTTP для Management API (порт 15672). Соединения WebSocket устанавливаются из клиентов / браузеров. HTTP-соединения происходят внутренне от Tomcat к RabbitMQ, но они также проходят через ALB. Я не могу найти способ настроить контейнер RabbitMQ, чтобы трафик шел к нему через оба порта. Я использую части шаблона CloudFormation, относящиеся к серверу RabbitMQ. Используя этот шаблон, соединения WebSocket, похоже, работают нормально, но соединения HTTP завершаются с ошибкой 404. Приветствуются идеи, как включить HTTP-соединения (порт 15672).

  ECSAutoScalingGroup:
    Type: "AWS::AutoScaling::AutoScalingGroup"
    Properties:
      VPCZoneIdentifier:        
        - Ref: "Subnet1"
        - Ref: "Subnet2"
      LaunchConfigurationName: !Ref "AutoScalingGroupConfig"
      MinSize: "1"
      MaxSize: "1"
      DesiredCapacity: "1"
    CreationPolicy:
      ResourceSignal:
        Timeout: "PT5M"
    UpdatePolicy:
      AutoScalingReplacingUpdate:
        WillReplace: true
...
  ECSALB:
    Type: "AWS::ElasticLoadBalancingV2::LoadBalancer"
    DependsOn: "AttachGateway"
    Properties:
      Name: "ECSALB"
      LoadBalancerAttributes:
        - Key: idle_timeout.timeout_seconds
          Value: 30
      Subnets: 
        - Ref: "Subnet1"
        - Ref: "Subnet2"
      SecurityGroups: [!Ref "LoadBalancerSecurityGroup"]
...
  ALBRabbitMQManagementListener:
    Type: "AWS::ElasticLoadBalancingV2::Listener"
    DependsOn: [ "ECSServiceRole", "RabbitMQTargetGroup" ]
    Properties:
      DefaultActions:
        - Type: "forward"
          TargetGroupArn: !Ref "RabbitMQTargetGroup"
      LoadBalancerArn: !Ref "ECSALB"
      Port: 15672
      Protocol: "HTTP"
...
  ALBListenerHTTPS:
    Type: "AWS::ElasticLoadBalancingV2::Listener"
    DependsOn: [ "ECSServiceRole", "ECSALB" ]
    Properties:
      Certificates:
        - CertificateArn: “some_certificate”      
      DefaultActions:
        - Type: "redirect"
          RedirectConfig: 
            Protocol: "HTTPS"
            Host: "static.domain.com"
            Path: "/#{path}"
            Query: "#{query}"
            StatusCode: "HTTP_301"
      LoadBalancerArn: !Ref "ECSALB"
      Port: 443
      Protocol: "HTTPS"
...
  ECSALBListenerRuleWebSocket:
    Type: "AWS::ElasticLoadBalancingV2::ListenerRule"
    DependsOn: [ "ALBListenerHTTPS", "RabbitMQTargetGroup" ]
    Properties:
      Actions:
        - Type: "forward"
          TargetGroupArn: !Ref "RabbitMQTargetGroup"
      Conditions:
        - Field: "path-pattern"
          Values: [ "/ws" ]
      ListenerArn: !Ref "ALBListenerHTTPS"
      Priority: 2
...
  RabbitMQTargetGroup:
    Type: "AWS::ElasticLoadBalancingV2::TargetGroup"
    DependsOn: "ECSALB"
    Properties:
      HealthCheckIntervalSeconds: 30
      HealthCheckPath: "/"
      HealthCheckPort: 15672
      HealthCheckProtocol: "HTTP"
      HealthCheckTimeoutSeconds: 5
      HealthyThresholdCount: 2
      Name: "RabbitMQTargetGroup"
      Port: 15674 
      Protocol: "HTTP"
      TargetGroupAttributes:
        - Key: "stickiness.enabled"
          Value: true  # Needed to support WebSockets
        - Key: "stickiness.lb_cookie.duration_seconds"
          Value: 604800  # One week (this is the maximum)
      UnhealthyThresholdCount: 3
      VpcId: !Ref "Vpc"
...
  RabbitMQService:
    Type: AWS::ECS::Service
    DependsOn: [ "ALBListenerHTTPS", "RabbitMQTargetGroup", "ECSALBListenerRuleWebSocket" ]
    Properties:
      Cluster: !Ref “MyCluster"
      Role: !Ref "ECSServiceRole"
      DesiredCount: 1
      TaskDefinition: !Ref "RabbitMQTask"
      DeploymentConfiguration:
        MinimumHealthyPercent: 100
      LoadBalancers:
        - ContainerName: "rabbitmq-service"
          ContainerPort: 15674
          TargetGroupArn: !Ref "RabbitMQTargetGroup"
...
  RabbitMQTask:
    Type: "AWS::ECS::TaskDefinition"
    Properties:
      Family: "rabbitmq-service"
      NetworkMode: "host"
      ContainerDefinitions:
        - Name: "rabbitmq-service"
          Essential: true
          Image: “some_docker_image”
          MemoryReservation: 1024
          PortMappings:
            - ContainerPort: 15672
            - ContainerPort: 15674
          LogConfiguration:
            LogDriver: "awslogs"
            Options:
              awslogs-group: "rabbitmq"
              awslogs-region: !Ref "AWS::Region"
              awslogs-stream-prefix: “my_prefix”
              awslogs-datetime-format: "%Y-%m-%d %H:%M:%S.%L"