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角色:適用於所有Container ServiceKubernetes叢集。
使用ServiceAccount維度細粒度RRSA授權
基於Namespace維度下不同ServiceAccount的RRSA授權實現多租情境下的KMS憑據管家存取權限隔離。相比其他授權方式,RRSA授權方式可以實現Pod維度許可權隔離,還可以避免直接使用AK、SK引起的憑據泄露風險。

在Container Service管理主控台開啟叢集的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憑據時所需的權限原則。具體操作,請參見建立自訂權限原則。
{ "Version": "1", "Statement": [ { "Action": [ "kms:GetSecretValue", "kms:Decrypt" ], "Resource": "acs:kms:<REGION_ID>:<ACCOUNT_ID>:secret/xxxx", // 指定的KMS憑據ARN "Effect": "Allow" } ] }為上一步建立的RAM角色授權。具體操作,請參見管理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引起的憑據泄露風險。
在Container Service管理主控台開啟叢集的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角色授權。
建立ack-secret-manager匯入KMS憑據時所需的權限原則。策略內容如下。具體操作,請參見建立自訂權限原則。
{ "Version": "1", "Statement": [ { "Action": [ "kms:GetSecretValue", "kms:Decrypt" ], "Resource": [ "*" ], "Effect": "Allow" } ] }為上一步建立的RAM角色授權。具體操作,請參見管理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角色授權。
建立訪問KMS服務憑據所需的權限原則。策略內容如下。具體操作,請參見建立自訂權限原則。
{ "Version": "1", "Statement": [ { "Action": [ "kms:GetSecretValue", "kms:Decrypt" ], "Resource": [ "*" ], "Effect": "Allow" } ] }為上一步已建立的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(叢集所在的阿里雲帳號)許可權配置
在Container Service管理主控台開啟叢集的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 | 使用Regex匹配允許訪問的命名空間名稱列表 | 否 |
跨命名空間存取控制
為了增強安全性和靈活性,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:使用Regex匹配允許訪問的命名空間名稱列表。
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的落盤加密。