将最小服务部署到 ECS Fargate,无需通过 public 互联网访问负载均衡器
Deploy minimal service to ECS Fargate without load balancer accessible via public internet
我有一个小应用程序,我想以尽可能低的成本部署到 AWS,这样仍然可以在 public 互联网上访问该应用程序,并在需要时进一步扩展。除此之外,我还想简化我的流程并使一切自动化。
这就是我选择以下设置的原因:
- AWS ECS
- AWS Fargate Spot
- AWS 服务发现
- 无负载均衡器
我暂时不想使用负载均衡器,因为一开始它的成本太高,尤其是当我不时想完全缩减应用程序时。
到目前为止有什么:
AWSTemplateFormatVersion: "2010-09-09"
Description: ECS deployment
Parameters:
Image:
Type: String
Application:
Type: String
Namespace:
Type: String
Cluster:
Type: String
Cpu:
Type: String
Memory:
Type: String
Resources:
TaskDefinition:
Type: AWS::ECS::TaskDefinition
Properties:
Family: !Ref Application
ExecutionRoleArn: arn:aws:iam::**:role/ecsTaskExecutionRole
NetworkMode: awsvpc
Cpu: !Ref Cpu
Memory: !Ref Memory
RequiresCompatibilities:
- FARGATE
ContainerDefinitions:
- Name: !Ref Application
Image: !Ref Image
Cpu: !Ref Cpu
Memory: !Ref Memory
PortMappings:
- HostPort: 8080
ContainerPort: 8080
Essential: true
SecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Security group
SecurityGroupIngress:
- CidrIp: 0.0.0.0/0
IpProtocol: -1
ServiceDiscoveryService:
Type: AWS::ServiceDiscovery::Service
Properties:
Name: !Ref Application
DnsConfig:
DnsRecords:
- Type: A
TTL: 300
NamespaceId: !Ref Namespace
HealthCheckCustomConfig:
FailureThreshold: 1
ECSService:
Type: AWS::ECS::Service
Properties:
Cluster: !Ref Cluster
ServiceName: !Ref Application
TaskDefinition: !Ref TaskDefinition
DesiredCount: 1
CapacityProviderStrategy:
- Base: 0
CapacityProvider: FARGATE_SPOT
Weight: 1
NetworkConfiguration:
AwsvpcConfiguration:
AssignPublicIp: ENABLED
SecurityGroups:
- !GetAtt SecurityGroup.GroupId
Subnets:
- **
- **
- **
ServiceRegistries:
- RegistryArn: !GetAtt ServiceDiscoveryService.Arn
如果我不使用负载均衡器,我不确定我是否完全能够 运行 Fargate 上的容器与 80 不同的端口。因为我读到 SRV 记录不能被 curl 和 httpie 解释。我绝对希望能够用它来调用我的 api。由于我没有负载均衡器,我无法配置动态主机映射,因为 Fargate 无法做到这一点。
If you are using the Fargate launch type, the awsvpc network mode is required.
With the host and awsvpc network modes, exposed container ports are mapped directly to the corresponding host port (for the host network mode) or the attached elastic network interface port (for the awsvpc network mode), so you cannot take advantage of dynamic host port mappings.
通过上面的部署,我能够将所有内容部署到 AWS,任务 运行ning 成功。它有一个 public ip,我可以使用
从我的笔记本电脑成功查询它
http PUBLIC_IP/stocks/MMM
我现在已经注册了一个新域,假设 test-1234.com
并注册了我创建的主机区域的名称服务器。
对 my-service.test-1234.com
使用 dig
会导致 运行ning 任务的私有 ip。
我假设这是成功注册任务的预期答案,但我不确定。
用
查询
http my-service.test-1234.com/stocks/MMM
失败 Failed to establish a new connection
有谁知道如何让它工作吗?
总结评论:
目前不可能使用 Fargate 做到这一点。
更多详情 here.
尽管如此,还有两个其他选项可行:
- 在 EC2 而不是 Fargate 上部署容器,因为您使用的网络模式不同于
awsvpc
并且可以配置端口映射。
- 通过 AWS App Runner 部署容器,您也可以在不需要服务时暂停服务,这也是一个低预算的选择,您不需要处理任何事情,除了创建 App Runner 服务。缺点是目前只能通过 CLI 或 UI 创建 App Runner 服务,但还不能通过 CloudFormation。
我有一个小应用程序,我想以尽可能低的成本部署到 AWS,这样仍然可以在 public 互联网上访问该应用程序,并在需要时进一步扩展。除此之外,我还想简化我的流程并使一切自动化。
这就是我选择以下设置的原因:
- AWS ECS
- AWS Fargate Spot
- AWS 服务发现
- 无负载均衡器
我暂时不想使用负载均衡器,因为一开始它的成本太高,尤其是当我不时想完全缩减应用程序时。
到目前为止有什么:
AWSTemplateFormatVersion: "2010-09-09"
Description: ECS deployment
Parameters:
Image:
Type: String
Application:
Type: String
Namespace:
Type: String
Cluster:
Type: String
Cpu:
Type: String
Memory:
Type: String
Resources:
TaskDefinition:
Type: AWS::ECS::TaskDefinition
Properties:
Family: !Ref Application
ExecutionRoleArn: arn:aws:iam::**:role/ecsTaskExecutionRole
NetworkMode: awsvpc
Cpu: !Ref Cpu
Memory: !Ref Memory
RequiresCompatibilities:
- FARGATE
ContainerDefinitions:
- Name: !Ref Application
Image: !Ref Image
Cpu: !Ref Cpu
Memory: !Ref Memory
PortMappings:
- HostPort: 8080
ContainerPort: 8080
Essential: true
SecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Security group
SecurityGroupIngress:
- CidrIp: 0.0.0.0/0
IpProtocol: -1
ServiceDiscoveryService:
Type: AWS::ServiceDiscovery::Service
Properties:
Name: !Ref Application
DnsConfig:
DnsRecords:
- Type: A
TTL: 300
NamespaceId: !Ref Namespace
HealthCheckCustomConfig:
FailureThreshold: 1
ECSService:
Type: AWS::ECS::Service
Properties:
Cluster: !Ref Cluster
ServiceName: !Ref Application
TaskDefinition: !Ref TaskDefinition
DesiredCount: 1
CapacityProviderStrategy:
- Base: 0
CapacityProvider: FARGATE_SPOT
Weight: 1
NetworkConfiguration:
AwsvpcConfiguration:
AssignPublicIp: ENABLED
SecurityGroups:
- !GetAtt SecurityGroup.GroupId
Subnets:
- **
- **
- **
ServiceRegistries:
- RegistryArn: !GetAtt ServiceDiscoveryService.Arn
如果我不使用负载均衡器,我不确定我是否完全能够 运行 Fargate 上的容器与 80 不同的端口。因为我读到 SRV 记录不能被 curl 和 httpie 解释。我绝对希望能够用它来调用我的 api。由于我没有负载均衡器,我无法配置动态主机映射,因为 Fargate 无法做到这一点。
If you are using the Fargate launch type, the awsvpc network mode is required. With the host and awsvpc network modes, exposed container ports are mapped directly to the corresponding host port (for the host network mode) or the attached elastic network interface port (for the awsvpc network mode), so you cannot take advantage of dynamic host port mappings.
通过上面的部署,我能够将所有内容部署到 AWS,任务 运行ning 成功。它有一个 public ip,我可以使用
从我的笔记本电脑成功查询它http PUBLIC_IP/stocks/MMM
我现在已经注册了一个新域,假设 test-1234.com
并注册了我创建的主机区域的名称服务器。
对 my-service.test-1234.com
使用 dig
会导致 运行ning 任务的私有 ip。
我假设这是成功注册任务的预期答案,但我不确定。
用
查询http my-service.test-1234.com/stocks/MMM
失败 Failed to establish a new connection
有谁知道如何让它工作吗?
总结评论:
目前不可能使用 Fargate 做到这一点。 更多详情 here.
尽管如此,还有两个其他选项可行:
- 在 EC2 而不是 Fargate 上部署容器,因为您使用的网络模式不同于
awsvpc
并且可以配置端口映射。 - 通过 AWS App Runner 部署容器,您也可以在不需要服务时暂停服务,这也是一个低预算的选择,您不需要处理任何事情,除了创建 App Runner 服务。缺点是目前只能通过 CLI 或 UI 创建 App Runner 服务,但还不能通过 CloudFormation。