Amazon ECS 容器编排 - 任务定义与服务设计
从任务定义设计到服务部署策略、Fargate 与 EC2 的选择、Auto Scaling 配置模式的系统介绍。
任务定义与集群设计
ECS 的任务定义是以 JSON 描述容器执行规范的模板。一个任务定义可包含多个容器,通过 Sidecar 模式在同一任务内放置日志收集或代理容器。启动类型有 EC2 和 Fargate 两种,EC2 启动类型需要管理实例但可使用 GPU 和自定义 AMI。Fargate 启动类型无需管理基础设施,按任务的 vCPU 和内存计费。任务定义的修订管理使回滚到旧版本变得容易。任务定义可通过 ephemeralStorage (最大 200 GiB) 扩展临时存储,适用于生成大量中间数据的批处理作业。此外,将任务角色 (taskRoleArn) 与任务执行角色 (executionRoleArn) 分离,可按最小权限原则分别管理容器使用的 AWS API 权限和镜像拉取/日志输出所需的权限。
服务与部署策略
ECS 服务维持任务的期望数量,自动重启异常终止的任务。与 ALB 目标组集成后,自动排空健康检查失败的任务并替换为新任务。滚动更新通过设置 minimumHealthyPercent 和 maximumPercent 分阶段替换任务。例如设置 minimumHealthyPercent=50、maximumPercent=200 时,保持现有任务的一半运行同时启动新任务,新任务通过健康检查后停止旧任务。CodeDeploy 集成的蓝绿部署创建新版本的任务集并逐步切换流量,实现零停机部署。在生产环境中,建议使用 CodeDeploy 的钩子 (BeforeAllowTraffic / AfterAllowTraffic) 插入自动测试,测试失败时在 5 分钟内自动回滚到旧版本。使用 ECS Service Connect 可在 ECS 原生完成服务间的服务发现和负载均衡,无需单独配置 App Mesh 或 Cloud Map。
Fargate 与 EC2 的选择
Fargate 是无服务器计算引擎,无需管理 EC2 实例。按任务指定 vCPU 和内存,仅按运行时间计费。EC2 启动类型适用于需要选择实例、使用 GPU 或自定义 AMI 的场景。Fargate Spot 面向批处理或容错工作负载,比普通 Fargate 最多便宜 70%。通过 ECS Exec 可启动任务容器内的交互式 shell 进行调试和故障排除。Fargate 自 2024 年起支持每个任务最高 16 vCPU / 120 GB 内存,可满足大多数 Web 应用和数据处理工作负载的需求。EC2 启动类型建议仅在需要特殊硬件的场景下选择,例如在 p5 实例上使用 NVIDIA H100 GPU 进行 ML 推理,或在 inf2 实例上使用 AWS Inferentia2。 如需系统学习容器编排,可参考技术书籍 (Amazon)。
ECS 成本优化
Fargate 按 vCPU (每小时约 0.04048 美元) 和内存 (每 GB 小时约 0.004445 美元) 计费。Compute Savings Plans 可享受最高 50% 折扣。EC2 启动类型可利用 Spot 实例,通过任务放置策略 (binpack) 最大化实例利用率。根据 Container Insights 指标优化任务定义的 CPU 和内存,避免过度分配。配置服务 Auto Scaling 的目标追踪策略,根据 CPU 利用率自动调整任务数量。一个容易忽略的成本因素是 CloudWatch Logs 的数据摄取费用。如果容器产生大量日志,可通过 awslogs 驱动控制日志级别,或使用 FireLens (Fluent Bit) 过滤不必要的日志后再发送到 CloudWatch,可能每月节省数十美元。
设计最佳实践与常见陷阱
在任务定义中配置 healthCheck 时,如果 startPeriod (宽限期) 设置不足,启动较慢的应用会在启动后立即因健康检查失败而进入重启循环。对于需要 JIT 预热的语言 (如 Java 或 .NET),将 startPeriod 设为 60-120 秒是实用的做法。任务间通信推荐使用 awsvpc 网络模式,因为每个任务分配独立的 ENI,可通过安全组实现任务级别的访问控制。但需注意 ENI 密度限制 (每种实例类型的 ENI 上限),小型实例无法部署大量任务。密钥管理方面,应在任务定义的 secrets 字段中直接引用 Secrets Manager 或 SSM Parameter Store 的值,避免在环境变量中硬编码。此外,在生产环境中草率启用 execute-command 会允许通过 SSM 会话执行任意命令,务必通过 IAM 策略严格限制使用者。
ECS 与 EKS 的选择
ECS 是 AWS 原生的编排器,EKS 是托管的 Kubernetes 版本。如果团队没有 Kubernetes 运维经验,且重视与 AWS 服务的紧密集成 (无需 ALB Controller 的原生 ALB 集成、CloudFormation/SAM 原生定义),ECS 更合适。反之,如果需要多云或本地的可移植性,或希望利用以 Helm Charts 发布的 OSS 工具生态 (Argo CD、Istio、Prometheus Operator 等),EKS 更有优势。从运维负担角度看,ECS + Fargate 的控制平面和数据平面都由 AWS 管理,YAML 学习成本低,适合小团队。EKS 虽然控制平面是托管的,但仍需处理节点组升级、插件版本管理、RBAC 设计和 NetworkPolicy 管理等 Kubernetes 特有的运维工作。成本方面,EKS 的控制平面有每小时 0.10 美元 (约每月 74 美元) 的集群费用,而 ECS 没有这项固定成本。建议根据工作负载特性和团队技能组合进行选择。
总结
ECS 通过任务定义提供声明式容器管理,通过服务提供自动恢复和扩缩。使用 Fargate 无服务器运行容器,Fargate Spot 实现最高 70% 成本削减。通过滚动更新和蓝绿部署实现零停机发布,Container Insights 可视化性能。理解 healthCheck 的 startPeriod 和 ENI 密度限制等实际运维陷阱,并使用 ECS Service Connect 简化服务间通信,是实现稳定生产运维的关键。