跳到正文

AWS ECS on Fargate 架构图:服务、任务与负载均衡

画出并讲解 ECS 加 Fargate 上的生产 Web 服务:任务网络、ALB、IAM 角色、密钥、自动扩缩容、Fargate Spot 与部署。

· 创始人兼开发者

发布于

跨两个 Availability Zone 的 VPC。用户访问公有子网之间的 Application Load Balancer,它转发到每个私有子网中的一个 Fargate 任务。任务查询 Multi-AZ 的 RDS,并通过 VPC 终端节点访问 ECR、Secrets Manager 和 CloudWatch Logs。

你推送了镜像,创建了服务,但第一批任务始终无法进入 RUNNING。它们带着 ResourceInitializationError 停止:unable to pull secrets or registry auth。镜像没有问题。任务位于私有子网中,没有通往 Amazon ECR 或 Secrets Manager 的路由,所以 Fargate 无法启动它们。

许多 ECS on Fargate 的问题都是这样:容器本身能跑,但它周围的网络、角色或负载均衡器设置不对。本文介绍 Amazon ECS 加 AWS Fargate 上的一个生产 Web 服务,从网络和负载均衡到 IAM、扩缩容、部署以及 ECS 与 EKS 的比较,并附带一张可以直接复制的图。

一张表看懂 ECS 概念

概念 含义 示例中
集群(Cluster) 服务和任务的逻辑分组 prod
任务定义(Task definition) 带版本的蓝图:镜像、CPU、内存、端口、角色、密钥、日志 orders-api:42
任务(Task) 任务定义的一个运行副本;在 Fargate 上拥有独立的内核、内存和网络接口 2 到 10 个副本
服务(Service) 保持期望的任务数,把任务注册到负载均衡器,执行部署 orders-api
容量提供程序(Capacity provider) 任务运行的位置:FARGATE、FARGATE_SPOT、EC2 Auto Scaling 组或 ECS Managed Instances FARGATE 和 FARGATE_SPOT

集群不是网络边界:任务运行在你指定的子网中,并处于各自安全组的保护之下。ECS 不收取编排费用;Fargate 按秒计费每个任务的 vCPU、内存和存储,最少计费一分钟。

网络:每个任务一个 ENI

Fargate 任务始终使用 awsvpc 网络模式:每个任务都有自己的弹性网络接口(ENI)、来自其子网的私有 IP 和自己的安全组(Fargate 任务网络)。这带来三个后果:

  • 子网需要空间。 每个任务占用一个 IP,AWS 在每个子网中保留五个。两个 AZ 中的六十个任务意味着每个子网 30 个,而 200% 的滚动部署会短暂需要 60 个。/24(251 个可用)够用;/27(27 个可用)不够。
  • 安全组按任务生效。 只向负载均衡器的组开放容器端口,只向任务的组开放数据库的 5432 端口。
  • 任务需要一条通往 AWS API 的路径。 在你的代码运行之前,Fargate 会通过任务的 ENI 拉取镜像、获取密钥并开始发送日志。

在私有子网中,这条路径是 NAT 网关或 VPC 终端节点(US East 价格,撰写时为 2026 年 11 月):

路径 需要创建 成本 取舍
NAT 网关 每个 AZ 一个,或一个区域级 NAT 网关 每个 AZ 每小时 $0.045,外加每 GB $0.045 也能访问第三方 API
VPC 终端节点 接口终端节点 ecr.api、ecr.dkr、logs、secretsmanager,外加 S3 网关终端节点 每个终端节点每个 AZ 每小时 $0.01,外加每 GB $0.01;S3 网关免费 完全没有通往互联网的路径

不要漏掉 S3 网关终端节点:ECR 把镜像层存放在 S3 中(ECR 接口终端节点)。两个 AZ 中的四个接口终端节点,在计入数据费用之前每月约 $58(8 × $0.01 × 730 小时),接近两个 $66 的 NAT 网关。所以在数据费用和隐私方面终端节点胜出,在访问范围方面 NAT 胜出。自 2025 年 11 月起,区域级 NAT 网关可自行跨 AZ,并且不需要公有子网。给任务分配公有 IP 也可行,但每个任务离互联网只差一条安全组规则。AWS VPC 图介绍了路由和 NAT 的放置。

负载均衡器:目标组与健康检查

ALB 需要至少两个 AZ 中的子网,每个子网为 /27 或更大,并有八个空闲地址。由于 awsvpc 任务是 ENI 而不是 EC2 实例,目标组的类型必须是 ip。每个服务使用一个目标组;任务由 ECS 注册和注销。

设置 默认值 建议考虑
健康检查间隔 30 秒 如果服务在 10 秒内启动,用 5 秒(AWS 的建议)
不健康阈值 2 次检查 出错的任务大约一分钟后被摘除
健康阈值 5 次检查 新目标只需通过一次检查
注销延迟(deregistration delay) 300 秒 短请求用 30 秒或更少;旧任务最多会排空这么久
healthCheckGracePeriodSeconds 0 要覆盖启动时间,否则启动慢的任务会被循环替换

自 2025 年 11 月起,ECS Express Mode 可以根据容器镜像创建这套 ALB、HTTPS 和扩缩容配置。负载均衡器图概括地介绍了健康检查和排空。

IAM:执行角色与任务角色

两个角色,两项工作:

  • 任务执行角色由 ECS 和 Fargate 代理使用,而不是你的代码:它拉取镜像、写入日志,并读取任务定义中指定的密钥(任务执行角色)。AmazonECSTaskExecutionRolePolicy 涵盖 ECR 和日志;secretsmanager:GetSecretValue 需要你自己添加,客户管理的密钥还要加上 kms:Decrypt。
  • 任务角色是你的代码通过 AWS SDK 使用的角色,比如访问 S3 或 SQS,ECS Exec 也需要它。

密钥以环境变量的形式传入:

"secrets": [{
  "name": "DB_PASSWORD",
  "valueFrom": "arn:aws:secretsmanager:us-east-1:111122223333:secret:prod/orders/db-AbCdEf:password::"
}]

ECS 在容器启动时读取该值。轮换后的密钥不会到达正在运行的任务,所以轮换后要重新部署,或者让应用用任务角色自己读取密钥。像上面这样只选一个 JSON 键,需要平台版本 1.4.0,也就是当前的 LATEST。

扩缩容:目标跟踪与 Fargate Spot

对于 Service Auto Scaling,先从 ECSServiceAverageCPUUtilization、ECSServiceAverageMemoryUtilization 或 ALBRequestCountPerTarget 的目标跟踪开始。它扩容快、缩容慢,并在部署期间暂停缩容;有多个策略时,只有全部同意才会缩容。每个 AZ 至少保留一个任务。

Fargate Spot 最多便宜 70%。当 AWS 回收容量时,任务会收到两分钟的警告,形式是停止代码为 SpotInterruption 的 EventBridge 事件和 SIGTERM(Fargate 容量提供程序)。stopTimeout 最大为 120 秒,而且 Fargate 绝不会自行回退到常规容量,所以要保留一个 base:

"capacityProviderStrategy": [
  { "capacityProvider": "FARGATE", "base": 2, "weight": 1 },
  { "capacityProvider": "FARGATE_SPOT", "weight": 1 }
]

前两个任务始终运行在常规 Fargate 上;其余的按一比一分配。Spot 上只有一个任务的服务,会直接停止,直到容量恢复。

部署:滚动、蓝绿、线性与金丝雀

滚动是默认方式:minimumHealthyPercent 为 100、maximumPercent 为 200 时,ECS 会先启动新任务再停止旧任务。请开启带回滚的 deployment circuit breaker;默认情况下,一旦失败的任务达到期望数量的一半(至少 3 个,至多 200 个),它就会判定部署失败。CloudWatch 告警也可以触发同样的回滚。

自 2025 年 7 月起,ECS 无需 CodeDeploy 就能自己执行蓝绿部署,自 2025 年 10 月起还支持线性和金丝雀。它们把新版本启动在第二个目标组之后,切换监听器流量,并把旧任务保留一段 bake time,所以回滚只是一次流量切换。

策略 流量切换 回滚 额外容量
滚动 任务分批替换 重新部署 最多到 maximumPercent
蓝绿 在可选的测试流量之后一次性切换 切回 2 倍
线性 等量分步,例如每隔几分钟 10% 切回 2 倍
金丝雀 先切一小部分,再切其余 切回 2 倍

Lambda 或暂停钩子可以为每个阶段设置关卡。蓝绿部署不支持对 ALBRequestCountPerTarget 的目标跟踪。部署策略图比较了这些模式。

可观测性

awslogs 驱动需要 awslogs-group、awslogs-region,在 Fargate 上还需要 awslogs-stream-prefix。自 2025 年 6 月 25 日起,它默认使用带 10 MB 缓冲区的 non-blocking 模式:CloudWatch 出现故障不会再卡住你的应用,但缓冲区满了会丢日志行。再加上启用增强可观测性的 Container Insights、用于进入 shell 的 ECS Exec,以及针对任务状态变化的 EventBridge 规则;停止原因(stopped reason)会告诉你任务为什么终止。要采集链路追踪,可在任务中以边车方式运行 OpenTelemetry Collector;它是用 OpenTelemetry 处理日志、指标和链路追踪这条管道中的代理层。

ECS 与 EKS

Amazon ECS Amazon EKS
控制平面 免费 每个集群每小时 $0.10,每月约 $73
API AWS 任务定义和服务 Kubernetes、Helm、Operator
计算 Fargate、EC2、ECS Managed Instances Fargate、EC2 节点组、EKS Auto Mode
升级 控制平面无需升级 每个 Kubernetes 版本提供 14 个月标准支持,之后每个集群每小时 $0.60
内置部署 滚动、蓝绿、线性、金丝雀 滚动;其他通过 Argo Rollouts 等工具

价格来自撰写时(2026 年 11 月)的 EKS 定价页面。需要 Kubernetes 的可移植性或生态时选择 EKS;Kubernetes 架构图展示了那种情形。对于短时、事件驱动的工作,基于 Lambda 的无服务器设计完全不需要常驻运行的服务。

ECS on Fargate 图

跨两个 Availability Zone 的 VPC。用户访问公有子网之间的 Application Load Balancer,它转发到每个私有子网中的一个 Fargate 任务。任务查询 Multi-AZ 的 RDS,并通过 VPC 终端节点访问 ECR、Secrets Manager 和 CloudWatch Logs。

22 个组件 · 10 个连接

在 Archboard 中打开
图表内容
  • VPC
  • Public subnet · AZ a
  • Public subnet · AZ b
  • Private subnet · AZ a
  • Private subnet · AZ b
  • Application Load Balancer
  • orders-api task
  • RDS for PostgreSQL
  • VPC endpoints
  • Users
  • Amazon ECR
  • Secrets Manager
  • CloudWatch Logs
  • HTTPS 443
  • HTTP 8080
  • SQL 5432
  • image pull
  • secrets at start
  • awslogs
跨两个 Availability Zone 的 Fargate 上的单个 ECS 服务。公有子网中的 ALB 转发到私有子网中的任务 IP,任务通过 VPC 终端节点而不是互联网访问 ECR、Secrets Manager 和 CloudWatch Logs。

这张图的读法如下:

  • AZ 是行。 每个 AZ 有一个公有子网和一个私有子网。ALB、RDS 和终端节点位于行与行之间,因为它们都跨两个 AZ:每个公有子网中各有一个 ALB 节点,数据库有一个 Multi-AZ 备用实例。
  • 蓝色实线是请求路径:到 ALB 的 HTTPS,到每个 AZ 一个任务的 HTTP 8080,以及 5432 端口上的 SQL。
  • 紫色虚线是平台流量:镜像拉取、密钥和日志,由 Fargate 使用任务执行角色,通过 VPC 终端节点发送。
  • 只有公有子网会把 0.0.0.0/0 路由到互联网网关。
  • Markdown 块列出了服务设置。

把 ECS 图画清楚

  • 把任务放进每个 AZ 的子网里。 一个包住一切的“ECS 集群”方框,会隐藏任务运行的位置以及它们能访问什么。
  • 每个 AZ 画一个任务,并在旁边标出扩缩容范围。
  • 画出通往 ECR、Secrets Manager 和 CloudWatch Logs 的路径。 缺少这条路径是任务无法启动的常见原因。
  • 在 ALB 的连线上标注端口和目标类型,并在图例中说明虚线背后使用的角色。
  • 省略边车、CI/CD 和 DNS 记录,除非图本身就是讲它们的。

AWS 三层架构模板用 EC2 实现了同样的 VPC 布局。

在 Archboard 中构建

  1. 用 Google 或 GitHub 登录并创建一个图表。
  2. 从网络包添加一个 VPC,并在其中放入四个子网节点,每个 AZ 一个公有、一个私有。
  3. 从云包在公有子网之间添加一个云负载均衡器,并在公有子网中添加文本备注,用于路由和 ALB 节点。
  4. 从云包在每个私有子网中添加一个计算实例节点,并在实例类型字段中填写任务规格。
  5. 在私有子网之间添加开启高可用的托管数据库,以及用于 VPC 终端节点的云资源,两者都来自云包。
  6. 在 VPC 之外,从网络包添加互联网,从 Docker 包添加镜像仓库,从安全包添加密钥保管库,从 DevOps 包添加日志。
  7. 画出带标签的连线,平台流量用虚线,并从基础包添加一个写有设置的 Markdown 块。

CloudFormation 转图表和 Terraform 转图表工具可以把现有的 stack 代码变成初稿;从 Terraform 画出服务时,先精简初稿,再手动补上请求路径。

这个示例共用 15 个图表节点,在 Free 套餐的限制之内。

常见问题

Fargate 必须使用 awsvpc 网络模式吗? 是的。每个 Fargate 任务都有自己的网络接口和私有 IP 地址,所以它的目标组必须使用 ip 目标类型。

ECS 任务角色和任务执行角色有什么区别? 执行角色让 ECS 启动任务:拉取镜像、获取密钥、发送日志。任务角色是你的应用代码用于自己的 AWS 调用的角色。

私有子网中的 Fargate 任务需要 NAT 网关吗? 访问 AWS 服务时不需要。ECR、CloudWatch Logs 和 Secrets Manager 的接口终端节点,加上 S3 网关终端节点就够了。只有要访问互联网时才需要 NAT。

ECS 支持不用 CodeDeploy 的蓝绿部署吗? 支持。ECS 自 2025 年 7 月起原生支持蓝绿,自 2025 年 10 月起原生支持线性和金丝雀,并带有 bake time、生命周期钩子和基于告警的回滚。

ECS 比 EKS 便宜吗? 就控制平面而言是的:ECS 没有编排费用,而标准支持下的 EKS 集群每小时 $0.10。Fargate 和 EC2 实例的价格在两者下是一样的。

免费开始 — 1 个席位,无需信用卡。

相关文章

← 返回博客

一分钟打开画布

使用 Google 或 GitHub 登录。单席位免费,团队加入后再升级。