

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 启用 Amazon EMR on EKS 的集群访问
<a name="setting-up-cluster-access"></a>

下面几节介绍了启用集群访问的几种方法。第一种是使用 Amazon EKS 集群访问管理（CAM），后者展示了如何手动启用集群访问。

## 使用 EKS 访问条目启用集群访问（推荐）
<a name="setting-up-cluster-access-cam-integration"></a>

**注意**  
`aws-auth` ConfigMap 已弃用。[管理 Kubernetes 访问权限的推荐方法 APIs 是访问条目。](https://docs.aws.amazon.com/eks/latest/userguide/access-entries.html)

Amazon EMR 已与 [Amazon EKS 集群访问管理（CAM）](https://docs.aws.amazon.com/eks/latest/userguide/access-entries.html)集成，因此您可以自动配置必要的 AuthN 和 AuthZ 策略，以便在 Amazon EKS 集群的命名空间中运行 Amazon EMR Spark 作业。从 Amazon EKS 集群命名空间创建虚拟集群时，Amazon EMR 会自动配置所有必要的权限，因此您无需在当前工作流中添加任何额外步骤。

**注意**  
只有新的 Amazon EMR on EKS 虚拟集群支持 Amazon EMR 与 Amazon EKS CAM 集成。您无法迁移现有虚拟集群以使用此集成。

### 先决条件
<a name="setting-up-cluster-access-cam-integration-prereqs"></a>
+ 确保你运行的是 2.15.3 或更高版本的 AWS CLI
+ Amazon EKS 集群必须为 1.23 或更高版本。

### 设置
<a name="setting-up-cluster-access-cam-integration-setup"></a>

要在 Amazon EMR 和 Amazon EKS AccessEntry 的 API 操作之间设置集成，请确保您已完成以下各项：
+ 确保将 Amazon EKS 集群的 `authenticationMode` 设置为 `API_AND_CONFIG_MAP`。

  ```
  aws eks describe-cluster --name <eks-cluster-name>
  ```

  如果还未设置，请将 `authenticationMode` 设置为 `API_AND_CONFIG_MAP`。

  ```
  aws eks update-cluster-config 
      --name <eks-cluster-name> 
      --access-config authenticationMode=API_AND_CONFIG_MAP
  ```

  有关身份验证模式的更多信息，请参阅[集群身份验证模式](https://docs.aws.amazon.com/eks/latest/userguide/access-entries.html#authentication-modes)。
+ 确保用于运行 `CreateVirtualCluster` 和 `DeleteVirtualCluster` API 操作的 [IAM 角色](https://docs.aws.amazon.com/emr/latest/EMR-on-EKS-DevelopmentGuide/setting-up-iam.html)也具有以下权限：

  ```
  {
    "Effect": "Allow",
    "Action": [
      "eks:CreateAccessEntry"
    ],
    "Resource": "arn:<AWS_PARTITION>:eks:<AWS_REGION>:<AWS_ACCOUNT_ID>:cluster/<EKS_CLUSTER_NAME>"
  }, 
  {
    "Effect": "Allow",
    "Action": [
      "eks:DescribeAccessEntry",
      "eks:DeleteAccessEntry",
      "eks:ListAssociatedAccessPolicies",
      "eks:AssociateAccessPolicy",
      "eks:DisassociateAccessPolicy"
    ],
    "Resource": "arn:<AWS_PARTITION>:eks:<AWS_REGION>:<AWS_ACCOUNT_ID>:access-entry/<EKS_CLUSTER_NAME>/role/<AWS_ACCOUNT_ID>/AWSServiceRoleForAmazonEMRContainers/*"
  }
  ```

### 概念和术语
<a name="setting-up-cluster-access-cam-integration-concepts"></a>

以下是 Amazon EKS CAM 的相关术语和概念列表。
+ 虚拟集群（VC）：在 Amazon EKS 中创建的命名空间的逻辑表示。这是指向 Amazon EKS 集群命名空间的 1:1 链接。您可以使用虚拟集群在指定命名空间内的 Amazon EKS 集群上运行 Amazon EMR 工作负载。
+ 命名空间：在单个 EKS 集群中隔离资源组的机制。
+ 访问策略：允许 EKS 集群中的 IAM 角色访问和操作的权限。
+ 访问条目：使用角色 arn 创建的条目。您可以将访问条目关联到访问策略，以便在 Amazon EKS 集群中分配特定权限。
+ EKS 访问条目集成虚拟集群：使用 Amazon EKS 中的[访问条目 API 操作](https://docs.aws.amazon.com/eks/latest/APIReference/API_Operations_Amazon_Elastic_Kubernetes_Service.html)创建的虚拟集群。

## 使用 `aws-auth` 启用集群访问
<a name="setting-up-cluster-access-aws-auth"></a>

您必须通过执行以下操作来允许 Amazon EMR on EKS 访问集群中的特定命名空间：创建 Kubernetes 角色、将角色绑定到 Kubernetes 用户以及将 Kubernetes 用户映射为服务关联角色 [https://docs.aws.amazon.com/emr/latest/EMR-on-EKS-DevelopmentGuide/using-service-linked-roles.html](https://docs.aws.amazon.com/emr/latest/EMR-on-EKS-DevelopmentGuide/using-service-linked-roles.html)。当 IAM 身份映射命令与 `emr-containers` 一起作为服务名称时，这些操作在 `eksctl` 中自动执行。您可以使用以下命令轻松地执行这些操作。

```
eksctl create iamidentitymapping \
    --cluster my_eks_cluster \
    --namespace kubernetes_namespace \
    --service-name "emr-containers"
```

*my\$1eks\$1cluster*替换为您的 Amazon EKS 集群的名称，替换*kubernetes\$1namespace*为为运行 Amazon EMR 工作负载而创建的 Kubernetes 命名空间。

**重要**  
必须使用上一步[设置 kubectl 和 eksctl](https://docs.aws.amazon.com/eks/latest/userguide/install-kubectl.html) 下载最新的 eksctl 才能使用此功能。

### 执行手动步骤以启用 Amazon EMR on EKS 的集群访问
<a name="setting-up-cluster-access-manual"></a>

您还可以使用以下手动步骤来启用 Amazon EMR on EKS 的集群访问。

1. **在特定命名空间中创建 Kubernetes 角色**

------
#### [ Amazon EKS 1.22 - 1.29 ]

   对于 Amazon EKS 1.22-1.29，运行以下命令以在特定命名空间中创建 Kubernetes 角色。此角色向 Amazon EMR on EKS 授予必要的 RBAC 权限。

   ```
   namespace=my-namespace
   cat - >>EOF | kubectl apply -f - >>namespace "${namespace}"
   apiVersion: rbac.authorization.k8s.io/v1
   kind: Role
   metadata:
     name: emr-containers
     namespace: ${namespace}
   rules:
     - apiGroups: [""]
       resources: ["namespaces"]
       verbs: ["get"]
     - apiGroups: [""]
       resources: ["serviceaccounts", "services", "configmaps", "events", "pods", "pods/log"]
       verbs: ["get", "list", "watch", "describe", "create", "edit", "delete", "deletecollection", "annotate", "patch", "label"]
     - apiGroups: [""]
       resources: ["secrets"]
       verbs: ["create", "patch", "delete", "watch"]
     - apiGroups: ["apps"]
       resources: ["statefulsets", "deployments"]
       verbs: ["get", "list", "watch", "describe", "create", "edit", "delete", "annotate", "patch", "label"]
     - apiGroups: ["batch"]
       resources: ["jobs"]
       verbs: ["get", "list", "watch", "describe", "create", "edit", "delete", "annotate", "patch", "label"]
     - apiGroups: ["extensions", "networking.k8s.io"]
       resources: ["ingresses"]
       verbs: ["get", "list", "watch", "describe", "create", "edit", "delete", "annotate", "patch", "label"]
     - apiGroups: ["rbac.authorization.k8s.io"]
       resources: ["roles", "rolebindings"]
       verbs: ["get", "list", "watch", "describe", "create", "edit", "delete", "deletecollection", "annotate", "patch", "label"]
     - apiGroups: [""]
       resources: ["persistentvolumeclaims"]
       verbs: ["get", "list", "watch", "describe", "create", "edit", "delete",  "deletecollection", "annotate", "patch", "label"]
   EOF
   ```

------
#### [ Amazon EKS 1.21 and below ]

   使用 Amazon EKS 1.21 及更低版本，运行以下命令以在特定命名空间中创建 Kubernetes 角色。此角色向 Amazon EMR on EKS 授予必要的 RBAC 权限。

   ```
   namespace=my-namespace
   cat - >>EOF | kubectl apply -f - >>namespace "${namespace}"
   apiVersion: rbac.authorization.k8s.io/v1
   kind: Role
   metadata:
     name: emr-containers
     namespace: ${namespace}
   rules:
     - apiGroups: [""]
       resources: ["namespaces"]
       verbs: ["get"]
     - apiGroups: [""]
       resources: ["serviceaccounts", "services", "configmaps", "events", "pods", "pods/log"]
       verbs: ["get", "list", "watch", "describe", "create", "edit", "delete", "deletecollection", "annotate", "patch", "label"]
     - apiGroups: [""]
       resources: ["secrets"]
       verbs: ["create", "patch", "delete", "watch"]
     - apiGroups: ["apps"]
       resources: ["statefulsets", "deployments"]
       verbs: ["get", "list", "watch", "describe", "create", "edit", "delete", "annotate", "patch", "label"]
     - apiGroups: ["batch"]
       resources: ["jobs"]
       verbs: ["get", "list", "watch", "describe", "create", "edit", "delete", "annotate", "patch", "label"]
     - apiGroups: ["extensions"]
       resources: ["ingresses"]
       verbs: ["get", "list", "watch", "describe", "create", "edit", "delete", "annotate", "patch", "label"]
     - apiGroups: ["rbac.authorization.k8s.io"]
       resources: ["roles", "rolebindings"]
       verbs: ["get", "list", "watch", "describe", "create", "edit", "delete", "deletecollection", "annotate", "patch", "label"]
     - apiGroups: [""]
       resources: ["persistentvolumeclaims"]
       verbs: ["get", "list", "watch", "describe", "create", "edit", "delete", "deletecollection", "annotate", "patch", "label"]
   EOF
   ```

------

1. **创建作用域为命名空间的 Kubernetes 角色绑定**

   运行以下命令以创建绑定在特定命名空间中的 Kubernetes 角色。此角色绑定将在上一步中创建的角色中定义的权限授予名为 `emr-containers` 的用户。此用户确定 [Amazon EMR on EKS 的服务相关角色](https://docs.aws.amazon.com/emr/latest/EMR-on-EKS-DevelopmentGuide/using-service-linked-roles.html)，因此允许 Amazon EMR on EKS 执行由您创建的角色所定义的操作。

   ```
   namespace=my-namespace
   
   cat - <<EOF | kubectl apply -f - --namespace "${namespace}"
   apiVersion: rbac.authorization.k8s.io/v1
   kind: RoleBinding
   metadata:
     name: emr-containers
     namespace: ${namespace}
   subjects:
   - kind: User
     name: emr-containers
     apiGroup: rbac.authorization.k8s.io
   roleRef:
     kind: Role
     name: emr-containers
     apiGroup: rbac.authorization.k8s.io
   EOF
   ```

1. **更新 Kubernetes `aws-auth` 配置映射**

   您可以使用以下选项之一将 Amazon EMR on EKS 与服务关联的角色映射到 `emr-containers` 用户，并且该用户在上一步中绑定了 Kubernetes 角色。

   **选项 1：使用 `eksctl`**

   运行以下 `eksctl` 命令：将 Amazon EMR on EKS 服务相关角色映射到 `emr-containers` 用户。

   ```
   eksctl create iamidentitymapping \
       --cluster my-cluster-name \
       --arn "arn:aws:iam::my-account-id:role/AWSServiceRoleForAmazonEMRContainers" \
       --username emr-containers
   ```

   **选项 2：不使用 eksctl**

   1. 运行以下命令可在文本编辑器中打开 `aws-auth` 配置映射。

      ```
      kubectl edit -n kube-system configmap/aws-auth
      ```
**注意**  
如果您收到错误信息`Error from server (NotFound): configmaps "aws-auth" not found`，请参阅 Amazon EKS [用户指南中添加用户角色](https://docs.aws.amazon.com/eks/latest/userguide/add-user-role.html)中的步骤来应用该股票 ConfigMap。

   1. 在 `data` 下，将 Amazon EMR on EKS 服务相关角色详细信息添加到 `ConfigMap` 的 `mapRoles` 部分。如果此部分在文件中尚不存在，请添加它。已更新的 `mapRoles` 部分类似于以下示例。

      ```
      apiVersion: v1
      data:
        mapRoles: |
          - rolearn: arn:aws:iam::<your-account-id>:role/AWSServiceRoleForAmazonEMRContainers
            username: emr-containers
          - ... <other previously existing role entries, if there's any>.
      ```

   1. 保存文件并退出文本编辑器。