这是我的设置:
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;
}
}