AWS ECS启用ServiceConnect后服务无法启动任务求助
问题描述
后端任务原本以单任务模式运行,切换为ECS服务并启用ServiceConnect后,服务部署失败,事件标签页提示:
service (...) was unable to place a task because no container instance met all of its requirements.
The closest matching container-instance (...) is missing an attribute required by your task.
For more information, see the Troubleshooting section of the Amazon ECS Developer Guide.
使用ecs-cli check-attributes --task-def some-task-definition --container-instances ... --cluster some-cluster检查容器实例属性,结果显示无缺失:
Container Instance Missing Attributes heyvie-backend-dev None
相关配置信息如下:
任务定义
{ "family": "some-task-definition", "taskRoleArn": "arn:aws:iam::...:role/ecsTaskExecutionRole", "executionRoleArn": "arn:aws:iam::...:role/ecsTaskExecutionRole", "networkMode": "awsvpc", "cpu": "1024", "memory": "982", "containerDefinitions": [ { "name": "...", "image": "...", "essential": true, "healthCheck": { "command": ["..."], "startPeriod": 20, "retries": 3 }, "portMappings": [ { "name": "somePortName", "containerPort": 4321 } ], "mountPoints": [ { "sourceVolume": "...", "containerPath": "..." } ], "logConfiguration": { "logDriver": "awslogs", "options": { "awslogs-group": "...", "awslogs-region": "eu-...", "awslogs-stream-prefix": "..." } } } ], "volumes": [ { "name": "...", "efsVolumeConfiguration": { "fileSystemId": "...", "rootDirectory": "/", "transitEncryption": "ENABLED" } } ], "requiresCompatibilities": ["EC2"] }
服务定义
{ "cluster": "some-cluster", "serviceName": "...", "taskDefinition": "some-task-definition", "desiredCount": 1, "launchType": "EC2", "deploymentConfiguration": { "maximumPercent": 100, "minimumHealthyPercent": 0 }, "placementConstraints": [ { "type": "distinctInstance" } ], "networkConfiguration": { "awsvpcConfiguration": { "subnets": [ ... ], "securityGroups": ["..."], "assignPublicIp": "DISABLED" } }, "serviceConnectConfiguration": { "enabled": true, "namespace": "someNamespace", "services": [ { "portName": "somePortName", "clientAliases": [ { "port": 4321 } ] } ] }, "schedulingStrategy": "REPLICA", "enableECSManagedTags": true, "propagateTags": "SERVICE" }
启动模板用户数据
#!/bin/bash cat <<<'EOF' >> /etc/ecs/ecs.config ECS_ENABLE_TASK_IAM_ROLE=true ECS_CLUSTER=some-cluster EOF
排查方向与解决方案
1. 检查ECS代理版本是否达标
ServiceConnect要求ECS Agent版本至少为1.59.0,旧版本代理不支持该功能,会导致容器实例无法被调度:
- 登录容器实例,执行以下命令查看当前代理版本:
docker inspect amazon/amazon-ecs-agent | grep "Version" - 若版本过低,升级ECS Agent:
sudo stop ecs sudo docker pull amazon/amazon-ecs-agent:latest sudo start ecs - 重启后,验证容器实例是否注册了
ecs.capability.service-connect属性:
确认返回结果中包含aws ecs describe-container-instances --cluster some-cluster --container-instances <实例ID> --query 'containerInstances[0].attributes'{"name": "ecs.capability.service-connect", "value": "true"}
2. 验证任务执行角色权限
ServiceConnect需要ECS任务执行角色具备Cloud Map相关权限,需确保角色包含以下策略:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "servicediscovery:RegisterInstance", "servicediscovery:DeregisterInstance", "servicediscovery:GetInstance", "servicediscovery:GetInstancesHealthStatus" ], "Resource": "arn:aws:servicediscovery:<区域>:<账户ID>:service/<命名空间ID>/<服务ID>" }, { "Effect": "Allow", "Action": "servicediscovery:DiscoverInstances", "Resource": "*" } ] }
- 若权限不足,更新任务执行角色的IAM策略,覆盖ServiceConnect所需的Cloud Map操作
3. 检查Cloud Map命名空间配置
- 确认ServiceConnect指定的
namespace已存在,且与ECS集群处于同一AWS区域 - 命名空间类型需为DNS_PRIVATE或DNS_PUBLIC,且VPC配置与任务的awsvpc子网匹配
- 验证命名空间的权限,确保ECS服务有权限访问该命名空间
4. 检查容器实例网络配置
- 容器实例所在的安全组需允许与Cloud Map服务(53端口/UDP/TCP)的通信,以及ServiceConnect代理的内部通信
- 任务的awsvpc子网需具备访问Cloud Map的网络路径,若使用私有子网,需配置NAT网关或Cloud Map VPC端点
5. 手动验证容器实例属性
ecs-cli的check-attributes命令仅检查任务定义中requiresAttributes指定的属性,ServiceConnect的属性要求属于服务层面,需手动验证:
aws ecs describe-container-instances --cluster some-cluster --container-instances <实例ID>
确认存在ecs.capability.service-connect和ecs.capability.service-connect.namespace属性(若使用自定义命名空间)
内容的提问来源于stack exchange,提问作者Erik Bent

