文档首页/ 华为云UCS/ 最佳实践/ 本地集群/ 使用工作负载Identity安全访问云服务
更新时间:2024-11-01 GMT+08:00

使用工作负载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流程

获取本地集群私钥签发的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. 登录IAM控制台,创建身份提供商,协议选择OpenID Connect。

    图2 创建身份提供商

  2. 单击“确定”,然后修改身份提供商信息,需要修改的信息如表1 身份提供商配置参数说明。若需要创建身份转换规则,单击“创建规则”进行创建。

    图3 修改身份提供商信息
    图4 创建身份转换规则
    表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。

  4. 构造请求体数据,项目ID的获取请参见获取项目ID

    {
        "auth" : { 
          "id_token" : { 
            "id" : "eyJhbGciOiJSUzIXXXXX"   // 上一步获得的 token 内容
          },
          "scope": {
            "project" : {
              "id" : "05495693df80d3c92fa1c01795c2be02",  // 项目 ID
              "name" : "cn-north-7"  
            }
          }
        }
      }

  5. 请求IAM接口以获取IAM Token,IAM的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。

使用IAM Token访问云服务

本小节以请求LTS服务为例,介绍如何使用IAM Token访问云服务。

  1. 在使用IAM Token访问云服务前,应为用户组配置相应服务的权限。
  2. 请求LTS服务需要在用户组中加上 LTS FullAccess 权限,如图所示。

  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服务内进行查询。

    期望的返回结果如图所示