无法从 Fargate 容器内访问 S3 存储桶(错误请求且无法找到凭据)

新手上路,请多包涵

我使用 python 3boto3 尝试从该存储桶中读取一个简单的任务,创建了一个私有 s3 存储桶和一个 fargate 集群。我已经在 2 个不同的 docker 图像上尝试过这个,在一个上我得到一个 ClientError 从 boto 说 HeadObject Bad request (400) 另一个我得到 NoCredentialsError: Unable to locate credentials

图像中唯一真正不同的是,一个说错误请求正在正常运行,另一个是由我通过 ssh 手动运行到任务容器。所以我不确定为什么一张图片说“请求错误”而另一张图片说“无法找到凭据”。

我尝试了几种不同的 IAM 策略,包括( terraform )以下策略:

 data "aws_iam_policy_document" "access_s3" {
  statement {
    effect    = "Allow"
    actions   = ["s3:ListBucket"]
    resources = ["arn:aws:s3:::bucket_name"]
  }

  statement {
    effect = "Allow"

    actions = [
      "s3:GetObject",
      "s3:GetObjectVersion",
      "s3:GetObjectTagging",
      "s3:GetObjectVersionTagging",
    ]

    resources = ["arn:aws:s3:::bucket_name/*"]
  }
}

第二次尝试:

 data "aws_iam_policy_document" "access_s3" {
  statement {
    effect    = "Allow"
    actions   = ["s3:*"]
    resources = ["arn:aws:s3:::*"]
  }
}

我尝试的最后一个是内置策略:

 resource "aws_iam_role_policy_attachment" "access_s3" {
  role       = "${aws_iam_role.ecstasks.name}"
  policy_arn = "arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess"
}

桶定义非常简单:

 resource "aws_s3_bucket" "bucket" {
  bucket = "${var.bucket_name}"
  acl    = "private"
  region = "${var.region}"
}

用于访问 s3 存储桶的代码:

 try:
    s3 = boto3.client('s3')
    tags = s3.head_object(Bucket='bucket_name', Key='filename')
    print(tags['ResponseMetadata']['HTTPHeaders']['etag'])
except ClientError:
    traceback.print_exc()

无论我做什么,我都无法使用 boto3Fargate 容器任务中访问 AWS 资源。我可以在 EC2 boto3 同一个 s3 存储桶,无需提供任何类型的凭据,仅使用 IAM 角色/策略。我究竟做错了什么?从 Fargate 容器以同样的方式访问 AWS 资源是不可能的吗?

忘记提及我正在将 IAM 角色分配给任务定义执行策略和任务策略。

更新:事实证明,我遇到的 unable to find credentials 错误是一条红鲱鱼。我无法获得凭据的原因是因为我的直接 ssh 会话没有设置 AWS_CONTAINER_CREDENTIALS_RELATIVE_URI 环境变量。

AWS Fargate 将代表您注入一个名为 AWS_CONTAINER_CREDENTIALS_RELATIVE_URI 的环境变量,其中包含 boto 应该用于获取 API 访问凭证的 url。所以 Bad request 错误是我实际遇到的错误,需要帮助解决。我检查了容器内的环境变量,Fargate 正在设置 AWS_CONTAINER_CREDENTIALS_RELATIVE_URI 值。

原文由 vane 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 627
1 个回答

我在这个问题上纠结了很久,并且经常将 AWS_CONTAINER_CREDENTIALS_RELATIVE_URI 错误地设置为 None ,直到我在当前 任务执行角色之外添加了自定义任务角色

1) 任务执行角色负责访问 ECR 中的容器并授予运行任务本身的权限,而 2) 任务角色负责您的 docker 容器向其他授权 AWS 服务发出 API 请求。

  1. 对于我的任务执行角色,我使用 AmazonECSTaskExecutionRolePolicy 和以下 JSON;
 {
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ecr:GetAuthorizationToken",
                "ecr:BatchCheckLayerAvailability",
                "ecr:GetDownloadUrlForLayer",
                "ecr:BatchGetImage",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "*"
        }
    ]
}

2)我终于摆脱了 NoCredentialsError: Unable to locate credentials ,除了任务执行角色外,我还添加了一个任务角色,例如负责从某个桶中读取;

 {
    "Version": "2012-10-17",
    "Statement": [
           {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject"
            ],
            "Resource": "arn:aws:s3:::bucket_name/*"
        }
    ]
}

总之;确保两者都具有以下角色: 1) executionRoleArn 用于访问以运行任务, 2) taskRoleArn 用于访问以向任务定义中设置的授权 AWS 服务发出 API 请求。

原文由 NorahKSakal 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进