![网络负载均衡器到 Fargate/ECS 集群-如何将多个端口/目标组映射到一个服务?](https://linux22.com/image/737420/%E7%BD%91%E7%BB%9C%E8%B4%9F%E8%BD%BD%E5%9D%87%E8%A1%A1%E5%99%A8%E5%88%B0%20Fargate%2FECS%20%E9%9B%86%E7%BE%A4-%E5%A6%82%E4%BD%95%E5%B0%86%E5%A4%9A%E4%B8%AA%E7%AB%AF%E5%8F%A3%2F%E7%9B%AE%E6%A0%87%E7%BB%84%E6%98%A0%E5%B0%84%E5%88%B0%E4%B8%80%E4%B8%AA%E6%9C%8D%E5%8A%A1%EF%BC%9F.png)
这是我的设置:
Route53 别名记录 -> 网络负载均衡器 -> Fargate/ECS 集群
集群中的容器拥有自己的 TLS 证书,并开放了 80 和 443 端口。如果您访问 80 端口,容器中的 http 服务器会将 302 重定向到 443 端口,因此用户不必输入完整的 https url。
一切工作正常,只是我找不到让 NLB 转发多个端口的方法。
在 ECS 服务描述中,您可以将服务映射到 ELB 目标组,但每个服务只能指定一个映射(LoadBalancers
是列表类型,但只允许一个条目)并且必须包含一个端口,即:
EcsService:
Type: AWS::ECS::Service
Properties:
Cluster: !Ref EcsCluster
DeploymentConfiguration:
MaximumPercent: 100
MinimumHealthyPercent: 0
ServiceName: ecs-service
LaunchType: FARGATE
LoadBalancers:
- ContainerName: !Ref ContainerName
ContainerPort: 443
TargetGroupArn: !Ref TargetGroup
DesiredCount: 1
TaskDefinition: !Ref TaskDefinition
NetworkConfiguration:
AwsvpcConfiguration:
AssignPublicIp: ENABLED
SecurityGroups:
- !Ref SecurityGroup
Subnets:
- !Ref Subnet
我考虑过以另一种方式进行映射,即在定义中指定目标TargetGroup
,但文档指出,对于ip
目标,您必须指定一个 IP 地址作为目标(而不是对服务的引用) - 因此当容器被删除和添加时,这似乎也会失败。
我这里遗漏了什么吗?我试图避免使用 ALB 来实现这一点。
答案1
我可以问一下你为什么要尝试避免使用 ALB? 它非常适合基于 Web 的服务,可以为您完成 SSL 终止,支持多个端口,您可以通过 Cognito 等添加身份验证。在您的设置中,ALB 有什么不能为您做的事情吗?
在我看来人们过度使用 NLB 并且我仍然不明白为什么...
答案2
因此,回答我自己的问题 - 这在 NLB 中无法直接实现。不过,我的解决方案非常简单。
我在同一个 ECS 集群中创建了第二个服务和任务定义,它由一个非常轻量级的容器(nginx-alpine)组成,它只是使用 301 重定向到端口 443 来响应端口 80。
端口 80 的侦听器指向映射到此第二个服务的 TargetGroup,因此对端口 80 的 http 请求会立即重定向到同一请求的 https 版本,该版本转到端口 443 的侦听器,该侦听器指向实际的应用程序。
它运行良好并且占用最少的资源。
nginx.conf 是:
events {}
http {
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
return 301 https://$host$request_uri;
}
}