csi-secrets-store-provider-alibabacloud支援以Kubernetes Secret執行個體的形式向叢集匯入或同步KMS憑據資訊,確保叢集內的應用能夠安全地訪問敏感資訊;還支援通過CSI Inline的形式將憑據密鑰作為檔案系統直接掛載到應用程式中,適用於通過檔案系統介面(例如讀取檔案)來擷取敏感資訊的應用。通過該組件,可實現密鑰資料的自動更新,從而降低憑據密文在Secrets執行個體中暴露的可能,同時解決工作負載和阿里雲憑據管家互動的相容性問題。
安全記事
預設情況下,直接從檔案系統讀取密鑰和阿里雲KMS憑據管家之間的直接互動可能存在相容性問題,csi-secrets-store-provider-alibabacloud可以用於解決此類相容性問題,同時支援將密鑰同步建立為叢集中的Kubernetes原生Secrets執行個體,以供環境變數掛載使用。使用前請評估如下的安全風險。
當密鑰在檔案系統中可以被訪問時,如果應用中存在某些有缺陷的軟體,該軟體的漏洞可能會造成目錄遍曆的風險,導致敏感資訊泄露。
一些Debug端點或Logs許可權的誤配置可能導緻密鑰泄露,所以通過環境變數掛載引用的方式消費密鑰是一個不安全且不推薦的做法。
當開啟Secret執行個體同步特性時,需要基於許可權最小化原則嚴格控制存取權限。
鑒於上述原因,如果應用中並不需要密文的持久化儲存,推薦通過RRSA配置ServiceAccount的RAM許可權實現Pod許可權隔離為應用配置Pod維度最小化許可權,並通過GetSecretValue直接在應用中擷取金鑰認證,以減少金鑰產製原料在Pod檔案系統或Kubernetes叢集Secrets中的暴露風險。
前提條件
已建立符合如下要求的ACK叢集。具體操作,請參見建立ACK託管叢集、建立ACK One註冊叢集。
叢集為1.20及以上版本。支援ACK託管叢集、ACK專有叢集、ACK Edge叢集和ACK One註冊叢集,暫不支援ACK Serverless叢集。
步驟一:配置組件認證資訊
需配置csi-secrets-store-provider-alibabacloud的認證資訊,以確保該組件有許可權擷取KMS服務中的憑據資訊,否則csi-secrets-store-provider-alibabacloud將無法向叢集中匯入或同步憑據資訊。可根據叢集類型選擇如下三種授權方式進行配置。
通過RRSA授權:適用於1.22及以上版本的ACK託管叢集。
為叢集對應的Worker RAM角色添加許可權:適用於ACK託管叢集、ACK專有叢集和ACK One註冊叢集。
通過設定AK扮演指定RAM角色:適用於所有Container ServiceKubernetes叢集。
通過RRSA授權
相比其他授權方式,RRSA授權方式可以實現Pod維度許可權隔離,還可以避免直接使用AK、SK引起的憑據泄露風險。
在Container Service管理主控台開啟叢集的RRSA功能,用於建立叢集的身份供應商資訊。具體操作,請參見啟用RRSA功能。
建立可信實體為身份供應商的RAM角色,以供csi-secrets-store-provider-alibabacloud使用。主要參數設定如下,具體操作,請參見建立OIDC身份供應商的RAM角色。
配置項
描述
身份供應商類型
OIDC。
身份供應商
選擇ack-rrsa-<cluster_id>。其中,<cluster_id>為叢集ID。
條件
oidc:iss:保持預設。
oidc:aud:保持預設。
oidc:sub:需手動添加該條件。
條件鍵:選擇oidc:sub。
運算子:選擇StringEquals。
條件值:填入
system:serviceaccount:<namespace>:<serviceAccountName>,其中,<namespace>為應用所在的命名空間。<serviceAccountName>為服務賬戶名稱。根據本文測試應用的資訊,此處需填入system:serviceaccount:kube-system:csi-secrets-store-provider-alibabacloud。說明建議將組件安裝在預設的
kube-system命名空間下。如將csi-secrets-store-provider-alibabacloud安裝在其他的命名空間,請將kube-system替換為對應命名空間的名稱。
建立自訂授權策略並為上一步建立的RAM角色授權。
建立csi-secrets-store-provider-alibabacloud匯入KMS憑據時所需的權限原則。策略內容如下。具體操作,請參見建立自訂權限原則。
{ "Action": [ "kms:GetSecretValue", "kms:Decrypt" ], "Resource": [ "*" ], "Effect": "Allow" }為上一步建立的RAM角色授權。具體操作,請參見管理RAM角色的許可權。
在叢集中建立名為alibaba-credentials的Secret,配置模板如下,需要替換部分欄位。
使用以下內容,替換相關欄位後,建立secretstore-rrsa.yaml檔案。
{rolearn}:替換為步驟2建立的RAM角色的ARN(需要Base64編碼)。{oidcproviderarn}:替換為叢集開啟RRSA後產生的供應商ARN(需要Base64編碼)。
apiVersion: v1 data: rolearn: {rolearn} oidcproviderarn: {oidcproviderarn} kind: Secret metadata: name: alibaba-credentials namespace: kube-system type: Opaque執行以下命令,部署Secret。
kubectl apply -f secretstore-rrsa.yaml
為叢集對應的Worker RAM角色添加許可權
適用於ACK託管叢集、ACK專有叢集和ACK One註冊叢集
建立如下自訂權限原則。具體操作,請參見建立自訂權限原則。
{ "Action": [ "kms:GetSecretValue", "kms:Decrypt" ], "Resource": [ "*" ], "Effect": "Allow" }為叢集的WorkerRole添加上一步建立的自訂許可權。具體操作,請參見為叢集的Worker RAM角色授權。
通過設定AK扮演指定RAM角色
適用於所有Container ServiceKubernetes叢集。
建立可信實體為阿里雲帳號的RAM角色,以供csi-secrets-store-provider-alibabacloud組件使用。具體操作,請參見建立可信實體為阿里雲帳號的RAM角色。
說明在選擇信任主體名稱時,請選擇當前雲帳號。
建立自訂授權策略並為上一步已建立的RAM角色授權。
建立訪問KMS服務憑據所需的權限原則。策略內容如下。具體操作,請參見建立自訂權限原則。
{ "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使用者的許可權。
在叢集中建立名為alibaba-credentials的Secret,配置模板如下,需要替換部分欄位。
使用以下內容,替換相關欄位後,建立alibaba-credentials.yaml檔案。
{rolearn}:替換為步驟1已建立的RAM角色的ARN(需要Base64編碼)。{ak}:替換為RAM使用者的AK(需要Base64編碼)。{sk}:替換為RAM使用者的SK(需要Base64編碼)。apiVersion: v1 data: id: {ak} secret: {sk} rolearn: {rolearn} kind: Secret metadata: name: alibaba-credentials namespace: kube-system type: Opaque
執行以下命令,部署Secret。
kubectl apply -f alibaba-credentials.yaml
步驟二:安裝csi-secrets-store-provider-alibabacloud組件
登入Container Service管理主控台,在左側導覽列選擇叢集列表。
在叢集列表頁面,單擊目的地組群名稱,然後在左側導覽列,選擇。
在Helm頁面,單擊建立,在Chart地區搜尋並選中csi-secrets-store-provider-alibabacloud,其他設定保持預設,然後單擊下一步。
根據彈出的頁面提示確認,組件將被安裝在預設的kube-system命名空間中,並以組件名稱發布應用。如需自訂應用程式名稱和命名空間,請根據頁面提示設定。
選擇Chart版本為最新版本,在參數地區根據步驟一選擇的認證方式,設定相關參數,然後單擊確定。
如果選擇通過RRSA授權,需將參數
rrsa.enable設定為true,以開啟RRSA認證功能。
其他相關參數配置如下。
envVarsFromSecret: # ACCESS_KEY_ID: # secretKeyRef: alibaba-credentials # key: id # SECRET_ACCESS_KEY: # secretKeyRef: alibaba-credentials # key: secret ALICLOUD_ROLE_ARN: secretKeyRef: alibaba-credentials key: rolearn # ALICLOUD_ROLE_SESSION_NAME: # secretKeyRef: alibaba-credentials # key: rolesessionname # ALICLOUD_ROLE_SESSION_EXPIRATION: # secretKeyRef: alibaba-credentials # key: rolesessionexpiration ALICLOUD_OIDC_PROVIDER_ARN: secretKeyRef: alibaba-credentials key: oidcproviderarn如果選擇為叢集對應的Worker RAM角色添加許可權,可採用預設參數配置直接安裝。
如果選擇通過設定AK扮演指定RAM角色,需配置如下相關參數。
envVarsFromSecret: ACCESS_KEY_ID: secretKeyRef: alibaba-credentials key: id SECRET_ACCESS_KEY: secretKeyRef: alibaba-credentials key: secret ALICLOUD_ROLE_ARN: secretKeyRef: alibaba-credentials key: rolearn # ALICLOUD_ROLE_SESSION_NAME: # secretKeyRef: alibaba-credentials # key: rolesessionname # ALICLOUD_ROLE_SESSION_EXPIRATION: # secretKeyRef: alibaba-credentials # key: rolesessionexpiration # ALICLOUD_OIDC_PROVIDER_ARN: # secretKeyRef: alibaba-credentials # key: oidcproviderarn如需同步產生 Kubernetes Secret,需要配置如下相關參數。

secrets-store-csi-driver.syncSecret.enabled:是否啟用同步為 Kubernetes Secret的功能。設定為true時,將部署必要的 RBAC Role和RoleBinding。如需開啟定時同步憑據的功能,需要配置如下相關參數。

secrets-store-csi-driver.enableSecretRotation:是否開啟憑據的自動輪詢功能,設定為true表示開啟。secrets-store-csi-driver.rotationPollInterval:憑據同步的頻率,設定為120s,此處以兩分鐘同步一次憑據為例,可根據實際需求調整。
建立成功後,會自動跳轉到目的地組群的csi-secrets-store-provider-alibabacloud頁面,檢查安裝結果。若下圖中所有資源建立成功,則表明組件安裝成功。

步驟三:配置資料同步資訊
認證資訊配置完成後,需通過SecretProviderClass來進行KMS憑據資訊的配置。
配置模板說明
SecretProviderClass模板格式定義如下所示。
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: <NAME>
spec:
provider: alibabacloud # 此處配置固定為'alibabacloud'。
parameters:
objects: |
- objectName: <KMS Encryption Parameter Name> # KMS 憑據名稱
objectType: kms # 同步 KMS 憑據時固定為 kms其中parameters通常包含掛載請求的三個欄位:
參數 | 類型 | 說明 |
objects | 必選 | 掛載Secrets憑據的YAML配置聲明。例如:
|
region | 可選 | 用於請求指定Region下的阿里雲憑據管家後端。如果不指定該參數,則預設使用節點對應的阿里雲Region。但在大規模應用Pod部署時,可能會帶來額外的效能開銷,所以推薦配置該參數指定Region。 |
pathTranslation | 可選 |
|
配置使用樣本
本樣本以ACK託管叢集同一地區下的KMS服務憑據test為例,介紹如何通過SecretProviderClass將其匯入到叢集應用中。
使用以下簡單的SecretProviderClass樣本,建立secretstore.yaml檔案。
apiVersion: secrets-store.csi.x-k8s.io/v1 kind: SecretProviderClass metadata: name: test-secrets spec: provider: alibabacloud # 此處固定配置為alibabacloud。 parameters: objects: | # objectType 支援oos和kms, 預設為kms - objectName: "test-hangzhou" objectType: "kms" objectAlias: "hangzhou-public" kmsEndpoint: "kms.{region}.aliyuncs.com"執行以下命令,部署SecretProviderClass。
kubectl apply -f secretstore.yaml使用以下內容,建立deploy.yaml。
包含一個Nginx Deployment執行個體,通過CSI Inline檔案系統的形式聲明使用了上面樣本中已經建立的SecretProviderClass,並在Pod中的
/mnt/secrets-store目錄下掛載憑據密鑰。關於Deployment執行個體更多資訊,請參見Deployment樣本。apiVersion: apps/v1 # 1.8.0之前版本請使用apps/v1beta1。 kind: Deployment metadata: name: nginx-deployment-basic labels: app: nginx spec: replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: volumes: - name: secrets-store-inline csi: driver: secrets-store.csi.k8s.io readOnly: true volumeAttributes: secretProviderClass: "test-secrets" containers: - name: nginx image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6 # 替換為您的實際鏡像。 ports: - containerPort: 80 resources: limits: cpu: "500m" volumeMounts: - name: secrets-store-inline mountPath: "/mnt/secrets-store" readOnly: true執行以下命令,部署Deploy應用。
kubectl apply -f deploy.yaml驗證密鑰是否被正常掛載。
登入Pod查看Secret的目標掛載路徑
/mnt/secrets-store下是否已經建立了SecretProviderClass執行個體中指定密鑰名稱為檔案名稱的密鑰檔案,同時查看檔案內容是否為KMS憑據中指定的密文。
將 KMS 憑據同步為 Kubernetes Secret
Secrets Store CSI Driver 支援將從外部金鑰管理服務(如阿里雲KMS、OOS)中擷取的密鑰,自動同步並建立為叢集內原生的 Kubernetes Secret。應用無需修改代碼,就能以標準方式使用這些外部金鑰。
配置方法:SecretProviderClass
您可以在 SecretProviderClass 資源的 spec 中添加 secretObjects 可選欄位來啟用此功能。
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: <NAME>
spec:
provider: alibabacloud # 此處配置固定為alibabacloud,請勿修改。
parameters:
objects: |
- objectName: <KMS Encryption Parameter Name> # KMS 憑據名稱
objectType: kms # 同步 KMS 憑據時固定為 kms
secretObjects:
- secretName: <Kubernetes Secret Name> # Kubernetes Secret 名稱
type: <Kubernetes Secret Type> # Kubernetes Secret 類型
data:
- objectName: <parameters.objects.objectName> # parameters.objects.objectName 名稱,當指定別名時,使用別名
key: <Kubernetes Secret Data Key> # Kubernetes Secret Data Key 欄位名稱secretObjects通常包含以下三個參數:
參數 | 類型 | 說明 |
secretName | 必選 | 指定將在叢集中建立的 Kubernetes Secret 的名稱。 |
type | 必選 | 定義所建立的 Secret 的類型。可取值: |
data | 必選 | 定義如何將從外部擷取的密鑰映射到
|
同步生命週期
Secret 對象的同步和清理是由掛載了對應 SecretProviderClass的 Pod 動態觸發的:
建立:當第一個使用該
SecretProviderClass的 Pod 啟動並成功掛載卷時,Secrets Store CSI Driver 才會執行同步操作,建立對應的 Kubernetes Secret。更新:當安裝 csi-secrets-store-provider-alibabacloud 組件,設定
secrets-store-csi-driver.enableSecretRotation參數為true時,會根據參數secrets-store-csi-driver.rotationPollInterval來定時同步更新對應的 Kubernetes Secret,否則不會更新。刪除:當最後一個使用該
SecretProviderClass的 Pod 被刪除後,由 Secrets Store CSI Driver 自動建立的 Kubernetes Secret 也會被隨之刪除。
操作樣本:同步KMS憑據並注入Pod環境變數
以下步驟將示範如何將KMS憑據同步為 Kubernetes Secret,並最終通過環境變數注入到 Nginx Pod 中。
建立 SecretProviderClass。
參見以下內容建立 syncSecret.yaml 檔案,定義如何擷取外部金鑰以及如何將其同步。
apiVersion: secrets-store.csi.x-k8s.io/v1 kind: SecretProviderClass metadata: name: alibabacloud-sync-secret spec: provider: alibabacloud parameters: objects: | - objectName: test-kms objectAlias: secretalias objectType: kms secretObjects: - secretName: test-sync-secret # 產生的 Kubernetes Secret 名稱 type: Opaque data: - objectName: secretalias # 對應 objectName 或 objectAlias key: test # 填充產生的 Kubernetes Secret data部署 SecretProviderClass。
kubectl apply -f syncSecret.yaml建立應用 Pod 以觸發同步。
參見以下內容建立 pod-sync-secret.yaml 檔案。此 Pod 會掛載上述
SecretProviderClass,並嘗試通過secretKeyRef引用將要產生的名為test-sync-secret的Secret。kind: Pod apiVersion: v1 metadata: name: pod-sync-secret spec: containers: - name: nginx image: nginx:latest volumeMounts: - name: secrets-store-inline mountPath: "/mnt/secrets-store" readOnly: true env: - name: SECRET_TEST valueFrom: secretKeyRef: name: test-sync-secret key: test volumes: - name: secrets-store-inline csi: driver: secrets-store.csi.k8s.io readOnly: true volumeAttributes: secretProviderClass: "alibabacloud-sync-secret"部署 Pod,同時觸發 Secret 的同步。
kubectl apply -f pod-sync-secret.yaml驗證結果:
檢查 Kubernetes Secret 是否已產生。
kubectl get secret test-sync-secret執行後,您將看到名為 test-sync-secret 的 Secret。
檢查 Pod 環境變數是否成功注入:
kubectl exec -it $(kubectl get pods | awk '/pod-sync-secret/{print $1}' | head -1) -- env您將看到環境變數
SECRET_TEST及其從KMS加密參數中擷取到的值。
kmsEndpoint配置說明
可通過專屬網關訪問或共用網關訪問兩種方式訪問KMS服務擷取憑據,請參考以下要求進行Endpoint配置。關於專屬網關訪問和共用網關訪問的更多差異,請參見共用網關和專屬網關的差異。
KMS Endpoint地址說明
網關類型 | 網域名稱類型 | Endpoint 地址 | 使用說明 |
專屬網關 | KMS私網網域名稱 | {kms-instance-id}.cryptoservice.kms.aliyuncs.com |
|
共用網關 | VPC網域名稱 | kms-vpc.{region}.aliyuncs.com |
|
共用網關 | 公網 | kms.{region}.aliyuncs.com |
|
KMS Endpoint配置樣本
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: test
spec:
provider: alibabacloud # 固定值為 'alibabacloud'
parameters:
# 樣本使用網關說明:
# hangzhou-public 使用共用網關公網網域名稱,需要將{region}替換為KMS憑據所在的Region,此方式可擷取和叢集不在同一Region的KMS憑據
# hangzhou-vpc 未指定kmsEndpoint欄位,使用預設的共用網關VPC網域名稱
# hangzhou-cryptoservice 使用專屬網關,需要替換{kms-instance-id}為KMS憑據所屬執行個體ID
# london-public 使用共用網關公網網域名稱,需要將{region}替換為KMS憑據所在的Region,此方式可擷取和叢集不在同一Region的KMS憑據
objects: |
- objectName: "test-hangzhou"
objectType: "kms"
objectAlias: "hangzhou-public"
kmsEndpoint: "kms.{region}.aliyuncs.com"
- objectName: "test-hangzhou"
objectType: "kms"
objectAlias: "hangzhou-vpc"
- objectName: "test-hangzhou"
objectType: "kms"
objectAlias: "hangzhou-cryptoservice"
kmsEndpoint: "{kms-instance-id}.cryptoservice.kms.aliyuncs.com"
- objectName: "test-london"
objectAlias: "london-public"
kmsEndpoint: "kms.{region}.aliyuncs.com"相關文檔
如需為ACK Serverless叢集中的應用匯入阿里雲KMS憑據,請參見使用ack-secret-manager匯入阿里雲KMS服務憑據。
為了保護從KMS讀取後緩衝在ACK叢集中的Secret,可對ACK叢集Secret進行一鍵加密。具體操作,請參見使用阿里雲KMS進行Secret的落盤加密。