使用客戶自行管理的加密金鑰 (CMEK)


本頁面介紹如何在 Google Kubernetes Engine (GKE) 上使用客戶代管的加密金鑰 (CMEK)。如果您需要控制金鑰的管理權限,可以使用 Cloud Key Management Service 和 CMEK 來保護 GKE 叢集中的連結永久磁碟和自訂開機磁碟

總覽

根據預設, Google Cloud會加密靜態的客戶內容,而 GKE 會為您管理加密作業,您不必進行任何操作。

如果要自行控制和管理加密金鑰的輪換作業,則可以使用 CMEK。這類金鑰會加密用於加密資料的資料加密金鑰。詳情請參閱金鑰管理一節。

您也可以使用自行管理的金鑰,加密叢集中的密鑰。詳情請參閱應用程式層 Secret 加密功能

在 GKE 中,CMEK 可保護兩種儲存磁碟的資料:節點開機磁碟和連結的磁碟。

節點開機磁碟
節點開機磁碟是叢集節點集區的一部分。建立叢集和節點集區時,您可以建立 CMEK 加密的節點開機磁碟。
已連接的磁碟
附加磁碟是 Pod 用於持久儲存空間的 PersistentVolume。在 GKE 中,連結的 CMEK 加密永久磁碟會做為動態佈建的 PersistentVolume 提供。

如要進一步瞭解儲存空間磁碟,請參閱儲存空間選項。 用於 GKE 控制層的控制層磁碟無法以 CMEK 保護。

事前準備

  1. 如要進行本主題的練習,您需要兩個 Google Cloud 專案:

    • 金鑰專案:這是您建立加密金鑰的專案。

    • 叢集專案:這是您建立啟用 CMEK 的叢集。

  2. 在金鑰專案中,請務必啟用 Cloud KMS API。

    啟用 Cloud KMS API

  3. 金鑰專案中,建立金鑰環和金鑰的使用者需具備下列 IAM 權限:

    • cloudkms.keyRings.getIamPolicy
    • cloudkms.keyRings.setIamPolicy

    這些權限會授予預先定義的 roles/cloudkms.admin Identity and Access Management 角色。詳情請參閱 Cloud KMS 說明文件中的授予管理金鑰的權限一節。

  4. 叢集專案中,請務必啟用 Cloud KMS API。

    啟用 Cloud KMS API

  5. 確認您已安裝 gcloud CLI

  6. gcloud 更新到最新版本:

    gcloud components update
    

建立 Cloud KMS 金鑰

如要使用 CMEK 保護節點開機磁碟或附加磁碟,您必須先擁有 Cloud KMS 金鑰環和金鑰

金鑰環和金鑰必須符合下列規定:

  • 金鑰應使用對稱式加密。

  • 您需要授予 GKE 服務帳戶權限,才能使用金鑰。

  • 金鑰環的位置必須與 GKE 叢集的位置一致:

    • 區域叢集應使用來自超集合位置的金鑰環,舉例來說,us-central1-a 區域中的叢集只能使用 us-central1 地區中的金鑰。

    • 地區叢集應使用來自同一個位置的金鑰環。舉例來說,asia-northeast1 地區的叢集應使用 asia-northeast1 地區的金鑰環加以保護。

    • Cloud KMS global 地區不支援使用 GKE。

如需建立金鑰環和金鑰的操作說明,請參閱「建立對稱金鑰」。

授予金鑰使用權限

您必須在 Cloud KMS 金鑰上,將 Cloud KMS CryptoKey Encrypter/Decrypter (roles/cloudkms.cryptoKeyEncrypterDecrypter) IAM 角色授予叢集專案中的 Compute Engine 服務代理人。授予這個角色後,GKE 永久磁碟就能存取及使用您的加密金鑰。

如要將 roles/cloudkms.cryptoKeyEncrypterDecrypter 角色授予 Compute Engine 服務代理人,請選取下列其中一個選項:

gcloud

執行下列指令:

gcloud kms keys add-iam-policy-binding KEY_NAME \
    --location LOCATION \
    --keyring RING_NAME \
    --member serviceAccount:service-PROJECT_NUMBER@compute-system.iam.gserviceaccount.com \
    --role roles/cloudkms.cryptoKeyEncrypterDecrypter \
    --project KEY_PROJECT_ID

更改下列內容:

  • KEY_NAME:金鑰的名稱。
  • LOCATION:您建立金鑰環的地區。
  • RING_NAME:金鑰環的名稱。
  • PROJECT_NUMBER:叢集的專案編號。
  • KEY_PROJECT_ID:您的金鑰專案 ID。

控制台

  1. 前往 Google Cloud 控制台的「金鑰管理」頁面。

    前往「金鑰管理」

  2. 按一下包含金鑰的金鑰環名稱。

  3. 按一下要修改的金鑰名稱。

  4. 按一下「Permissions」(權限) 分頁標籤。

  5. 按一下「授予存取權」。 「授予金鑰存取權」窗格隨即開啟。

  6. 在「新增主體」欄位中,輸入 Compute Engine 服務代理人的名稱:

    service-PROJECT_NUMBER@compute-system.iam.gserviceaccount.com
    

    PROJECT_NUMBER 替換為叢集的專案編號。

  7. 在「Select a role」(選取角色) 選單中,選取「Cloud KMS CryptoKey Encrypter/Decrypter」(Cloud KMS 加密編譯金鑰加密者/解密者)

  8. 按一下 [儲存]

使用受 CMEK 保護的節點開機磁碟

在本節中,您將建立新的叢集或節點集區,並使用受 CMEK 保護的開機磁碟。

您無法在現有叢集上為節點開機磁碟啟用客戶管理加密,因為現有叢集或節點集區的開機磁碟類型不能變更。不過,您可以為叢集建立新的節點集區,並啟用客戶自行管理的加密功能,然後刪除先前的節點集區。

此外,您也無法在現有叢集或節點集區上,停用節點開機磁碟的客戶管理加密功能。不過,您可以為叢集建立新的節點集區,並停用客戶自行管理的加密功能,然後刪除先前的節點集區。

建立叢集,並使用受 CMEK 保護的節點開機磁碟

您可以使用 gcloud CLI 或 Google Cloud 控制台,建立具有受 CMEK 保護節點開機磁碟的叢集。

如果是標準叢集,只有標準永久磁碟 (pd-standard) 或 SSD 永久磁碟 (pd-ssd) 可以使用 CMEK 金鑰加密。

gcloud

如要建立開機磁碟以 CMEK 金鑰加密的叢集,請在叢集建立指令中指定 --boot-disk-kms-key 參數的值。

建立標準叢集

如要建立開機磁碟以 CMEK 金鑰加密的 Standard 叢集,請使用下列指令:

gcloud container clusters create CLUSTER_NAME \
    --cluster-version=latest \
    --location CONTROL_PLANE_LOCATION \
    --boot-disk-kms-key projects/KEY_PROJECT_ID/locations/LOCATION/keyRings/RING_NAME/cryptoKeys/KEY_NAME \
    --project CLUSTER_PROJECT_ID \
    --disk-type DISK_TYPE

建立 Autopilot 叢集

如要建立開機磁碟以 CMEK 金鑰加密的 Autopilot 叢集,請使用下列指令:

gcloud container clusters create-auto CLUSTER_NAME \
    --cluster-version=latest \
    --location CONTROL_PLANE_LOCATION \
    --boot-disk-kms-key projects/KEY_PROJECT_ID/locations/LOCATION/keyRings/RING_NAME/cryptoKeys/KEY_NAME \
    --project CLUSTER_PROJECT_ID

更改下列內容:

  • CLUSTER_NAME:新叢集的名稱。
  • CONTROL_PLANE_LOCATION:叢集控制層的 Compute Engine 位置。為區域性 Standard 和 Autopilot 叢集提供區域,或為可用區 Standard 叢集提供可用區。
  • KEY_PROJECT_ID:您的金鑰專案 ID。
  • LOCATION:金鑰環的位置。
  • RING_NAME:金鑰環的名稱。
  • KEY_NAME:金鑰的名稱。
  • CLUSTER_PROJECT_ID 是您的叢集專案 ID。
  • DISK_TYPEpd-standard (預設) 或 pd-ssd

控制台

建立標準叢集

如要建立開機磁碟以 CMEK 金鑰加密的 Standard 叢集,請執行下列步驟:

  1. 在 Google Cloud 控制台中,前往「建立 Kubernetes 叢集」頁面。

    前往「建立 Kubernetes 叢集」

  2. 視需求設定叢集。
  3. 在導覽窗格的「節點集區」下方,按一下「節點」
  4. 在「Boot disk type」(開機磁碟類型) 下拉式清單中,選取「Standard persistent disk」(標準永久磁碟) 或「SSD Persistent Disk」(SSD 永久磁碟)
  5. 選取「啟用開機磁碟適用的客戶管理加密功能」核取方塊,然後選擇您先前建立的 Cloud KMS 加密金鑰。
  6. 點選「建立」

建立 Autopilot 叢集

如要建立開機磁碟以 CMEK 金鑰加密的 Autopilot 叢集,請執行下列步驟:

  1. 在 Google Cloud 控制台中,前往「Create an Autopilot cluster」(建立 Autopilot 叢集) 頁面。

    前往「Create an Autopilot cluster」(建立 Autopilot 叢集) 頁面

  2. 視需求設定叢集。
  3. 展開「Advanced Options」(進階選項) 部分,找出「Security」(安全性) 選項。
  4. 選取「啟用開機磁碟適用的客戶管理加密功能」核取方塊,然後選擇您先前建立的 Cloud KMS 加密金鑰。
  5. 點選「建立」

建立受 CMEK 保護的節點開機磁碟的新節點集區

如要在現有標準叢集上建立啟用 CMEK 的新節點集區,可以使用 gcloud CLI 或 Google Cloud 控制台。

gcloud

如要建立節點集區,並為節點開機磁碟啟用客戶管理的加密功能,請在建立指令中指定 --boot-disk-kms-key 參數的值。

gcloud container node-pools create NODE_POOL_NAME \
    --location CONTROL_PLANE_LOCATION \
    --disk-type DISK_TYPE \
    --boot-disk-kms-key projects/KEY_PROJECT_ID/locations/LOCATION/keyRings/RING_NAME/cryptoKeys/KEY_NAME \
    --project CLUSTER_PROJECT_ID \
    --cluster CLUSTER_NAME

更改下列內容:

  • NODE_POOL_NAME:您為節點集區選擇的名稱。
  • CONTROL_PLANE_LOCATION:叢集控制層的 Compute Engine 位置。為地區叢集提供地區,或為區域叢集提供區域。
  • DISK_TYPEpd-standard (預設) 或 pd-ssd
  • KEY_PROJECT_ID:您的金鑰專案 ID。
  • LOCATION:金鑰環的位置。
  • RING_NAME:金鑰環的名稱。
  • KEY_NAME:金鑰的名稱。
  • CLUSTER_PROJECT_ID:叢集專案 ID。
  • CLUSTER_NAME:您在上一步驟中建立的標準叢集名稱。

控制台

  1. 前往 Google Cloud 控制台的「Google Kubernetes Engine」頁面。

    前往「Google Kubernetes Engine」

  2. 在叢集清單中,按一下您要修改的叢集名稱。

  3. 按一下 「Add Node Pool」(新增節點集區)

  4. 按一下導覽窗格中的「Nodes」(節點)

  5. 在「Machine Configuration」(機器設定) 區段中,確認「Boot disk type」(開機磁碟類型) 為「Standard persistent disk」(標準永久磁碟) 或「SSD persistent disk」(SSD 永久磁碟)

  6. 選取「Enable customer-managed encryption for boot disk」(為開機磁碟啟用客戶自行管理的加密功能) 核取方塊,然後選取您建立的 Cloud KMS 加密金鑰。

  7. 點選「建立」

使用受 CMEK 保護的 Filestore 執行個體或永久磁碟

以下資訊說明如何加密新建的 Filestore 執行個體或永久磁碟。您可以使用新的或現有的 Cloud KMS 金鑰,在新叢集或現有叢集上啟用 CMEK。

以下說明需要在每個 GKE 叢集上完成一遍:

建立參照 Cloud KMS 金鑰的 StorageClass

  1. 將以下內容複製到名為 cmek-sc.yaml 的 YAML 檔案中。這項設定能夠動態佈建加密磁碟區。

    Filestore 執行個體

    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: csi-filestore-cmek
    provisioner: filestore.csi.storage.gke.io
    allowVolumeExpansion: true
    parameters:
      tier: enterprise
      instance-encryption-kms-key: projects/KEY_PROJECT_ID/locations/LOCATION/keyRings/RING_NAME/cryptoKeys/KEY_NAME
    
    • instance-encryption-kms-key 欄位必須是金鑰的完整資源識別碼,該金鑰會用來加密新的 Filestore 執行個體。
    • instance-encryption-kms-key 中的值區分大小寫 (例如:keyRingscryptoKeys)。如果使用不正確的值來佈建新磁碟區,會導致 invalidResourceUsage 錯誤。
    • 您無法將 instance-encryption-kms-key 參數新增至現有的 StorageClass 物件。不過,您可以刪除 StorageClass 物件,然後使用相同名稱重新建立,但參數集不同。

    永久磁碟

    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: csi-gce-pd-cmek
    provisioner: pd.csi.storage.gke.io
    volumeBindingMode: "WaitForFirstConsumer"
    allowVolumeExpansion: true
    parameters:
      type: pd-standard
      disk-encryption-kms-key: projects/KEY_PROJECT_ID/locations/LOCATION/keyRings/RING_NAME/cryptoKeys/KEY_NAME
    
    • disk-encryption-kms-key 欄位必須是金鑰的完整資源識別碼,該金鑰會用來加密新磁碟。
    • disk-encryption-kms-key 中的值區分大小寫 (例如:keyRingscryptoKeys)。如果使用不正確的值來佈建新磁碟區,會導致 invalidResourceUsage 錯誤。
    • 您無法將 disk-encryption-kms-key 參數新增至現有的 StorageClass 物件。不過,您可以刪除 StorageClass 物件,然後使用相同名稱重新建立,但參數集不同。確認現有類別的供應商為 pd.csi.storage.gke.io

    您可以將 StorageClass 設為預設值

  2. 使用 kubectl 在您的 GKE 叢集上部署 StorageClass

    kubectl apply -f cmek-sc.yaml
    
  3. 確認您的 StorageClass 使用 Compute Engine Filestore 或 Persistent Disk CSI 驅動程式,並包含金鑰 ID:

    Filestore 執行個體

    kubectl describe storageclass csi-filestore-cmek
    

    在指令的輸出結果中,確認以下項目:

    • 佈建工具已設為 filestore.csi.storage.gke.io。
    • 您金鑰的 ID 在 instance-encryption-kms-key 後方。
    Name:                  csi-filestore-cmek
    IsDefaultClass:        No
    Annotations:           None
    Provisioner:           filestore.csi.storage.gke.io
    Parameters:            instance-encryption-kms-key=projects/KEY_PROJECT_ID/locations/LOCATION/keyRings/RING_NAME/cryptoKeys/KEY_NAME,type=pd-standard
    AllowVolumeExpansion:  true
    MountOptions:          none
    ReclaimPolicy:         Delete
    VolumeBindingMode:     WaitForFirstConsumer
    Events:                none
    

    永久磁碟

    kubectl describe storageclass csi-gce-pd-cmek
    

    在指令的輸出結果中,確認以下項目:

    • 佈建工具設為 pd.csi.storage.gke.io
    • 您的金鑰 ID 緊接在 disk-encryption-kms-key 後面。
    Name:                  csi-gce-pd-cmek
    IsDefaultClass:        No
    Annotations:           None
    Provisioner:           pd.csi.storage.gke.io
    Parameters:            disk-encryption-kms-key=projects/KEY_PROJECT_ID/locations/LOCATION/keyRings/RING_NAME/cryptoKeys/KEY_NAME,type=pd-standard
    AllowVolumeExpansion:  unset
    MountOptions:          none
    ReclaimPolicy:         Delete
    VolumeBindingMode:     WaitForFirstConsumer
    Events:                none
    

在 GKE 中建立加密儲存空間磁碟區

在本節中,要使用新的 StorageClass 和 Cloud KMS 金鑰來動態佈建加密的 Kubernetes 儲存磁碟區。

  1. 將下列內容複製到名為 pvc.yaml 的新檔案,並確認 storageClassName 的值與 StorageClass 物件的名稱相符:

    Filestore 執行個體

    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
      name: podpvc
    spec:
      accessModes:
        - ReadWriteMany
      storageClassName: csi-filestore-cmek
      resources:
        requests:
          storage: 1Ti
    

    永久磁碟

    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
      name: podpvc
    spec:
      accessModes:
        - ReadWriteOnce
      storageClassName: csi-gce-pd-cmek
      resources:
        requests:
          storage: 6Gi
    
  2. 在 GKE 叢集上套用 PersistentVolumeClaim (PVC):

    kubectl apply -f pvc.yaml
    
  3. 如果 StorageClassvolumeBindingMode 欄位設為 WaitForFirstConsumer,您必須先建立 Pod 來使用 PVC,才能驗證 PVC。將下列內容複製到名為 pod.yaml 的新檔案內,並確認 claimName 的值與 PersistentVolumeClaim 物件的名稱相符:

    apiVersion: v1
    kind: Pod
    metadata:
      name: web-server
    spec:
      containers:
       - name: web-server
         image: nginx
         volumeMounts:
           - mountPath: /var/lib/www/html
             name: mypvc
      volumes:
       - name: mypvc
         persistentVolumeClaim:
           claimName: podpvc
           readOnly: false
    
  4. 在 GKE 叢集上套用 Pod:

    kubectl apply -f pod.yaml
    
  5. 取得叢集的 PersistentVolumeClaim 狀態,並確認 PVC 已建立並繫結到新佈建的 PersistentVolume

    Filestore 執行個體

    kubectl get pvc
    

    輸出結果會與下列內容相似:

    NAME      STATUS    VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS     AGE
    podpvc    Bound     pvc-e36abf50-84f3-11e8-8538-42010a800002   1Ti        RWO            csi-filestore-cmek  9s
    

    永久磁碟

    kubectl get pvc
    

    輸出結果會與下列內容相似:

    NAME      STATUS    VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS     AGE
    podpvc    Bound     pvc-e36abf50-84f3-11e8-8538-42010a800002   6Gi       RWO            csi-gce-pd-cmek  9s
    

現在可以將 CMEK 保護的永久磁碟與 GKE 叢集搭配使用。

移除 CMEK 保護

使用 Cloud KMS 金鑰加密永久磁碟後,加密作業會永久生效。即使刪除或停用 Cloud KMS 金鑰,也無法從該特定磁碟移除加密金鑰。如要變更加密金鑰或從永久磁碟中移除 CMEK 保護,唯一方法是根據現有磁碟的快照建立新的永久磁碟。詳情請參閱「從永久磁碟中移除 Cloud KMS 加密金鑰」。

無法從 Filestore 執行個體移除 CMEK 加密。

GKE 和 CMEK 組織政策

GKE 支援客戶自行管理的加密金鑰 (CMEK) 組織政策 (搶先版),可要求採用 CMEK 保護措施,並限制您可使用哪些 Cloud KMS 金鑰進行 CMEK 保護。

如果 container.googleapis.com 位於 constraints/gcp.restrictNonCmekServices 限制的服務Deny政策清單中,則在您未啟用 CMEK 保護措施的情況下,GKE 會拒絕建立下列資源:

  • 新叢集和節點集區
  • 新的 Filestore 執行個體和永久磁碟

在機構政策中設定 constraints/gcp.restrictNonCmekCryptoKeyProjects 限制後,GKE 只會建立受 CMEK 保護的資源,這些資源使用來自允許專案、資料夾或機構的加密金鑰。

後續步驟