ack-secret-manager支持以Kubernetes Secret實例的形式向集群導入或同步KMS憑據信息,確保您集群內的應用能夠安全地訪問敏感信息。通過該組件,您可以實現密鑰數據的自動更新,使應用負載通過文件系統掛載指定Secret實例來使用憑據信息,同時幫助您解決負載應用和阿里云憑據管家交互的兼容性問題。
安全說明
通常情況下,用戶的密鑰會保存在文件中供應用程序讀取,這種情況和通過阿里云KMS憑據管家直接讀取密鑰存在兼容性問題。ack-secret-manager可以解決此類兼容性問題,同時支持將密鑰同步創(chuàng)建為集群中的Kubernetes原生Secrets實例,以供環(huán)境變量掛載使用。使用前請您評估如下的安全風險。
當密鑰在文件系統中可以被訪問時,如果應用中存在某些有缺陷的軟件,該軟件的漏洞可能會造成目錄遍歷的風險,導致敏感信息泄露。
由于一些Debug端點或Logs權限的誤配置都可能導致密鑰泄露,所以通過環(huán)境變量掛載引用的方式消費密鑰是一個不安全且不推薦的方式。
當開啟Secret實例同步特性時,需要基于權限最小化原則嚴格控制訪問權限。
鑒于上述原因,如果應用中并不需要密文的持久化存儲,推薦使用通過RRSA配置ServiceAccount的RAM權限實現Pod權限隔離為應用配置Pod維度的最小化權限,并通過憑據管理直接在應用中獲取密鑰憑據,以減少密鑰內容在Pod文件系統或Kubernetes集群Secrets中的暴露風險。
前提條件
已創(chuàng)建ACK集群,且集群與您的KMS服務憑據在同一地域。支持ACK托管集群、ACK專有集群、ACK注冊集群、ACK Serverless集群。具體操作,請參見創(chuàng)建ACK托管集群、通過控制臺創(chuàng)建注冊集群、創(chuàng)建ACK Serverless集群。
步驟一:安裝ack-secret-manager組件
登錄容器服務管理控制臺,在左側導航欄選擇集群。
在集群列表頁面,單擊目標集群名稱,然后在左側導航欄,選擇 。
在Helm頁面,單擊創(chuàng)建,在Chart區(qū)域搜索并選中ack-secret-manager,其他設置保持默認,然后單擊下一步。
根據彈出的頁面提示確認,組件將被安裝在默認的kube-system命名空間中,并以組件名稱發(fā)布應用。如果您需要自定義應用名和命名空間,請根據頁面提示設置。
在參數配置頁面,選擇Chart版本為最新版本,并設置相應參數,然后單擊確定。
如需開啟RRSA認證功能,您需要將參數rrsa.enable設置為true。
如需開啟定時同步憑據功能,您需要配置如下參數。
command.disablePolling
:是否關閉憑據的自動輪詢功能,設置為false,開啟憑據自動輪詢功能。command.pollingInterval
:憑據同步的頻率,設置為120s,此處以兩分鐘同步一次憑據為例,您可以根據實際需求調整。
創(chuàng)建成功后,會自動跳轉到目標集群的ack-secret-manager頁面,檢查安裝結果。若下圖中所有資源創(chuàng)建成功,則表明組件安裝成功。
步驟二:配置組件認證信息
您需要通過自定義資源SecretStore來配置ack-secret-manager的認證信息,以確保該組件有權限獲取KMS服務中的憑據信息,否則ack-secret-manager將無法向集群中導入或同步憑據信息。您可以根據集群類型選擇如下三種授權方式進行配置。
通過RRSA授權:適用于1.22及以上版本的ACK托管集群和ACK Serverless集群。
為集群對應的Worker RAM角色添加權限:適用于ACK托管集群、ACK專有集群和ACK注冊集群。
通過設置AK扮演指定RAM角色:適用于所有容器服務Kubernetes集群。
通過RRSA授權
RRSA適用于1.22及以上版本的ACK托管集群和ACK Serverless集群。相比其他授權方式,RRSA授權方式可以實現Pod維度的權限隔離,還可以避免直接使用AK、SK引起的憑據泄漏風險。
創(chuàng)建可信實體為身份提供商的RAM角色,以供ack-secret-manager使用。
使用阿里云賬號(主賬號)登錄RAM控制臺。
在左側導航欄,選擇 。
在角色頁面,單擊創(chuàng)建角色。
在創(chuàng)建角色頁面,選擇可信實體類型為身份提供商,然后單擊下一步。
在配置角色頁面,配置如下角色信息后,單擊完成。
oidc:iss:保持默認。
oidc:aud:選擇sts.aliyuncs.com。
oidc:sub:條件判定方式選擇StringEquals,值的格式為system:serviceaccount:<namespace>:<serviceAccountName>。
<namespace>
:應用所在的命名空間。<serviceAccountName>
:服務賬戶名稱。
根據測試應用的信息,此處需要填入
system:serviceaccount:kube-system:ack-secret-manager
。
說明阿里云賬號(主賬號)對賬號中的資源具有完全管理權限,您也可以在RAM中創(chuàng)建一個RAM用戶,授予AdministratorAccess權限,充當賬號管理員,該管理員可以對賬號下所有云資源進行管控操作。更多信息,請參見創(chuàng)建RAM用戶作為賬號管理員。
配置項
描述
角色名稱
自定義角色名稱。
備注
選填有關該角色的備注信息。
身份提供商類型
OIDC。
選擇身份提供商
ack-rrsa-<cluster_id>。其中,<cluster_id>為您的集群ID。
限制條件
說明如果您將ack-secret-manager安裝在其他的命名空間,請將
kube-system
替換為對應命名空間的名稱。創(chuàng)建自定義授權策略并為上一步創(chuàng)建的RAM角色授權。
創(chuàng)建ack-secret-manager導入KMS憑據時所需的權限策略。
策略內容如下。具體操作,請參見創(chuàng)建自定義權限策略。
為上一步創(chuàng)建的RAM角色授權。具體操作,請參見為RAM角色授權。
{ "Action": [ "kms:GetSecretValue", "kms:Decrypt" ], "Resource": [ "*" ], "Effect": "Allow" }
創(chuàng)建自定義資源SecretStore關聯對應的認證方式并部署。
使用以下內容,替換相關字段后,創(chuàng)建secretstore-rrsa.yaml文件。
{accountID}
:替換為同步KMS憑據的阿里云賬號ID。{clusterID}
:替換為您的集群ID。{roleName}
:替換為步驟2中創(chuàng)建的RAM角色名稱。
執(zhí)行以下命令,部署SecretStore。
apiVersion: 'alibabacloud.com/v1alpha1' kind: SecretStore metadata: name: scdemo-rrsa spec: KMS: KMSAuth: oidcProviderARN: "acs:ram::{accountID}:oidc-provider/ack-rrsa-{clusterID}" ramRoleARN: "acs:ram::{accountID}:role/{roleName}"
kubectl apply -f secretstore-rrsa.yaml
安裝ack-secret-manager時,需要將參數rrsa.enable設置為true,以啟用RRSA功能。
為集群對應的Worker RAM角色添加權限
由于ACK Serverless集群沒有綁定Worker RAM角色,該方式只適用于ACK托管集群、ACK專有集群和ACK注冊集群。
創(chuàng)建如下自定義權限策略。具體操作,請參見創(chuàng)建自定義權限策略。
為集群的Worker RAM角色添加上一步創(chuàng)建的自定義權限。具體操作,請參見為集群的Worker RAM角色授權。
{
"Action": [
"kms:GetSecretValue",
"kms:Decrypt"
],
"Resource": [
"*"
],
"Effect": "Allow"
}
通過設置AK扮演指定RAM角色
適用于所有容器服務Kubernetes集群。
創(chuàng)建可信實體為阿里云賬號的RAM角色,以供ack-secret-manager組件使用。具體操作,請參見創(chuàng)建可信實體為阿里云賬號的RAM角色。
創(chuàng)建自定義授權策略并為上一步已創(chuàng)建的RAM角色授權。
創(chuàng)建訪問KMS服務憑據所需的權限策略。
策略內容如下。具體操作,請參見創(chuàng)建自定義權限策略。
為上一步已創(chuàng)建的RAM角色授權。具體操作,請參見為RAM角色授權。
{ "Action": [ "kms:GetSecretValue", "kms:Decrypt" ], "Resource": [ "*" ], "Effect": "Allow" }
創(chuàng)建扮演上述角色的自定義授權策略,并為指定的RAM用戶授權。
創(chuàng)建扮演上述角色的自定義授權策略。
為指定的RAM用戶授權。具體操作,請參見為RAM用戶授權。
策略內容如下。具體操作,請參見創(chuàng)建自定義權限策略。
{ "Statement": [ { "Action": "sts:AssumeRole", "Effect": "Allow", "Resource": "acs:ram::***:role/****" # 方式三的步驟1創(chuàng)建的RAM角色ARN。 } ], "Version": "1" }
創(chuàng)建Secret用于存放指定RAM用戶的AK、SK信息。
使用以下內容,替換您的AK、SK的Base64編碼信息后,創(chuàng)建ramuser.yaml文件。
apiVersion: v1 data: accessKey: {AK base64編碼} accessKeySecret: {SK base64 編碼} kind: Secret metadata: name: ramuser namespace: kube-system type: Opaque
執(zhí)行以下命令,創(chuàng)建名為ramuser的Secret。
kubectl apply -f ramuser.yaml
創(chuàng)建自定義資源SecretStore關聯對應的認證方式并部署。
使用以下內容,替換相關字段后,創(chuàng)建secretstore-ramrole.yaml文件。
{accountID}
:替換為同步KMS憑據的阿里云賬號ID。{roleName}
:替換為步驟1中創(chuàng)建的RAM角色名稱。{secretName}
:替換為存儲AK、SK的Secret名稱。{secretNamespace}
:替換為存儲AK、SK的Secret的Namespace。{secretKey}
:替換為存儲AK、SK的Secret Key。{roleSessionName}
:替換為角色會話名稱(自定義字符串)。
執(zhí)行以下命令,部署SecretStore。
apiVersion: 'alibabacloud.com/v1alpha1' kind: SecretStore metadata: name: scdemo-ramrole spec: KMS: KMSAuth: accessKey: name: {secretName} namespace: {secretNamespace} key: {secretKey} accessKeySecret: name: {secretName} namespace: {secretNamespace} key: {secretKey} ramRoleARN: "acs:ram::{accountID}:role/{roleName}" ramRoleSessionName: {roleSessionName}
kubectl apply -f secretstore-ramrole.yaml
步驟三:配置數據同步信息
認證信息配置完成后,您需要通過自定義資源ExternalSecret來配置待訪問的KMS憑據信息,從而導入KMS憑據到Kubernetes Secret。
KMS憑據導入的Kubernetes Secret的命名空間、名稱均與ExternalSecret的命名空間、名稱一致。
創(chuàng)建自定義資源ExternalSecret并部署。
使用以下內容,替換相關字段后,創(chuàng)建external.yaml文件。
參數
替換說明
{KMS secret name}
替換為目標KMS憑據名稱。
{Kubernetes secret key}
為一系列鍵值對的集合。KMS的單條憑據會存放在Kubernetes Secret Data的某一條鍵值對中,需將
{Kubernetes secret key}
替換為目標鍵值對的鍵。{KMS secret version stage}
替換為KMS憑據的版本狀態(tài)(并非憑據的版本號),例如ACSCurrent。
如需指定KMS憑據版本號進行同步,請將以下模板中的
versionStage
字段替換為versionId
,并填入KMS憑據版本號。{secret store name}
替換為對應
SecretStore
的名稱,表示使用某個認證配置來導入目標KMS憑據。{secret store namespace}
替換為對應
SecretStore
的Namespace。apiVersion: 'alibabacloud.com/v1alpha1' kind: ExternalSecret metadata: name: esdemo spec: data: # 無需特殊處理的數據源。 - key: {KMS secret name} name: {Kubernetes secret key} versionStage: {KMS secret version stage} secretStoreRef: name: {secret store name} namespace: {secret store namespace}
執(zhí)行以下命令,部署ExternalSecret。
kubectl apply -f external.yaml
執(zhí)行以下命令,查看集群中是否存在對應的Kubernetes Secret生成。
kubectl get secret esdemo
查詢存在Secret,表明Secret同步成功。
ack-secret-manager組件更多高級用法
跨賬號同步憑據
如果您的KMS實例與集群不在同一個阿里云賬號中,您需要將KMS憑據跨賬號同步到集群中。ack-secret-manager支持跨賬號同步憑據。下文以RRSA認證方式為例,介紹如何將賬號A中的KMS實例導入賬號B的集群中。
KMS實例所在賬號A下的配置步驟
創(chuàng)建信任集群所在賬號的RAM角色。具體操作,請參見創(chuàng)建可信實體為阿里云賬號的RAM角色。
重要在選擇信任的云賬號時,選擇其他云賬號,填入集群所在的阿里云賬號B的賬號ID。
創(chuàng)建訪問KMS服務憑據所需的權限策略。
策略內容如下。具體操作,請參見創(chuàng)建自定義權限策略。
{ "Action": [ "kms:GetSecretValue", "kms:Decrypt" ], "Resource": [ "*" ], "Effect": "Allow" }
為上一步創(chuàng)建的RAM角色授權。具體操作,請參見為RAM角色授權。
集群所在賬號B下的配置步驟
創(chuàng)建可信實體為身份提供商的RAM角色,以供ack-secret-manager使用。
使用阿里云賬號(主賬號)登錄RAM控制臺。
在左側導航欄,選擇 。
在角色頁面,單擊創(chuàng)建角色。
在創(chuàng)建角色頁面,選擇可信實體類型為身份提供商,然后單擊下一步。
在配置角色頁面,配置如下角色信息后,單擊完成。
oidc:iss:保持默認。
oidc:aud:選擇sts.aliyuncs.com。
oidc:sub:條件判定方式選擇StringEquals,值的格式為system:serviceaccount:<namespace>:<serviceAccountName>。
<namespace>
:應用所在的命名空間。<serviceAccountName>
:服務賬戶名稱。
根據測試應用的信息,此處需要填入
system:serviceaccount:kube-system:ack-secret-manager
。
說明阿里云賬號(主賬號)對賬號中的資源具有完全管理權限,您也可以在RAM中創(chuàng)建一個RAM用戶,授予AdministratorAccess權限,充當賬號管理員,該管理員可以對賬號下所有云資源進行管控操作。更多信息,請參見創(chuàng)建RAM用戶作為賬號管理員。
配置項
描述
角色名稱
自定義角色名稱。
備注
選填有關該角色的備注信息。
身份提供商類型
OIDC。
選擇身份提供商
ack-rrsa-<cluster_id>。其中,<cluster_id>為您的集群ID。
限制條件
說明如果您將ack-secret-manager安裝在其他的命名空間,請將
kube-system
替換為對應命名空間的名稱。創(chuàng)建自定義授權策略并為上一步賬號B下創(chuàng)建的RAM角色授權。
創(chuàng)建ack-secret-manager導入KMS憑據時所需的權限策略。
策略內容如下,其中,
Resource
為在KMS所在賬號A下創(chuàng)建的RAM角色的ARN。具體操作,請參見創(chuàng)建自定義權限策略。{ "Statement": [ { "Action": "sts:AssumeRole", "Effect": "Allow", "Resource": "acs:ram::***:role/****" # KMS所在賬號A下的RAM角色的ARN。 } ], "Version": "1" }
為上一步在賬號B下創(chuàng)建的RAM角色授權。具體操作,請參見為RAM角色授權。
創(chuàng)建自定義資源SecretStore并部署。
使用以下內容,替換相關字段后,創(chuàng)建secretstore-ramrole.yaml文件。
{ACK-accountID}
:替換為集群所在的阿里云賬號B的賬號ID。{clusterID}
:替換為您的集群ID。{ACK-roleName}
:替換為集群所在的阿里云賬號B下創(chuàng)建的RAM角色的名稱。{KMS-accountID}
:替換為KMS實例所在的阿里云賬號A的賬號ID。{KMS-roleName}
:替換為KMS實例所在的阿里云賬號A下創(chuàng)建的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中指定的Key解析
如果您需要解析一個JSON格式的KMS Secret,并將其中指定的key-value鍵值對同步到Kubernetes Secret中,可以使用JMESPath字段。以下是一個使用JMESPath字段的樣例,例如,如果您在KMS憑據管家中有如下JSON格式的Secret。
{"name":"tom","friends":[{"name":"lily"},{"name":"mark"}]}
對應的ExternalSecret樣例如下。當您使用JMESPath字段時,必須指定以下兩個子字段:
path
:必選項,基于JMESPath規(guī)范解析JSON中的指定字段。objectAlias
:必選項,用于指定解析出的字段同步Kubernetes Secret中的Key名稱。
apiVersion: 'alibabacloud.com/v1alpha1'
kind: ExternalSecret
metadata:
name: es-json-demo
spec:
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
字段,針對解析后的字段鍵進行規(guī)則替換,以防止不規(guī)則的Secret data key導致無法創(chuàng)建Secret。
例如,如果您在KMS憑據管家中有如下JSON格式的Secret。
{"/name-invalid":"lily","name-invalid/":[{"name":"mark"}]}
對應的ExternalSecret樣例如下。
apiVersion: 'alibabacloud.com/v1alpha1'
kind: ExternalSecret
metadata:
name: extract-secret
spec:
dataProcess:
- extract:
key: {KMS secret name}
versionStage: ACSCurrent # KMS憑據版本。
secretStoreRef:
name: {secret store name}
namespace: {secret store namespace}
replaceRule: # 替換規(guī)則。
- source: "^/.*d$" # 替換以“/“開頭以”d“結尾的key為tom。
target: "tom"
- source: "^n.*/$" # 替換以”n“開頭以”/“結尾的key為mark。
target: "mark"
相關文檔
為了保護從KMS讀取后緩存在ACK集群中的Secret,您可以對ACK集群Secret進行一鍵加密。具體操作,請參見使用阿里云KMS進行Secret的落盤加密。