将最小服务部署到 ECS Fargate,无需通过 public 互联网访问负载均衡器

Deploy minimal service to ECS Fargate without load balancer accessible via public internet

我有一个小应用程序,我想以尽可能低的成本部署到 AWS,这样仍然可以在 public 互联网上访问该应用程序,并在需要时进一步扩展。除此之外,我还想简化我的流程并使一切自动化。

这就是我选择以下设置的原因:

我暂时不想使用负载均衡器,因为一开始它的成本太高,尤其是当我不时想完全缩减应用程序时。

到目前为止有什么:

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 无法做到这一点。

https://docs.aws.amazon.com/de_de/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-taskdefinition.html

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.

尽管如此,还有两个其他选项可行:

  1. 在 EC2 而不是 Fargate 上部署容器,因为您使用的网络模式不同于 awsvpc 并且可以配置端口映射。
  2. 通过 AWS App Runner 部署容器,您也可以在不需要服务时暂停服务,这也是一个低预算的选择,您不需要处理任何事情,除了创建 App Runner 服务。缺点是目前只能通过 CLI 或 UI 创建 App Runner 服务,但还不能通过 CloudFormation。