如何解决将环境变量传递给我的 Amazon ECS 任务时出现的问题?
我想解决将环境变量传递给我的 Amazon Elastic Container Service (Amazon ECS) 任务时出现的问题。
简短描述
当您在任务中传递环境变量或敏感数据时,根据您的配置,您可能会收到以下错误之一。
AWS Secrets Manager
“ResourceInitializationError 错误”或 Amazon Elastic Compute Cloud (Amazon EC2) 上的“AccessDenied 错误”
要解决这些错误,请参阅如何解决 Amazon ECS 中与 AWS Secrets Manager 密钥相关的问题?
Amazon Elastic Block Store (Amazon EBS) 卷或 Sidecar
“ECS 无法代入配置的 ECS 基础设施角色 'arn:aws:iam::111122223333:role/ecsInfrastructureRole'。请验证所传递的角色与 Amazon ECS 的信任关系是否正确”,或“ECS 在将 EBS 卷附加到您的任务时发生超时。”
要解决这些问题,请参阅 Amazon EBS 卷附加到 Amazon ECS 任务的状态原因。
Amazon Simple Storage Service (Amazon S3)
“ResourceInitializationError:无法下载 env 文件:文件下载命令:非空错误流”。
要解决此问题,请完成以下解决步骤。
Parameter Store,AWS Systems Manager 的一项功能
“从区域中的 SSM Parameter Store 中获取机密数据: AccessDeniedException: 用户 arn:aws:sts::123456789:assumed-role/ecsExecutionRole/f512996041234a63ac354214 未获得授权,无法对以下资源执行 ssm:GetParameters 操作:arn:aws:ssm:ap-south-1:12345678:parameter/状态代码: 400,请求 ID:e46b40ee-0a38-46da-aedd-05f23a41e861”。或者,“ResourceInitializationError:无法拉取密钥或注册表身份验证:执行资源检索失败:无法从 ssm 检索密钥:服务调用已重试 5 次: RequestCanceled”。
要解决这些问题,请完成以下解决步骤。
**注意:**最佳安全做法是将敏感数据存储在 Secrets Manager 密钥或 Parameter Store 参数中。
解决方法
**注意:**如果您在运行 AWS 命令行界面 (AWS CLI) 命令时收到错误,请参阅 AWS CLI 错误故障排除。此外,请确保您使用的是最新版本的 AWS CLI。
确定问题的原因
在与您的 Amazon ECS 集群资源所在的同一 AWS 区域使用 AWSSupport-TroubleshootECSTaskFailedToStart 运行手册。此外,请使用最近失败的任务的 ID。如果失败的任务是 Amazon ECS 服务的一部分,则使用服务中最近一次失败的任务。在自动化执行期间,失败任务必须在 ECS:DescribeTasks 中可见。默认情况下,已停止的 ECS 任务将在进入 Stopped(已停止)状态后的 1 小时内保持可见。
根据自动化的输出,使用以下任一手动故障排除步骤。
您的 Amazon ECS 任务执行角色没有所需的 IAM 权限
如果您在 Parameter Store 或 Secrets Manage 中使用环境变量,请查看 AWS CloudTrail 事件中是否存在以下 API 调用:
- GetParameters(适用于 Parameter Store)
- GetSecretValue(适用于 Secrets Manager)
如果您收到针对任务执行角色的 AccessDenied 错误,则必须手动将所需的权限作为内联策略添加到该角色。您还可以创建自定义托管策略,将其添加到您的 Amazon ECS 任务执行角色中。
如果您使用 S3 存储桶将环境变量存储为 .env 文件,请向任务执行角色添加访问 Amazon S3 所需的权限。
您的网络配置存在问题
如果您的任务位于私有子网中,请确认以下配置:
- 任务或服务的安全组允许端口 443 上的出站流量。
- 如果您使用 NAT 网关,则您的任务必须具有指向 NAT 网关的默认路由。
- 您的任务使用所需的虚拟私有云 (VPC) 端点来访问 Secrets Manager、Parameter Store 或 Amazon S3。
使用 telnet 命令验证与 Systems Manager、Secrets Manager 或 Amazon S3 端点的连接。
此外,请确认以下 VPC 端点配置:
- 您的 VPC 端点的安全组允许来自任务或服务的出站流量通过端口 443。
- 网络访问控制列表(网络 ACL)允许端口 443 上的出站流量。
- 您已将 VPC 端点与正确的 VPC 相关联。
- 您已激活 DNS 主机名和 DNS 解析 VPC 属性。
如果您的 Amazon ECS 任务位于公有子网中,请确认以下配置:
- 您已为该任务激活了公共 IP 地址。
- 您的 VPC 的安全组允许通过端口 443 对互联网进行出站访问。
- 网络 ACL 允许子网和互联网之间的所有入站流量和出站流量。
您的应用程序无法读取环境变量
要检查任务容器中是否填充了正确的环境变量,请使用 ECS Exec 列出容器中的所有环境变量。激活 ECS Exec,然后运行以下命令,以与您的容器进行交互:
aws ecs execute-command --cluster cluster-name \ --task task-id \ --container container-name \ --interactive \ --command "/bin/sh"
**注意:**请将 cluster-name 替换为您的集群名称,将 task-id 替换为您的任务 ID,将 container-name 替换为您的容器名称。
输出示例:
The Session Manager plugin was installed successfully. Use the AWS CLI to start a session. Starting session with SessionId: ecs-execute-command-hlei32fctyur2bn63rhe2uraaq sh-5.2#
然后,运行 env 命令以列出所有环境变量:
sh-5.2# env
输出示例:
sh-5.2# env AWS_EXECUTION_ENV=AWS_ECS_FARGATE AWS_DEFAULT_REGION=us-east-1 AWS_REGION=us-east-1 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin _=/usr/bin/env
如果您使用 Amazon EC2 启动类型,那么您也可以使用 Docker exec 命令与您的容器进行交互。要使用 Docker exec,请完成以下步骤:
-
运行以下 Docker 命令以查找容器 ID:
docker container ps -
要打开容器,请运行以下 Docker 命令:
docker exec -it example-container-id bash**注意:**请将 example-container-id 替换为您的容器 ID。此外,请根据您的容器的默认 Shell 选择相应的 Shell。
-
在容器上运行 env 命令以列出所有环境变量。
确保您在任务定义或 .env 文件中定义的环境变量位于变量列表中。
容器定义中的变量格式不正确
在容器定义中定义环境变量时,必须将环境变量定义为键值对对象:
"environment": [ { "name": "variable", "value": "value" } ]
在 .env 文件中定义环境变量时,也必须使用此格式。
任务不会自动刷新环境变量
任务不会在当前运行的容器内自动刷新您在 .env 文件或密钥中更新的环境变量。
要将更新后的环境变量添加到容器实例中,请运行以下 update-service 命令:
aws ecs update-service --cluster example-cluster --service example-service --force-new-deployment
**注意:**请将 example-cluster 替换为您的集群名称,将 example-service 替换为您的服务名称。
如果您在容器定义中使用环境变量,则必须创建新的任务定义来更新环境变量。然后,运行以下 update-service 命令,以使用新的任务定义来创建新任务或更新您的 Amazon ECS 服务:
aws ecs update-service --cluster example-cluster --service example-service --task-definition family:revision
**注意:**请将 example-cluster 替换为您的集群名称,将 example-service 替换为您的服务名称,将 family:revision 替换为您的新任务定义。
将环境变量传递给任务时,Amazon ECS 会使用以下配置:
- 容器定义中使用 environment 参数的环境变量优先于环境文件中的变量。
- 如果您指定多个环境文件,并且它们使用相同的变量,则这些文件按输入顺序进行处理。Amazon ECS 将采用变量的首个值,并忽略重复变量的后续值。最佳做法是使用唯一的变量名称。
- 如果您将环境文件指定为容器覆盖,则 Amazon ECS 将采用该文件并忽略容器定义中的其他环境文件。
- 来自 /proc/1/environ 文件的环境变量可供容器中的 PID 1 进程使用。如果容器运行了多个进程或 init 进程(例如包装器脚本或 supervisord),则环境变量对非 PID 1 进程不可用。
