跳至内容

如何在 Amazon EKS 中使用 IRSA 限制对 Amazon S3 存储桶的访问?

3 分钟阅读
0

我想在 Amazon Elastic Kubernetes Service (Amazon EKS) 中在容器组 (Pod) 级别限制 Amazon Simple Storage Service (Amazon S3) 存储桶的访问权限。我还想使用服务账户 (IRSA) 的 AWS Identity and Access Management (IAM) 角色保留我的应用程序的最低权限。

解决方案

**注意:**如果您在运行 AWS 命令行界面 (AWS CLI) 命令时收到错误,请参阅 AWS CLI 错误故障排除。此外,请确保您使用的是最新版本的 AWS CLI

先决条件:为您的集群创建 IAM OpenID Connect (OIDC) 提供商

创建 IAM 策略和角色

完成以下步骤:

  1. 创建名为 iam-policy.json 的 JSON 文件。策略示例:
    {    
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": [
                    "s3:ListBucket"
                ],
                "Resource": "arn:aws:s3:::YOUR_BUCKET"
            },
            {
                "Sid": "List",
                "Effect": "Allow",
                "Action": [
                    "s3:GetObject",
                    "s3:GetObjectVersion"
                ],
                "Resource": "arn:aws:s3:::YOUR_BUCKET/*"
            }
        ]
    }
    **注意:**请将 YOUR_BUCKET 替换为您的 S3 存储桶名称。上述示例策略将限制 Amazon S3 权限,以便 IAM 用户只能列出和检索来自 S3 存储桶的对象。
  2. 要创建 IAM 策略,请运行以下 AWS CLI 命令 create-policy
    aws iam create-policy \
        --policy-name YOUR_IAM_POLICY_NAME \
        --policy-document file://iam-policy.json
    **注意:**请将 YOUR_IAM_POLICY_NAME 替换为您的策略名称。
  3. 创建 IAM 角色并将其与您的集群服务 AWS 账户关联
  4. 确认您正确配置了 IAM 策略和角色
  5. (可选)要获取角色名称,请运行以下命令:
    kubectl get sa SERVICE_ACCOUNT_NAME -n NAMESPACE_NAME -o yaml | grep eks.amazonaws.com/role-arn | cut -d '/' -f 3
    **注意:**请将 SERVICE_ACCOUNT_NAME 替换为您的服务帐号名称,将 NAMESPACE_NAME 替换为您的命名空间名称。
    示例输出:
    eksctl-EKS-LAB-addon-iamserviceaccount-defau-Role1-ASA1UEXAMPLE

创建 Amazon EKS 容器组 (Pod)

确认您的容器组 (Pod) 可以代入具有正确权限的 IAM 角色。完成以下步骤,在 AWS CLI 中将您的应用程序替换为官方映像

  1. 创建名为 aws-cli-pod.yaml 的 YAML 文件。示例文件:
    apiVersion: v1
    kind: Pod
    metadata:
      name: aws-cli
      namespace: NAMESPACE_NAME
    spec:
      serviceAccountName: SERVICE_ACCOUNT_NAME
      containers:
      - name: aws-cli
        image: amazon/aws-cli:latest
        command:
          - sleep
          - "3600"
        imagePullPolicy: IfNotPresent
      restartPolicy: Always
    **注意:**请将 NAMESPACE_NAME 替换为您的命名空间,将 SERVICE_ACCOUNT_NAME 替换为您的 Kubernetes 服务账户名称。
  2. 要创建 Amazon EKS 容器组 (Pod),请运行以下命令:
    kubectl apply -f ./aws-cli-pod.yaml

测试您的 Amazon EKS 容器组 (Pod)

**注意:**在以下示例中,容器组 (Pod) 可以列出并从 YOUR_BUCKET S3 存储桶中获取对象。

要确认您的容器组 (Pod) 对 Amazon S3 使用了正确的 IAM 角色和操作,请完成以下步骤:

  1. 要查找使用凭证的 IAM 角色,请运行以下命令:

    kubectl -n NAMESPACE_NAME exec -it aws-cli -- aws sts get-caller-identity

    **注意:**请将 NAMESPACE_NAME 替换为您的命名空间名称。
    示例输出:

    {   
        "UserId": "AIDACKCEVSQ6C2EXAMPLE:botocore-session-123456789012",
        "Account": "123456789012",
        "Arn": "arn:aws:sts::123456789012:assumed-role/eksctl-EKS-LAB-addon-iamserviceaccount-defau-Role1-ASA1UEXAMPLE/botocore-session-123456789012"
    }
  2. 验证您的容器组 (Pod) 是否对 S3 存储桶具有正确的权限。
    要验证您的容器组 (Pod) 是否具有 s3:ListBuckets 权限,请运行以下命令:

    kubectl -n NAMESPACE_NAME exec -it aws-cli -- aws s3 ls s3://YOUR_BUCKET

    **注意:**请将 NAMESPACE_NAME 替换为您的命名空间名称,将 YOUR_BUCKET 替换为您的存储桶。
    示例输出:

    2025-03-25 22:28:06         14 hello_s3.txt

    要验证您的容器组 (Pod) 是否具有 s3:GetObject 权限,请运行以下命令:

    kubectl -n NAMESPACE_NAME exec -it aws-cli -- aws s3api get-object --bucket YOUR_BUCKET --key DIR/S3_OBJECT_FILE S3_FILE_NAME_LOCAL

    **注意:**请将 NAMESPACE_NAME 替换为您的命名空间名称,将 YOUR_BUCKET 替换为您的存储桶。此外,请将 DIR/S3_OBJECT_FILE 替换为目录和对象文件名,将 S3_FILE_NAME_LOCAL 替换为新的本地 Amazon S3 对象。
    示例输出:

    {
        "AcceptRanges": "bytes",
        "LastModified": "2025-03-14T01:49:38+00:00",
        "ContentLength": 19,
        "ETag": "\"678b33365329cce6cd2bb1882e62fe3a\"",
        "ContentType": "text/plain",
        "ServerSideEncryption": "AES256",
        "Metadata": {}
    }
  3. 要验证您的容器组 (Pod) 是否没有 s3:DeleteObject 权限,请运行以下命令:

    kubectl -n NAMESPACE_NAME exec -it aws-cli -- aws s3 rm s3://YOUR_BUCKET/DEMO_TEST_FILE

    **注意:**请将 NAMESPACE_NAME 替换为您的命名空间名称,将 YOUR_BUCKET 替换为您的存储桶。此外,请将 DEMO_TEST_FILE 替换为您的 Amazon S3 对象文件。
    如果容器组 (Pod) 没有 s3:DeleteObject 权限,则您会在输出中收到以下 Access Denied(拒绝访问)错误:

    delete failed: s3://YOUR_BUCKET/DEMO_TEST_FILE An error occurred (AccessDenied) when calling the DeleteObject operation: User: arn:aws:sts::123456789012:assumed-role/eksctl-EKS-LAB-addon-iamserviceaccount-defau-Role1-ASA1UEXAMPLE/botocore-session-123456789012 is not authorized to perform: s3:DeleteObject on resource: "arn:aws:s3:::YOUR_BUCKET/DEMO_TEST_FILE" because no identity-based policy allows the s3:DeleteObject action
    command terminated with exit code 1

对问题进行故障排除

**重要事项:**进行更改后,请务必创建新的容器组 (Pod)。Amazon EKS 仅会在新创建的容器组 (Pod) 中反映更新,而不在现有容器组 (Pod) 中反映更新。

NoSuchBucket 错误

如果您因为 S3 存储桶不存在而找不到它,则会收到以下错误:

“调用 ListObjectsV2 操作时出错 (NoSuchBucket): 指定的存储桶不存在,命令已终止,退出代码为 254”

要解决此问题,请确保在命令中使用正确的 S3 存储桶名称。

NoSuchKey 错误

如果您无法从特定的 S3 存储桶路径下载,则会收到以下错误:

“调用 GetObject 操作时出错 (NoSuchKey): 指定的密钥不存在。”

要解决此问题,请验证您的 AWS 账户中是否存在 Amazon S3 路径和文件名。

AccessDenied 错误

如果您没有权限对 S3 存储桶执行操作,则会收到错误。例如,如果您无法运行 ListObjectsV2 操作,则会发生以下错误:

“调用 ListObjectsV2 操作时出错 (AccessDenied): 用户 arn:aws:sts::123456789012:assumed-role/eksctl-EKS-LAB-addon-iamserviceaccount-defau-Role1-ASA1UEXAMPLE/botocore-session-123456789012 无权对资源 "arn:aws:s3:::YOUR_BUCKET" 执行 s3:ListBucket 操作,因为没有基于身份的策略允许 s3:ListBucket 操作,命令已终止,退出代码为 254”

要解决此问题,请确保您已将权限添加到 IAM 角色策略中。

如果 IAM 身份提供商出现错误,则您会收到以下错误:

调用 AssumeRoleWithWebIdentity 操作时出错 (AccessDenied): 无权执行 sts:AssumeRoleWithWebIdentity,命令已终止,退出代码为 254”

要解决此问题,请确认以下配置:

InvalidIdentityToken 错误

如果 Amazon EKS 找不到您的账户的 OIDC 提供商,则您会收到以下错误:

“调用 AssumeRoleWithWebIdentity 操作时出错 (InvalidIdentityToken): 在您的账户中未找到 OpenIDConnect 提供商:https://oidc.eks.us-east-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE,命令已终止,退出代码为 254”

要解决此问题,请验证 IAM 中是否存在 OIDC 的身份提供商。

相关信息

使用 IAM 策略模拟器测试 IAM 策略

AWS 服务的操作、资源和条件键

AWS 官方已更新 1 年前