本文說明如何將 Secret Manager 中儲存的密鑰,同步至 Google Kubernetes Engine (GKE) 叢集內的 Kubernetes Secret。
透過同步程序,在 GKE 上執行的應用程式就能使用標準 Kubernetes 方法 (例如環境變數或磁碟區掛接) 存取 Secret Manager 中的密鑰。如果應用程式已設計為從 Kubernetes Secret 物件讀取密鑰,而非必須更新才能直接存取 Secret Manager,這項功能就非常實用。
建議:密鑰同步功能是 Secret Manager 外掛程式的替代方案,可將密鑰以記憶體內檔案的形式直接掛接至 Pod。只要應用程式支援,請一律使用 Secret Manager 外掛程式,因為這是從 GKE 的 Secret Manager 存取密鑰時,更安全的方法。
事前準備
同步處理密鑰前,請先完成下列先決條件:
-
Enable the Secret Manager and Google Kubernetes Engine APIs.
Roles required to enable APIs
To enable APIs, you need the Service Usage Admin IAM role (
roles/serviceusage.serviceUsageAdmin
), which contains theserviceusage.services.enable
permission. Learn how to grant roles. 安裝並初始化 gcloud CLI。如果您先前已安裝 gcloud CLI,請執行
gcloud components update
指令來取得最新版本。確認您已啟動 GKE 叢集。這項功能需要 GKE 1.34 以上版本。
確認 GKE 叢集已啟用 Workload Identity Federation for GKE。 這是驗證程序所需步驟。Autopilot 叢集預設會啟用 Workload Identity Federation for GKE。
確認您具備管理 GKE 叢集和 Secret Manager 的必要 Identity and Access Management 權限。
在 GKE 叢集上啟用密鑰同步功能
建立新叢集或更新現有叢集時,請啟用密鑰同步功能。這項功能適用於 Standard 和 Autopilot 叢集。
在新叢集上啟用密鑰同步
如要建立啟用密鑰同步功能的新叢集,請使用下列其中一個 gcloud CLI 指令:
Standard 叢集
如要在指令列上使用 Secret Manager,請先安裝或升級至 Google Cloud CLI 378.0.0 以上版本。在 Compute Engine 或 GKE 上,您必須使用 cloud-platform 範圍進行驗證。
啟用密鑰同步功能,但不啟用自動輪替。
gcloud beta container clusters create CLUSTER_NAME \ --location=CONTROL_PLANE_LOCATION \ --workload-pool=PROJECT_ID.svc.id.goog \ --enable-secret-sync
啟用密碼自動輪替功能,並同步密碼。預設間隔為 2 分鐘。
gcloud beta container clusters create CLUSTER_NAME \ --location=CONTROL_PLANE_LOCATION \ --workload-pool=PROJECT_ID.svc.id.goog \ --enable-secret-sync \ --enable-secret-sync-rotation
啟用密鑰同步功能,並設定自訂輪替間隔。間隔下限為 1 分鐘。
gcloud beta container clusters create CLUSTER_NAME \ --location=CONTROL_PLANE_LOCATION \ --workload-pool=PROJECT_ID.svc.id.goog \ --enable-secret-sync \ --enable-secret-sync-rotation \ --secret-sync-rotation-interval=1m
更改下列內容:
CLUSTER_NAME
:GKE 叢集名稱CONTROL_PLANE_LOCATION
:叢集控制平面的區域或可用區,例如us-central1
或us-east1-a
PROJECT_ID
:您的 Google Cloud 專案 ID
Autopilot 叢集
如要在指令列上使用 Secret Manager,請先安裝或升級至 Google Cloud CLI 378.0.0 以上版本。在 Compute Engine 或 GKE 上,您必須使用 cloud-platform 範圍進行驗證。
啟用密鑰同步功能,但不啟用自動輪替。
gcloud beta container clusters create-auto CLUSTER_NAME \ --location=CONTROL_PLANE_LOCATION \ --enable-secret-sync
啟用密碼自動輪替功能,並同步密碼。預設間隔為 2 分鐘。
gcloud beta container clusters create-auto CLUSTER_NAME \ --location=CONTROL_PLANE_LOCATION \ --enable-secret-sync \ --enable-secret-sync-rotation
啟用密鑰同步功能,並設定自訂輪替間隔。間隔下限為 1 分鐘。
gcloud beta container clusters create-auto CLUSTER_NAME \ --location=CONTROL_PLANE_LOCATION \ --enable-secret-sync \ --enable-secret-sync-rotation \ --secret-sync-rotation-interval=1m
更改下列內容:
CLUSTER_NAME
:GKE 叢集名稱CONTROL_PLANE_LOCATION
:叢集控制平面的區域或可用區,例如us-central1
或us-east1-a
在現有叢集上啟用密鑰同步
如要更新現有叢集以進行密鑰同步,請使用下列其中一個 gcloud CLI 指令:
gcloud
如要在指令列上使用 Secret Manager,請先安裝或升級至 Google Cloud CLI 378.0.0 以上版本。在 Compute Engine 或 GKE 上,您必須使用 cloud-platform 範圍進行驗證。
在現有叢集上啟用密鑰同步
gcloud beta container clusters update CLUSTER_NAME \ --location=CONTROL_PLANE_LOCATION \ --enable-secret-sync
以自訂間隔啟用輪播功能
gcloud beta container clusters update CLUSTER_NAME \ --location=CONTROL_PLANE_LOCATION \ --enable-secret-sync-rotation \ --secret-sync-rotation-interval=5m
停用輪播
gcloud beta container clusters update CLUSTER_NAME \ --location=CONTROL_PLANE_LOCATION \ --no-enable-secret-sync-rotation
更改下列內容:
CLUSTER_NAME
:GKE 叢集名稱CONTROL_PLANE_LOCATION
:叢集控制平面的區域或可用區,例如us-central1
或us-east1-a
設定密鑰同步
如要同步處理密鑰,請完成下列步驟:
使用下列指令建立 Kubernetes ServiceAccount:
kubectl create serviceaccount KSA_NAME --namespace NAMESPACE
更改下列內容:
KSA_NAME
:Kubernetes ServiceAccount 的名稱NAMESPACE
:要建立 ServiceAccount 的 Kubernetes 命名空間
建立 IAM 允許政策,參照新的 Kubernetes ServiceAccount,並授予 ServiceAccount 存取密碼的權限:
gcloud
如要在指令列上使用 Secret Manager,請先安裝或升級至 Google Cloud CLI 378.0.0 以上版本。在 Compute Engine 或 GKE 上,您必須使用 cloud-platform 範圍進行驗證。
gcloud secrets add-iam-policy-binding SECRET_PROJECT_ID \ --role=roles/secretmanager.secretAccessor \ --member=principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_IDsvc.id.goog/subject/ns/NAMESPACE/sa/KSA_NAME
更改下列內容:
SECRET_PROJECT_ID
:儲存密鑰的專案 ID。如果密鑰與 GKE 叢集儲存在同一個專案中,這項設定可以與 PROJECT_ID 相同。PROJECT_NUMBER
:您的 Google Cloud 專案編號PROJECT_ID
:您的 Google Cloud 專案 IDNAMESPACE
:Kubernetes 命名空間KSA_NAME
:Kubernetes ServiceAccount 的名稱
使用 YAML 資訊清單建立 SecretProviderClass 自訂資源。SecretProviderClass 資源會定義要從 Secret Manager 擷取的特定密鑰,包括資源名稱和路徑。Secret Manager 外掛程式也會使用 SecretProviderClass 資源,列出要掛接的密鑰和掛接檔案名稱。
建立
spc.yaml
檔案,並加入以下內容:apiVersion: secrets-store.csi.x-k8s.io/v1 kind: SecretProviderClass metadata: name: SECRET_PROVIDER_CLASS_NAME namespace: NAMESPACE spec: provider: gke parameters: secrets: | - resourceName: "projects/SECRET_PROJECT_ID/secrets/SECRET_NAME/versions/SECRET_VERSION" path: "FILENAME.txt" - resourceName: "projects/SECRET_PROJECT_ID/secrets/SECRET_NAME/versions/SECRET_VERSION" path: "FILENAME1.txt"
更改下列內容:
SECRET_PROVIDER_CLASS_NAME
:SecretProviderClass 物件的名稱。NAMESPACE
:您要建立這個資源的 Kubernetes 命名空間。resourceName
:Secret Manager 中密碼的完整資源 ID。這必須包含專案 ID、密鑰名稱和版本,格式如下:projects/SECRET_PROJECT_ID/secrets/SECRET_NAME/versions/SECRET_VERSION。SECRET_PROJECT_ID
:儲存密鑰的 Google Cloud 專案 ID。如果密鑰與 GKE 叢集儲存在同一個專案中,這項設定可以與 PROJECT_ID 相同。SECRET_NAME
:密鑰名稱。SECRET_VERSION
:密鑰版本。密碼版本必須與叢集位於相同區域。
path
:Secret 值在 Kubernetes 環境中公開時的本機檔案名稱或別名。這是專屬 ID,可將特定 Secret Manager 版本連結至叢集使用的本機表示法。使用 SecretSync 資源將密鑰同步至 Kubernetes Secret 時,sourcePath
欄位會參照這個路徑,找出要同步的密鑰值。您可以在同一個 SecretProviderClass 中,將多個密鑰 (由resourceName
定義) 對應至不同的路徑名稱。
如要套用資訊清單,請執行下列指令:
kubectl apply -f spc.yaml
使用 YAML 資訊清單建立 SecretSync 自訂資源。這項資源會指示同步控制器,根據 SecretProviderClass 中定義的內容建立或更新 Kubernetes 密鑰。
建立
secret-sync.yaml
檔案,並加入以下內容:apiVersion: secret-sync.gke.io/v1 kind: SecretSync metadata: name: KUBERNETES_SECRET_NAME namespace: NAMESPACE spec: serviceAccountName: KSA_NAME secretProviderClassName: SECRET_PROVIDER_CLASS_NAME secretObject: type: KUBERNETES_SECRET_TYPE data: - sourcePath: "FILENAME.txt" targetKey: "TARGET_KEY1" - sourcePath: "FILENAME1.txt" targetKey: "TARGET_KEY2"
更改下列內容:
KUBERNETES_SECRET_NAME
:您要授予新 Kubernetes Secret 的名稱,該 Secret 會由 SecretSync 資源建立。NAMESPACE
:建立新資源的 Kubernetes 命名空間。必須與 SecretProviderClass 位於相同命名空間。KSA_NAME
:SecretSync 控制器用來建立及更新目標 Kubernetes Secret 的 Kubernetes ServiceAccount 名稱。這個 ServiceAccount 必須具備必要權限,才能從 Secret Manager 存取外部密鑰。SECRET_PROVIDER_CLASS_NAME
:您在上一步建立的 SecretProviderClass 物件名稱。SecretSync 資源會使用這項資訊,找出密鑰的正確設定。KUBERNETES_SECRET_TYPE
:要建立的 Kubernetes Secret 類型,例如Opaque
、tls
或docker-registry
。這會決定 Kubernetes 如何處理密鑰資料。sourcePath
:本機檔案名稱或別名 (SecretProviderClass 中path
欄位的值),用於識別要擷取的密鑰資料。SecretSync 控制器會使用這個sourcePath
要求特定密鑰內容,並將其轉換為新的 Kubernetes 密鑰。targetKey
:將用於建立新 Kubernetes Secret 的data
區段。這會定義使用sourcePath
擷取的密鑰內容,在最終 Kubernetes Secret 物件中的命名和儲存方式。在資料陣列中使用多個項目,即可在同一個目標 Secret 中定義多個鍵/值組合。
如要套用資訊清單,請執行下列指令:
kubectl apply -f secret-sync.yaml
同步控制器會在指定命名空間中建立 Kubernetes Secret。這個密鑰包含從 Secret Manager 對應的資料。
確認 Kubernetes Secret 是否已建立:
kubectl get secret KUBERNETES_SECRET_NAME -n NAMESPACE -o yaml
更改下列內容:
KUBERNETES_SECRET_NAME
:新 Kubernetes Secret 的名稱NAMESPACE
:建立新 Secret 的 Kubernetes 命名空間
如要排解同步問題,請使用下列指令:
kubectl describe secretSync KUBERNETES_SECRET_NAME -n NAMESPACE
更改下列內容:
KUBERNETES_SECRET_NAME
:新 Kubernetes Secret 的名稱NAMESPACE
:新 Secret 應存在的 Kubernetes 命名空間
管理密鑰輪替
如果在叢集上--enable-secret-sync-rotation
啟用旗標,同步控制器會定期檢查 Secret Manager,確認 SecretProviderClass 資源中指定的密鑰是否有新版本。--secret-sync-rotation-interval
旗標會決定控制器檢查更新的頻率。
如果控制器在 Secret Manager 中偵測到新的密鑰版本,就會更新對應的 Kubernetes 密鑰。控制器會比較密鑰內容的雜湊,只有在發生變更時才會更新密鑰。
使用這些密鑰的應用程式必須偵測 Kubernetes Secret 中的更新密鑰值,並重新載入。應用程式的設計決定了處理方式。
停用密鑰同步
如要停用 Secret 同步功能,請執行下列 gcloud CLI 指令:
gcloud
如要在指令列上使用 Secret Manager,請先安裝或升級至 Google Cloud CLI 378.0.0 以上版本。在 Compute Engine 或 GKE 上,您必須使用 cloud-platform 範圍進行驗證。
gcloud beta container clusters update CLUSTER_NAME \ --location=CONTROL_PLANE_LOCATION \ --no-enable-secret-sync
更改下列內容:
CLUSTER_NAME
:GKE 叢集名稱CONTROL_PLANE_LOCATION
:叢集控制平面的區域或可用區,例如us-central1
或us-east1-a
這項指令會停止同步控制器。不會刪除任何已建立的 Kubernetes Secret。如不再需要任何已同步的 Kubernetes 密鑰,請手動刪除。
刪除已同步處理的密碼
如要刪除已同步的 Kubernetes Secret,請使用下列指令刪除 SecretSync
資源:
kubectl delete secretsync KUBERNETES_SECRET_NAME --namespace NAMESPACE
更改下列內容:
KUBERNETES_SECRET_NAME
:Kubernetes Secret 的名稱NAMESPACE
:Secret 所在的 Kubernetes 命名空間
從現有 Secrets Store CSI 驅動程式遷移
如要從現有的 Secrets Store CSI 驅動程式安裝遷移,請按照下列步驟操作:
將 SecretProviderClass 中的
provider
欄位從gcp
更新為gke
。 以下範例說明如何更新provider
欄位:apiVersion: secrets-store.csi.x-k8s.io/v1 kind: SecretProviderClass metadata: name: app-secrets-gke spec: provider: gke parameters: secrets: | - resourceName: "projects/87654321/secrets/api-key-secret/versions/2" path: "good1.txt"
建立 SecretSync 資源。請使用下列範例設定:
apiVersion: secret-sync.gke.io/v1 kind: SecretSync metadata: name: my-kube-secret namespace: NAMESPACE spec: serviceAccountName: KSA_NAME secretProviderClassName: my-app-secrets secretObject: type: Opaque # Or other Kubernetes Secret types data: - sourcePath: "my-secret.txt" targetKey: "USERNAME" - sourcePath: "another-secret.txt" targetKey: "PASSWORD"
安全性考量
Secret Manager 提供多種安全性功能,例如透過 IAM 控管存取權、客戶管理的加密金鑰 (CMEK),以及稽核記錄。Secret Manager 會加密儲存的密鑰,以及傳輸中的密鑰。將密鑰同步至 Kubernetes 密鑰時,密鑰在叢集內的安全性取決於 GKE 叢集的設定。請考量下列事項:
儲存:Kubernetes Secret 會儲存在 etcd 中,這是 GKE 的主要資料存放區。根據預設,GKE 會加密靜態資料。為提升安全性,請使用您在 Cloud Key Management Service(Cloud KMS) 中管理的金鑰,在應用程式層加密 Kubernetes 密鑰。加密 Secret 可為機密工作負載提供額外一層安全防護。
存取權控管:GKE 支援多種選項,可讓您使用角色型存取權控管 (RBAC),管理專案及其叢集內資源的存取權。過於寬鬆的 RBAC 權限可能會將密鑰暴露給非預期的工作負載或使用者。請遵循最低權限原則授予存取權,並定期稽核 Secret Manager 和 Kubernetes 密鑰的存取權。
環境變數:為提升安全性,請將 Kubernetes 密鑰掛接為磁碟區,而非做為環境變數。這樣做可降低意外記錄或暴露於其他程序的風險。
後續步驟
- 探索 Kubernetes Secret。
- 瞭解 Workload Identity。