为AWS Fargate附加taskRoleArn后无法调用AWS API求助
问题描述
我正尝试为AWS Fargate容器附加IAM角色,容器能正常启动运行,但无法调用AWS API。在容器内执行以下操作时出现异常:
- 运行
aws命令,返回Unable to locate credentials错误; - 执行
curl http://169.254.169.254/latest/meta-data/iam/info失败。
我的任务定义JSON如下:
{ "executionRoleArn": "arn:aws:iam::my-account-id:role/test-ecs-role", "containerDefinitions": [ { "dnsSearchDomains": null, "logConfiguration": { "logDriver": "awslogs", "options": { "awslogs-group": "Fargate", "awslogs-region": "us-west-2", "awslogs-stream-prefix": "my-app" } }, "entryPoint": null, "portMappings": [], "command": null, "linuxParameters": null, "cpu": 0, "environment": [], "ulimits": null, "dnsServers": null, "mountPoints": [], "workingDirectory": null, "dockerSecurityOptions": null, "memory": null, "memoryReservation": null, "volumesFrom": [], "image": "my-account-id.dkr.ecr.us-west-2.amazonaws.com/app/submit_data:3e87860f128a286d9b557c90664ad99c", "disableNetworking": null, "healthCheck": null, "essential": true, "links": null, "hostname": null, "extraHosts": null, "user": null, "readonlyRootFilesystem": null, "dockerLabels": null, "privileged": null, "name": "my-app" } ], "placementConstraints": [], "memory": "2048", "taskRoleArn": "arn:aws:iam::my-account-id:role/MasterFargate", "compatibilities": [ "EC2", "FARGATE" ], "taskDefinitionArn": "arn:aws:ecs:us-west-2:my-account-id:task-definition/my-app:10", "family": "my-app", "requiresAttributes": [ { "targetId": null, "targetType": null, "value": null, "name": "ecs.capability.execution-role-ecr-pull" }, { "targetId": null, "targetType": null, "value": null, "name": "com.amazonaws.ecs.capability.docker-remote-api.1.18" }, { "targetId": null, "targetType": null, "value": null, "name": "ecs.capability.task-eni" }, { "targetId": null, "targetType": null, "value": null, "name": "com.amazonaws.ecs.capability.ecr-auth" }, { "targetId": null, "targetType": null, "value": null, "name": "com.amazonaws.ecs.capability.task-iam-role" }, { "targetId": null, "targetType": null, "value": null, "name": "ecs.capability.execution-role-awslogs" }, { "targetId": null, "targetType": null, "value": null, "name": "com.amazonaws.ecs.capability.logging-driver.awslogs" }, { "targetId": null, "targetType": null, "value": null, "name": "com.amazonaws.ecs.capability.docker-remote-api.1.19" } ], "requiresCompatibilities": [ "FARGATE" ], "networkMode": "awsvpc", "cpu": "256", "revision": 10, "status": "ACTIVE", "volumes": [] }
解决方案
根据你的情况,我整理了几个实用的排查和解决步骤,你可以一步步验证:
1. 检查Task Role的信任关系配置
首先要确保MasterFargate角色的信任策略允许ECS任务扮演它。正确的信任策略应该包含以下内容:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "ecs-tasks.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
你可以在IAM控制台找到这个角色,进入「信任关系」标签页查看并修改。如果信任关系配置错误,Fargate任务根本无法获取角色的临时凭证。
2. 验证Task Role的权限范围
虽然容器能正常启动,但要确认MasterFargate角色拥有你需要调用的AWS API对应权限。比如如果要操作S3,角色需要有s3:GetObject这类具体权限,或者先临时附加AmazonS3FullAccess这类管理权限做测试(测试完成后记得改回最小权限原则),看看是否能正常调用API。
3. 检查awsvpc模式下的网络配置
你的任务用了awsvpc网络模式,每个任务会分配独立的ENI,这时候要确认:
- 任务所在的安全组允许出站访问
169.254.169.254(AWS元数据服务地址,Fargate必须通过它获取凭证)。默认安全组通常允许所有出站流量,但如果是自定义安全组,一定要确保没有拦截这个地址的访问。 - 如果任务部署在私有子网,子网的路由表必须指向NAT网关;如果是公有子网,要确保有指向互联网的路由,且ENI分配了公网IP(或通过NAT访问内部服务)。
4. 确认任务使用的是最新版本的任务定义
你的任务定义已经指定了taskRoleArn,但要确认实际启动的任务用的是这个revision 10的最新版本。有时候会不小心选择旧版本的任务定义,导致没有关联上正确的Task Role。
5. 尝试容器内的另一种凭证获取方式
如果上面的检查都没问题,可以在容器内尝试访问http://169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI——这是Fargate容器获取凭证的专用路径。先执行echo $AWS_CONTAINER_CREDENTIALS_RELATIVE_URI看看这个环境变量是否存在,如果存在,用curl访问完整地址,看是否能返回有效凭证信息。
6. 查看CloudWatch日志排查细节
通过CloudWatch的Fargate日志组查看容器的启动日志,里面可能会有关于IAM角色加载失败的具体错误提示,能帮你快速定位问题根源。
我之前遇到过类似的情况,大多是信任关系配置错误或者安全组拦截了元数据服务的访问,你可以先从这两个点入手排查。
内容的提问来源于stack exchange,提问作者akira

