

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

# EKS Pod 身份关联
<a name="pod-identity-associations"></a>

AWS EKS 引入了一种名为 Pod Identity Association 的新增强机制，供集群管理员配置 Kubernetes 应用程序，使其获得在集群外连接 AWS 服务所需的 IAM 权限。Pod Identity Association 利用 IRSA，但是，它可以直接通过 EKS API 对其进行配置，从而完全无需使用 IAM API。

因此，IAM 角色不再需要引用 [OIDC 提供商](iamserviceaccounts.md#iam-how-works)，因此也不会再绑定到单个集群。这意味着，IAM 角色现在可以在多个 EKS 集群中使用，而无需在每次创建新集群时更新角色信任策略。这反过来又消除了角色重复的需求，并简化了完全自动化 IRSA 的流程。

## 先决条件
<a name="_prerequisites"></a>

在幕后，pod 身份关联的实现是在工作节点上以守护程序集的形式运行代理。为了在集群上运行先决条件代理，EKS 提供了一个名为 EKS Pod Identity Agent 的新插件。因此，创建 pod 身份关联（一般而言，和 wit `eksctl` h）需要在集`eks-pod-identity-agent`群上预先安装插件。可以使用与任何其他受支持的插件相同`eksctl`的方式创建此插件。

```
eksctl create addon --cluster my-cluster --name eks-pod-identity-agent
```

此外，如果在创建 pod 身份关联时使用预先存在的 IAM 角色，则必须将该角色配置为信任新引入的 EKS 服务委托人 (`pods.eks.amazonaws.com`)。可以在下面找到 IAM 信任策略的示例：

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "pods.eks.amazonaws.com"
            },
            "Action": [
                "sts:AssumeRole",
                "sts:TagSession"
            ]
        }
    ]
}
```

相反，如果您没有向 create 命令提供现有角色的 ARN，则`eksctl`将在幕后创建一个角色并配置上述信任策略。

## 创建 Pod 身份关联
<a name="_creating_pod_identity_associations"></a>

为了操纵 pod 身份关联，`eksctl`在下面添加了一个新字段`iam.podIdentityAssociations`，例如

```
iam:
  podIdentityAssociations:
  - namespace: <string> #required
    serviceAccountName: <string> #required
    createServiceAccount: true #optional, default is false
    roleARN: <string> #required if none of permissionPolicyARNs, permissionPolicy and wellKnownPolicies is specified. Also, cannot be used together with any of the three other referenced fields.
    roleName: <string> #optional, generated automatically if not provided, ignored if roleARN is provided
    permissionPolicy: {} #optional
    permissionPolicyARNs: [] #optional
    wellKnownPolicies: {} #optional
    permissionsBoundaryARN: <string> #optional
    tags: {} #optional
```

有关完整示例，请参阅 [pod-identity-associations.yaml。](https://github.com/eksctl-io/eksctl/blob/main/examples/39-pod-identity-association.yaml)

**注意**  
除了`permissionPolicy`用作内联策略文档外，所有其他字段都有对应的 CLI 标志。

可以通过以下方式创建 pod 身份关联。在创建集群期间，通过在配置文件中指定所需的 pod 身份关联并运行：

```
eksctl create cluster -f config.yaml
```

创建集群后，使用配置文件，例如

```
eksctl create podidentityassociation -f config.yaml
```

或者使用 CLI 标志，例如

```
eksctl create podidentityassociation \
    --cluster my-cluster \
    --namespace default \
    --service-account-name s3-reader \
    --permission-policy-arns="arn:aws:iam::111122223333:policy/permission-policy-1, arn:aws:iam::111122223333:policy/permission-policy-2" \
    --well-known-policies="autoScaler,externalDNS" \
    --permissions-boundary-arn arn:aws:iam::111122223333:policy/permissions-boundary
```

**注意**  
一次只能将一个 IAM 角色与一个服务账号关联。因此，尝试为同一个服务帐号创建第二个 pod 身份关联将导致错误。

## 获取 Pod 身份关联
<a name="_fetching_pod_identity_associations"></a>

要检索特定集群的所有 pod 身份关联，请运行以下命令之一：

```
eksctl get podidentityassociation -f config.yaml
```

或

```
eksctl get podidentityassociation --cluster my-cluster
```

此外，要仅检索给定命名空间内的 pod 身份关联，请使用`--namespace`标志，例如

```
eksctl get podidentityassociation --cluster my-cluster --namespace default
```

最后，要检索与某个 K8s 服务帐号对应的单个关联，还`--service-account-name`需要在上面的命令中加上，即

```
eksctl get podidentityassociation --cluster my-cluster --namespace default --service-account-name s3-reader
```

## 更新 Pod 身份关联
<a name="_updating_pod_identity_associations"></a>

要更新一个或多个 pod 身份关联的 IAM 角色，请将新的`roleARN(s)`角色传递给配置文件，例如

```
iam:
  podIdentityAssociations:
    - namespace: default
      serviceAccountName: s3-reader
      roleARN: new-role-arn-1
    - namespace: dev
      serviceAccountName: app-cache-access
      roleARN: new-role-arn-2
```

然后运行：

```
eksctl update podidentityassociation -f config.yaml
```

或者（更新单个关联）`--role-arn`通过 CLI 标志传递新的：

```
eksctl update podidentityassociation --cluster my-cluster --namespace default --service-account-name s3-reader --role-arn new-role-arn
```

## 删除 Pod 身份关联
<a name="_deleting_pod_identity_associations"></a>

要删除一个或多个 pod 身份关联，`serviceAccountName(s)`请将`namespace(s)`和传递给配置文件，例如

```
iam:
  podIdentityAssociations:
    - namespace: default
      serviceAccountName: s3-reader
    - namespace: dev
      serviceAccountName: app-cache-access
```

然后运行：

```
eksctl delete podidentityassociation -f config.yaml
```

或者（删除单个关联）`--service-account-name`通过 CLI 传递`--namespace`和标志：

```
eksctl delete podidentityassociation --cluster my-cluster --namespace default --service-account-name s3-reader
```

## EKS 插件支持 pod 身份关联
<a name="pod-id-support"></a>

EKS 插件还支持通过 EKS Pod 身份关联接收 IAM 权限。配置文件公开了三个允许配置这些字段的字段：`addon.podIdentityAssociations`、`addonsConfig.autoApplyPodIdentityAssociations`和。`addon.useDefaultPodIdentityAssociations`您可以使用显式配置所需的 pod 身份关联`addon.podIdentityAssociations`，也可以使用或`eksctl`自动解析（并应用）推荐的 pod 身份配置`addon.useDefaultPodIdentityAssociations`。`addonsConfig.autoApplyPodIdentityAssociations`

**注意**  
并非所有 EKS 插件在启动时都支持 pod 身份关联。在这种情况下，应继续使用 I [RSA 设置提供所需的 I](addons.md#addons-create) AM 权限。

### 使用 IAM 权限创建插件
<a name="_creating_addons_with_iam_permissions"></a>

在创建需要 IAM 权限的插件时，`eksctl`将首先检查 pod 身份关联或 IRSA 设置是否被明确配置为配置文件的一部分，如果是，则使用其中一个来配置插件的权限。例如

```
addons:
- name: vpc-cni
  podIdentityAssociations:
  - serviceAccountName: aws-node
    permissionPolicyARNs: ["arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy"]
```

然后跑

```
eksctl create addon -f config.yaml
2024-05-13 15:38:58 [ℹ] pod identity associations are set for "vpc-cni" addon; will use these to configure required IAM permissions
```

**注意**  
不允许同时设置 pod 身份和 IRSA，这将导致验证错误。

对于支持 Pod 身份的 EKS 插件，`eksctl`提供了在创建插件时自动配置任何推荐的 IAM 权限的选项。这可以通过简单地在配置文件`addonsConfig.autoApplyPodIdentityAssociations: true`中进行设置来实现。例如

```
addonsConfig:
  autoApplyPodIdentityAssociations: true
# bear in mind that if either pod identity or IRSA configuration is explicitly set in the config file,
# or if the addon does not support pod identities,
# addonsConfig.autoApplyPodIdentityAssociations won't have any effect.
addons:
- name: vpc-cni
```

然后跑

```
eksctl create addon -f config.yaml
2024-05-13 15:38:58 [ℹ] "addonsConfig.autoApplyPodIdentityAssociations" is set to true; will lookup recommended pod identity configuration for "vpc-cni" addon
```

同样，也可以通过 CLI 标志来完成同样的事情，例如

```
eksctl create addon --cluster my-cluster --name vpc-cni --auto-apply-pod-identity-associations
```

要将现有插件迁移到使用带有推荐的 IAM 策略的 pod 身份，请使用

```
addons:
- name: vpc-cni
  useDefaultPodIdentityAssociations: true
```

```
eksctl update addon -f config.yaml
```

### 使用 IAM 权限更新插件
<a name="_updating_addons_with_iam_permissions"></a>

更新插件时，指定`addon.PodIdentityAssociations`将代表更新操作完成后插件应具有的状态的单一真实来源。在幕后，为了达到所需的状态，会执行不同类型的操作，即
+ 创建配置文件中存在但集群上缺少的 pod 标识
+ 删除从配置文件中移除的现有 pod 标识以及任何关联的 IAM 资源
+ 更新配置文件中也存在且其 IAM 权限集已更改的现有 pod 身份

**注意**  
EKS Addons 拥有的 pod 身份关联的生命周期由 EKS Addons API 直接处理。

对于与 Amazon EKS 插件一起使用的关联，您不能使用`eksctl delete podidentityassociations`（更新 IAM 权限）或（移除关联）。`eksctl update podidentityassociation`取而代之的是，`eksctl update addon`或`eksctl delete addon`应使用。

让我们来看上面的例子，首先分析插件的初始 pod 身份配置：

```
eksctl get podidentityassociation --cluster my-cluster --namespace opentelemetry-operator-system --output json
[
    {
        ...
        "ServiceAccountName": "adot-col-prom-metrics",
        "RoleARN": "arn:aws:iam::111122223333:role/eksctl-my-cluster-addon-adot-podident-Role1-JwrGA4mn1Ny8",
        # OwnerARN is populated when the pod identity lifecycle is handled by the EKS Addons API
        "OwnerARN": "arn:aws:eks:us-west-2:111122223333:addon/my-cluster/adot/b2c7bb45-4090-bf34-ec78-a2298b8643f6"
    },
    {
        ...
        "ServiceAccountName": "adot-col-otlp-ingest",
        "RoleARN": "arn:aws:iam::111122223333:role/eksctl-my-cluster-addon-adot-podident-Role1-Xc7qVg5fgCqr",
        "OwnerARN": "arn:aws:eks:us-west-2:111122223333:addon/my-cluster/adot/b2c7bb45-4090-bf34-ec78-a2298b8643f6"
    }
]
```

现在使用以下配置：

```
addons:
- name: adot
  podIdentityAssociations:

  # For the first association, the permissions policy of the role will be updated
  - serviceAccountName: adot-col-prom-metrics
    permissionPolicyARNs:
    #- arn:aws:iam::aws:policy/AmazonPrometheusRemoteWriteAccess
    - arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy

  # The second association will be deleted, as it's been removed from the config file
  #- serviceAccountName: adot-col-otlp-ingest
  #  permissionPolicyARNs:
  #  - arn:aws:iam::aws:policy/AWSXrayWriteOnlyAccess

  # The third association will be created, as it's been added to the config file
  - serviceAccountName: adot-col-container-logs
    permissionPolicyARNs:
    - arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy
```

然后跑

```
eksctl update addon -f config.yaml
...
# updating the permission policy for the first association
2024-05-14 13:27:43 [ℹ]  updating IAM resources stack "eksctl-my-cluster-addon-adot-podidentityrole-adot-col-prom-metrics" for pod identity association "a-reaxk2uz1iknwazwj"
2024-05-14 13:27:44 [ℹ]  waiting for CloudFormation changeset "eksctl-opentelemetry-operator-system-adot-col-prom-metrics-update-1715682463" for stack "eksctl-my-cluster-addon-adot-podidentityrole-adot-col-prom-metrics"
2024-05-14 13:28:47 [ℹ]  waiting for CloudFormation stack "eksctl-my-cluster-addon-adot-podidentityrole-adot-col-prom-metrics"
2024-05-14 13:28:47 [ℹ]  updated IAM resources stack "eksctl-my-cluster-addon-adot-podidentityrole-adot-col-prom-metrics" for "a-reaxk2uz1iknwazwj"
# creating the IAM role for the second association
2024-05-14 13:28:48 [ℹ]  deploying stack "eksctl-my-cluster-addon-adot-podidentityrole-adot-col-container-logs"
2024-05-14 13:28:48 [ℹ]  waiting for CloudFormation stack "eksctl-my-cluster-addon-adot-podidentityrole-adot-col-container-logs"
2024-05-14 13:29:19 [ℹ]  waiting for CloudFormation stack "eksctl-my-cluster-addon-adot-podidentityrole-adot-col-container-logs"
# updating the addon, which handles the pod identity config changes behind the scenes
2024-05-14 13:29:19 [ℹ]  updating addon
# deleting the IAM role for the third association
2024-05-14 13:29:19 [ℹ]  deleting IAM resources for pod identity service account adot-col-otlp-ingest
2024-05-14 13:29:20 [ℹ]  will delete stack "eksctl-my-cluster-addon-adot-podidentityrole-adot-col-otlp-ingest"
2024-05-14 13:29:20 [ℹ]  waiting for stack "eksctl-my-cluster-addon-adot-podidentityrole-adot-col-otlp-ingest" to get deleted
2024-05-14 13:29:51 [ℹ]  waiting for CloudFormation stack "eksctl-my-cluster-addon-adot-podidentityrole-adot-col-otlp-ingest"
2024-05-14 13:29:51 [ℹ]  deleted IAM resources for addon adot
```

现在检查 pod 标识配置是否已正确更新

```
eksctl get podidentityassociation --cluster my-cluster --output json
[
    {
        ...
        "ServiceAccountName": "adot-col-prom-metrics",
        "RoleARN": "arn:aws:iam::111122223333:role/eksctl-my-cluster-addon-adot-podident-Role1-nQAlp0KktS2A",
        "OwnerARN": "arn:aws:eks:us-west-2:111122223333:addon/my-cluster/adot/1ec7bb63-8c4e-ca0a-f947-310c4b55052e"
    },
    {
        ...
        "ServiceAccountName": "adot-col-otlp-ingest",
        "RoleARN": "arn:aws:iam::111122223333:role/eksctl-my-cluster-addon-adot-podident-Role1-1k1XhAdziGzX",
        "OwnerARN": "arn:aws:eks:us-west-2:111122223333:addon/my-cluster/adot/1ec7bb63-8c4e-ca0a-f947-310c4b55052e"
    }
]
```

要从插件中移除所有 pod 身份关联，`addon.PodIdentityAssociations`必须明确设置为`[]`，例如

```
addons:
- name: vpc-cni
  # omitting the `podIdentityAssociations` field from the config file,
  # instead of explicitly setting it to [], will result in a validation error
  podIdentityAssociations: []
```

然后跑

```
eksctl update addon -f config.yaml
```

### 删除具有 IAM 权限的插件
<a name="_deleting_addons_with_iam_permissions"></a>

删除插件还会移除与该插件关联的所有 Pod 身份。对于所有插件，删除集群的效果都是一样的。由`eksctl`创建的任何 Pod 身份的 IAM 角色也将被删除。

## 将现有的 iamservice 账户和插件迁移到 pod 身份关联
<a name="_migrating_existing_iamserviceaccounts_and_addons_to_pod_identity_associations"></a>

有一个 `eksctl` utils 命令用于将服务账户的现有 IAM 角色迁移到 pod 身份关联，即

```
eksctl utils migrate-to-pod-identity --cluster my-cluster --approve
```

在幕后，该命令将应用以下步骤：
+ 如果该`eks-pod-identity-agent`插件尚未在集群上处于活动状态，请安装该插件
+ 识别与 iamservice 账户关联的所有 IAM 角色
+ 识别与支持 pod 身份关联的 EKS 插件关联的所有 IAM 角色
+ 更新所有已识别角色的 IAM 信任策略，添加一个指向新的 EKS 服务主体的可信实体（并可选择删除现有的 OIDC 提供商信任关系）
+ 为与 iamserviceAccounts 关联的筛选角色创建 pod 身份关联
+ 使用 pod 身份更新 EKS 插件（EKS API 将在幕后创建 pod 身份）

运行不带`--approve`标志的命令只会输出一个计划，该计划由一组反映上述步骤的任务组成，例如

```
[ℹ]  (plan) would migrate 2 iamserviceaccount(s) and 2 addon(s) to pod identity association(s) by executing the following tasks
[ℹ]  (plan)

3 sequential tasks: { install eks-pod-identity-agent addon,
    ## tasks for migrating the addons
    2 parallel sub-tasks: {
        2 sequential sub-tasks: {
            update trust policy for owned role "eksctl-my-cluster--Role1-DDuMLoeZ8weD",
            migrate addon aws-ebs-csi-driver to pod identity,
        },
        2 sequential sub-tasks: {
            update trust policy for owned role "eksctl-my-cluster--Role1-xYiPFOVp1aeI",
            migrate addon vpc-cni to pod identity,
        },
    },
    ## tasks for migrating the iamserviceaccounts
    2 parallel sub-tasks: {
        2 sequential sub-tasks: {
            update trust policy for owned role "eksctl-my-cluster--Role1-QLXqHcq9O1AR",
            create pod identity association for service account "default/sa1",
        },
        2 sequential sub-tasks: {
            update trust policy for unowned role "Unowned-Role1",
            create pod identity association for service account "default/sa2",
        },
    }
}
[ℹ]  all tasks were skipped
[!]  no changes were applied, run again with '--approve' to apply the changes
```

现有的 OIDC 提供商信任关系始终会从与 EKS 插件关联的 IAM 角色中删除。此外，要从与 iamserviceAccounts 关联的 IAM 角色中删除现有的 OIDC 提供商信任关系，请运行带标志的命令，例如 `--remove-oidc-provider-trust-relationship`

```
eksctl utils migrate-to-pod-identity --cluster my-cluster --approve --remove-oidc-provider-trust-relationship
```

## 跨账户 Pod 身份支持
<a name="_cross_account_pod_identity_support"></a>

eksctl 支持 EK [S Pod Identity 跨账户访问](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies-cross-account-resource-access.html)。此功能允许在您的 EKS 集群中运行的 Pod 访问其他 AWS 账户中的 AWS 资源。

### 用法
<a name="_usage"></a>

要创建具有跨账户访问权限的 pod 身份关联，请先设置 IAM 角色和策略，允许从源 AWS 账户（使用集群）访问目标 AWS 账户（使用集群可以访问的资源）。有关示例，请参阅 [“Amazon EKS Pod Identity 简化了跨账户访问”。](https://aws.amazon.com/blogs/containers/amazon-eks-pod-identity-streamlines-cross-account-access/)

在每个账户中配置了 IAM 角色后，使用 eksctl 创建 pod 身份关联：

```
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
  # The cluster name and service account name should match the target
  # account policy's trust relationship.
  name: my-cluster
  region: us-west-2
  version: "1.32"

addons:
  - name: vpc-cni
  - name: coredns
  - name: kube-proxy
  - name: eks-pod-identity-agent

iam:
  podIdentityAssociations:
  - namespace: default
    serviceAccountName: demo-app-sa
    createServiceAccount: true
    # The source role in the same account as the cluster
    roleARN: arn:aws:iam::1111111111:role/account-a-role
    # The target role in a different account
    targetRoleARN: arn:aws:iam::2222222222:role/account-b-role
    # Optional: Disable session tags
    disableSessionTags: false

managedNodeGroups:
  - name: my-cluster
    instanceType: m6a.large
    privateNetworking: true
    minSize: 2
    desiredCapacity: 2
    maxSize: 3
```

## 更多参考文献
<a name="_further_references"></a>

 [适用于 EKS 的官方 AWS 用户文档插件支持 pod 身份](https://docs.aws.amazon.com/eks/latest/userguide/add-ons-iam.html) 

 [关于 Pod 身份关联的 AWS 官方博客文章](https://aws.amazon.com/blogs/aws/amazon-eks-pod-identity-simplifies-iam-permissions-for-applications-on-amazon-eks-clusters/) 

 [Pod 身份关联的官方 AWS 用户文档](https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html) 