全部产品
Search
文档中心

密钥管理服务:ACK 快速接入

更新时间:Jun 04, 2026

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 在本地缓存凭据,减少重复请求,降低凭据获取延迟。

image

适用范围

  • 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功能。

image

在集群信息页面开启

  1. 登录容器服务管理控制台,在左侧导航栏选择集群列表

  2. 集群列表页面,单击目标集群名称,然后在左侧导航栏,选择集群信息

  3. 基本信息页签的安全与审计区域,单击RRSA OIDC右侧的开启image

  4. 在弹出的启用 RRSA对话框,单击确定

    基本信息区域,当集群状态由更新中变为运行中后,表明该集群的RRSA特性已变更完成。

步骤 1 :创建 Namespace 和 ServiceAccount(可选)

Namespace 将 ACK 集群划分为逻辑隔离的虚拟空间,用于区分开发、测试、生产等环境。不同 Namespace 中的应用默认无法互访资源。若业务应用已创建过对应的空间和账号,可跳过此步骤。

  1. 创建 Namespace 。

    1. 通过 YAML(以 app1-namespace.yaml 为例)文件创建 Namespace(以 app1-dev 为例):

      apiVersion: v1
      kind: Namespace
      metadata:
        name: app1-dev
    2. 执行以下命令创建 Namespace :

      kubectl apply -f app1-namespace.yaml
    3. 验证 Namespace 是否创建成功:若输出中包含 app1-dev,即代表创建成功。

      kubectl get namespaces
  2. 创建 ServiceAccount 。

    1. 通过 YAML(以 app1-serviceaccount.yaml 为例)文件创建 ServiceAccount(以 app1-service 为例),其中 namespace 为上一步创建的命名空间 app1-dev

      apiVersion: v1
      kind: ServiceAccount
      metadata:
        name: app1-service
        namespace: app1-dev
    2. 执行以下命令创建 ServiceAccount :

      kubectl apply -f app1-serviceaccount.yaml
    3. 验证 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)

  1. 登录密钥管理服务控制台,在左侧导航栏,选择应用接入 > 云原生接入,在弹性计算区域的 ACK 列表中,单击目标 ACK 实例操作列的配置 ACK 接入

  2. 在弹出的配置面板中,选择认证方式OIDC(ACK)

  3. 配置以下参数:

    参数

    说明

    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 字符。

  4. 单击确定,进入下一步。

RAMRole

  1. 获取提供商信息

    1. 登录容器服务管理控制台,在左侧导航栏选择集群列表

    2. 单击目标集群名称,进入详情页。

    3. 基本信息页签的安全与审计区域,将鼠标悬浮至 RRSA OIDC 右侧已开启上面,查看提供商的 URL 链接和 ARN 信息。image

  2. 创建 RAM 角色。

    1. 登录RAM 控制台,在左侧导航栏选择身份管理 > 角色,单击创建角色

    2. 选择可信实体类型为身份提供商,单击切换编辑器

    3. 可视化编辑区域,完成如下配置:

      • 基础配置

        配置项

        描述

        效果

        选择允许

        操作

        保持默认值 sts:AssumeRole

        条件

        新增 oidc:sub 条件,运算符 StringEquals,值为 system:serviceaccount:<namespace>:<ServiceAccountName>namespaceServiceAccountName 为业务运行 Pod 对应的空间和账号名称)。

      • 主体配置:

        1. 选择主体身份提供商后,单击下方的编辑

        2. 身份提供商配置页面,配置相关参数后,单击确定

          配置项

          描述

          身份供应商类型

          选择 OIDC 。

          身份提供商

          选择上一步中开启 RRSA 后 ACK 集群自动创建的身份提供商 ack-rrsa-<cluster_id>

    4. 配置完成后,单击确定设置角色名称(如 app1-rrsa),单击确定

  3. 创建权限策略并授权:具体操作,请参见创建自定义权限策略管理RAM角色的权限

    1. 在左侧导航栏选择权限管理 > 权限策略

    2. 单击创建权限策略,选择脚本编辑,参见如下示例完成配置。

      说明

      本文以权限策略名称 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"
                          ]
                      }
                  }
              }
          ]
      }
    3. 返回策略列表,单击目标策略操作列的新增授权

    4. 授权主体区域勾选上一步创建的 RAM 角色后,单击确认新增授权

步骤 3 :安装 ack-kms-agent-webhook-injector

  1. 登录容器服务管理控制台,在左侧导航栏选择集群列表

  2. 在集群列表页面,单击目标集群名称,进入集群详情页。

  3. 在详情页左侧导航栏,选择应用 > Helm

  4. 在 Helm 页面,单击创建,配置基本信息,然后单击下一步

    配置项

    说明

    应用名

    建议使用默认应用名 ack-kms-agent-webhook-injector

    命名空间

    建议使用 Chart 默认的运行空间 kube-system。一个 ACK 集群中安装到一个命名空间即可,无需重复安装。

    来源

    默认为应用市场,不支持修改。

    Chart

    搜索并选中 ack-kms-agent-webhook-injector

  5. 弹出提醒对话框时,确认信息无误后,单击

  6. 参数配置页面,根据步骤 2 选择的认证方式进行配置。

    • OIDC(ACK):保持默认配置即可。

    • RAMRoleagent.auth.roleArn 留空,agent.auth.roleArnMapping 需配置为 <Namespace>:<ServiceAccountName>: <RAM Role ARN>。以下以步骤 2 新建的数据为例:

      说明

      NamespaceServiceAccountName 为业务运行 Pod 对应的空间和账号名称RAM Role ARN 可在 RAM 角色详情页查看。

      agent:
        auth:
          roleArn:
          roleArnMapping:
            app1-dev:app1-service: acs:ram::190325303126****:role/app1-rrsa
  7. 配置完成后,单击确定,跳转至应用详情页。

步骤 4 :注入 Agent Sidecar

  1. 添加 Pod 注解:注解名称为 kms-agent-webhook-injector/inject,值为 true

    1. 在目标集群详情页左侧导航栏,选择工作负载 > 无状态

    2. 切换至业务实际运行的命名空间,为工作负载(Deployment)添加 Pod 注解。

      重要

      若为 RAMRole 认证方式,请修改工作负载的 YAML 配置文件,将 ServiceAccountName 参数改为业务运行 Pod 对应的服务账户名称(本文为 app1-service)。若为 OIDC(ACK) 认证方式,则无需修改。

      • 新增 Deployment

        使用镜像创建

        1. 单击 Deployment 列表上方的使用镜像创建,完成各项配置。

        2. 填写高级配置时,在标签和注解区域添加 Pod 注解:名称 填入 kms-agent-webhook-injector/inject 填入 true

        3. 完成后单击创建

        使用YAML创建资源

        1. 单击 Deployment 列表上方的使用YAML创建资源

        2. 编辑 YAML 中 spec.template.metadata.annotations(若不存在,需手动创建),添加 kms-agent-webhook-injector/inject: "true"

        3. 完成后单击创建

      • 已有 Deployment

        1. 定位到目标工作负载,单击操作列的详情

        2. 在详情页单击右上角的YAML 编辑

        3. spec.template.metadata.annotations(若不存在,需手动创建)中添加 kms-agent-webhook-injector/inject: "true"

        4. 单击更新,等待工作负载重新就绪。

  2. 注入验证

    1. 返回工作负载 > 无状态,单击目标业务 Deployment 名称,进入详情页。

    2. 工作负载容器组页签的镜像列,可以看到 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 侧的费用:

    • 计费方式为包年包月:使用KMS Agent前您需要购买KMS实例,使用KMS Agent本身不会额外收取您的费用。详细介绍,请参见包年包月

    • 计费方式为按量付费:除您已产生的费用外,使用KMS Agent获取凭据时,会因API调用请求产生额外的QPS调用费用。详细介绍,请参见按量付费

  • 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 实例网络连通。

权限不足

检查以下配置项:

  • OIDC(ACK):Namespace 和 ServiceAccount 是否正确,是否设置了 PodNamePrefix 过滤。

  • RAMRole:RAM 角色已正确绑定身份提供商,且权限策略包含 kms:GetSecretValuekms:Decrypt 权限。

Agent 注入失败

检查 ack-kms-agent-webhook-injector 组件是否正确安装并正常运行。确认 Pod 注解 kms-agent-webhook-injector/inject: "true" 已正确配置。

RRSA 未开启

OIDC(ACK) 认证方式依赖 RRSA 功能。请在 ACK 控制台的集群安全与审计模块中开启 RRSA,具体操作请参见步骤 2 中的 RRSA 开启步骤。