全部产品
Search
文档中心

容器服务 Kubernetes 版 ACK:使用ack-secret-manager导入阿里云KMS服务凭据

更新时间:Dec 24, 2025

ack-secret-manager支持以Kubernetes Secret实例的形式向集群导入或同步KMS凭据信息,确保集群内的应用能够安全地访问敏感信息。通过该组件,可以实现密钥数据的自动更新,使应用负载通过文件系统挂载指定Secret实例来使用凭据信息,同时帮助解决负载应用和阿里云凭据管家交互的兼容性问题。

image

安全说明

通常情况下,用户的密钥会保存在文件中供应用程序读取,这种情况和通过阿里云KMS凭据管家直接读取密钥存在兼容性问题。ack-secret-manager可以解决此类兼容性问题,同时支持将密钥同步创建为集群中的Kubernetes原生Secrets实例,以供环境变量挂载使用。使用前请评估如下的安全风险。

  • 当密钥在文件系统中可以被访问时,如果应用中存在某些有缺陷的软件,该软件的漏洞可能会造成目录遍历的风险,导致敏感信息泄露。

  • 一些Debug端点或Logs权限的误配置可能导致密钥泄露,所以通过环境变量挂载引用的方式消费密钥是一个不安全且不推荐的做法。

  • 当开启Secret实例同步特性时,需要基于权限最小化原则严格控制访问权限。

鉴于上述原因,如果应用中并不需要密文的持久化存储,推荐通过RRSA配置ServiceAccount的RAM权限实现Pod权限隔离为应用配置Pod维度的最小化权限,并通过GetSecretValue直接在应用中获取密钥凭据,以减少密钥内容在Pod文件系统或Kubernetes集群Secrets中的暴露风险。

前提条件

步骤一:安装ack-secret-manager组件

  1. ACK集群列表页面,单击目标集群名称,在集群详情页左侧导航栏,选择应用 > Helm

  2. Helm页面,单击创建,在Chart区域搜索并选中ack-secret-manager,其他设置保持默认,然后单击下一步

    根据弹出的页面提示确认,组件将被安装在默认的kube-system命名空间中,并以组件名称发布应用。如果需要自定义应用名和命名空间,请根据页面提示设置。

  3. 参数配置页面,选择Chart版本为最新版本,并设置相应参数,然后单击确定

    • 如需开启RRSA认证功能,需要将参数rrsa.enable设置为trueimage

    • 如需开启定时同步凭据功能,需要配置如下参数。image

      • command.disablePolling:是否关闭凭据的自动轮询功能,设置为false,开启凭据自动轮询功能。

      • command.pollingInterval:凭据同步的频率,设置为120s,此处以两分钟同步一次凭据为例,可以根据实际需求调整。

    • 配置限流参数:如果集群中具有较多的ExternalSecret(待同步的 KMS 凭据),配置不当可能会引发KMS或RAM侧的限流,因此,需要配置以下限流参数避免发生限流。imagecommand.maxConcurrentKmsSecretPulls:每秒可以同步的最大KMS凭据数量,默认为10。

    • 如需指定KMS服务Endpoint地址,需要配置kmsEndpoint参数。

      image

      command.kmsEndpoint:参数支持KMS服务的共享网关和专属网关,可按需配置,该参数是全局配置,当前也支持凭据级的配置,具体的配置说明请参见配置KMS服务Endpoint地址

    • 如需禁止ExternalSecret跨命名空间引用SecretStore,需要将参数command.enableCrossNamespaceSecretStore设置为false

      image

    • 如需禁止SecretStore跨命名空间引用ServiceAccount,需要将参数command.enableCrossNamespaceAuthRef设置为false

      image

    • 如需禁用集群维度的控制器,需要配置以下参数,crdscommand 参数值是相互关联的,对于集群维度的控制器说明请参考集群级别资源说明

      image

      • crds.createClusterSecretStore:控制是否安装 ClusterSecretStore CRD,默认为true安装

      • crds.createClusterExternalSecret:控制是否安装 ClusterExternalSecret CRD,默认为true安装

      • command.processClusterSecretStore:控制是否处理 ClusterSecretStore 资源,默认为true处理

      • command.processClusterExternalSecret:控制是否处理 ClusterExternalSecret 资源,默认为true处理

创建成功后,会自动跳转到目标集群的ack-secret-manager页面,检查安装结果。若下图中所有资源创建成功,则表明组件安装成功。image.png

步骤二:配置组件认证信息

需要通过自定义资源SecretStore来配置ack-secret-manager的认证信息,以确保该组件有权限获取KMS服务中的凭据信息,否则ack-secret-manager将无法向集群中导入或同步凭据信息。可以根据集群类型选择如下四种授权方式进行配置。

使用ServiceAccount维度的细粒度RRSA授权

基于Namespace维度下不同ServiceAccount的RRSA授权实现多租场景下的KMS凭据管家访问权限隔离。相比其他授权方式,RRSA授权方式可以实现Pod维度的权限隔离,还可以避免直接使用AK、SK引起的凭据泄露风险。

image

  1. 容器服务管理控制台开启集群的RRSA功能,用于创建集群的身份提供商信息具体操作,请参见启用RRSA功能

    说明

    安装ack-secret-manager时,需要将参数rrsa.enable设置为true,以启用RRSA功能。

  2. 为不同的ServiceAccount创建可信实体为身份提供商的RAM角色。

    选择信任主体类型身份提供商,添加主体时主要参数设置如下,具体操作,请参见创建OIDC身份提供商的RAM角色

    配置项

    描述

    身份提供商类型

    OIDC

    身份提供商

    选择ack-rrsa-<CLUSTER_ID>。其中,<CLUSTER_ID>为集群ID。

    条件

    • oidc:iss:保持默认。

    • oidc:aud:保持默认。

    • oidc:sub:需手动添加该条件。

      • 条件键:选择oidc:sub

      • 运算符:选择StringEquals

      • 条件值:输入system:serviceaccount:<NAMESPACE>:<SERVICEACCOUNT_NAME>。其中<NAMESPACE>为指定ServiceAccount的命名空间,<SERVICEACCOUNT_NAME>为服务账户ServiceAccount的名称。

        说明

        其中<NAMESPACE><SERVICEACCOUNT_NAME>需要与4. 在指定命名空间下创建访问指定KMS凭据管家的独立ServiceAccount中的配置保持一致。

  3. 创建自定义权限策略并为上一步创建的RAM角色授权。

    1. 创建指定导入KMS凭据时所需的权限策略。具体操作,请参见创建自定义权限策略

      {
        "Version": "1",
        "Statement": [
          {
            "Action": [
              "kms:GetSecretValue",
              "kms:Decrypt"
            ],
            "Resource": "acs:kms:<REGION_ID>:<ACCOUNT_ID>:secret/xxxx",  // 指定的KMS凭据ARN
            "Effect": "Allow"
          }
        ]
      }
    2. 为上一步创建的RAM角色授权。具体操作,请参见为RAM角色授权

  4. 在指定命名空间下创建访问指定KMS凭据管家的独立ServiceAccount。注意ServiceAccount需要添加键值为ack.alibabacloud.com/role-arn的指定annotation,值为该ServiceAccount绑定的目标RAM角色ARN。

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      annotations:
        ack.alibabacloud.com/role-arn: acs:ram::<ACCOUNT_ID>:role/<ROLE_NAME> # RAM角色的ARN
      name: <SERVICEACCOUNT_NAME>     # 需与RAM角色配置的oidc:sub条件值<SERVICEACCOUNT_NAME>保持一致
      namespace: <NAMESPACE>         # 需与RAM角色配置的oidc:sub条件值<NAMESPACE>保持一致
  5. 使用serviceAccountRef认证方式部署自定义资源SecretStore。

    1. 基于以下内容,替换相关字段后,创建secretstore-rrsa.yaml文件。

      1. <NAME>:替换为指定的SecretStore实例名称。

      2. <NAMESPACE>:替换为指定的集群命名空间名称。

      3. <SERVICEACCOUNT_NAME>:替换为上一步中创建的ServiceAccount实例名称。

        apiVersion: alibabacloud.com/v1alpha1
        kind: SecretStore
        metadata:
          name: <NAME>
          namespace: <NAMESPACE>
        spec:
          KMS:
            KMSAuth:
              serviceAccountRef:
                name: <SERVICEACCOUNT_NAME>
    2. 执行以下命令,部署SecretStore。

      kubectl apply -f secretstore-rrsa.yaml

使用ack-secret-manager的ServiceAccount无AK授权

相比其他授权方式,RRSA授权方式可以实现Pod维度的权限隔离,还可以避免直接使用AK、SK引起的凭据泄露风险。

  1. 容器服务管理控制台开启集群的RRSA功能,用于创建集群的身份提供商信息具体操作,请参见启用RRSA功能

    说明

    安装ack-secret-manager时,需要将参数rrsa.enable设置为true,以启用RRSA功能。

  2. 创建可信实体为身份提供商的RAM角色,以供ack-secret-manager使用。

    选择信任主体类型身份提供商,添加主体时主要参数设置如下,具体操作,请参见创建OIDC身份提供商的RAM角色

    配置项

    描述

    身份提供商类型

    OIDC

    身份提供商

    选择ack-rrsa-<CLUSTER_ID>。其中,<CLUSTER_ID>为集群ID。

    条件

    • oidc:iss:保持默认。

    • oidc:aud:保持默认。

    • oidc:sub:需手动添加该条件。

      • 条件键:选择oidc:sub

      • 运算符:选择StringEquals

      • 条件值:输入system:serviceaccount:<NAMESPACE>:<SERVICEACCOUNT_NAME>。其中,<NAMESPACE>为应用所在的命名空间。<SERVICEACCOUNT_NAME>为服务账户名称。根据本文测试应用的信息,此处需填入system:serviceaccount:kube-system:ack-secret-manager

        说明

        如果将ack-secret-manager安装在其他的命名空间,请将kube-system替换为对应命名空间的名称。

  3. 创建自定义权限策略并为上一步创建的RAM角色授权。

    1. 创建ack-secret-manager导入KMS凭据时所需的权限策略。策略内容如下。具体操作,请参见创建自定义权限策略

      {
          "Version": "1",
          "Statement": [
              {
                  "Action": [
                      "kms:GetSecretValue",
                      "kms:Decrypt"
                  ],
                  "Resource": [
                      "*"
                  ],
                  "Effect": "Allow"
              }
          ]
      }
    2. 为上一步创建的RAM角色授权。具体操作,请参见为RAM角色授权

  4. 创建自定义资源SecretStore关联对应的认证方式并部署。

    1. 使用以下内容,替换相关字段后,创建secretstore-rrsa.yaml文件。

      • <ACCOUNT_ID>:替换为同步KMS凭据的阿里云账号ID。

      • <CLUSTER_ID>:替换为集群ID。

      • <ROLE_NAME>:替换为步骤2中创建的RAM角色名称。

        apiVersion: alibabacloud.com/v1alpha1
        kind: SecretStore
        metadata:
          name: scdemo-rrsa
        spec:
          KMS:
            KMSAuth:
              oidcProviderARN: "acs:ram::<ACCOUNT_ID>:oidc-provider/ack-rrsa-<CLUSTER_ID>"
              ramRoleARN: "acs:ram::<ACCOUNT_ID>:role/<ROLE_NAME>"	                     
    2. 执行以下命令,部署SecretStore。

      kubectl apply -f secretstore-rrsa.yaml

为集群对应的Worker RAM角色添加权限

  1. 创建如下自定义权限策略。具体操作,请参见创建自定义权限策略

    {
        "Version": "1",
        "Statement": [
            {
                "Action": [
                    "kms:GetSecretValue",
                    "kms:Decrypt"
                ],
                "Resource": [
                    "*"
                ],
                "Effect": "Allow"
            }
        ]
    }
  2. 为集群的Worker RAM角色添加上一步创建的自定义权限。具体操作,请参见为集群的Worker RAM角色授权

通过设置AK扮演指定RAM角色

  1. 创建可信实体为阿里云账号的RAM角色,以供ack-secret-manager组件使用。具体操作,请参见创建可信实体为阿里云账号的RAM角色

    说明

    在选择信任主体类型时,请选择当前云账号

  2. 创建自定义权限策略并为上一步已创建的RAM角色授权。

    1. 创建访问KMS服务凭据所需的权限策略。策略内容如下。具体操作,请参见创建自定义权限策略

      {
          "Version": "1",
          "Statement": [
              {
                  "Action": [
                      "kms:GetSecretValue",
                      "kms:Decrypt"
                  ],
                  "Resource": [
                      "*"
                  ],
                  "Effect": "Allow"
              }
          ]
      }
    2. 为上一步已创建的RAM角色授权。具体操作,请参见为RAM角色授权

  3. 创建自定义权限策略,并为指定的RAM用户授权。

    1. 创建扮演上述角色的自定义权限策略。策略内容如下。具体操作,请参见创建自定义权限策略

      {
          "Statement": [
              {
                  "Action": "sts:AssumeRole",
                  "Effect": "Allow",
                  "Resource": "acs:ram:*:<ACCOUNT_ID>:role/<ROLE_NAME>"  
              }
          ],
          "Version": "1"
      }

      上述自定义策略中的Resource为角色ARN,其中,<ACCOUNT_ID>为阿里云账号ID,<ROLE_NAME>为RAM角色名称。关于如何查看角色ARN,请参见如何查看RAM角色的ARN?

    2. 将上述自定义策略授权给RAM用户,便可以指定具体可以扮演的RAM角色。关于如何为RAM用户授权,请参见为RAM用户授权

  4. 创建Secret用于存放指定RAM用户的访问凭证信息。

    1. 使用以下内容,替换您的AccessKey ID和AccessKey Secret的Base64编码信息后,创建ramuser.yaml文件。

      apiVersion: v1
      data:
        accessKey: <AccessKey ID的Base64编码>
        accessKeySecret: <AccessKey Secret的Base64编码>
      kind: Secret
      metadata:
        name: ramuser
        namespace: kube-system
      type: Opaque
    2. 执行以下命令,创建名为ramuser的Secret。

      kubectl apply -f ramuser.yaml
  5. 创建自定义资源SecretStore关联对应的认证方式并部署。

    1. 使用以下内容,替换相关字段后,创建secretstore-ramrole.yaml文件。

      • <ACCOUNT_ID>:替换为同步KMS凭据的阿里云账号ID。

      • <ROLE_NAME>:替换为步骤1中创建的RAM角色名称。

      • <SECRET_NAME> :替换为存储AK、SK的Secret名称。

      • <SECRET_NAMESPACE> :替换为存储AK、SK的Secret的命名空间。

      • <SECRET_KEY_AK><SECRET_KEY_SK> :替换为存储AK、SK的Secret中data字段下的键名(key)。

      • <ROLE_SESSION_NAME> :替换为角色会话名称(自定义字符串)。

      apiVersion: alibabacloud.com/v1alpha1
      kind: SecretStore
      metadata:
        name: scdemo-ramrole
      spec:
        KMS:
          KMSAuth:
            accessKey:
              name: <SECRET_NAME>
              namespace: <SECRET_NAMESPACE>
              key: <SECRET_KEY_AK>
            accessKeySecret:
              name: <SECRET_NAME>
              namespace: <SECRET_NAMESPACE>
              key: <SECRET_KEY_SK>
            ramRoleARN: "acs:ram::<ACCOUNT_ID>:role/<ROLE_NAME>"  
            ramRoleSessionName: <ROLE_SESSION_NAME>
    2. 执行以下命令,部署SecretStore。

      kubectl apply -f secretstore-ramrole.yaml

步骤三:配置数据同步信息

认证信息配置完成后,需要通过自定义资源ExternalSecret来配置待访问的KMS凭据信息,从而将KMS凭据导入到Kubernetes Secret。

说明

KMS凭据导入的Kubernetes Secret的命名空间、名称均与ExternalSecret的命名空间、名称一致。

  1. 创建自定义资源ExternalSecret并部署。

    1. 使用以下内容,替换相关字段后,创建external.yaml文件。

      参数

      替换说明

      <KMS_SECRET_NAME>

      必填,替换为目标KMS凭据名称。

      <KUBERNETES_SECRET_KEY>

      必填,为一系列键值对的集合。KMS的单条凭据会存放在Kubernetes Secret Data的某一条键值对中,需将<KUBERNETES_SECRET_KEY>替换为目标键值对的键。

      <KMS_SECRET_VERSION_STAGE>

      • 选填,替换为KMS凭据的版本状态(并非凭据的版本号),例如ACSCurrent。

      • RDS 凭据、PolarDB 凭据、Redis/Tair 凭据、RAM 凭据和 ECS 凭据只能获取 ACSPrevious 和 ACSCurrent 对应版本的凭据值。

      • 如需指定KMS凭据版本号进行同步,请将以下模板中的versionStage字段替换为versionId,并填入KMS凭据版本号。

      • RDS 凭据、PolarDB 凭据、Redis/Tair 凭据、RAM 凭据和 ECS 凭据不支持指定 VersionId,设置该参数将被忽略。

      关于凭据版本号和版本状态请参考凭据的组成中凭据版本的说明

      <KMS_SERVICE_ENDPOINT>

      • 选填,如需指定KMS服务请求Endpoint,需将其替换为对应的Endpoint的地址。

      • 参数支持KMS服务的共享网关和专属网关,可按需配置。

      • 参数是凭据级配置,可以为KMS凭据单独配置Endpoint地址,同时也支持全局配置,具体的配置说明请参考配置KMS服务Endpoint地址

      • 参数设置后,会覆盖全局配置和默认配置,该凭据请求的Endpoint地址为该参数值。

      <SECRET_STORE_NAME>

      选填,替换为对应SecretStore的名称,表示使用某个认证配置来导入目标KMS凭据。

      说明

      组件通过Worker RAM角色授权时,无需配置该参数。

      <SECRET_STORE_NAMESPACE>

      选填,替换为对应SecretStore的Namespace。

      说明

      组件通过Worker RAM角色授权时,无需配置该参数。

      apiVersion: alibabacloud.com/v1alpha1
      kind: ExternalSecret
      metadata:
        name: esdemo
      spec:
        provider: kms # 需要同步的阿里云服务类型,默认是kms,当同步KMS凭据时,可以不填写该字段或者指定字段值为 kms
        data: # 无需特殊处理的数据源。
          - key: <KMS_SECRET_NAME>
            name: <KUBERNETES_SECRET_KEY>
            versionStage: <KMS_SECRET_VERSION_STAGE>
            secretStoreRef: # 组件通过Worker RAM授权时,无需配置该参数。
              name: <SECRET_STORE_NAME>
              namespace: <SECRET_STORE_NAMESPACE>
          - key: <KMS_SECRET_NAME>
            name: <KUBERNETES_SECRET_KEY>
            versionStage: <KMS_SECRET_VERSION_STAGE>
            kmsEndpoint: <KMS_SERVICE_ENDPOINT>
    2. 执行以下命令,部署ExternalSecret。

      kubectl apply -f external.yaml
  2. 执行以下命令,查看集群中是否存在对应的Kubernetes Secret。

    kubectl get secret esdemo

    查询存在Secret,表明Secret同步成功。

ack-secret-manager组件更多高级用法

跨账号同步凭据

如果KMS实例(账号A中)与集群(账号B中)不在同一个阿里云账号中,可以通过ack-secret-manager组件将KMS凭据跨账号同步到集群中。下文通过RRSA认证机制,使ack-secret-manager组件能够获取跨账号访问KMS实例的权限。集群中的组件通过其OIDC提供商扮演账号A中的角色,从而获得对账号A中KMS实例的访问权限,并将该KMS实例导入到账号B的集群中。

账号A(KMS实例所在阿里云账号)权限配置

  1. 创建信任集群所在账号的RAM角色。具体操作,请参见创建可信实体为阿里云账号的RAM角色

    重要

    在选择信任主体名称时,选择其他云账号,填入账号B(集群所在的阿里云账号)的账号ID。

  2. 创建访问KMS服务凭据所需的权限策略。策略内容如下。具体操作,请参见创建自定义权限策略

    {
        "Version": "1",
        "Statement": [
            {
                "Action": [
                    "kms:GetSecretValue",
                    "kms:Decrypt"
                ],
                "Resource": [
                    "*"
                ],
                "Effect": "Allow"
            }
        ]
    }
  3. 为上一步创建的RAM角色授权。具体操作,请参见为RAM角色授权

账号B(集群所在的阿里云账号)权限配置

  1. 容器服务管理控制台开启集群的RRSA功能,用于创建集群的身份提供商信息具体操作,请参见启用RRSA功能

    说明

    安装ack-secret-manager时,需要将参数rrsa.enable设置为true,以启用RRSA功能。

  2. 创建可信实体为身份提供商的RAM角色,以供ack-secret-manager使用。

    选择信任主体类型身份提供商,添加主体时主要参数设置如下,具体操作,请参见创建OIDC身份提供商的RAM角色

    配置项

    描述

    身份提供商类型

    OIDC

    身份提供商

    选择ack-rrsa-<CLUSTER_ID>。其中,<CLUSTER_ID>为集群ID。

    条件

    • oidc:iss:保持默认。

    • oidc:aud:保持默认。

    • oidc:sub:需手动添加该条件。

      • 条件键:选择oidc:sub

      • 运算符:选择StringEquals

      • 条件值:输入system:serviceaccount:<NAMESPACE>:<SERVICEACCOUNT_NAME>。其中,<NAMESPACE>为应用所在的命名空间。<SERVICEACCOUNT_NAME>为服务账户名称。根据本文测试应用的信息,此处需填入system:serviceaccount:kube-system:ack-secret-manager

        说明

        如果将ack-secret-manager安装在其他的命名空间,请将kube-system替换为对应命名空间的名称。

  3. 创建自定义权限策略并为上一步账号B下创建的RAM角色授权。

    1. 创建ack-secret-manager导入KMS凭据时所需的权限策略,其中Resource的值为KMS所在账号A下的RAM角色的ARN。具体操作,请参见创建自定义权限策略

      {
        "Statement": [
          {
            "Action": "sts:AssumeRole",
            "Effect": "Allow",
            "Resource": "acs:ram:*:<account-id>:role/<role-name>"
          }
        ],
        "Version": "1"
      }

      上述自定义策略中的Resource为角色ARN,其中,<account-id>为KMS实例所在的阿里云账号A的账号ID,<role-name>为账号A中创建的RAM角色名称。关于如何查看角色ARN,请参见如何查看RAM角色的ARN?

    2. 为上一步在账号B下创建的RAM角色授权。具体操作,请参见为RAM角色授权

  4. 创建自定义资源SecretStore并部署。

    1. 使用以下内容,替换相关字段后,创建secretstore-ramrole.yaml文件。

      • <ACK-accountID>:替换为集群所在的阿里云账号B的账号ID。

      • <clusterID>:替换为集群ID。

      • <ACK-roleName>:替换为集群所在的阿里云账号B下创建的RAM角色的名称。

      • <KMS-accountID>:替换为KMS实例所在的阿里云账号A的账号ID。

      • <KMS-roleName>:替换为KMS实例所在的阿里云账号A下创建的RAM角色的名称。

      • <roleSessionName>:替换为角色会话名称(自定义字符串)。

      apiVersion: alibabacloud.com/v1alpha1
      kind: SecretStore
      metadata:
        name: scdemo-cross-account
      spec:
        KMS:
          KMSAuth:
            oidcProviderARN: "acs:ram::<ACK-accountID>:oidc-provider/ack-rrsa-<clusterID>"
            ramRoleARN: "acs:ram::<ACK-accountID>:role/<ACK-roleName>"
            remoteRamRoleARN: "acs:ram::<KMS-accountID>:role/<KMS-roleName>"
            remoteRamRoleSessionName: <roleSessionName>
  5. 配置数据同步信息。具体操作,请参见步骤三:配置数据同步信息

凭据解析与Key替换

可以参考以下方式对JSON格式和YAML格式的凭据进行解析。

JSON格式的凭据解析

JSON中指定的Key解析

如果需要解析一个JSON格式的KMS Secret,并将其中指定的key-value键值对同步到Kubernetes Secret中,可以使用JMESPath字段。以下是一个使用JMESPath字段的样例,例如,如果在KMS凭据管家中有如下JSON格式的Secret。

{"name":"tom","friends":[{"name":"lily"},{"name":"mark"}]}

对应的ExternalSecret样例如下。当使用JMESPath字段时,必须指定以下两个子字段:

  • path:必选项,基于JMESPath规范解析JSON中的指定字段。

  • objectAlias:必选项,用于指定解析出的字段同步到Kubernetes Secret中的Key名称。

apiVersion: alibabacloud.com/v1alpha1
kind: ExternalSecret
metadata:
  name: es-json-demo
spec:
  provider: kms
  data: 
    - key: <KMS secret name>
      versionStage: <KMS secret version stage>
      secretStoreRef:
        name: <secret store name>
        namespace: <secret store namespace>
      jmesPath: # Parse some fields in json string
        - path: "name"
          objectAlias: "myname"
        - path: "friends[0].name"
          objectAlias: "friendname"

JSON自解析

如果不知道凭据的具体结构,但还需要将JSON凭据解析后再存储在Secret中,可以定义dataProcess.extract字段采用JSON自解析功能,同时还可以定义dataProcess.replaceRule字段,针对解析后的字段键进行规则替换,以防止不规则的Secret data key导致无法创建Secret。

例如,如果在KMS凭据管家中有如下JSON格式的Secret。

{"/name-invalid":"lily","name-invalid/":[{"name":"mark"}]}

对应的ExternalSecret样例如下。

apiVersion: alibabacloud.com/v1alpha1
kind: ExternalSecret
metadata:
  name: extract-secret
spec:
  provider: kms
  dataProcess:
    - extract:
        key: <KMS secret name>
        versionStage: ACSCurrent # KMS凭据版本。
        secretStoreRef:
          name: <secret store name>
          namespace: <secret store namespace>
      replaceRule: # 替换规则。
        - source: "^/.*d$" # 替换以“/“开头以”d“结尾的key为tom。
          target: "tom"
        - source: "^n.*/$" # 替换以”n“开头以”/“结尾的key为mark。
          target: "mark"

YAML格式的凭据解析

YAML中指定的Key解析

如果需要解析一个YAML格式的KMS Secret,并将其中指定的key-value键值对同步到Kubernetes Secret中,可以使用JMESPath字段。以下是一个使用JMESPath字段的样例,例如,如果在KMS凭据管家中有如下YAML格式的Secret。

name: tom
friends:
  - name: lily
  - name: mark

对应的ExternalSecret样例如下。当使用JMESPath字段时,必须指定以下两个子字段:

  • path:必选项,基于JMESPath规范解析YAML中的指定字段。

  • objectAlias:必选项,用于指定解析出的字段同步到Kubernetes Secret中的Key名称。

apiVersion: alibabacloud.com/v1alpha1
kind: ExternalSecret
metadata:
  name: es-yaml-demo
spec:
  provider: kms
  data: 
    - key: <KMS secret name>
      versionStage: <KMS secret version stage>
      secretStoreRef:
        name: <secret store name>
        namespace: <secret store namespace>
      jmesPath: # Parse some fields in yaml string
        - path: "name"
          objectAlias: "myname"
        - path: "friends[0].name"
          objectAlias: "friendname"

YAML自解析

如果不知道凭据的具体结构,但还需要将YAML凭据解析后再存储在Secret中,可以定义dataProcess.extract字段采用YAML自解析功能,同时还可以定义dataProcess.replaceRule字段,针对解析后的字段键进行规则替换,以防止不规则的Secret data key导致无法创建Secret。

例如,如果在KMS凭据管家中有如下YAML格式的Secret。

/name-invalid: lily
name-invalid/:
  - name: mark

对应的ExternalSecret样例如下。

apiVersion: alibabacloud.com/v1alpha1
kind: ExternalSecret
metadata:
  name: extract-secret
spec:
  provider: kms
  dataProcess:
    - extract:
        key: <KMS secret name>
        versionStage: ACSCurrent # KMS凭据版本。
        secretStoreRef:
          name: <secret store name>
          namespace: <secret store namespace>
      replaceRule: # 替换规则。
        - source: "^/.*d$" # 替换以“/“开头以”d“结尾的key为tom。
          target: "tom"
        - source: "^n.*/$" # 替换以”n“开头以”/“结尾的key为mark。
          target: "mark"

配置KMS服务Endpoint地址

可以通过专属网关访问或共享网关访问两种方式访问KMS服务获取凭据,请参考以下要求进行Endpoint配置。关于专属网关访问和共享网关访问的更多差异,请参见共享网关和专属网关的差异

KMS Endpoint优先级规则

类型

配置字段

用途

优先级

说明

凭据级配置

ExternalSecret.spec.data.kmsEndpoint

为需要导入的每个KMS凭据单独指定Endpoint地址。

最高

针对单个凭据优先使用该配置,会覆盖全局配置和默认配置。

全局配置

command.kmsEndpoint(启动参数)

用于所有KMS请求。

提供了凭据级配置以外的其他KMS凭据使用的Endpoint地址

默认配置

当未明确配置Endpoint地址时使用。

最低

默认使用的KMS Endpoint地址 kms-vpc.{region}.aliyuncs.com,替换 {region} 为 KMS凭据所在的Region。

apiVersion: "alibabacloud.com/v1alpha1"
kind: ExternalSecret
metadata:
  name: esdemo
spec:
  provider: kms
  data:
    - key: test-hangzhou # 实际Endpoint 地址:全局配置存在时使用全局配置,否则为默认配置地址:kms-vpc.{region}.aliyuncs.com
      name: hangzhou-vpc
      versionId: v1
    - key: test-hangzhou # 实际Endpoint 地址:字段 kmsEndpoint 指定的 kms.cn-hangzhou.aliyuncs.com
      name: hangzhou-public
      versionId: v1
      kmsEndpoint: kms.cn-hangzhou.aliyuncs.com

KMS Endpoint配置地址说明

网关类型

域名类型

Endpoint 地址

使用说明

专属网关

KMS私网域名

{kms-instance-id}.cryptoservice.kms.aliyuncs.com

  • 要求KMS凭据所属实例和集群在同一Region及同一VPC中。

  • 替换 {kms-instance-id} 为KMS凭据所属实例ID。

  • KMS凭据所属实例版本为3.0以上。

共享网关

VPC域名

kms-vpc.{region}.aliyuncs.com

  • 要求KMS凭据和集群在同一Region。

  • 替换 {region} 为 KMS凭据所在的Region。

  • 应用默认配置,使用此地址时无需配置。

共享网关

公网

kms.{region}.aliyuncs.com

  • 替换 {region} 为 KMS凭据所在的Region。

  • 集群具有公网访问能力。

CRD 资源说明

当前提供了四种自定义资源定义(CRD),分为两类:

认证资源配置类

  1. SecretStore: 命名空间级别资源,用于定义访问凭据(如RRSA、ClientKey、AK配置等)。

  2. ClusterSecretStore: 集群级别资源,功能与SecretStore相同,但可被集群中任意命名空间的ExternalSecret引用,并支持访问控制配置。

数据同步配置类

  1. ExternalSecret: 命名空间级别资源,用于定义需要同步的凭据基础信息(如凭据名称、版本等)以及指定SecretStore。

  2. ClusterExternalSecret: 集群级别资源,用于管理和协调多个命名空间下的ExternalSecret,能够在匹配的命名空间中自动创建ExternalSecret。

集群级别资源说明

ClusterExternalSecret

集群级别资源,用于管理和协调多个命名空间下的ExternalSecret,支持使用 spec.namespaceSelectors 配置匹配的命名空间,在匹配的命名空间中自动创建ExternalSecret

apiVersion: "alibabacloud.com/v1alpha1"
kind: ClusterExternalSecret
metadata:
  name: cluster-kms
spec:
  externalSecretSpec:
    provider: kms
    data:
      - key: test
        name: test
        versionId: v1
        secretStoreRef:
          name: alibaba-credentials
          kind: ClusterSecretStore
  externalSecretName: kms
  externalSecretMetadata:
    labels:
      app: "my-app"
      team: "backend"
    annotations:
      annotation-key1: "annotation-value1"
      annotation-key2: "annotation-value2"
  namespaceSelectors:
  - matchLabels:
      kubernetes.io/metadata.name: default
  - matchExpressions: 
    - key: kubernetes.io/metadata.name
      operator: In
      values:
      - test
  rotationInterval: 10s

spec字段说明

crd 字段

描述

是否必选

externalSecretSpec

要创建的 ExternalSecret 的规格定义

externalSecretName

要创建的 ExternalSecret 的名称,默认是 ClusterExternalSecret 的名称

externalSecretMetadata

要创建的 ExternalSecret 的元数据

namespaceSelectors

用于选择目标命名空间的标签选择器列表

rotationInterval

控制器检查命名空间标签和协调对象的时间间隔

externalSecretMetadata字段说明

externalSecretMetadata 字段允许您自动为 ClusterExternalSecret 创建的 ExternalSecret 资源添加额外的元数据:

crd 字段

描述

是否必选

annotations

要创建的 ExternalSecret 的注解

labels

要创建的 ExternalSecret 的标签

ClusterSecretStore

集群级别资源,功能与SecretStore相同,但可被集群中任意命名空间的ExternalSecret引用,并支持使用 spec.conditions 配置访问控制

apiVersion: alibabacloud.com/v1alpha1
kind: ClusterSecretStore
metadata:
  name: alibaba-credentials
spec:
  conditions: 
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: test
  KMS:
    KMSAuth:
      oidcProviderARN: acs:ram::<role-name>:oidc-provider/ack-rrsa-<cluster-id>
      serviceAccountRef:
        name: test-serviceaccount-auth
        namespace: test

spec字段说明

crd 字段

描述

是否必选

conditions

定义允许访问该资源的命名空间条件

KMS

连接KMS凭据管家服务获取密钥

OOS

连接OOS服务获取加密参数

conditions字段说明

crd 字段

描述

是否必选

namespaceSelector

使用标签选择器匹配允许访问的命名空间

namespaces

明确列出允许访问的命名空间名称列表

namespaceRegexes

使用正则表达式匹配允许访问的命名空间名称列表

跨命名空间访问控制

为了增强安全性和灵活性,ack-secret-manager提供了多种跨命名空间访问控制机制:

ExternalSecret 引用 SecretStore 控制
  • 通过 command.enableCrossNamespaceSecretStore参数控制ExternalSecret是否可以跨命名空间引用SecretStore。

  • 默认值为true,即允许跨命名空间引用。

  • 设置为false时,ExternalSecret只能引用同命名空间的SecretStore。

SecretStore 引用认证资源控制
  • 通过 command.enableCrossNamespaceAuthRef参数控制SecretStore是否可以跨命名空间引用认证资源(ServiceAccount、AccessKey Secret)。

  • 默认值为true,即允许跨命名空间引用。

  • 设置为false时,SecretStore只能引用同命名空间的认证资源。

ClusterSecretStore 访问控制
  • ClusterSecretStore 通过 spec.conditions 字段定义允许访问该资源的命名空间条件

  • 支持三种访问控制方式,条件之间是或的关系:

    1. namespaceSelector:使用标签选择器匹配允许访问的命名空间。

    2. namespaces:明确列出允许访问的命名空间名称列表。

    3. namespaceRegexes:使用正则表达式匹配允许访问的命名空间名称列表。

      conditions: 
        - namespaceSelector:
            matchLabels:
              app: myapp
            matchExpressions: 
            - key: environment
              operator: In
              values:
              - dev
        - namespaces:
          - default
          - test
        - namespaceRegexes:
          - "kube-.*"

推荐使用方式

跨命名空间访问推荐方案

对于需要跨命名空间访问的场景,推荐使用以下组合:

  1. ClusterSecretStore + ExternalSecret:当多个命名空间需要使用相同的认证配置时。

  2. ClusterSecretStore + ClusterExternalSecret:当需要在多个命名空间中自动创建相同配置的ExternalSecret时。

安全最佳实践
  1. 最小权限原则:

    • 在不需要跨命名空间访问的场景中,将 command.enableCrossNamespaceSecretStore 和 command.enableCrossNamespaceAuthRef设置为false

    • 优先使用命名空间级别的资源(SecretStore 和 ExternalSecret)。

  2. 访问控制配置:

    • 使用 ClusterSecretStore 时,明确配置 spec.conditions 来限制可访问的命名空间。

    • 避免创建无访问限制的 ClusterSecretStore。

  3. 认证方式选择:

    • 优先使用 RRSA 或 ServiceAccount 方式进行认证,避免在配置中直接暴露AccessKey。

    • 将认证配置与数据配置分离,提高安全性。

  4. 非必要不使用 ClusterExternalSecret,以减少Secrets在不同命名空间中的泄露风险:

    • 如果业务需要在多个命名空间中同步Secrets实例,可以利用 spec.namespaceSelectors 精确控制 ExternalSecret 的创建范围。

相关文档

为了保护从KMS读取后缓存在ACK集群中的Secret,可以对ACK集群Secret进行一键加密。具体操作,请参见使用阿里云KMS进行Secret的落盘加密