應用程式層密鑰加密

本頁面說明如何使用您在 Cloud Key Management Service (Cloud KMS) 中管理的金鑰,在應用程式層加密 Kubernetes 密鑰

GKE 1.11.2 版開始提供應用程式層密鑰加密功能。

總覽

GKE 預設會為靜態儲存的客戶內容加密,包括密鑰在內。GKE 會處理及管理這項預設的加密作業,您不需要另行操作。

「應用程式層密鑰加密」針對機密資料 (例如儲存在 etcd 中的密鑰) 提供多一層的安全防護。有了這項功能,您就可以使用您在 Cloud KMS 中管理的金鑰在應用程式層進行資料加密,藉此防範成功破解離線版 etcd 的攻擊者。

如要使用應用程式層密鑰加密功能,您必須先建立一個 Cloud KMS 金鑰,並將這個金鑰的存取權授予 GKE 服務帳戶。之後,您可以在建立新叢集時指定要使用的金鑰,即可啟用這項功能。

信封式加密

Kubernetes 透過 KMS 提供者為密鑰進行信封式加密,也就是使用通常稱為「資料加密金鑰 (DEK)」的本機金鑰進行密鑰加密。DEK 本身使用另一個稱為「金鑰加密金鑰」的金鑰進行加密。Kubernetes 不會儲存這個金鑰加密金鑰。

信封式加密有兩大優點:

  • 不需重新加密所有密鑰,即可輪替金鑰加密金鑰。這表示您可以更輕鬆地遵循一般金鑰輪替最佳做法,不用擔心對效能造成大幅影響。

  • 儲存在 Kubernetes 中的密鑰可以採用外部的信任根。也就是說,您的所有密鑰皆可使用中央信任根 (例如硬體安全模組),離線存取容器的攻擊者將無法取得您的密鑰。

GKE 中的應用程式層密鑰加密功能可以使用 AES-CBC 提供者,利用本機 DEK 將您的密鑰進行本機加密,DEK 本身則是使用您在 Cloud KMS 中管理的金鑰加密金鑰進行加密。

若要進一步瞭解信封式加密,請參閱信封式加密

建立密鑰時會發生什麼情況

建立新密鑰時會發生的情形如下:

  • Kubernetes API 伺服器會使用隨機號碼產生器,為密鑰產生一個不重複的 DEK。

  • Kubernetes API 伺服器會在本機使用這個 DEK 加密密鑰。

  • KMS 外掛程式會將 DEK 傳送至 Cloud KMS 進行加密。KMS 外掛程式使用您的專案的 GKE 服務帳戶進行 Cloud KMS 驗證。

  • Cloud KMS 會將 DEK 加密,再將其傳回 KMS 外掛程式。

  • Kubernetes API 伺服器會儲存加密過的密鑰和加密過的 DEK,但不會將純文字 DEK 儲存在磁碟中。

用戶端向 Kubernetes API 伺服器要求密鑰時,會反向執行上述流程。

銷毀金鑰時會發生什麼情況

在 Cloud KMS 中銷毀 GKE 中用於加密密鑰的金鑰後,就無法再使用該金鑰,叢集也將無法啟動。銷毀的金鑰和任何使用此版本加密的資料均無法復原。

銷毀金鑰之前,建議確認您的叢集是否在使用這個金鑰。您也可以針對 Clooud KMS 中的金鑰銷毀作業建立快訊政策

事前準備

  • 要進行本主題的練習,您需要兩個 Google Cloud Platform 專案。

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

    • 叢集專案:這是您建立可用應用程式層密鑰加密作業的叢集。

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

    啟用 Cloud KMS API

  • 在叢集專案中,請務必啟用 Google Kubernetes Engine API。

    啟用 Google Kubernetes Engine API

  • 確認您已安裝 Cloud SDK

  • gcloud 更新到最新版本:

    gcloud components update

建立 Cloud KMS 金鑰

建立金鑰環時,請指定與 GKE 叢集位置一致的位置:

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

  • 地區叢集應使用來自同一個位置的金鑰環。例如,asia-northeast1 地區的叢集應使用 asia-northeast1 地區的金鑰環進行保護。

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

在您的金鑰專案中建立一個金鑰環:

gcloud kms keyrings create [RING_NAME] \
    --location [LOCATION] \
    --project [KEY_PROJECT_ID]

其中:

  • [RING_NAME] 是您為金鑰環選擇的名稱。
  • [LOCATION] 是您要在其中建立金鑰環的地區。
  • [KEY_PROJECT_ID] 是您的金鑰專案 ID。

建立金鑰:

gcloud kms keys create [KEY_NAME] \
    --location [LOCATION] \
    --keyring [RING_NAME] \
    --purpose encryption \
    --project [KEY_PROJECT_ID]

其中:

  • [KEY_NAME] 是您為金鑰選擇的名稱。
  • [LOCATION] 是您建立金鑰環的地區。
  • [RING_NAME] 是金鑰環的名稱。
  • [KEY_PROJECT_ID] 是您的金鑰專案 ID。

授予金鑰使用權限

叢集中的 GKE 服務帳戶名稱是:

service-[CLUSTER_PROJECT_NUMBER]@container-engine-robot.iam.gserviceaccount.com

其中,[CLUSTER_PROJECT_NUMBER] 是叢集的專案編號

將 Cloud KMS 的 CryptoKey 加密者/解密者角色授予您的 GKE 服務帳戶:

gcloud kms keys add-iam-policy-binding [KEY_NAME] \
  --location [LOCATION] \
  --keyring [RING_NAME] \
  --member serviceAccount:[SERVICE_ACCOUNT_NAME] \
  --role roles/cloudkms.cryptoKeyEncrypterDecrypter \
  --project [KEY_PROJECT_ID]

其中:

  • [KEY_NAME] 是金鑰的名稱。
  • [LOCATION] 是您建立金鑰環的地區。
  • [RING_NAME] 是金鑰環的名稱。
  • [SERVICE_ACCOUNT_NAME] 是您的 GKE 服務帳戶名稱。
  • [KEY_PROJECT_ID] 是您的金鑰專案 ID。

建立使用應用程式層密鑰加密的叢集

要建立支援應用程式層密鑰加密的叢集,請在建立指令中指定 --database-encryption-key 參數的值。使用 1.11.2 以上的叢集版本:

gcloud beta container clusters create [CLUSTER_NAME] \
  --cluster-version=latest \
  --zone [ZONE] \
  --database-encryption-key projects/[KEY_PROJECT_ID]/locations/[LOCATION]/keyRings/[RING_NAME]/cryptoKeys/[KEY_NAME] \
  --project [CLUSTER_PROJECT_ID]

其中:

  • [CLUSTER_NAME] 是您為叢集選擇的名稱。
  • [ZONE] 是您要在其中建立叢集的區域。
  • [KEY_PROJECT_ID] 是您的金鑰專案 ID。
  • [LOCATION] 是金鑰環的位置。
  • [RING_NAME] 是金鑰環的名稱。
  • [KEY_NAME] 是金鑰的名稱。
  • [CLUSTER_PROJECT_ID] 是您的叢集專案 ID。

判斷您的叢集是否使用應用程式層密鑰加密

查看叢集是否使用應用程式層密鑰加密:

gcloud beta container clusters describe [CLUSTER_NAME] \
  --zone [COMPUTE_ZONE] \
  --format 'value(databaseEncryption)' \
  --project [CLUSTER_PROJECT_ID]

其中:

  • [CLUSTER_NAME] 是現有叢集的名稱。
  • [COMPUTE_ZONE] 是叢集區域的名稱。
  • [CLUSTER_PROJECT_ID] 是您的叢集專案 ID。

若叢集使用應用程式層密鑰加密,回應會包含 EncryptionConfig

keyName=projects/[PROJECT]/locations/[LOCATION]/keyRings/[RING_NAME]/cryptoKeys/[KEY_NAME];state=ENCRYPTED

限制

現有叢集

目前您無法啟用現有叢集的應用程式層密鑰加密功能。

金鑰位置

您選取的金鑰必須和使用該金鑰的叢集位於同一個地區。例如,us-central1-a 中的區域叢集只能使用 us-central1 地區中的金鑰。地區叢集的金鑰必需在同一個地區。

金鑰輪替

在 Cloud KMS 中輪替金鑰時,不會重新加密 GKE 中的資料。雖然不會重新加密之前加密過的現有資料,但會使用新的金鑰加密任何新資料。

目前無法強制自動重新加密密鑰。如有必要,您可以建立新的金鑰版本,手動輪替金鑰加密金鑰:

gcloud kms keys versions create --location [LOCATION] \
   --keyring [RING_NAME] \
   --key [KEY_NAME] \
   --primary \
   --project [KEY_PROJECT_ID]

接著在 GKE 中輕觸每一個密鑰,強制重新加密:

kubectl get secrets --all-namespaces -o json | kubectl replace -f -

EncryptionConfig

目前 GKE 只開放使用有 Cloud KMS 金鑰的 KMS 提供者。您無法使用其他 Kubernetes KMS 提供者加密提供者

後續步驟

本頁內容對您是否有任何幫助?請提供意見:

傳送您對下列選項的寶貴意見...

這個網頁
Kubernetes Engine 說明文件