文档首页/ 云容器引擎 CCE/ 最佳实践/ 安全/ 在CCE集群中使用工作负载Identity的安全配置建议
更新时间:2024-12-17 GMT+08:00
分享

在CCE集群中使用工作负载Identity的安全配置建议

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

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

约束与限制

支持1.19.16及以上版本集群。

使用流程

  1. 在CCE侧获取集群Service Account Token的签名公钥,操作步骤请参见步骤一:获取CCE集群的签名公钥
  2. 在IAM创建身份提供商,操作步骤请参见步骤二:配置身份提供商
  3. 在工作负载中获取IAM Token模拟IAM用户访问云服务,操作步骤请参见步骤三:使用工作负载Identity

    主要流程如下:
    1. 部署应用Pod并通过挂载身份提供商获取OIDC Token文件。
    2. Pod内程序使用挂载的OIDC Token文件访问IAM获取临时的IAM Token。
    3. Pod内程序使用IAM Token访问云服务。
    图1 工作流程

步骤一:获取CCE集群的签名公钥

  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,类型选择虚拟用户SSO,单击“确定”

  2. 在身份提供商列表中找到新增的身份提供商,在操作列单击“修改”修改身份提供商信息。

    访问方式:选择编程访问

    配置信息

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

    身份转换规则

    身份映射规则是将工作负载的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

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

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

  2. 在工作负载中挂载身份提供商,获取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              # 路径名称,可自定义

  3. 创建完成后登录到容器中,/var/run/secrets/tokens/oidc-token文件内容就是Kubernetes生成的serviceAccountToken。

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

  4. 使用OIDC Token调用获取联邦认证token(OpenID Connect ID token方式)接口,响应消息头中X-Subject-Token字段即为IAM Token,从而使用IAM Token访问云服务。

    接口调用示例如下:

    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" : ******
             } 
           } 
         } 
       }
      • $.auth.id_token.id:此处取值为容器中/var/run/secrets/tokens/oidc-token文件的内容。
      • $.auth.scope.project.id:项目ID。获取方式请参见获取项目ID
      • $.auth.scope.project.name:项目名称,例如cn-north-4。

相关文档