1. AWS容器平台全景与交付链路
在 AWS 上交付一个容器化应用,从来不是“把镜像推到仓库、再跑一条部署命令”这么简单。真正决定交付是否稳定、可观测、可回滚的,是背后一整套组件的协作:容器运行时负责把镜像变成进程,编排服务负责把进程调度到合适的位置,镜像仓库负责分发不可变的制品,网络组件负责让流量找到正确的 Pod,安全组件则贯穿从拉取镜像到访问后端服务的每一个环节。理解这条链路上每个角色的职责与接口,是后续所有实操章节的基础。
一、四类核心组件及其职责边界
可以把 AWS 容器平台拆成四个层次来理解。
容器运行时层:这是最贴近操作系统的一层。在 EC2 上,Docker 或 containerd 负责拉取镜像、解压层、创建命名空间与 cgroup 隔离,最终启动容器进程。在 AWS Fargate 上,运行时被托管,用户看不到节点,但仍遵循同样的镜像与进程模型。运行时的关键输入是镜像引用(如 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/order-api:v1.4.2)和启动参数(环境变量、端口、CPU/内存限制),输出是一个正在运行的容器进程。
编排服务层:Amazon ECS 和 Amazon EKS 是两种主流选择。ECS 使用 Task Definition 描述“一个任务需要哪些容器、多少 CPU/内存、暴露哪些端口”,再由 Service 维持期望副本数;EKS 则基于 Kubernetes 的 Deployment、Service、Ingress 等对象,由控制平面完成调度与自愈。编排层解决的是“在哪里跑、跑几个、挂了怎么办”的问题,它不关心镜像内部是什么,只关心声明的期望状态是否被满足。
镜像仓库层:Amazon ECR 承担镜像的存储与分发。它提供私有仓库、镜像扫描、跨区域复制和生命周期策略。交付链路上,CI 流水线构建镜像后推送到 ECR,运行时再从 ECR 拉取。ECR 的镜像标签应当与 Git 提交或构建号绑定,避免使用 latest 这类可变标签,否则回滚时无法确定具体版本。
网络与安全层:网络方面,VPC、子网、安全组、ALB/NLB 以及 EKS 的 VPC CNI 共同决定 Pod 的 IP 分配和流量路径;安全方面,IAM 角色(Task Role / IRSA)、Secrets Manager、KMS、安全组规则和镜像扫描共同构成最小权限与数据保护的基础。这一层往往是最容易被忽视、却最容易在故障排查时暴露问题的部分。
二、交付链路上的数据流与依赖顺序
把上述组件串起来看,一次典型的交付会经历如下顺序。CI 系统在代码合并后构建镜像,打上形如 v1.4.2-20240612 的标签并推送到 ECR。随后更新 ECS Task Definition 或 EKS Deployment 中的镜像引用,触发一次新的部署。编排服务读取新的期望状态,向运行时下发拉取指令;运行时从 ECR 拉取镜像层,创建容器进程。容器启动后,VPC CNI 为其分配 IP,安全组决定哪些来源可以访问该端口,ALB 通过目标组健康检查确认实例可用后,才开始转发用户流量。整个过程里,IAM 角色在容器启动时被注入,Secrets Manager 中的数据库密码通过环境变量或挂载卷进入容器。
这条链路有一个重要特征:依赖是单向的,但故障排查是反向的。部署失败时,现象可能出现在最上层(用户访问 502),但根因可能在最下层(安全组未放行、镜像拉取失败、IAM 权限不足)。因此,理解每一层的输入输出,比记住某个命令更重要。
三、一个可复现的示例:部署 order-api 到 ECS Fargate
下面以一个订单服务为例,给出关键参数与观察点。示例中的账号、区域和镜像标签均为教学假设值。
# 1. 构建并推送镜像(CI 阶段)
docker build -t order-api:v1.4.2-20240612 .
docker tag order-api:v1.4.2-20240612 \
123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/order-api:v1.4.2-20240612
docker push 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/order-api:v1.4.2-20240612
# 2. Task Definition 关键字段(节选)
{
"family": "order-api",
"cpu": "512",
"memory": "1024",
"networkMode": "awsvpc",
"requiresCompatibilities": ["FARGATE"],
"containerDefinitions": [{
"name": "order-api",
"image": "123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/order-api:v1.4.2-20240612",
"portMappings": [{"containerPort": 8080, "protocol": "tcp"}],
"environment": [{"name": "APP_ENV", "value": "prod"}],
"secrets": [{"name": "DB_PASSWORD",
"valueFrom": "arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:order-api/db-xxxx"}]
}]
}
部署后,按以下顺序观察结果。第一,在 ECS 控制台查看 Service 的 desiredCount 与 runningCount 是否一致;若 runningCount 长期为 0,优先查看 Stopped Task 的 stoppedReason,常见原因是镜像拉取失败或 Secrets 权限不足。第二,查看目标组的健康检查状态,若为 unhealthy,检查容器端口是否与 containerPort 一致、安全组是否放行 ALB 所在子网的流量。第三,从 ALB DNS 名称发起一次请求,确认返回 200 且响应体包含预期字段。第四,在 CloudWatch Logs 中确认应用启动日志无异常。
四、常见误区与排查方向
初学者最容易踩的坑有三个。其一,使用 latest 标签,导致回滚时无法定位具体版本,也无法判断线上运行的是哪次构建。其二,把 IAM 权限直接给到节点角色而非 Task Role,造成权限过大且难以审计;在 EKS 中应优先使用 IRSA 将角色绑定到 ServiceAccount。其三,忽略安全组的“最小放行”原则,直接开放 0.0.0.0/0 到容器端口,使服务绕过 ALB 暴露在公网。
当出现访问异常时,建议按“运行时 → 编排 → 网络 → 安全”的顺序反向排查:先确认容器是否启动、日志是否正常,再确认编排层期望状态是否达成,然后检查安全组与目标组,最后核对 IAM 与 Secrets 权限。这条排查路径与交付链路的依赖方向相反,但正是它让每一层的职责边界变得清晰。