
# 在CCE集群中使用容器组身份获取IAM凭证
容器组身份（Pod Identity）是云容器引擎（CCE）提供的一项强大功能，它允许Kubernetes中的Pod以安全、可控的方式访问华为云服务资源。与[基于OIDC的工作负载身份认证](https://support.huaweicloud.com/usermanual-cce/cce_10_2188.html)相比，Pod Identity的配置方式更加简单，具备更强的隔离性。本文档介绍如何CCE集群中使用Pod Identity。
#### Pod Identity简介
Pod Identity为集群中的Pod提供了一种标准化的方式来获取华为云IAM临时凭证：通过将华为云IAM委托直接与[Kubernetes的服务账户（Service Account）](https://kubernetes.io/docs/concepts/security/service-accounts/)相关联，使得Pod可以使用服务账户Token（Service Account Token）直接获取IAM临时凭证。
**核心优势**
- 配置简单：仅需要为Service Account绑定委托，无需配置OIDC身份提供商。
- 权限最小化：为特定的Service Account绑定委托，委托仅授权使用该Kubernetes服务账户的Pod依赖的权限，从而精确控制Pod所拥有的权限。
- 权限隔离：Pod仅能获取其使用的Service Account所绑定的委托的凭据，无法获取其他Service Account绑定的委托的凭据，确保使用不同Service Account的Pod之间的权限完全隔离。
**适用场景**
需要在Pod中访问华为云服务（如ELB、EVS、VPC等）
**Pod Identity原理**
图1原理图   
![](https://support.huaweicloud.com/bestpractice-dew/zh-cn_image_0000002686746964.png "点击放大")
Pod Identity的凭据获取流程如下：
1. 准备工作：创建Service Account与IAM委托的关联，配置Pod使用该Service Account。
2. Pod启动阶段：当Pod配置了开启Pod Identity之后，CCE在创建Pod时，会通过admission自动为Pod注入Pod Identity依赖的相关环境变量以及卷挂载。
   - 环境变量：
     - HC_CONTAINER_AUTHORIZATION_TOKEN_FILE：指向授权令牌文件的路径。
     
     - HC_CONTAINER_CREDENTIALS_FULL_URI：指向凭证提供端点的完整URI。
      
   
   - 卷挂载：
     - 挂载一个projected类型的卷，名称为cce-pod-identity-token，包含服务账户令牌，用于身份验证。
      
    
3. 当Pod需要获取凭据时，使用Service Account Token向节点上的系统组件求凭证。
4. 节点系统组件读取HC_CONTAINER_AUTHORIZATION_TOKEN_FILE所指定的文件中挂载的Service Account Token，并使用它请求HC_CONTAINER_CREDENTIALS_FULL_URI指定的凭证提供端点获取凭证。
5. 返回IAM临时凭证供工作负载使用。
#### 约束与限制
- 仅支持v1.28.15-r80、v1.29.15-r40、v1.30.14-r40、v1.31.14-r0、v1.32.9-r0、v1.33.7-r0、v1.34.2-r0及以上版本集群。
- 通过Pod Identity获取IAM凭据存在流控限制，建议您根据获取到的凭据有效期对其进行缓存（华为云SDK已实现），并避免在Daemonset中使用Pod Identity。
 
#### 在Pod中配置使用Pod Identity
1. **创建IAM委托**
   
   ![](https://support.huaweicloud.com/bestpractice-dew/public_sys-resources/caution_3.0-zh-cn.png)
   请勿删除正在使用中的委托，并确保委托不过期，否则会导致功能异常。
   **使用IAM 3.0委托**
   1. 登录[统一身份认证服务控制台](https://console.huaweicloud.com/iam/#/iam/users)统一身份认证服务 IAM控制台。
   
   2. 在左侧导航栏中选择"委托"，单击"创建委托"。详情请参见[委托其他云服务管理资源](https://support.huaweicloud.com/usermanual-iam/iam_06_0004.html)。
   
   3. 设置"委托名称"，"委托类型"选择"云服务"，并在"云服务"中选择"CCE"，将"持续时间"设为永久。 ![](https://support.huaweicloud.com/bestpractice-dew/zh-cn_image_0000002658536334.png "点击放大")
      
      
   
   4. 单击"完成"。
    
   **使用IAM 5.0信任委托**
   1. 登录[统一身份认证服务新版控制台](https://console.huaweicloud.com/iam5)统一身份认证服务 IAM控制台。
   
   2. 在左侧导航栏中选择"委托"，单击"创建信任委托"。
   
   3. 设置委托参数。
      - 委托名称：自定义委托名称。
      
      - 信任主体类型：选择"自定义信任策略"。
      
      - 最大会话持续时长：自定义最大会话时长，**必须大于等于5小时（18000秒）**。
      
      - 信任策略：设置自定义信任策略内容，信任策略中必须至少允许sts:agencies:assume、sts::setSourceIdentity、sts::tagSession操作。 信任策略示例如下：
        ```
        {
          "Version": "5.0",
          "Statement": [
            {
              "Action": [
                "sts:agencies:assume",
                "sts::setSourceIdentity",
                "sts::tagSession"
              ],
              "Effect": "Allow",
              "Principal": {
                "Service": [
                  "service.CCE"
                ]
              }
            }
          ]
        }
        ```
        
      
      
      ![](https://support.huaweicloud.com/bestpractice-dew/zh-cn_image_0000002688535941.png "点击放大")
      
      
   
   4. 单击"完成"。
    
   
   
2. **创建Kubernetes服务账户** 。
   
   您需要在CCE集群中为Pod创建Service Account。以1.29版本集群为例，使用如下命令在default命名空间内创建ServiceAccount。
   ```
   kubectl create serviceaccount my-service-account
   ```
   使用以下命令可以检查my-service-account是否创建成功，若NAME列出现my-service-account则说明创建成功。
   ```
   kubectl get sa
   ```
   更多关于Service Account的信息请参见[Kubernetes服务账户](https://kubernetes.io/zh-cn/docs/concepts/security/service-accounts/)。
   
   
3. **创建Pod Identity关联** **，将创建好的委托与Kubernetes服务账户进行关联。**
   
   1. 登录[CCE控制台](https://console.huaweicloud.com/cce2.0/?#/cce/cluster/list)CCE控制台，在左侧导航栏中选择"权限管理"，切换至"容器组身份关联"页签。
   
   2. 在左边下拉列表中选择需要创建容器组身份关联的集群。
   
   3. 单击"创建"，选择创建好的委托与服务账户，单击"确定"完成创建。 ![](https://support.huaweicloud.com/bestpractice-dew/zh-cn_image_0000002658536340.png "点击放大")
      
      
   
   
   ![](https://support.huaweicloud.com/bestpractice-dew/public_sys-resources/caution_3.0-zh-cn.png)
   - 同一服务账户只允许创建一条Pod Identity关联记录。
   
   - 请勿删除正在使用中的Pod Identity关联，否则会导致功能异常。
   
   - 新建或更新Pod Identity关联后需要等待15秒生效。
    
   
   
4. **为Pod配置创建好的服务账户** 。
   
   示例如下：
   ```
   apiVersion: v1
   kind: Pod
   metadata:
     name: my-app
   spec:
     serviceAccountName: my-service-account  # 指定服务账户
     containers:
     - name: my-app
       image: my-app:latest
   ```
   
   
5. **启用Pod Identity注入** 。
   
   方式一：命名空间级别启用
   - 您需要为命名空间添加标签pod-identity.cce.io/injection: "on"，例如：
     ```
     kubectl label namespace default pod-identity.cce.io/injection=on
     ```
     
    
   方式二：Pod级别启用
   - 您需要为Pod添加标签pod-identity.cce.io/injection: "on"，例如：
     ```
     apiVersion: v1
     kind: Pod
     metadata:
       name: my-app
       labels:
         pod-identity.cce.io/injection: "on"
     spec:
       serviceAccountName: my-service-account
       containers:
       - name: my-app
         image: my-app:latest
     ```
     
    
   启用后，会自动为Pod注入如下环境变量：
   - HC_CONTAINER_AUTHORIZATION_TOKEN_FILE：指向授权令牌文件的路径。
   
   - HC_CONTAINER_CREDENTIALS_FULL_URI：指向凭证提供端点的完整URI。
   
   
   并且在Pod中挂载如下卷：
   ```
   volumes:
     - name: cce-pod-identity-token
       projected:
         defaultMode: 420
         sources:
         - serviceAccountToken:
             audience: service.cce.pods
             expirationSeconds: 86400 # 超时时间，单位为秒
             path: cce-pod-identity-token
   ```
   
   
6. **通过Pod Identity获取IAM临时凭证** 。
   
   **方式一：使用华为云SDK（SDK版本需高于3.1.211）**
   华为云SDK当前已经实现通过Pod Identity获取IAM凭证，示例如下：
   ![](https://support.huaweicloud.com/bestpractice-dew/zh-cn_image_0000002658377832.png "点击放大")
   **方式二：自主编码实现**
   可在Pod中访问环境变量HC_CONTAINER_CREDENTIALS_FULL_URI指定的地址获取IAM临时凭证，命令示例如下：
   ```
   curl -XPOST http://169.254.170.23:3230/v1/credentials -H "Authorization: service-account-token"
   ```
   其中*http://169.254.170.23:3230/v1/credentials* 为环境变量HC_CONTAINER_CREDENTIALS_FULL_URI指定的地址，*service-account-token*为从环境变量HC_CONTAINER_AUTHORIZATION_TOKEN_FILE指定的文件中读取的服务账户Token。
   
   
 
#### 配置特定Pod不使用Pod Identity
如果您不希望为Pod中某些特定的容器注入使用Pod Identity的环境变量配置，可以通过为Pod配置注解pod-identity.cce.io/skip-containers来指定哪些容器不注入，参数值为容器名称，如有多个容器则以英文逗号分隔，例如：
```
apiVersion: v1
kind: Pod
metadata:
  name: my-app
  labels:
    pod-identity.cce.io/injection: "on"
  annotations:
    pod-identity.cce.io/skip-containers: "sidecar,init-container"  # 指定容器不注入使用Pod Identity的环境变量
spec:
  serviceAccountName: my-service-account
  containers:
  - name: my-app
    image: my-app:latest
  - name: sidecar
    image: sidecar:latest
```
