如何在非默认端口上将 ECS 服务注册为网络负载均衡器目标?

How can I register an ECS Service as a Network Load Balancer target on a non-default port?

我正在尝试部署一个水平扩展应用程序,该应用程序由多个容器组成,在 EC2 支持的 AWS ECS 前面有一个反向代理。由于某些原因,我无法使用应用程序负载均衡器,但想使用网络负载均衡器将端口 80 和 443 上的所有流量转发到反向代理容器。我使用 AWS CDK 来定义设置。

我在尝试将两个端口上的流量路由到代理时遇到了问题运行。无论我做什么,创建的目标组中的所有目标都指向容器上的 80 端口。 IE。当我想要 80->80, 443->443.[= 时,我得到了 80->80, 443->80 的映射12=]

我的 CDK 代码如下所示:

const proxyService = new ecs.Ec2Service(this, 'ProxyService', {
  serviceName: 'proxy',
  cluster,
  taskDefinition: proxyTaskDefinition,
  minHealthyPercent: 0,
  desiredCount: 1,
  securityGroups: [securityGroup],
  cloudMapOptions: {
    name: 'proxy',
    cloudMapNamespace: cluster.defaultCloudMapNamespace
  }
})

const loadbalancer = new lb.NetworkLoadBalancer(this, 'NetworkLoadBalancer', {
  vpc,
  internetFacing: true
})

new cdk.CfnOutput(this, 'LoadBalancerDnsName', {
  value: loadbalancer.loadBalancerDnsName
})

loadbalancer.addListener('HTTPListener', {
  port: 80
})
  .addTargets('HTTPTarget', {
    port: 80,
    targets: [proxyService]
  })

loadbalancer.addListener('HTTPSListener', {
  port: 443,
})
  .addTargets('HTTPSTarget', {
    port: 443,
    // the proxyService seems to always register itself at port 80
    // by calling its attachToNetworkTargetGroup method
    targets: [proxyService]
  })
}

为目标组生成的 Cloudformation 如下所示:

NetworkLoadBalancerHTTPListener792E96F1:
  Type: AWS::ElasticLoadBalancingV2::Listener
  Properties:
    DefaultActions:
      - TargetGroupArn:
          Ref: NetworkLoadBalancerHTTPListenerHTTPTargetGroupCEAF8C0F
        Type: forward
    LoadBalancerArn:
      Ref: NetworkLoadBalancer8E753273
    Port: 80
    Protocol: TCP
  Metadata:
    aws:cdk:path: SplitClusterStack/NetworkLoadBalancer/HTTPListener/Resource
NetworkLoadBalancerHTTPListenerHTTPTargetGroupCEAF8C0F:
  Type: AWS::ElasticLoadBalancingV2::TargetGroup
  Properties:
    Protocol: TCP
    TargetType: ip
    VpcId:
      Ref: VPCB9E5F0B4
  Metadata:
    aws:cdk:path: SplitClusterStack/NetworkLoadBalancer/HTTPListener/HTTPTargetGroup/Resource
NetworkLoadBalancerHTTPSListenerAF8F470A:
  Type: AWS::ElasticLoadBalancingV2::Listener
  Properties:
    DefaultActions:
      - TargetGroupArn:
          Ref: NetworkLoadBalancerHTTPSListenerHTTPSTargetGroup4BC6FF0B
        Type: forward
    LoadBalancerArn:
      Ref: NetworkLoadBalancer8E753273
    Port: 443
    Protocol: TCP
  Metadata:
    aws:cdk:path: SplitClusterStack/NetworkLoadBalancer/HTTPSListener/Resource
NetworkLoadBalancerHTTPSListenerHTTPSTargetGroup4BC6FF0B:
  Type: AWS::ElasticLoadBalancingV2::TargetGroup
  Properties:
    Protocol: TCP
    TargetType: ip
    VpcId:
      Ref: VPCB9E5F0B4
  Metadata:
    aws:cdk:path: SplitClusterStack/NetworkLoadBalancer/HTTPSListener/HTTPSTargetGroup/Resource

部署后,我可以在 Web 控制台中编辑创建的目标组,以在同一 IP 上注册一个指向 443 的新目标,并注销端口 80 以使一切正常运行。

如何创建负载均衡器目标:

  1. 指向ECS服务
  2. 使用端口 443

如果它能帮助我解决这个问题,我很乐意自己构建它甚至添加覆盖。

ECS 服务公开了可用于此的 loadBalancerTarget 方法:

    loadbalancer.addListener('HTTPSListener', {
      port: 443,
    })
      .addTargets('HTTPSTarget', {
        port: 443,
        targets: [proxyService.loadBalancerTarget({
          containerPort: 443,
          containerName: 'proxy'
        })]
      })