如何在 Amazon EKS 中使用面向服务账户的 IAM 角色 (IRSA) 功能来限制对 Amazon S3 存储桶的访问?

上次更新日期:2021 年 10 月 11 日

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

解决方法

重要提示:在将 IRSA 与 Amazon EKS 结合使用之前,您必须为集群创建 IAM OIDC 提供商

创建 IAM 策略和角色

1.    创建名为 iam-policy.json 的 JSON 文件。

以下示例策略限制了 Amazon S3 和 Amazon DynamoDB 的权限。允许 IAM 用户访问一个 S3 存储桶访问特定的 DynamoDB 表

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "ListAndDescribe",
            "Effect": "Allow",
            "Action": [
                "dynamodb:List*",
                "dynamodb:Describe*"
            ],
            "Resource": "arn:aws:dynamodb:*:*:table/YOUR_TABLE"
        },
        {
            "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_TABLE 替换为您的表。将 YOUR_NAMESPACE 替换为您的命名空间。

2.    创建名为 YOUR-IAM-POLICY 的 IAM 策略。

$ aws iam create-policy \
    --policy-name YOUR-IAM-POLICY \
    --policy-document file://iam-policy.json

注意:请将 YOUR-IAM-POLICY 替换为您的策略名称。

3.    使用 IAM 控制台为您的服务账户创建 IAM 角色,然后使用该 IAM 角色为服务账户添加注释。或者,使用 eksctl 为您的服务账户创建 IAM 角色。例如:

$ eksctl create iamserviceaccount \
  --name YOUR-SERVICEACCOUNT \
  --namespace YOUR-NAMESPACE \
  --cluster YOUR-CLUSTER \
  --attach-policy-arn arn:aws:iam::1111122222:policy/YOUR-IAM-POLICY \
  --approve

注意:请将 1111122222 替换为您的 Amazon Resource Name (ARN)。您还可以使用 IAM 控制台为服务账户创建 IAM 角色。

创建 Amazon EKS Pod

在以下步骤中,将您自己的应用程序替换为 aws-cli 镜像。这可让您检查自己的容器是否可以使用正确的 IAM 权限代入指定的 IAM 角色。

1.    创建名为 aws-cli-pod.yaml 的 YAML 文件。例如:

apiVersion: v1
kind: Pod
metadata:
  name: aws-cli
  namespace: YOUR_NAMESPACE
spec:
  serviceAccountName: YOUR_SERVICEACCOUNT
  containers:
  - name: aws-cli
    image: amazon/aws-cli:latest
    command:
      - sleep
      - "3600"
    imagePullPolicy: IfNotPresent
  restartPolicy: Always

注意:YOUR_NAMESPACE 替换为您的命名空间。将 SERVICE_ACCOUNT 替换为您的 Kubernetes 服务账户名称。

2.    创建 Amazon EKS Pod:

$ kubectl apply -f ./aws-cli.yaml

测试您的 Amazon EKS Pod

确认您的 Pod 使用对 Amazon S3 和 DynamoDB 限制操作的正确 IAM 角色。在以下示例中,Pod 只能列出 S3 存储桶 (YOUR_BUCKET) 和 DynamoDB 表 (YOUR_TABLE)。

1.    查找正在使用凭证的 IAM 角色:

$ kubectl exec -it aws-cli -- aws sts get-caller-identity

输出:

{
    "UserId": "AIDACKCEVSQ6C2EXAMPLE:botocore-session-1111122222",
    "Account": "111122223333",
    "Arn": "arn:aws:sts::111122223333:assumed-role/eksctl-EKS-LAB-addon-iamserviceaccount-defau-Role1-ASA1UEXAMPLE/botocore-session-1111122222"
}

2.    验证您的 Pod 是否具有 S3 存储桶 (YOUR_BUCKET) 的 s3:ListBuckets 权限:

$ kubectl exec -it aws-cli -- aws s3 ls s3://YOUR_BUCKET

注意:YOUR_BUCKET 替换为您的 IRSA。

输出:

2021-09-28 09:59:22        269 demo-test-file

3.    验证您的 Pod 是否无法删除 S3 存储桶 (YOUR_BUCKET):

$ kubectl exec -it aws-cli -- aws s3 rm s3://YOUR_BUCKET/demo-test-file

注意:YOUR_BUCKET 替换为您的 S3 存储桶。

该命令返回以下“访问被拒绝”错误,因为该 Pod 没有 s3:DeleteObject 权限:

delete failed: s3://YOUR_BUCKET/demo-test-file An error occurred (AccessDenied) when calling the DeleteObject operation: Access Denied
command terminated with exit code 1

4.    验证您的容器是否具有 DynamoDB 表 (YOUR_TABLE) 的 dynamodb:List 权限:

$ kubectl exec -it aws-cli -- aws dynamodb describe-table --table-name YOUR_TABLE

注意:YOUR_TABLE 替换为您的 DynamoDB 表。

输出:

{
    "Table": {
        "AttributeDefinitions": [
            {
                "AttributeName": "demo",
                "AttributeType": "S"
            }
        ],
        "TableName": "YOUR_TABLE",
        "KeySchema": [
            {
                "AttributeName": "demo",
                "KeyType": "HASH"
            }
        ],
        "TableStatus": "ACTIVE",
        "CreationDateTime": "2021-09-28T10:05:53.599000+00:00",
        "ProvisionedThroughput": {
            "NumberOfDecreasesToday": 0,
            "ReadCapacityUnits": 5,
            "WriteCapacityUnits": 5
        },
        "TableSizeBytes": 0,
        "ItemCount": 0,
        "TableArn": "arn:aws:dynamodb:eu-west-1:000000000000:table/YOUR_TABLE",
        "TableId": "42bd1238-e042-4016-b6b2-77548939c101"
    }
}

5.    验证您的容器是否无法删除 DynamoDB 表 (YOUR_TABLE):

$ kubectl exec -it aws-cli -- aws dynamodb delete-table --table-name YOUR_TABLE

注意:YOUR_TABLE 替换为您的 DynamoDB 表。

该命令返回以下“访问被拒绝”错误,因为该 Pod 没有 dynamodb:DeleteTable 权限:

An error occurred (AccessDeniedException) when calling the DeleteTable operation: User: arn:aws:sts::1111122222:assumed-role/eksctl-EKS-LAB-addon-iamserviceaccount-defau-Role1-ASA1U7NRNSEC/botocore-session-1632822777 is not authorized to perform: dynamodb:DeleteTable on resource: arn:aws:dynamodb:eu-west-1: 1111122222:table/MyTable
command terminated with exit code 254

这篇文章对您有帮助吗?


您是否需要账单或技术支持?