在CCE集群中使用工作负载Identity的安全配置建议
工作负载Identity允许集群中的工作负载模拟IAM用户来访问云服务,从而无需直接使用IAM账号的AK/SK等信息,降低安全风险。
本文档介绍如何在CCE中使用工作负载Identity。
约束与限制
支持1.19.16及以上版本集群。
使用流程
- 在CCE侧获取集群Service Account Token的签名公钥,操作步骤请参见步骤一:获取CCE集群的签名公钥。
- 在IAM创建身份提供商,操作步骤请参见步骤二:配置身份提供商。
- 在工作负载中获取IAM Token模拟IAM用户访问云服务,操作步骤请参见步骤三:使用工作负载Identity。
主要流程如下:
- 部署应用Pod并通过挂载身份提供商获取OIDC Token文件。
- Pod内程序使用挂载的OIDC Token文件访问IAM获取临时的IAM Token。
- Pod内程序使用IAM Token访问云服务。
图1 工作流程
步骤一:获取CCE集群的签名公钥
- 使用kubectl连接集群。
- 执行如下命令获取公钥。
kubectl get --raw /openid/v1/jwks
# kubectl get --raw /openid/v1/jwks {"keys":[{"use":"sig","kty":"RSA","kid":"*****","alg":"RS256","n":"*****","e":"AQAB"}]}
返回的字段即集群的公钥。
步骤二:配置身份提供商
- 登录IAM控制台,在左侧导航栏选择“身份提供商”,在右上角单击“创建身份提供商”,协议选择OpenID Connect,类型选择虚拟用户SSO,单击“确定”。
- 在身份提供商列表中找到新增的身份提供商,在操作列单击“修改”修改身份提供商信息。
访问方式:选择编程访问。
配置信息
- 身份提供商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" ] } ] } ]
- 单击“确定”。
步骤三:使用工作负载Identity
- 创建ServiceAccount,此处ServiceAccount的名称需要与步骤二:配置身份提供商时填写的ServiceAccountName保持一致。
apiVersion: v1 kind: ServiceAccount metadata: name: oidc-token
- 在工作负载中挂载身份提供商,获取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。
当serviceAccountToken超过24小时或超过80%的过期时间时,kubelet会主动轮转serviceAccountToken。
- 使用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" : "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。