3. ECS任务定义深度配置
任务定义(Task Definition)是 ECS 的“部署契约”,它把镜像、端口、环境变量、密钥、日志、资源与依赖关系一次性声明清楚。容器实例只是执行者,真正决定“跑什么、怎么跑、跑多大、依赖谁”的是任务定义。理解它,等于掌握了 ECS 应用交付的配置中枢。
容器镜像与启动命令
镜像通过 image 指定,建议使用带 tag 或 digest 的完整地址,例如 123456789012.dkr.ecr.cn-north-1.amazonaws.com.cn/order-api:1.4.2,避免 latest 导致版本漂移。可用 command 覆盖镜像 ENTRYPOINT 之后的参数,用 entryPoint 覆盖入口点。若镜像来自私有仓库,需在任务定义中声明 repositoryCredentials 或使用 Secrets Manager 注入凭据。
端口映射:host 与 awsvpc 的差异
端口映射由 portMappings 定义,包含 containerPort、hostPort、protocol。在 bridge 模式下,hostPort 为空表示动态映射;在 awsvpc 模式下,容器直接使用 ENI 的 IP,hostPort 通常等于 containerPort。若同一任务内多个容器共享端口,需保证不冲突。ALB 目标组注册的是任务 ENI 的 IP 与 containerPort,因此 awsvpc 模式下端口声明必须与监听规则一致。
环境变量与密钥注入
普通配置用 environment 键值对,例如 SPRING_PROFILES_ACTIVE=prod。敏感信息不要写进环境变量明文,应使用 secrets 引用 Secrets Manager 或 SSM Parameter Store,例如:
"secrets": [
{ "name": "DB_PASSWORD",
"valueFrom": "arn:aws:secretsmanager:cn-north-1:123456789012:secret:prod/db-abc123:password::" }
]
执行角色(taskRoleArn)决定容器内应用能调用哪些 AWS API;任务执行角色(executionRoleArn)决定 ECS 代理能否拉取镜像、写日志、读取密钥。两者职责不同,切勿混用。
日志驱动
常用 awslogs 驱动,需指定 awslogs-group、awslogs-region、awslogs-stream-prefix。流名称默认为 prefix/容器名/任务ID,便于在 CloudWatch Logs 中按任务检索。若使用 FireLens,可配置 fluentbit 或 fluentd 驱动,把日志转发到 OpenSearch、Kinesis Firehose 等目标。
资源限制与依赖编排
cpu 与 memory 是任务级硬限制,容器级可用 cpu、memory、memoryReservation 细分。Fargate 必须声明任务级 CPU/内存组合,如 0.5 vCPU + 1 GB。依赖关系通过 dependsOn 声明,condition 可取 START、COMPLETE、SUCCESS、HEALTHY。例如 sidecar 需在应用启动前就绪,可让应用容器依赖 sidecar 的 HEALTHY。
一个可参考的任务定义片段
下面示例展示 order-api 与 log-router 两个容器的关键字段,参数为教学示例,实际请按业务调整:
{
"family": "order-api",
"executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole",
"taskRoleArn": "arn:aws:iam::123456789012:role/orderApiTaskRole",
"networkMode": "awsvpc",
"requiresCompatibilities": ["FARGATE"],
"cpu": "1024",
"memory": "2048",
"containerDefinitions": [
{
"name": "order-api",
"image": "123456789012.dkr.ecr.cn-north-1.amazonaws.com.cn/order-api:1.4.2",
"portMappings": [{ "containerPort": 8080, "protocol": "tcp" }],
"environment": [{ "name": "SPRING_PROFILES_ACTIVE", "value": "prod" }],
"secrets": [{ "name": "DB_PASSWORD",
"valueFrom": "arn:aws:secretsmanager:cn-north-1:123456789012:secret:prod/db-abc123:password::" }],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/order-api",
"awslogs-region": "cn-north-1",
"awslogs-stream-prefix": "ecs"
}
},
"dependsOn": [{ "containerName": "log-router", "condition": "HEALTHY" }]
},
{
"name": "log-router",
"image": "public.ecr.aws/aws-observability/aws-for-fluent-bit:2.31.0",
"essential": true,
"logConfiguration": { "logDriver": "awslogs",
"options": { "awslogs-group": "/ecs/log-router",
"awslogs-region": "cn-north-1", "awslogs-stream-prefix": "ecs" } }
}
]
}
START;需等待初始化脚本结束用 COMPLETE;需确认退出码为 0 用 SUCCESS;需通过健康检查用 HEALTHY。生产环境优先使用 HEALTHY,避免应用在依赖未就绪时接收流量。把任务定义当作“可版本化的部署契约”来管理:每次变更生成新 revision,配合 CodeDeploy 蓝绿或滚动更新,回滚时只需指向旧 revision。这样镜像、端口、密钥、日志、资源与依赖关系全部可追溯,应用交付才真正可控。