更新时间:2024-04-11 GMT+08:00
分享

工作负载Identity

工作负载Identity允许集群中的工作负载模拟IAM用户来访问云服务,从而无需直接使用IAM账号的AK/SK等信息,降低安全风险。

本文档介绍如何在CCE中使用工作负载Identity。

约束与限制

支持1.19.16及以上版本集群。

使用流程

  1. 在CCE侧获取集群的jwks(即集群的service account token的签名公钥)。
  2. 在IAM创建身份提供商。
  3. 部署应用并将挂载身份提供商。
    1. 使用oidc token访问IAM获取IAM Token(用户实现)
    2. 使用IAM Token访问云服务(用户实现)

获取CCE集群的jwks

  1. 使用kubectl连接集群。
  2. 执行如下命令获取公钥。

    kubectl get --raw /openid/v1/jwks

    # kubectl get --raw /openid/v1/jwks
    {"keys":[{"use":"sig","kty":"RSA","kid":"*****","alg":"RS256","n":"*****","e":"AQAB"}]}

    返回的字段即集群的公钥。

配置身份提供商

  1. 登录IAM控制台,创建身份提供商,协议选择OpenID Connect。

  2. 单击“确定”,然后修改身份提供商信息。

    访问方式:选择编程访问

    配置信息

    • 身份提供商URL:填写为 https://kubernetes.default.svc.cluster.local
    • 客户端ID:填写一个ID,后续创建容器时使用。
    • 签名公钥:CCE集群的jwks,获取方法请参见获取CCE集群的jwks

    身份转换规则

    身份映射规则是将工作负载的ServiceAccount和IAM用户组做映射。

    例如在集群default命名空间下创建一个名为oidc-token的ServiceAccount,映射到demo用户组(后续使用身份提供商ID访问云服务就具有demo用户组的权限)。此处属性必须是sub,值的格式为:system:serviceaccount:Namespace:ServiceAccountName

    规则的json格式如下。

    [
        {
            "local": [
                {
                    "user": {
                        "name": "test"
                    }
                },
                {
                    "group": {
                        "name": "demo"
                    }
                }
            ],
            "remote": [
                {
                    "type": "sub",
                    "any_one_of": [
                        "system:serviceaccount:default:oidc-token"
                    ]
                }
            ]
        }
    ]

  3. 单击“确定”

使用工作负载Identity

创建ServiceAccount,此处ServiceAccount的名称需要与配置身份提供商时填写的ServiceAccountName保持一致。

apiVersion: v1
kind: ServiceAccount
metadata:
  name: oidc-token

在工作负载中使用示例如下。

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/oidc-token文件内
          name: oidc-token
      imagePullSecrets:
      - name: default-secret
      serviceAccountName: oidc-token      # 前面创建的ServiceAccount的名称
      volumes:
      - name: oidc-token
        projected:
          defaultMode: 420
          sources:
          - serviceAccountToken:
              audience: client_id   # 此处取值必须为身份提供商的客户端ID
              expirationSeconds: 7200       # 过期时间
              path: oidc-token              # 路径名称,可自定义

创建完成后登录到容器中,/var/run/secrets/tokens/oidc-token文件内容就是Kubernetes生成的serviceAccountToken,调用获取联邦认证token(OpenID Connect ID token方式)接口即可获取IAM Token,响应消息头中X-Subject-Token字段即为IAM Token,从而使用IAM Token访问云服务。

当serviceAccountToken超过24小时或超过80%的过期时间时,kubelet会主动轮转serviceAccountToken

访问示例如下:

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

其中:

  • {{iam endpoint}}为IAM服务的Endpoint,具体请参见地区和终端节点
  • workload_identity即为身份提供商名称,与配置身份提供商中配置的名称相同。
  • token_body.json为本地文件,内容如下所示:
     { 
       "auth" : { 
         "id_token" : { 
           "id" : "eyJhbGciOiJSU..."
         }, 
         "scope": { 
           "project" : { 
             "id" : "46419baef4324...",
             "name" : "cn-north-4"
           } 
         } 
       } 
     }
    • $.auth.id_token.id:此处取值为容器中/var/run/secrets/tokens/oidc-token文件的内容。
    • $.auth.scope.project.id:项目ID。获取方式请参见获取项目ID
    • $.auth.scope.project.name:项目名称,例如cn-north-4。
分享:

    相关文档

    相关产品