ack-secret-manager支持以Kubernetes Secret实例的形式向集群导入或同步KMS凭据信息,确保集群内的应用能够安全地访问敏感信息。通过该组件,可以实现密钥数据的自动更新,使应用负载通过文件系统挂载指定Secret实例来使用凭据信息,同时帮助解决负载应用和阿里云凭据管家交互的兼容性问题。
安全说明
通常情况下,用户的密钥会保存在文件中供应用程序读取,这种情况和通过阿里云KMS凭据管家直接读取密钥存在兼容性问题。ack-secret-manager可以解决此类兼容性问题,同时支持将密钥同步创建为集群中的Kubernetes原生Secrets实例,以供环境变量挂载使用。使用前请评估如下的安全风险。
当密钥在文件系统中可以被访问时,如果应用中存在某些有缺陷的软件,该软件的漏洞可能会造成目录遍历的风险,导致敏感信息泄露。
一些Debug端点或Logs权限的误配置可能导致密钥泄露,所以通过环境变量挂载引用的方式消费密钥是一个不安全且不推荐的做法。
当开启Secret实例同步特性时,需要基于权限最小化原则严格控制访问权限。
鉴于上述原因,如果应用中并不需要密文的持久化存储,推荐通过RRSA配置ServiceAccount的RAM权限实现Pod权限隔离为应用配置Pod维度的最小化权限,并通过GetSecretValue直接在应用中获取密钥凭据,以减少密钥内容在Pod文件系统或Kubernetes集群Secrets中的暴露风险。
前提条件
已创建ACK集群。请参见创建ACK托管集群、创建ACK One注册集群、创建ACK Serverless集群。
支持ACK托管集群、ACK专有集群、ACK Serverless集群、ACK Edge集群、和ACK One注册集群。
步骤一:安装ack-secret-manager组件
在ACK集群列表页面,单击目标集群名称,在集群详情页左侧导航栏,选择。
在Helm页面,单击创建,在Chart区域搜索并选中ack-secret-manager,其他设置保持默认,然后单击下一步。
根据弹出的页面提示确认,组件将被安装在默认的kube-system命名空间中,并以组件名称发布应用。如果需要自定义应用名和命名空间,请根据页面提示设置。
在参数配置页面,选择Chart版本为最新版本,并设置相应参数,然后单击确定。
如需开启RRSA认证功能,需要将参数rrsa.enable设置为true。

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

command.disablePolling:是否关闭凭据的自动轮询功能,设置为false,开启凭据自动轮询功能。command.pollingInterval:凭据同步的频率,设置为120s,此处以两分钟同步一次凭据为例,可以根据实际需求调整。
配置限流参数:如果集群中具有较多的ExternalSecret(待同步的 KMS 凭据),配置不当可能会引发KMS或RAM侧的限流,因此,需要配置以下限流参数避免发生限流。

command.maxConcurrentKmsSecretPulls:每秒可以同步的最大KMS凭据数量,默认为10。如需指定KMS服务Endpoint地址,需要配置kmsEndpoint参数。

command.kmsEndpoint:参数支持KMS服务的共享网关和专属网关,可按需配置,该参数是全局配置,当前也支持凭据级的配置,具体的配置说明请参见配置KMS服务Endpoint地址。如需禁止ExternalSecret跨命名空间引用SecretStore,需要将参数
command.enableCrossNamespaceSecretStore设置为false
如需禁止SecretStore跨命名空间引用ServiceAccount,需要将参数
command.enableCrossNamespaceAuthRef设置为false
如需禁用集群维度的控制器,需要配置以下参数,crds 和 command 参数值是相互关联的,对于集群维度的控制器说明请参考集群级别资源说明。

crds.createClusterSecretStore:控制是否安装 ClusterSecretStore CRD,默认为true安装crds.createClusterExternalSecret:控制是否安装 ClusterExternalSecret CRD,默认为true安装command.processClusterSecretStore:控制是否处理 ClusterSecretStore 资源,默认为true处理command.processClusterExternalSecret:控制是否处理 ClusterExternalSecret 资源,默认为true处理
创建成功后,会自动跳转到目标集群的ack-secret-manager页面,检查安装结果。若下图中所有资源创建成功,则表明组件安装成功。
步骤二:配置组件认证信息
需要通过自定义资源SecretStore来配置ack-secret-manager的认证信息,以确保该组件有权限获取KMS服务中的凭据信息,否则ack-secret-manager将无法向集群中导入或同步凭据信息。可以根据集群类型选择如下四种授权方式进行配置。
使用ServiceAccount维度的细粒度RRSA授权:适用于1.22及以上版本的ACK托管集群和ACK Serverless集群。
使用ack-secret-manager的ServiceAccount无AK授权:适用于1.22及以上版本的ACK托管集群和ACK Serverless集群。
为集群对应的Worker RAM角色添加权限:由于ACK Serverless集群没有绑定Worker RAM角色,该方式只适用于ACK托管集群、ACK专有集群和ACK One注册集群。
通过设置AK扮演指定RAM角色:适用于所有容器服务Kubernetes集群。
使用ServiceAccount维度的细粒度RRSA授权
基于Namespace维度下不同ServiceAccount的RRSA授权实现多租场景下的KMS凭据管家访问权限隔离。相比其他授权方式,RRSA授权方式可以实现Pod维度的权限隔离,还可以避免直接使用AK、SK引起的凭据泄露风险。

在容器服务管理控制台开启集群的RRSA功能,用于创建集群的身份提供商信息。具体操作,请参见启用RRSA功能。
说明安装ack-secret-manager时,需要将参数rrsa.enable设置为true,以启用RRSA功能。
为不同的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中的配置保持一致。
创建自定义权限策略并为上一步创建的RAM角色授权。
在指定命名空间下创建访问指定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>保持一致使用
serviceAccountRef认证方式部署自定义资源SecretStore。基于以下内容,替换相关字段后,创建secretstore-rrsa.yaml文件。
<NAME>:替换为指定的SecretStore实例名称。<NAMESPACE>:替换为指定的集群命名空间名称。<SERVICEACCOUNT_NAME>:替换为上一步中创建的ServiceAccount实例名称。apiVersion: alibabacloud.com/v1alpha1 kind: SecretStore metadata: name: <NAME> namespace: <NAMESPACE> spec: KMS: KMSAuth: serviceAccountRef: name: <SERVICEACCOUNT_NAME>
执行以下命令,部署SecretStore。
kubectl apply -f secretstore-rrsa.yaml
使用ack-secret-manager的ServiceAccount无AK授权
相比其他授权方式,RRSA授权方式可以实现Pod维度的权限隔离,还可以避免直接使用AK、SK引起的凭据泄露风险。
在容器服务管理控制台开启集群的RRSA功能,用于创建集群的身份提供商信息。具体操作,请参见启用RRSA功能。
说明安装ack-secret-manager时,需要将参数rrsa.enable设置为true,以启用RRSA功能。
创建可信实体为身份提供商的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替换为对应命名空间的名称。
创建自定义权限策略并为上一步创建的RAM角色授权。
创建自定义资源SecretStore关联对应的认证方式并部署。
使用以下内容,替换相关字段后,创建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>"
执行以下命令,部署SecretStore。
kubectl apply -f secretstore-rrsa.yaml
为集群对应的Worker RAM角色添加权限
创建如下自定义权限策略。具体操作,请参见创建自定义权限策略。
{ "Version": "1", "Statement": [ { "Action": [ "kms:GetSecretValue", "kms:Decrypt" ], "Resource": [ "*" ], "Effect": "Allow" } ] }为集群的Worker RAM角色添加上一步创建的自定义权限。具体操作,请参见为集群的Worker RAM角色授权。
通过设置AK扮演指定RAM角色
创建可信实体为阿里云账号的RAM角色,以供ack-secret-manager组件使用。具体操作,请参见创建可信实体为阿里云账号的RAM角色。
说明在选择信任主体类型时,请选择当前云账号。
创建自定义权限策略并为上一步已创建的RAM角色授权。
创建自定义权限策略,并为指定的RAM用户授权。
创建扮演上述角色的自定义权限策略。策略内容如下。具体操作,请参见创建自定义权限策略。
{ "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?。将上述自定义策略授权给RAM用户,便可以指定具体可以扮演的RAM角色。关于如何为RAM用户授权,请参见为RAM用户授权。
创建Secret用于存放指定RAM用户的访问凭证信息。
使用以下内容,替换您的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执行以下命令,创建名为ramuser的Secret。
kubectl apply -f ramuser.yaml
创建自定义资源SecretStore关联对应的认证方式并部署。
使用以下内容,替换相关字段后,创建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>执行以下命令,部署SecretStore。
kubectl apply -f secretstore-ramrole.yaml
步骤三:配置数据同步信息
认证信息配置完成后,需要通过自定义资源ExternalSecret来配置待访问的KMS凭据信息,从而将KMS凭据导入到Kubernetes Secret。
KMS凭据导入的Kubernetes Secret的命名空间、名称均与ExternalSecret的命名空间、名称一致。
创建自定义资源ExternalSecret并部署。
使用以下内容,替换相关字段后,创建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>执行以下命令,部署ExternalSecret。
kubectl apply -f external.yaml
执行以下命令,查看集群中是否存在对应的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实例所在阿里云账号)权限配置
创建信任集群所在账号的RAM角色。具体操作,请参见创建可信实体为阿里云账号的RAM角色。
重要在选择信任主体名称时,选择其他云账号,填入账号B(集群所在的阿里云账号)的账号ID。
创建访问KMS服务凭据所需的权限策略。策略内容如下。具体操作,请参见创建自定义权限策略。
{ "Version": "1", "Statement": [ { "Action": [ "kms:GetSecretValue", "kms:Decrypt" ], "Resource": [ "*" ], "Effect": "Allow" } ] }为上一步创建的RAM角色授权。具体操作,请参见为RAM角色授权。
账号B(集群所在的阿里云账号)权限配置
在容器服务管理控制台开启集群的RRSA功能,用于创建集群的身份提供商信息。具体操作,请参见启用RRSA功能。
说明安装ack-secret-manager时,需要将参数rrsa.enable设置为true,以启用RRSA功能。
创建可信实体为身份提供商的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替换为对应命名空间的名称。
创建自定义权限策略并为上一步账号B下创建的RAM角色授权。
创建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?。为上一步在账号B下创建的RAM角色授权。具体操作,请参见为RAM角色授权。
创建自定义资源SecretStore并部署。
使用以下内容,替换相关字段后,创建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>
配置数据同步信息。具体操作,请参见步骤三:配置数据同步信息。
凭据解析与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优先级规则
类型 | 配置字段 | 用途 | 优先级 | 说明 |
凭据级配置 |
| 为需要导入的每个KMS凭据单独指定Endpoint地址。 | 最高 | 针对单个凭据优先使用该配置,会覆盖全局配置和默认配置。 |
全局配置 |
| 用于所有KMS请求。 | 中 | 提供了凭据级配置以外的其他KMS凭据使用的Endpoint地址 |
默认配置 | 无 | 当未明确配置Endpoint地址时使用。 | 最低 | 默认使用的KMS Endpoint地址 |
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.comKMS Endpoint配置地址说明
网关类型 | 域名类型 | Endpoint 地址 | 使用说明 |
专属网关 | KMS私网域名 | {kms-instance-id}.cryptoservice.kms.aliyuncs.com |
|
共享网关 | VPC域名 | kms-vpc.{region}.aliyuncs.com |
|
共享网关 | 公网 | kms.{region}.aliyuncs.com |
|
CRD 资源说明
当前提供了四种自定义资源定义(CRD),分为两类:
认证资源配置类
SecretStore: 命名空间级别资源,用于定义访问凭据(如RRSA、ClientKey、AK配置等)。
ClusterSecretStore: 集群级别资源,功能与SecretStore相同,但可被集群中任意命名空间的ExternalSecret引用,并支持访问控制配置。
数据同步配置类
ExternalSecret: 命名空间级别资源,用于定义需要同步的凭据基础信息(如凭据名称、版本等)以及指定SecretStore。
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: 10sspec字段说明
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: testspec字段说明
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字段定义允许访问该资源的命名空间条件支持三种访问控制方式,条件之间是或的关系:
namespaceSelector:使用标签选择器匹配允许访问的命名空间。namespaces:明确列出允许访问的命名空间名称列表。namespaceRegexes:使用正则表达式匹配允许访问的命名空间名称列表。
conditions: - namespaceSelector: matchLabels: app: myapp matchExpressions: - key: environment operator: In values: - dev - namespaces: - default - test - namespaceRegexes: - "kube-.*"
推荐使用方式
跨命名空间访问推荐方案
对于需要跨命名空间访问的场景,推荐使用以下组合:
ClusterSecretStore + ExternalSecret:当多个命名空间需要使用相同的认证配置时。
ClusterSecretStore + ClusterExternalSecret:当需要在多个命名空间中自动创建相同配置的ExternalSecret时。
安全最佳实践
最小权限原则:
在不需要跨命名空间访问的场景中,将
command.enableCrossNamespaceSecretStore和command.enableCrossNamespaceAuthRef设置为false。优先使用命名空间级别的资源(SecretStore 和 ExternalSecret)。
访问控制配置:
使用 ClusterSecretStore 时,明确配置
spec.conditions来限制可访问的命名空间。避免创建无访问限制的 ClusterSecretStore。
认证方式选择:
优先使用 RRSA 或 ServiceAccount 方式进行认证,避免在配置中直接暴露AccessKey。
将认证配置与数据配置分离,提高安全性。
非必要不使用 ClusterExternalSecret,以减少Secrets在不同命名空间中的泄露风险:
如果业务需要在多个命名空间中同步Secrets实例,可以利用
spec.namespaceSelectors精确控制 ExternalSecret 的创建范围。
相关文档
为了保护从KMS读取后缓存在ACK集群中的Secret,可以对ACK集群Secret进行一键加密。具体操作,请参见使用阿里云KMS进行Secret的落盘加密。