
# 使用工作负载Identity安全访问云服务
#### 应用场景
工作负载Identity允许集群中的工作负载模拟IAM用户来访问云服务，从而无需直接使用IAM账号的 AK/SK 等信息，降低安全风险。
本文档介绍如何在UCS中使用工作负载Identity。
#### 方案流程
使用工作负载Identity的流程如[图1 使用工作负载Identity流程]，具体流程如下：
1. 前置授权。 
   1. 在UCS[获取本地集群私钥签发的jwks]，该公钥用于验证集群签发的ServiceAccount Token。
   
   2. 在 IAM [配置身份供应商]，标志当前集群在IAM侧的身份。
   
   3. 为身份提供商配置集群签发的公钥，后续负载使用Token发送请求时，IAM使用该公钥验证Token。
   
   4. 添加 ServiceAccount 与 IAM 账号的映射规则，配置后，当前 ServiceAccount 拥有对应用户的 IAM 权限。
   
   
   
   
2. 工作负载配置Token。 
   1. 部署应用并配置ServiceAccount。
   
   2. 挂载对应ServiceAccount的Token。
   
   
   
   
3. 验证获取的Token能否正常进行访问。 
   1. 访问IAM接口获取IAM Token。
   
   2. 使用IAMToken 访问云服务。
   
   
   
   
图1使用工作负载Identity流程   
![](https://support.huaweicloud.com/bestpractice-ucs/zh-cn_image_0000002048572596.png "点击放大")
 #### 获取本地集群私钥签发的jwks
1. 使用kubectl连接本地集群。
2. 执行如下命令获取公钥。 
   **kubectl get --raw /openid/v1/jwks**
   返回结果为一个 json 字符串，是当前集群的签名公钥，用于访问身份提供商。
   ```
   {
       "keys": [
           {
               "kty": "RSA",
               "e": "AQAB",
               "use": "sig",
               "kid": "Ew29q....",
               "alg": "RS256",
               "n": "peJdm...."
           }
       ]
   }
   ```
   
   
 
 #### 配置身份提供商
1. 登录[统一身份认证服务控制台](https://console.huaweicloud.com/iam/#/iam/users)，创建身份提供商，协议选择OpenID Connect。
   
   图2创建身份提供商   
   ![](https://support.huaweicloud.com/bestpractice-ucs/zh-cn_image_0000001768363710.png "点击放大")
   
   
2. 单击"确定"，然后修改身份提供商信息，需要修改的信息如[表1 身份提供商配置参数说明]。若需要创建身份转换规则，单击"创建规则"进行创建。
   
   图3修改身份提供商信息   
   ![](https://support.huaweicloud.com/bestpractice-ucs/zh-cn_image_0000001768365910.png "点击放大")
   图4创建身份转换规则   
   ![](https://support.huaweicloud.com/bestpractice-ucs/zh-cn_image_0000001734972304.png "点击放大")
    表1身份提供商配置参数说明 
   | 参数     | 说明                                                                                                                                                                                                                                                                                                                                                                                               |
   |:---|:---|
   | 访问方式   | 选择"编程访问"                                                                                                                                                                                                                                                                                                                                                                                         |
   | 配置信息   | - 身份提供商 URL：https://kubernetes.default.svc.cluster.local。  - 客户端 ID：ucs-cluster-identity。  - 签名公钥：本地集群的jwks，获取方法请参见[获取本地集群私钥签发的jwks]。   |
   | 身份转换规则 | 身份映射规则是将工作负载的 ServiceAccount 和 IAM 用户组做映射。 例如：在集群default命名空间下创建一个名为 XXX 的 ServiceAccount，映射到 demo 用户组（后续使用身份提供商 ID 访问云服务就具有 demo 用户组的权限）。 值的格式为：system:serviceaccount:*Namespace* :*ServiceAccountName*                                                                                                                               |
      
   
   
3. 单击"确定"。
 
#### 获取IAM Token
1. 创建 ServiceAccount，此处 ServiceAccount 的名称需要与[2]时填写的 ServiceAccountName 保持一致。
   
   ```
   apiVersion: v1 
   kind: ServiceAccount 
   metadata: 
    name: test_sa_name # 与配置身份转换规则处保持一致
   ```
   
   
2. 如下所示，在工作负载中新增 ServiceAccount 以及 Volume 相关配置。 
   ```
   apiVersion: apps/v1
   kind: Deployment
   metadata:
     name: nginx
   spec:
     replicas: 1
     selector:
       matchLabels:
         app: nginx
         version: v1
     template:
       metadata:
         labels:
           app: nginx
           version: v1
       spec:
         containers:
         - name: container-1
           image: nginx:latest
           volumeMounts
           - mountPath: "/var/run/secrets/tokens" # 将Kubernetes生成的ServiceAccountToken 挂载到 /var/run/secrets/tokens/token_path 文件内
             name: token-volume
         imagePullSecrets:
         - name: default-secret
         serviceAccountName: test_sa_name   # 上一步创建的ServiceAccount的名称
         volumes:
         - name: token-volume
           projected:
             defaultMode: 420
             sources:
             - serviceAccountToken:
                 audience: ucs-cluster-identity   # 此处取值必须为身份提供商的客户端ID
                 expirationSeconds: 7200     # 过期时间
                 path: token_path     # 路径名称，可自定义
   ```
   
   
3. 创建完成后，登录到容器中获取 Token。 
   ![](https://support.huaweicloud.com/bestpractice-ucs/zh-cn_image_0000001711722202.png "点击放大")
   
   
4. 构造请求体数据，项目ID的获取请参见[获取项目ID](https://support.huaweicloud.com/api-ucs/ucs_api_0018.html)。
   
   ```
   {
       "auth" : { 
         "id_token" : { 
           "id" : "eyJhbGciOiJSUzIXXXXX"   // 上一步获得的 token 内容
         },
         "scope": {
           "project" : {
             "id" : "05495693df80d3c92fa1c01795c2be02",  // 项目 ID
             "name" : "cn-north-7"  
           }
         }
       }
     }
   ```
   
   
5. 请求IAM接口以获取IAM Token，IAM的Endpoint信息请参见[地区和终端节点](https://console.huaweicloud.com/apiexplorer/#/endpoint)。
   
   ```
   curl -i --location --request POST 'https://{{iam endpoint}}/v3.0/OS-AUTH/id-token/tokens'  --header 'X-Idp-Id: {{workload_identity}}'  --header 'Content-Type: application/json'  --data @token_body.json
   ```
   - workload_identity为[1]中注册的身份提供商名称，此示例内为 ucs-cluster-identity。
   
   - token_body.json 为构造的请求体数据文件。
   
   
   
   
6. 返回体内获取IAM Token，响应消息头中 X-Subject-Token 字段即为 IAM Token。 
   ![](https://support.huaweicloud.com/bestpractice-ucs/zh-cn_image_0000001759761301.png "点击放大")
   
   
 
#### 使用IAM Token访问云服务
本小节以请求LTS服务为例，介绍如何使用IAM Token访问云服务。
1. 在使用IAM Token访问云服务前，应为用户组配置相应服务的权限。
2. 请求LTS服务需要在用户组中加上 LTS FullAccess 权限，如图所示。 
   ![](https://support.huaweicloud.com/bestpractice-ucs/zh-cn_image_0000001815248737.png "点击放大")
   
   
3. 执行如下命令，调用对应服务接口。 
   ```
   curl --location --request GET 'https://ltsperform.cn-north-7.myhuaweicloud.com/v2/{{项目 ID}}/groups/{{日志组 ID}}/streams' \--header 'Content-Type: application/json;charset=utf-8' \--header 'X-Auth-Token: {{上一步获得的 IAM token}}' \--data-raw ''
   ```
   日志组ID可在LTS服务内进行查询。
   ![](https://support.huaweicloud.com/bestpractice-ucs/zh-cn_image_0000001711881726.png "点击放大")
   期望的返回结果如图所示
   ![](https://support.huaweicloud.com/bestpractice-ucs/zh-cn_image_0000001711722206.png "点击放大")
   
   
 
