KMS 云原生接入是一种面向 ACK 集群的凭据分发方案,通过在 Pod 中注入 KMS Agent Sidecar,使应用通过本地 HTTP 请求即可安全获取托管在 KMS 中的凭据,无需在代码中管理 AccessKey。
工作原理
KMS 云原生接入功能提供向导式的组件安装与配置流程。ACK 集群中的 Pod 发起 HTTP 请求后,KMS Agent(通过 Helm 组件 ack-kms-agent-webhook-injector 自动注入到 Pod 中)接收请求并通过 OIDC JWT 或 RAM 角色完成认证。KMS 验证权限后返回凭据,最终由 Agent 将凭据返回给应用程序。Agent 在本地缓存凭据,减少重复请求,降低凭据获取延迟。
适用范围
ACK集群类型限制:支持ACK托管与专有集群、ACK Serverless集群。
说明ACK专有集群、ACK注册集群接入,请参见ACK容器环境中部署KMS Agent获取凭据。
地域限制:ACK集群与KMS实例需要在同一地域。
性能限制:由于每个Pod独立运行KMS Agent Sidercar容器,若业务部署大量Pod,在身份验证过程中如果STS Token请求每分钟超过500次则会触发限流,进而对KMS Agent的正常工作产生影响。
配置接入
创建集群时开启
创建ACK托管集群和ACK Edge集群时,您可以在集群配置的高级选项(选填)区域,选中开启RRSA功能。

在集群信息页面开启
-
登录容器服务管理控制台,在左侧导航栏选择集群列表。
-
在集群列表页面,单击目标集群名称,然后在左侧导航栏,选择集群信息。
-
在基本信息页签的安全与审计区域,单击RRSA OIDC右侧的开启。

-
在弹出的启用 RRSA对话框,单击确定。
在基本信息区域,当集群状态由更新中变为运行中后,表明该集群的RRSA特性已变更完成。
步骤 1 :创建 Namespace 和 ServiceAccount(可选)
Namespace 将 ACK 集群划分为逻辑隔离的虚拟空间,用于区分开发、测试、生产等环境。不同 Namespace 中的应用默认无法互访资源。若业务应用已创建过对应的空间和账号,可跳过此步骤。
创建 Namespace 。
通过 YAML(以
app1-namespace.yaml为例)文件创建 Namespace(以app1-dev为例):apiVersion: v1 kind: Namespace metadata: name: app1-dev执行以下命令创建 Namespace :
kubectl apply -f app1-namespace.yaml验证 Namespace 是否创建成功:若输出中包含
app1-dev,即代表创建成功。kubectl get namespaces
创建 ServiceAccount 。
通过 YAML(以
app1-serviceaccount.yaml为例)文件创建 ServiceAccount(以app1-service为例),其中namespace为上一步创建的命名空间app1-dev。apiVersion: v1 kind: ServiceAccount metadata: name: app1-service namespace: app1-dev执行以下命令创建 ServiceAccount :
kubectl apply -f app1-serviceaccount.yaml验证 ServiceAccount 是否创建成功:若输出中包含
app1-service,即代表创建成功。kubectl get serviceaccount -n app1-dev
步骤 2 :权限配置
KMS 云原生接入提供以下两种认证方式。
认证方式 | 特点 |
OIDC(ACK) | ACK 集群通过 OIDC 标准 JWT 认证,Agent 自动获取 ServiceAccount Token,向 KMS 证明 Pod 身份。无需创建 RAM 角色,配置最简单。 |
RAMRole | 通过 RAM 角色的 STS 临时凭证访问 KMS,适用于需要复用已有 RAM 角色体系的场景。 |
OIDC(ACK)
在弹出的配置面板中,选择认证方式为OIDC(ACK)。
配置以下参数:
参数
说明
Namespace
Pod 所在的空间名称,如
app1-dev。ServiceAccount
Pod 使用的账号,如
app1-service。PodNamePrefix
Pod 名称前缀。配置后,仅允许名称匹配前缀的 Pod 通过校验,未配置时,仅校验 Namespace 和 ServiceAccount 。
作用域
选择访问 KMS 的方式。可选值:
指定的 KMS 实例:通过 KMS 实例 Endpoint 访问指定实例中的密钥和凭据。
KMS共享网关:通过 KMS 服务 Endpoint 访问凭据。
应用接入点名称
自定义应用接入点(访问凭证)的名称,便于后续识别和管理。
权限策略名称
自定义 RAM 权限策略名称。在此步骤中可直接创建权限策略,无需预先在 RAM 控制台创建。
RBAC权限
选择 RBAC 权限级别,决定应用程序对凭据的操作权限。
作用域选择指定的 KMS 实例:
CryptoServiceKeyUser:允许使用 KMS 实例中的密钥,用于凭据加密。
CryptoServiceSecretUser:允许使用 KMS 实例中的凭据,支持实例 API 中的凭据接口。
作用域选择KMS共享网关:仅支持选择SecretUser,允许使用当前账号下的所有凭据。
允许访问的资源
勾选应用需要访问的凭据和密钥(用于凭据加解密)。
重要勾选多个凭据时,如果凭据名称总长度超限会报"参数非法"错误。此时请使用通配符配置允许访问的凭据,例如配置为
secret/rds-ibm*,表示允许访问前缀为 rds-ibm 的凭据。描述信息
选填。对该应用接入点的详细说明,最大支持 8192 字符。
单击确定,进入下一步。
RAMRole
获取提供商信息
登录容器服务管理控制台,在左侧导航栏选择集群列表。
单击目标集群名称,进入详情页。
在基本信息页签的安全与审计区域,将鼠标悬浮至 RRSA OIDC 右侧已开启上面,查看提供商的 URL 链接和 ARN 信息。

创建 RAM 角色。
登录RAM 控制台,在左侧导航栏选择,单击创建角色。
选择可信实体类型为身份提供商,单击切换编辑器。
在可视化编辑区域,完成如下配置:
基础配置
配置项
描述
效果
选择允许。
操作
保持默认值
sts:AssumeRole。条件
新增
oidc:sub条件,运算符StringEquals,值为system:serviceaccount:<namespace>:<ServiceAccountName>(namespace、ServiceAccountName为业务运行 Pod 对应的空间和账号名称)。主体配置:
选择主体为身份提供商后,单击下方的编辑。
在身份提供商配置页面,配置相关参数后,单击确定。
配置项
描述
身份供应商类型
选择 OIDC 。
身份提供商
选择上一步中开启 RRSA 后 ACK 集群自动创建的身份提供商
ack-rrsa-<cluster_id>。
配置完成后,单击确定设置角色名称(如
app1-rrsa),单击确定。
创建权限策略并授权:具体操作,请参见创建自定义权限策略和管理RAM角色的权限。
在左侧导航栏选择。
单击创建权限策略,选择脚本编辑,参见如下示例完成配置。
说明本文以权限策略名称 dev-role-for-rrsa-kms-policy 为例,策略内容以仅允许访问带有
env:app1标签的凭据为例。{ "Version": "1", "Statement": [ { "Effect": "Allow", "Action": [ "kms:Decrypt", "kms:GetSecretValue" ], "Resource": "*", "Condition": { "StringEqualsIgnoreCase": { "kms:tag/secret": [ "app1" ] } } } ] }返回策略列表,单击目标策略操作列的新增授权。
在授权主体区域勾选上一步创建的 RAM 角色后,单击确认新增授权。
步骤 3 :安装 ack-kms-agent-webhook-injector
在详情页左侧导航栏,选择。
在 Helm 页面,单击创建,配置基本信息,然后单击下一步。
配置项
说明
应用名
建议使用默认应用名
ack-kms-agent-webhook-injector。命名空间
建议使用 Chart 默认的运行空间
kube-system。一个 ACK 集群中安装到一个命名空间即可,无需重复安装。来源
默认为应用市场,不支持修改。
Chart
搜索并选中
ack-kms-agent-webhook-injector。弹出提醒对话框时,确认信息无误后,单击是。
在参数配置页面,根据步骤 2 选择的认证方式进行配置。
OIDC(ACK):保持默认配置即可。
RAMRole:
agent.auth.roleArn留空,agent.auth.roleArnMapping需配置为<Namespace>:<ServiceAccountName>: <RAM Role ARN>。以下以步骤 2 新建的数据为例:说明Namespace、ServiceAccountName为业务运行 Pod 对应的空间和账号名称,RAM Role ARN可在 RAM 角色详情页查看。agent: auth: roleArn: roleArnMapping: app1-dev:app1-service: acs:ram::190325303126****:role/app1-rrsa
配置完成后,单击确定,跳转至应用详情页。
步骤 4 :注入 Agent Sidecar
添加 Pod 注解:注解名称为
kms-agent-webhook-injector/inject,值为true。在目标集群详情页左侧导航栏,选择。
切换至业务实际运行的命名空间,为工作负载(Deployment)添加 Pod 注解。
重要若为 RAMRole 认证方式,请修改工作负载的 YAML 配置文件,将
ServiceAccountName参数改为业务运行 Pod 对应的服务账户名称(本文为app1-service)。若为 OIDC(ACK) 认证方式,则无需修改。新增 Deployment
使用镜像创建
单击 Deployment 列表上方的使用镜像创建,完成各项配置。
填写高级配置时,在标签和注解区域添加 Pod 注解:名称 填入
kms-agent-webhook-injector/inject,值 填入true。完成后单击创建。
使用YAML创建资源
单击 Deployment 列表上方的使用YAML创建资源。
编辑 YAML 中
spec.template.metadata.annotations(若不存在,需手动创建),添加kms-agent-webhook-injector/inject: "true"。完成后单击创建。
已有 Deployment
定位到目标工作负载,单击操作列的详情。
在详情页单击右上角的YAML 编辑。
向
spec.template.metadata.annotations(若不存在,需手动创建)中添加kms-agent-webhook-injector/inject: "true"。单击更新,等待工作负载重新就绪。
注入验证
返回,单击目标业务 Deployment 名称,进入详情页。
在工作负载容器组页签的镜像列,可以看到 KMS Agent 已经作为 Sidecar 注入到 Pod 中。
说明Pod 可能被注入两次 KMS Agent 镜像,这是因为使用了初始化容器(initContainer)进行初始化。初始化容器在初始化完成后会终止(Terminated),不会对应用产生负面影响,也不会持续占用计算资源。
应用程序集成
当 Deployment 注入了 KMS Agent 后,在应用容器中可通过 HTTP 协议向 KMS Agent 发起请求,获取存储在 KMS 中的凭据,无需在代码中配置 AccessKey。以下示例展示如何调用,使用时请将示例中的 <SecretId> 替换为实际的凭据名称。
KMS Agent 只监听 127.0.0.1,即仅允许同一机器上的应用或进程与其通信,外部网络设备无法连接。访问地址仅支持 localhost 或 127.0.0.1,不支持应用的本地 IP。以下示例以 localhost 为例。
除 KMS Agent 接入方式外,KMS 还支持通过 SDK 接入。具体操作,请参见凭据客户端。
OIDC(ACK)
使用 curl
# 从文件读取 token,指定 AapArn
curl -v -H "X-KMS-Token:$(</var/run/kmstoken/token)"
-H "AapArn:<AapArn>" 'http://localhost:2025/secretsmanager/get?secretId=<SecretId>'Go 代码示例
package main
import (
"fmt"
"io/ioutil"
"net/http"
)
func main() {
//支持指定versionStage或versionId以获取特定凭据值。
//以获取指定versionId的凭据值为例, url := fmt.Sprintf("http://localhost:2025/secretsmanager/get?secretId=%s&versionId=%s", "agent-test", "version-id")
aapArn := "acs:kms:cn-hangzhou:19*********224:applicationaccesspoint/****"
url := fmt.Sprintf("http://localhost:2025/secretsmanager/get?secretId=%s", "agent-test")
token, err := ioutil.ReadFile("/var/run/kmstoken/token")
if err != nil {
fmt.Printf("error reading token file: %v\n", err)
}
req, err := http.NewRequest("GET", url, nil)
if err != nil {
fmt.Printf("error creating request: %v\n", err)
}
req.Header.Add("X-KMS-Token", string(token))
req.Header.Add("AapArn", aapArn)
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
fmt.Printf("error sending request: %v \n", err)
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
fmt.Printf("status code %d - %s \n", resp.StatusCode, string(body))
}RAMRole
使用 curl
# 从文件读取 token
curl -v -H "X-KMS-Token:$(</var/run/kmstoken/token)" 'http://localhost:2025/secretsmanager/get?secretId=<SecretId>'
# 直接写 token
curl -v -H "X-KMS-Token:<token>" 'http://localhost:2025/secretsmanager/get?secretId=<SecretId>'Go 代码示例
package main
import (
"fmt"
"io/ioutil"
"net/http"
)
func main() {
//支持指定versionStage或versionId以获取特定凭据值。
//以获取指定versionId的凭据值为例, url := fmt.Sprintf("http://localhost:2025/secretsmanager/get?secretId=%s&versionId=%s", "agent-test", "version-id")
url := fmt.Sprintf("http://localhost:2025/secretsmanager/get?secretId=%s", "agent-test")
token, err := ioutil.ReadFile("/var/run/kmstoken/token")
if err != nil {
fmt.Printf("error reading token file: %v\n", err)
}
req, err := http.NewRequest("GET", url, nil)
if err != nil {
fmt.Printf("error creating request: %v\n", err)
}
req.Header.Add("X-KMS-Token", string(token))
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
fmt.Printf("error sending request: %v \n", err)
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
fmt.Printf("status code %d - %s \n", resp.StatusCode, string(body))
}计费说明
KMS 侧的费用:
ACK 侧的费用:
ack-kms-agent-webhook-injector 组件本身完全免费,但使用该组件的过程中可能会产生额外费用。
安装 ack-kms-agent-webhook-injector 组件后,会生成一个 Webhook 服务工作负载,该负载将占用一定计算资源并产生费用。可在配置文件中限制该负载的 CPU 和内存使用。
创建或更新符合条件的工作负载时,ack-kms-agent-webhook-injector 会将 KMS Agent 以 Sidecar 形式注入到容器中,KMS Agent 会使用一定计算资源并产生费用。
Agent 状态说明
在云原生接入列表页,可查看 ACK 集群中 KMS Agent 的运行状态。不同状态对应的说明和支持的操作如下:
状态 | 说明 |
运行中 | Agent 已安装并正常运行。 |
未安装 | 该 ACK 集群未安装 KMS Agent 组件。 |
未运行 | Agent 组件已安装但当前未运行。 |
未知 | 无法获取 Agent 状态,请检查集群网络配置。 |
故障排查
如果在安装或使用 KMS Agent 过程中遇到问题,请参见以下常见问题进行排查:
失败原因 | 解决方案 |
Agent 安装失败 | 检查 ACK 集群是否处于运行中状态,确认当前账号具有 KMS 相关操作权限。 |
网络不通或超时 | 确认 ACK 集群与 KMS 服务之间网络互通。如果通过 VPC 访问 KMS,请确保 ACK 集群所在 VPC 与 KMS 实例网络连通。 |
权限不足 | 检查以下配置项:
|
Agent 注入失败 | 检查 ack-kms-agent-webhook-injector 组件是否正确安装并正常运行。确认 Pod 注解 |
RRSA 未开启 | OIDC(ACK) 认证方式依赖 RRSA 功能。请在 ACK 控制台的集群安全与审计模块中开启 RRSA,具体操作请参见步骤 2 中的 RRSA 开启步骤。 |