如何在 Amazon EKS 中使用 IRSA 限制对 Amazon S3 存储桶的访问?
我想在 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 策略和角色
完成以下步骤:
- 创建名为 iam-policy.json 的 JSON 文件。策略示例:
**注意:**请将 YOUR_BUCKET 替换为您的 S3 存储桶名称。上述示例策略将限制 Amazon S3 权限,以便 IAM 用户只能列出和检索来自 S3 存储桶的对象。{ "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/*" } ] } - 要创建 IAM 策略,请运行以下 AWS CLI 命令 create-policy:
**注意:**请将 YOUR_IAM_POLICY_NAME 替换为您的策略名称。aws iam create-policy \ --policy-name YOUR_IAM_POLICY_NAME \ --policy-document file://iam-policy.json - 创建 IAM 角色并将其与您的集群服务 AWS 账户关联。
- 确认您正确配置了 IAM 策略和角色。
- (可选)要获取角色名称,请运行以下命令:
**注意:**请将 SERVICE_ACCOUNT_NAME 替换为您的服务帐号名称,将 NAMESPACE_NAME 替换为您的命名空间名称。kubectl get sa SERVICE_ACCOUNT_NAME -n NAMESPACE_NAME -o yaml | grep eks.amazonaws.com/role-arn | cut -d '/' -f 3
示例输出:eksctl-EKS-LAB-addon-iamserviceaccount-defau-Role1-ASA1UEXAMPLE
创建 Amazon EKS 容器组 (Pod)
确认您的容器组 (Pod) 可以代入具有正确权限的 IAM 角色。完成以下步骤,在 AWS CLI 中将您的应用程序替换为官方映像:
- 创建名为 aws-cli-pod.yaml 的 YAML 文件。示例文件:
**注意:**请将 NAMESPACE_NAME 替换为您的命名空间,将 SERVICE_ACCOUNT_NAME 替换为您的 Kubernetes 服务账户名称。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 - 要创建 Amazon EKS 容器组 (Pod),请运行以下命令:
kubectl apply -f ./aws-cli-pod.yaml
测试您的 Amazon EKS 容器组 (Pod)
**注意:**在以下示例中,容器组 (Pod) 可以列出并从 YOUR_BUCKET S3 存储桶中获取对象。
要确认您的容器组 (Pod) 对 Amazon S3 使用了正确的 IAM 角色和操作,请完成以下步骤:
-
要查找使用凭证的 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" } -
验证您的容器组 (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": {} } -
要验证您的容器组 (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”
要解决此问题,请确认以下配置:
- 您的集群的 IAM OIDC 提供商配置正确。
- IAM 角色信任关系配置正确。
- 服务账户使用正确的 IAM 角色。
InvalidIdentityToken 错误
如果 Amazon EKS 找不到您的账户的 OIDC 提供商,则您会收到以下错误:
“调用 AssumeRoleWithWebIdentity 操作时出错 (InvalidIdentityToken): 在您的账户中未找到 OpenIDConnect 提供商:https://oidc.eks.us-east-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE,命令已终止,退出代码为 254”
要解决此问题,请验证 IAM 中是否存在 OIDC 的身份提供商。
相关信息
- 语言
- 中文 (简体)
