如何在 Amazon ECS 中配置 IAM 任务角色以避免“访问被拒绝”错误?

上次更新时间:2019 年 7 月 16 日

当我的应用程序进行 AWS API 调用时,我收到“访问被拒绝”错误的消息。如何解决此错误?

简短描述

如果未正确配置 IAM 任务角色,则在应用程序进行 AWS API 调用时,您可能会收到“访问被拒绝”错误的消息。

要避免此错误,请在任务定义中为 Amazon Elastic Container Service (Amazon ECS) 提供 AWS Identity and Access Management (IAM) 任务角色。您的任务可以将此 IAM 角色用于 AWS API 调用。IAM 任务角色必须具有应用程序所需的所有权限。如果任务由于配置问题而无法找到 IAM 任务角色,则会转而使用 Amazon Elastic Compute Cloud (Amazon EC2) 实例角色。

解决方法

要为任务正确配置 IAM 角色,请检查以下内容:

确认 ECS 容器代理正在运行

要确认 ECS 容器代理程序正在运行,请运行以下命令:

docker ps

在 ECS 容器代理配置文件中启用 IAM 角色

1.    打开您的 /etc/ecs/ecs.config 文件。

2.    要为网桥默认网络模式的容器中的任务启用 IAM 角色,请将 ECS_ENABLE_TASK_IAM_ROLE 设置为 true。请参阅以下示例:

ECS_ENABLE_TASK_IAM_ROLE=true

3.    要为具有主机网络模式的容器中的任务启用 IAM 角色,请将 ECS_ENABLE_TASK_IAM_ROLE_NETWORK_HOST 设置为 true。请参阅以下示例:

ECS_ENABLE_TASK_IAM_ROLE_NETWORK_HOST=true

4.    要更新配置文件,请通过运行以下任一命令重新启动 AECS 容器代理:

对于 Amazon ECS 优化型 Amazon Linux AMI:

sudo stop ecs
sudo start ecs

对于 Amazon ECS 优化型 Amazon Linux 2 AMI:

sudo systemctl restart ecs

确认您的 IAM 策略与您的 Amazon ECS 任务具有正确的信任关系

要确认 IAM 角色具有正确的信任关系,请更新您的 IAM 策略,如下所示:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "ecs-tasks.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

验证 ECS 容器代理的代理设置

如果您在 Amazon ECS 容器代理配置中使用 HTTP_PROXY,请应用 NO_PROXY 设置,如下所示:

NO_PROXY=169.254.169.254,169.254.170.2,/var/run/docker.sock

确认您使用的是正确的 AWS 开发工具包

在容器中运行的应用程序必须使用不早于 2016 年 7 月版本的 AWS 开发工具包版本。

要更新 AWS 开发工具包,请参阅用于在 AWS 上进行构建的工具

满足非 Amazon ECS 优化型 AMI 的要求

如果您使用的是非 Amazon ECS 优化型 AMI,请为 iptables 设置必要规则

注意:如果重新启动实例,iptables 的规则将重置为默认值。要避免重置,请运行以下命令之一以保存规则:

对于 Amazon ECS 优化型 Amazon Linux AMI:

sudo service iptables save

对于 Amazon ECS 优化型 Amazon Linux 2 AMI:

sudo iptables-save | sudo tee /etc/sysconfig/iptables && sudo systemctl enable --now iptables

使凭证路径环境变量可用于非 PID 1 进程

环境变量 AWS_CONTAINER_CREDENTIALS_RELATIVE_URI 仅适用于容器内的 PID 1 进程。如果容器正在运行多个进程或 init 进程(例如包装器脚本、启动脚本或 supervisord),则环境变量对非 PID 1 进程不可用。

要设置环境变量以使其可用于非 PID 1 进程,请将环境变量导出到 .profile 文件中。例如,运行以下命令以将变量导出到容器映像的 Dockerfile 中:

RUN echo 'export $(strings /proc/1/environ | grep AWS_CONTAINER_CREDENTIALS_RELATIVE_URI)' >> /root/.profile

现在,其他进程可以访问环境变量。

注意:导出环境变量时,字符串和 grep 命令存在依赖关系。


这篇文章对您有帮助吗?

我们可以改进什么?


需要更多帮助吗?