帮你快速理解、总结文档立即下载
文档中心>容器服务>安全和稳定性>身份验证和授权>Pod 使用 CAM 角色(OIDC 身份)功能介绍

Pod 使用 CAM 角色(OIDC 身份)功能介绍

最近更新时间:2026-08-27 17:08:01
我的收藏
本文介绍 TKE OIDC Provider、ServiceAccount Token、CAM 身份提供商和 CAM 角色的作用及其协作关系,并说明 Pod 使用 OIDC 身份访问腾讯云资源的配置方法和运行流程。文末提供对接 AWS IAM 的配置示例。

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 角色的临时凭证(TmpSecretIdTmpSecretKeyToken)。
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. TKE 集群 OIDC Provider

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. 校验签名、有效期、issaud
TKE 会周期性轮换签名私钥,并在旧 Token 仍可能有效的时间范围内保留对应公钥。CAM 等验证方可以缓存 JWKS,并在密钥发生变化时重新获取。
说明:
OIDC Token 用于证明 Pod 的 Kubernetes 身份,不能直接用于调用腾讯云 API。应用需要使用该 Token 向 STS 申请 CAM 临时凭证。

3. CAM OIDC 身份与角色映射

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:audoidc:substs: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、audsub
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_REGIONTKE_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 身份与角色的绑定关系完成验证,验证通过后返回临时 SecretIdSecretKeyToken。应用随后使用这组临时凭证访问角色已授权的云资源。
如果目标服务还需要独立的业务凭据,例如数据库用户名和密码,应用可以先使用 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

在集群基本信息中编辑 ServiceAccountIssuerDiscovery,勾选“创建 CAM OIDC 提供商”与“创建 pod-identity-webhook 组件”,并填写客户端 ID 后确定


说明:
首次启用该能力前,需要完成服务角色 QcloudAccessForTKERoleInOIDCConfig 的授权。

首次开启 OIDC 时的“修改参数”弹窗,提示需完成服务授权



在角色管理页“同意授权” QcloudAccessForTKERoleInOIDCConfig 服务角色


3. 单击确定完成修改。
注意:
service-account-issuerservice-account-jwks-uri 由 TKE 托管,用户不能修改。
pod-identity-webhook 由 TKE 托管面安装和维护。可在集群的 组件管理 页面查看组件状态。

创建完成后在访问管理控制台查看 CAM OIDC 提供商详情



步骤 2:创建 CAM 角色并配置信任策略

1. 进入 访问管理控制台,单击新建角色,选择身份提供商
2. 新建自定义角色中,按以下步骤配置:
2.1 选择上一步创建的 OIDC Provider。

在访问管理控制台“新建角色 &gt; 身份提供商”中创建自定义角色并选择 OIDC 提供商


2.2 配置角色信任策略:
oidc:aud = 步骤 1 中的客户端 ID。
建议配置 oidc:sub = system:serviceaccount:<namespace>:<serviceaccount-name>,限定到具体的 ServiceAccount。

配置角色信任策略中的 oidc:aud 与 oidc:sub 条件


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: v1
kind: ServiceAccount
metadata:
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/v1
kind: Deployment
metadata:
name: my-app
namespace: prod
spec:
template:
spec:
serviceAccountName: cos-reader
containers:
- name: app
image: my-app:latest

步骤 4:应用侧使用 SDK 访问云资源

建议使用支持 OIDC 凭证提供器的腾讯云 SDK。SDK 可读取环境变量和投影 Token,并自动申请及刷新临时凭证。
如果所用 SDK 不支持该凭证提供器,需要调用 STS AssumeRoleWithWebIdentity,再使用返回的临时凭证初始化云产品客户端。

7. 腾讯云 SDK 集成

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 文件是否已正确注入。

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 包中的 DefaultProviderChainDefaultTkeOIDCRoleArnProvider
生产环境中应避免同时配置固定 AK/SK,以防 SDK 优先读取固定凭证而未使用 OIDC 凭证。

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(),
},
})

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 的配置。

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 内网端点的网络路径。

10. 常见问题与故障排查

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 接口。

FAQ 2:AssumeRoleWithWebIdentity 返回 401 或无权限

排查步骤如下:
确认 CAM 角色信任策略中的 oidc:aud 与 ServiceAccount 注解中的 Audience 一致。
确认 oidc:sub 与 Pod 使用的 ServiceAccount 完全匹配,格式为 system:serviceaccount:<namespace>:<serviceaccount>
确认 CAM OIDC Provider 仍然存在。如果 ServiceAccountIssuerDiscovery 提示身份提供商不存在,需要重新创建 Provider。

FAQ 3:临时凭证过期后 SDK 未自动刷新

检查 SDK 版本是否支持临时凭证自动刷新,必要时升级 SDK。
使用自定义凭证提供器时,建议在凭证剩余有效期低于 10% 前刷新。
不要将临时凭证写入磁盘,或在全局变量中长期复用已经过期的凭证。

FAQ 4:VPC 无出网的集群如何使用

确保 Pod 可以访问 CAM/STS 内网端点。
可通过 VPC 内网、PrivateLink 或 NAT 出口建立访问路径。
集群 OIDC Discovery 端点由 TKE 托管,供 CAM 获取验证公钥;Pod 仍需具备访问 STS 端点的网络条件。

FAQ 5:ServiceAccountIssuerDiscovery 无法编辑

确认已完成服务角色 QcloudAccessForTKERoleInOIDCConfig 的授权。
如果授权已经完成但仍无法编辑,请提交工单排查。

FAQ 6:如何撤销一个 Pod 的权限

移除 ServiceAccount 的 role-arn 注解并重新创建 Pod,使新 Pod 不再注入身份配置。
已签发的临时凭证在过期前仍可能有效。如需立即阻止访问,应在 CAM 角色权限策略中撤销相关权限。

FAQ 7:多个 Pod / 多命名空间共用一个角色是否安全

多个 Pod 或命名空间可以共用同一角色,但会扩大该角色的信任范围。
建议按业务模块配置独立的 ServiceAccount 和角色,并通过 oidc:sub 限定可扮演角色的身份。

11. pod-identity-webhook 组件说明

11.1 作用

对于引用了带 tke.cloud.tencent.com/role-arn 注解的 ServiceAccount 的 Pod,该组件会注入投影 ServiceAccount Token、环境变量和 Volume。组件由 TKE 托管面安装和维护,可在集群的 组件管理 页面查看运行状态。

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 权限,用于注入自签名证书。实际权限以组件版本为准。

11.3 升级与自愈

组件版本和升级操作由 TKE 组件管理功能统一管理。组件状态异常时,可先重启 Webhook Deployment;如果问题仍未解决,请提交工单排查。

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 侧的身份提供商和角色信任关系需要由用户配置。

12.1 AWS 侧对象及其作用

AWS 对象
作用
需要配置的关键内容
IAM OIDC Provider
注册并验证 TKE 集群签发的 Token
TKE Issuer URL、Discovery/JWKS、Audience,以及必要时使用的证书指纹
IAM Role 信任策略
定义允许扮演角色的 OIDC 身份
Provider ARN、sts:AssumeRoleWithWebIdentityaudsub
IAM Role 权限策略
定义角色可以调用的 AWS API
Action、Resource、Condition
IAM OIDC Provider 负责验证身份来源,IAM Role 信任策略负责限定可扮演角色的 ServiceAccount,IAM Role 权限策略负责限定角色的访问权限。

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 文档中的 issuerjwks_uri 获取验证信息。如果 OIDC 端点使用的根 CA 不受 AWS 信任,或 AWS 无法验证 TLS 证书链,还需要按照 AWS 要求配置证书指纹。具体要求参见 AWS:创建 IAM OIDC 身份提供商
说明:
IAM OIDC Provider 与信任该 Provider 的 IAM Role 必须位于同一 AWS 账号。跨账号访问需要在角色所在账号中建立 OIDC 信任,再通过角色或资源策略完成后续授权。

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 联合身份创建角色

12.4 创建用于 AWS 的 ServiceAccount

pod-identity-webhook 会将 role-arn 注解的值写入 TKE_ROLE_ARN。对接 AWS 时,可在该注解中填写 AWS IAM Role ARN:
apiVersion: v1
kind: ServiceAccount
metadata:
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-reader
TKE_WEB_IDENTITY_TOKEN_FILE=/var/run/secrets/cloud.tencent.com/serviceaccount/token

12.5 初始化 AWS SDK 客户端

AWS SDK 的 Web Identity 默认凭证链读取:
AWS_ROLE_ARN
AWS_WEB_IDENTITY_TOKEN_FILE
AWS_ROLE_SESSION_NAME(可选)
TKE Webhook 注入的变量名为 TKE_ROLE_ARNTKE_WEB_IDENTITY_TOKEN_FILE,AWS SDK 默认凭证链不会读取这两个变量。可采用以下方式进行适配。以下示例通过 AWS SDK for Go v2 显式读取 TKE 环境变量并初始化 S3 客户端:
package awsauth

import (
"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_ARNTKE_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。

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_* 环境变量。

13. 相关文档

场景实践:Pod 使用 CAM 对数据库身份验证,介绍 Pod 通过 CAM 和 SSM 访问 MySQL 数据库的配置方法。
问题反馈:请提交工单,或在集群的 组件管理 页面反馈 pod-identity-webhook 相关问题。