一、1. 背景与方案对比
Pod 访问云 API 时,需要提供云平台可识别的身份凭证。常见方式包括为 Pod 配置长期访问密钥(AK/SK),以及使用 TKE Pod OIDC 身份认证(以下简称 Pod OIDC)获取临时凭证。Pod OIDC 用于建立 Kubernetes ServiceAccount 与云角色之间的信任关系,使云平台能够依据 Pod 所使用的命名空间和 ServiceAccount 进行身份验证与授权。
二、1.1 长期访问密钥方案
长期访问密钥方案需要预先创建 AK/SK,并通过 Kubernetes Secret、环境变量或外部配置系统将凭证提供给 Pod。其调用流程如下:
固定 AK/SK → 保存到 Secret 或外部配置系统 → 注入 Pod → SDK 读取 AK/SK → 直接访问云 API
该方案的凭证生命周期通常较长,需要自行完成凭证的存储、分发和轮换。当多个工作负载共用同一组 AK/SK 时,权限范围和审计记录也难以精确对应到具体的 ServiceAccount。即使 AK/SK 存储在 Secret 或外部配置系统中,其长期凭证属性仍未发生变化。
三、1.2 Pod OIDC 方案
Pod OIDC 方案不在 Pod 中预置长期 AK/SK。TKE 集群为 ServiceAccount 签发短时效 OIDC Token,应用使用该 Token 向 STS 申请 CAM 角色的临时凭证。其调用流程如下:
Pod 使用的 ServiceAccount → TKE 签发短时效 OIDC Token → STS 验证 Token 和角色信任关系 → 返回 CAM 角色临时凭证 → SDK 访问云 API
运行阶段包含以下步骤:
1. TKE 集群为 Pod 使用的 ServiceAccount 签发一个短时效 OIDC Token。
2. CAM 验证 Token 的签发方、签名、有效期和 ServiceAccount 身份,并检查该身份是否允许扮演目标 CAM 角色。
3. STS 返回 CAM 角色的临时凭证(TmpSecretId、TmpSecretKey、Token)。
4. 应用使用临时凭证访问 COS、CLS、CDB、SSM 等云资源。
OIDC Token 和 CAM 临时凭证均具有明确的有效期,并分别由 kubelet 和云 SDK 负责刷新。应用只需配置 ServiceAccount 与 CAM 角色的绑定关系,无需分发或轮换长期 AK/SK。
四、1.3 两种方式的核心差异
| 对比项 | 固定 AK/SK | Pod OIDC |
| Pod 中持有的凭证 | 长期 AK/SK | 短时效 OIDC Token 和按需获取的 CAM 临时凭证 |
| 身份来源 | AK/SK 对应的云用户或云身份 | Kubernetes 命名空间 + ServiceAccount |
| 权限绑定 | 权限绑定在 AK/SK 对应身份上 | ServiceAccount 通过 OIDC 身份映射到 CAM 角色 |
| 权限隔离 | 多个 Pod 可能共用同一组凭证 | 可按业务或 ServiceAccount 绑定不同角色 |
| 凭证存储 | 需要保存和分发 AK/SK | Pod 中不保存长期 AK/SK;Token 通过投影 Volume 挂载 |
| 生命周期 | 通常长期有效,需要主动轮换 | Token 和临时凭证短时有效,可自动刷新 |
| 凭证泄露影响 | 在 AK/SK 被禁用或轮换前可能持续有效 | 受 Token 有效期、临时凭证有效期和角色权限约束 |
| 轮换成本 | 需要更新存储并通知使用方重新加载 | 集群和 SDK 自动刷新,应用无需感知 |
| 审计定位 | 需先定位 AK/SK 所属身份,再关联具体工作负载 | 可结合角色会话、ServiceAccount 和命名空间定位工作负载 |
长期访问密钥方案的管理对象是可重复使用的 AK/SK;Pod OIDC 方案的管理对象是 ServiceAccount 与 CAM 角色之间的信任关系。后者可以减少长期凭证在集群内的存储和分发,并将授权范围细化到 ServiceAccount。
五、1.4 系统组成
Pod OIDC 主要包含以下组件:
| 组件 | 主要职责 |
| TKE OIDC Provider | 为 ServiceAccount 签发 OIDC Token,并提供 Discovery 和 JWKS 端点。 |
| CAM OIDC 身份提供商与 CAM 角色 | 验证 OIDC 身份,将 ServiceAccount 映射到 CAM 角色,并依据角色策略授权。 |
| pod-identity-webhook | 根据 ServiceAccount 注解向 Pod 注入投影 Token、角色 ARN 和相关环境变量。 |
pod-identity-webhook 不签发 CAM 临时凭证,也不代理应用访问云资源。
七、2.1 功能说明
启用 ServiceAccountIssuerDiscovery 后,TKE 集群可作为 OIDC Provider,并提供以下能力:
1. 签发 ServiceAccount Token:Kubernetes API Server 使用集群托管的签名密钥签发短时效 JWT,并通过投影卷提供给 Pod。
2. 提供 Token 验证信息:外部系统通过 OIDC Discovery 端点获取 jwks_uri,再从 JWKS 端点获取公钥并验证 JWT 签名。
签名私钥由 TKE 托管,仅用于签发 Token;验证公钥通过 Discovery 和 JWKS 端点对外提供,供 CAM、AWS IAM 等外部系统验证 Token。签名密钥的存储和轮换由 TKE 负责。
八、2.2 Token 中的 ServiceAccount 身份
Pod 通过 serviceAccountName 指定 ServiceAccount。集群签发 Token 时,会将 ServiceAccount 身份写入 JWT 的标准声明。以下示例仅列出与身份验证相关的主要字段:
{ "iss": "<TKE 集群的 OIDC Issuer URL>", "sub": "system:serviceaccount:prod:cos-reader", "aud": ["sts.cloud.tencent.com"], "iat": 1720000000, "exp": 1720003600}
| 字段 | 含义 | 作用 |
| iss | Token 签发方 | 标识 TKE 集群对应的 OIDC Provider |
| sub | Token 主体 | 格式为 system:serviceaccount:<namespace>:<serviceaccount> |
| aud | Token 接收方 | 必须与云端身份提供商及角色信任策略中的 Audience 一致 |
| iat / exp | 签发时间和过期时间 | 限定 Token 的有效时间范围 |
不同 ServiceAccount 通过 sub 加以区分。例如:
·system:serviceaccount:prod:cos-reader
·system:serviceaccount:prod:log-writer
·system:serviceaccount:test:cos-reader
上述值分别表示三个独立的 OIDC 身份,可分别绑定不同的云角色。
九、2.3 Token 验证流程
外部系统按照 OIDC 标准完成 Token 验证,流程如下:
1. 根据 Token 的 iss 找到 /.well-known/openid-configuration。
2. 从 Discovery 文档读取 jwks_uri。
3. 从 JWKS 端点获取集群公钥,并按 JWT 中的 kid 选择对应公钥。
4. 校验签名、有效期、iss 和 aud。
TKE 会周期性轮换签名私钥,并在旧 Token 仍可能有效的时间范围内保留对应公钥。CAM 等验证方可以缓存 JWKS,并在密钥发生变化时重新获取。
注意:说明:
注意:OIDC Token 用于证明 Pod 的 Kubernetes 身份,不能直接用于调用腾讯云 API。应用需要使用该 Token 向 STS 申请 CAM 临时凭证。
十一、3.1 注册 CAM OIDC 身份提供商
启用集群 OIDC 能力时,如果选择创建 CAM OIDC 提供商,TKE 会将当前集群的 Issuer、Discovery/JWKS 信息和客户端 ID 注册到 CAM。注册完成后,CAM 可以验证由该集群签发且 Audience 符合配置的 OIDC Token。
CAM OIDC Provider 用于标识和验证外部身份来源,不直接授予 COS、CLS 或 CDB 等云资源的访问权限。
十二、3.2 配置角色信任策略
CAM 角色包含信任策略和权限策略,两者作用不同:
| 策略 | 用途 | 典型内容 |
| 角色信任策略 | 哪些身份可以扮演该角色 | OIDC Provider、oidc:aud、oidc:sub、sts:AssumeRoleWithWebIdentity |
| 角色权限策略 | 该角色可以执行哪些操作 | 云产品 API、资源范围和访问条件 |
角色信任策略可以通过 oidc:sub 将指定 ServiceAccount 映射到 CAM 角色。例如:
TKE OIDC Provider + aud = sts.cloud.tencent.com + sub = system:serviceaccount:prod:cos-reader └──> CAM 角色 cos-reader-role └──> 只读指定 COS Bucket
在此配置中,只有 prod 命名空间中的 cos-reader ServiceAccount 可以扮演 cos-reader-role。其他命名空间中的同名 ServiceAccount 不满足该条件。
十三、3.3 STS 身份验证与授权
应用调用 AssumeRoleWithWebIdentity 时,CAM 和 STS 将执行以下检查:
1. Token 的 iss 是否对应已注册的 CAM OIDC Provider。
2. JWT 签名是否能通过该 Provider 的 JWKS 公钥验证。
3. Token 是否在有效期内,aud 是否与配置一致。
4. 目标角色的信任策略是否允许该 Provider、aud 和 sub。
5. 会话参数是否符合角色及 STS 的相关限制。
全部检查通过后,STS 返回临时凭证。该凭证可执行的操作和可访问的资源由角色权限策略决定。
十四、4. pod-identity-webhook 组件职责
pod-identity-webhook 是一个突变准入 Webhook。创建 Pod 时,该组件读取 Pod 所使用 ServiceAccount 的注解,并注入以下内容:
·投影 ServiceAccount Token Volume 与只读挂载。
·TKE_ROLE_ARN:目标云角色 ARN。
·TKE_WEB_IDENTITY_TOKEN_FILE:投影 Token 文件路径。
·根据配置注入 TKE_REGION、TKE_PROVIDER_ID 等辅助环境变量。
各组件的职责如下:
| 动作 | 实际执行者 |
| 决定是否为 Pod 注入身份配置 | pod-identity-webhook |
| 签发 ServiceAccount Token | Kubernetes API Server |
| 将 Token 投射到 Pod 并在到期前刷新 | kubelet |
| 验证 Token 并签发 CAM 临时凭证 | CAM / STS |
| 缓存并刷新 CAM 临时凭证 | 应用使用的云 SDK |
该组件不保存 OIDC 签名私钥、不申请 CAM 临时凭证,也不代理应用访问云 API。
十五、5. 端到端流程
Pod 使用云上资源时,涉及的凭证及其关系如下:
| 凭证 | 如何获得 | 用途 |
| OIDC ServiceAccount Token | TKE 集群根据 Pod 使用的 ServiceAccount 签发,并挂载到 Pod 中 | 向 CAM 证明 Pod 的 Kubernetes 身份 |
| CAM 临时凭证 | 应用或云 SDK 使用 OIDC Token 和目标角色信息向 STS 申请 | 调用角色权限范围内的腾讯云 API |
| 业务凭据(可选) | 应用使用 CAM 临时凭证从 SSM 等服务读取 | 连接数据库等需要独立业务凭据的服务 |
OIDC ServiceAccount Token 不能直接调用腾讯云 API。应用或云 SDK 读取该 Token 后,向 STS 申请目标 CAM 角色的临时凭证。CAM 根据 ServiceAccount 身份与角色的绑定关系完成验证,验证通过后返回临时 SecretId、SecretKey 和 Token。应用随后使用这组临时凭证访问角色已授权的云资源。
如果目标服务还需要独立的业务凭据,例如数据库用户名和密码,应用可以先使用 CAM 临时凭证访问 SSM,再从 SSM 获取当前有效的数据库凭据。此时,OIDC Token 用于取得云身份,CAM 临时凭证用于访问 SSM,数据库凭据则用于连接数据库。具体实践请参见 Pod 使用 CAM 对数据库身份验证。
十六、6. 腾讯云配置流程
配置流程包括以下四个步骤。具体的控制台和命令行操作以对应产品文档为准。
十七、步骤 1:为集群启用 OIDC 身份提供商(每个集群一次)
1. 登录 容器服务控制台,进入集群的 基本信息 > APIServer 信息页面。
2. 编辑 ServiceAccountIssuerDiscovery,选择以下选项:
·创建 CAM OIDC 提供商。
·创建 pod-identity-webhook 组件。
·填写客户端 ID(Audience)。默认值为 sts.cloud.tencent.com。
注意:说明:
注意:首次启用该能力前,需要完成服务角色 QcloudAccessForTKERoleInOIDCConfig 的授权。
注意:
注意:
3. 单击确定完成修改。
注意:service-account-issuer 和 service-account-jwks-uri 由 TKE 托管,用户不能修改。
注意:pod-identity-webhook 由 TKE 托管面安装和维护。可在集群的 组件管理 页面查看组件状态。
注意:
十八、步骤 2:创建 CAM 角色并配置信任策略
1. 进入 访问管理控制台,单击新建角色,选择身份提供商。
2. 在新建自定义角色中,按以下步骤配置:
2.1 选择上一步创建的 OIDC Provider。
2.2 配置角色信任策略:
·oidc:aud = 步骤 1 中的客户端 ID。
·建议配置 oidc:sub = system:serviceaccount:<namespace>:<serviceaccount-name>,限定到具体的 ServiceAccount。
2.3 关联角色权限策略。建议按实际访问需求创建最小权限策略,避免直接绑定范围较大的 *ReadOnlyAccess 策略。
2.4 记录 RoleArn(格式示例:qcs::cam::uin/xxx:roleName/xxx)。
以下信任策略仅允许 prod 命名空间中的 cos-reader ServiceAccount 扮演该角色:
{ "version": "2.0", "statement": [{ "effect": "allow", "principal": { "federated": ["qcs::cam::uin/xxx:oidcProvider/tke-<cluster-id>"] }, "action": ["sts:AssumeRoleWithWebIdentity"], "condition": { "string_equal": { "oidc:aud": ["sts.cloud.tencent.com"], "oidc:sub": ["system:serviceaccount:prod:cos-reader"] } } }]}
以下权限策略仅允许读取指定 COS Bucket:
{ "version": "2.0", "statement": [{ "effect": "allow", "action": ["cos:GetObject", "cos:HeadObject", "cos:ListBucket"], "resource": ["qcs::cos:ap-guangzhou:uid/xxx:my-bucket-xxx/*"] }]}
十九、步骤 3:创建 ServiceAccount 并绑定角色
apiVersion: v1kind: ServiceAccountmetadata: name: cos-reader namespace: prod annotations: tke.cloud.tencent.com/role-arn: qcs::cam::uin/xxx:roleName/cos-reader-role tke.cloud.tencent.com/audience: sts.cloud.tencent.com tke.cloud.tencent.com/token-expiration: "3600"
在工作负载中通过 serviceAccountName 引用该 ServiceAccount:
apiVersion: apps/v1kind: Deploymentmetadata: name: my-app namespace: prodspec: template: spec: serviceAccountName: cos-reader containers: – name: app image: my-app:latest
20、步骤 4:应用侧使用 SDK 访问云资源
·建议使用支持 OIDC 凭证提供器的腾讯云 SDK。SDK 可读取环境变量和投影 Token,并自动申请及刷新临时凭证。
·如果所用 SDK 不支持该凭证提供器,需要调用 STS AssumeRoleWithWebIdentity,再使用返回的临时凭证初始化云产品客户端。
22、7.1 pod-identity-webhook 自动注入的内容
Pod 引用带有 tke.cloud.tencent.com/role-arn 注解的 ServiceAccount 后,Webhook 会向 Pod 注入以下内容:
| 类型 | 键 / 路径 | 说明 |
| 环境变量 | TKE_ROLE_ARN | 目标 CAM 角色 ARN |
| 环境变量 | TKE_WEB_IDENTITY_TOKEN_FILE | 投影 Token 文件路径,默认 /var/run/secrets/cloud.tencent.com/serviceaccount/token |
| 环境变量 | TKE_REGION(如已配置) | 默认地域 |
| Volume | tke-oidc-token | 投影 ServiceAccount Token 卷 |
| VolumeMount | 上述 Token 文件路径 | 只读挂载 |
如果 SDK 无法获取临时凭证,可进入 Pod 执行 env | grep TKE_,并检查 /var/run/secrets/cloud.tencent.com/serviceaccount/ 目录,确认环境变量和 Token 文件是否已正确注入。
23、7.2 各语言 SDK 使用方式
·Go:使用 common.DefaultTkeOIDCRoleArnProvider() 或自定义凭证提供器。
·Python、Java 和 Node.js:使用支持 TKE OIDC 凭证的 SDK 版本,并确认默认凭证链能够识别相关环境变量。
·不支持 OIDC 的 SDK:显式调用 STS AssumeRoleWithWebIdentity,并使用返回的临时凭证初始化客户端。
各语言 SDK 的默认凭证链存在差异。以下顺序仅用于说明常见的凭证解析逻辑;Go SDK 需要通过 DefaultTkeOIDCRoleArnProvider() 显式启用 TKE OIDC 凭证:
显式传入 SecretId/Key → 环境变量 TENCENTCLOUD_SECRET_ID/KEY → OIDC Web Identity Token(Pod OIDC 场景) → CVM 实例角色(节点角色) → 抛错
相关接口参见 Go SDK 凭证管理,以及 Go SDK common 包中的 DefaultProviderChain 和 DefaultTkeOIDCRoleArnProvider。
生产环境中应避免同时配置固定 AK/SK,以防 SDK 优先读取固定凭证而未使用 OIDC 凭证。
24、7.3 Go 语言示例
provider, err := common.DefaultTkeOIDCRoleArnProvider()if err != nil { /* … */ }cred, err := provider.GetCredential()if err != nil { /* … */ }client, _ := cos.NewClient(&cos.BaseURL{…}, &http.Client{ Transport: &cos.AuthorizationTransport{ SecretID: cred.GetSecretId(), SecretKey: cred.GetSecretKey(), SessionToken: cred.GetToken(), },})
25、8. ServiceAccount 注解参考
| 注解 | 必填 | 默认值 | 说明 |
| tke.cloud.tencent.com/role-arn | 是 | 无 | 目标 CAM 角色 ARN。 |
| tke.cloud.tencent.com/audience | 否 | sts.cloud.tencent.com | JWT Audience,必须与 CAM 角色信任策略中的 oidc:aud 一致;如果信任策略配置了多个 Audience,可填写其中任意一个。 |
| tke.cloud.tencent.com/token-expiration | 否 | 3600 | 投影 Token 有效期,单位为秒;取值范围为 600~86400。 |
如需为个别 Pod 配置不同的 Token 有效期,可以在 Pod 上设置同名注解覆盖 ServiceAccount 的配置。
26、9. 限制与配额
| 项 | 限制 |
| 支持集群类型 | TKE 托管集群;独立集群 / Serverless 集群 / 边缘集群支持情况请查看控制台或提工单确认。 |
| 集群版本要求 | ≥ v1.20.6-tke.27 或 ≥ v1.22.5-tke.1,更高版本默认支持。 |
| Pod 网络要求 | 需能访问腾讯云 STS 端点。VPC 无出网集群请使用内网 STS 端点或配置 PrivateLink。 |
| Token 有效期 | 600 ~ 86400 秒。 |
| 单个 ServiceAccount 可绑定的角色数量 | 1;如需使用多个角色,建议创建多个 ServiceAccount。 |
| AssumeRoleWithWebIdentity 频控 | 遵循 CAM 全局配额,建议 SDK 缓存临时凭证,接近过期再刷新。 |
| 超级节点 / 虚拟节点 | 支持,注解使用方式一致。 |
| 私有集群 / 无公网出口 | 需要配置 Pod 到 STS 内网端点的网络路径。 |
28、FAQ 1:SDK 提示未找到凭证
排查步骤如下:
1. 执行 kubectl describe pod,检查是否存在 TKE_ROLE_ARN 等环境变量。
·如果环境变量不存在,请检查 ServiceAccount 注解、Pod 的 serviceAccountName,以及 pod-identity-webhook 组件状态。
2. 执行 kubectl exec 进入 Pod,再执行 cat $TKE_WEB_IDENTITY_TOKEN_FILE。
·如果文件不存在,请检查投影卷是否已注入和挂载,以及 Pod 是否禁用了 ServiceAccount Token 自动挂载。
3. 确认 SDK 版本支持 TKE OIDC 凭证提供器;不支持时需要升级 SDK 或显式调用 STS 接口。
29、FAQ 2:AssumeRoleWithWebIdentity 返回 401 或无权限
排查步骤如下:
·确认 CAM 角色信任策略中的 oidc:aud 与 ServiceAccount 注解中的 Audience 一致。
·确认 oidc:sub 与 Pod 使用的 ServiceAccount 完全匹配,格式为 system:serviceaccount:<namespace>:<serviceaccount>。
·确认 CAM OIDC Provider 仍然存在。如果 ServiceAccountIssuerDiscovery 提示身份提供商不存在,需要重新创建 Provider。
30、FAQ 3:临时凭证过期后 SDK 未自动刷新
·检查 SDK 版本是否支持临时凭证自动刷新,必要时升级 SDK。
·使用自定义凭证提供器时,建议在凭证剩余有效期低于 10% 前刷新。
·不要将临时凭证写入磁盘,或在全局变量中长期复用已经过期的凭证。
31、FAQ 4:VPC 无出网的集群如何使用
·确保 Pod 可以访问 CAM/STS 内网端点。
·可通过 VPC 内网、PrivateLink 或 NAT 出口建立访问路径。
·集群 OIDC Discovery 端点由 TKE 托管,供 CAM 获取验证公钥;Pod 仍需具备访问 STS 端点的网络条件。
32、FAQ 5:ServiceAccountIssuerDiscovery 无法编辑
·确认已完成服务角色 QcloudAccessForTKERoleInOIDCConfig 的授权。
·如果授权已经完成但仍无法编辑,请提交工单排查。
33、FAQ 6:如何撤销一个 Pod 的权限
·移除 ServiceAccount 的 role-arn 注解并重新创建 Pod,使新 Pod 不再注入身份配置。
·已签发的临时凭证在过期前仍可能有效。如需立即阻止访问,应在 CAM 角色权限策略中撤销相关权限。
34、FAQ 7:多个 Pod / 多命名空间共用一个角色是否安全
·多个 Pod 或命名空间可以共用同一角色,但会扩大该角色的信任范围。
·建议按业务模块配置独立的 ServiceAccount 和角色,并通过 oidc:sub 限定可扮演角色的身份。
36、11.1 作用
对于引用了带 tke.cloud.tencent.com/role-arn 注解的 ServiceAccount 的 Pod,该组件会注入投影 ServiceAccount Token、环境变量和 Volume。组件由 TKE 托管面安装和维护,可在集群的 组件管理 页面查看运行状态。
37、11.2 最小权限(RBAC)
rules:- apiGroups: [""] resources: ["serviceaccounts"] verbs: ["get", "watch", "list"]- apiGroups: [""] resources: ["events"] verbs: ["patch", "update"]- apiGroups: ["admissionregistration.k8s.io"] resources: ["mutatingwebhookconfigurations"] verbs: ["get"]
部分版本需要对 mutatingwebhookconfigurations 增加 update 权限,用于注入自签名证书。实际权限以组件版本为准。
38、11.3 升级与自愈
组件版本和升级操作由 TKE 组件管理功能统一管理。组件状态异常时,可先重启 Webhook Deployment;如果问题仍未解决,请提交工单排查。
39、12. 对接 AWS 服务
TKE 签发的 ServiceAccount Token 是标准 OIDC JWT。除腾讯云 CAM 外,也可将 TKE OIDC Provider 注册到 AWS IAM,并使用 Web Identity 方式申请 AWS IAM Role 的临时凭证。调用关系如下:
TKE ServiceAccount └──> TKE OIDC Token └──> AWS STS AssumeRoleWithWebIdentity └──> AWS IAM Role 临时凭证 └──> S3 / DynamoDB / SQS / 其他 AWS 服务
TKE 可以在启用集群 OIDC 能力时自动创建 CAM OIDC Provider,但不会在用户的 AWS 账号中创建 IAM OIDC Provider、IAM Role 或权限策略。AWS 侧的身份提供商和角色信任关系需要由用户配置。
40、12.1 AWS 侧对象及其作用
| AWS 对象 | 作用 | 需要配置的关键内容 |
| IAM OIDC Provider | 注册并验证 TKE 集群签发的 Token | TKE Issuer URL、Discovery/JWKS、Audience,以及必要时使用的证书指纹 |
| IAM Role 信任策略 | 定义允许扮演角色的 OIDC 身份 | Provider ARN、sts:AssumeRoleWithWebIdentity、aud、sub |
| IAM Role 权限策略 | 定义角色可以调用的 AWS API | Action、Resource、Condition |
IAM OIDC Provider 负责验证身份来源,IAM Role 信任策略负责限定可扮演角色的 ServiceAccount,IAM Role 权限策略负责限定角色的访问权限。
41、12.2 在 AWS IAM 中注册 TKE OIDC Provider
1. 为 TKE 集群启用 ServiceAccountIssuerDiscovery,获取集群的 OIDC Issuer URL。
2. 确认以下端点可通过公网 HTTPS 访问:
·<Issuer URL>/.well-known/openid-configuration
·Discovery 文档中 jwks_uri 指向的 JWKS 端点
3. 在 AWS IAM 控制台进入 Identity providers > Add provider,类型选择 OpenID Connect。
4. Provider URL 填写 TKE 集群的 Issuer URL。
5. 在 Audience 中填写 sts.amazonaws.com。ServiceAccount 投影 Token 的 aud 必须与该值一致。
AWS 根据 Discovery 文档中的 issuer 和 jwks_uri 获取验证信息。如果 OIDC 端点使用的根 CA 不受 AWS 信任,或 AWS 无法验证 TLS 证书链,还需要按照 AWS 要求配置证书指纹。具体要求参见 AWS:创建 IAM OIDC 身份提供商。
注意:说明:
注意:IAM OIDC Provider 与信任该 Provider 的 IAM Role 必须位于同一 AWS 账号。跨账号访问需要在角色所在账号中建立 OIDC 信任,再通过角色或资源策略完成后续授权。
42、12.3 创建 AWS IAM Role 并绑定 OIDC 身份
IAM Role 需要同时配置权限策略和信任策略。以下权限策略仅允许列出并读取指定的 S3 Bucket:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": ["s3:ListBucket"], "Resource": ["arn:aws:s3:::example-bucket"] }, { "Effect": "Allow", "Action": ["s3:GetObject"], "Resource": ["arn:aws:s3:::example-bucket/*"] } ]}
以下信任策略将 prod 命名空间中的 s3-reader ServiceAccount 绑定到该角色:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::<AWS_ACCOUNT_ID>:oidc-provider/<ISSUER_HOST_AND_PATH>" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "<ISSUER_HOST_AND_PATH>:aud": "sts.amazonaws.com", "<ISSUER_HOST_AND_PATH>:sub": "system:serviceaccount:prod:s3-reader" } } } ]}
请按实际环境替换以下占位符:
·<AWS_ACCOUNT_ID>:AWS 账号 ID。
·<ISSUER_HOST_AND_PATH>:去掉 https:// 的完整 Issuer 主机名与路径,必须与 IAM OIDC Provider ARN 中的值一致。
·sub:允许扮演角色的 TKE 命名空间和 ServiceAccount。本例仅允许 prod/s3-reader。
·aud:必须与 IAM OIDC Provider 的 Audience 和 ServiceAccount 注解一致。
应避免使用不受限制的 sub 通配符,否则同一集群中的其他 ServiceAccount 也可能扮演该角色。Web Identity 角色的信任策略要求请参见 AWS:为 OIDC 联合身份创建角色。
43、12.4 创建用于 AWS 的 ServiceAccount
pod-identity-webhook 会将 role-arn 注解的值写入 TKE_ROLE_ARN。对接 AWS 时,可在该注解中填写 AWS IAM Role ARN:
apiVersion: v1kind: ServiceAccountmetadata: name: s3-reader namespace: prod annotations: tke.cloud.tencent.com/role-arn: arn:aws:iam::<AWS_ACCOUNT_ID>:role/tke-s3-reader tke.cloud.tencent.com/audience: sts.amazonaws.com tke.cloud.tencent.com/token-expiration: "3600"
Pod 通过 serviceAccountName: s3-reader 使用该 ServiceAccount。Webhook 将注入以下环境变量:
TKE_ROLE_ARN=arn:aws:iam::<AWS_ACCOUNT_ID>:role/tke-s3-readerTKE_WEB_IDENTITY_TOKEN_FILE=/var/run/secrets/cloud.tencent.com/serviceaccount/token
44、12.5 初始化 AWS SDK 客户端
AWS SDK 的 Web Identity 默认凭证链读取:
·AWS_ROLE_ARN
·AWS_WEB_IDENTITY_TOKEN_FILE
·AWS_ROLE_SESSION_NAME(可选)
TKE Webhook 注入的变量名为 TKE_ROLE_ARN 和 TKE_WEB_IDENTITY_TOKEN_FILE,AWS SDK 默认凭证链不会读取这两个变量。可采用以下方式进行适配。以下示例通过 AWS SDK for Go v2 显式读取 TKE 环境变量并初始化 S3 客户端:
package awsauthimport ( "context" "fmt" "os" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/credentials/stscreds" "github.com/aws/aws-sdk-go-v2/service/s3" "github.com/aws/aws-sdk-go-v2/service/sts")func NewS3Client(ctx context.Context, awsRegion string) (*s3.Client, error) { roleARN := os.Getenv("TKE_ROLE_ARN") tokenFile := os.Getenv("TKE_WEB_IDENTITY_TOKEN_FILE") if roleARN == "" || tokenFile == "" { return nil, fmt.Errorf("missing TKE_ROLE_ARN or TKE_WEB_IDENTITY_TOKEN_FILE") } baseCfg, err := config.LoadDefaultConfig(ctx, config.WithRegion(awsRegion)) if err != nil { return nil, fmt.Errorf("load AWS base config: %w", err) } stsClient := sts.NewFromConfig(baseCfg) roleSessionName := os.Getenv("HOSTNAME") if roleSessionName == "" { roleSessionName = "tke-pod" } provider := stscreds.NewWebIdentityRoleProvider( stsClient, roleARN, stscreds.IdentityTokenFile(tokenFile), func(options *stscreds.WebIdentityRoleOptions) { options.RoleSessionName = roleSessionName }, ) cfg, err := config.LoadDefaultConfig( ctx, config.WithRegion(awsRegion), config.WithCredentialsProvider(provider), ) if err != nil { return nil, fmt.Errorf("load AWS config with web identity: %w", err) } return s3.NewFromConfig(cfg), nil}
其他语言可以采用相同方式:显式创建 Web Identity Credential Provider,并将 TKE_ROLE_ARN 与 TKE_WEB_IDENTITY_TOKEN_FILE 分别作为角色 ARN 和 Token 文件路径传入。AWS 标准配置项参见 AWS SDK:Assume role credential provider,Go v2 Provider 用法参见 AWS SDK for Go v2:AssumeRoleWithWebIdentity。
注意:说明:
注意:TKE_REGION 表示腾讯云地域,不能用作 AWS Region。初始化 AWS 客户端时,需要单独配置 ap-southeast-1 等 AWS Region。
45、12.6 AWS 接入排查
可按以下顺序进行排查:
1. InvalidIdentityToken:确认 AWS 可以访问 TKE Discovery 和 JWKS 端点,并检查 Issuer URL 与 TLS 证书链。
2. Audience 不匹配:确认 IAM OIDC Provider、角色信任策略和 ServiceAccount 注解均使用 sts.amazonaws.com。
3. AccessDenied(无法扮演角色):确认 Provider ARN、sub 和目标 Role ARN 完全匹配。
4. 已获得临时凭证但无法访问资源:检查 IAM Role 权限策略中的 Action 和 Resource。
5. SDK 提示未找到凭证:确认应用显式读取 TKE_* 环境变量,或已将其映射为 AWS SDK 默认读取的 AWS_* 环境变量。
46、13. 相关文档
·场景实践:Pod 使用 CAM 对数据库身份验证,介绍 Pod 通过 CAM 和 SSM 访问 MySQL 数据库的配置方法。
·问题反馈:请提交工单,或在集群的 组件管理 页面反馈 pod-identity-webhook 相关问题。