安全性總覽

本頁面說明 Azure 上的 GKE 安全架構,包括加密和節點設定。

GKE 叢集提供多項功能,可協助保護工作負載,包括容器映像檔的內容、容器執行階段、叢集網路,以及叢集 API 伺服器的存取權。

使用 GKE 叢集時,您同意承擔叢集的特定責任。詳情請參閱「GKE 叢集共同責任」。

靜態資料加密

靜態資料加密是指加密儲存的資料,與傳輸中的資料不同。根據預設,Azure 上的 GKE 會使用 Azure 平台管理的金鑰,將 etcd 和儲存空間磁碟區中的靜態資料加密。

Azure 上的 GKE 叢集會將資料儲存在 Azure 磁碟區中。這些磁碟區一律會使用 Azure Key Vault 金鑰加密靜態資料。建立叢集和節點集區時,您可以提供客戶管理的 Keyvault 金鑰,加密叢集的基礎磁碟磁碟區。如未指定金鑰,Azure 會在叢集執行的 Azure 區域內,使用預設的 Azure 管理金鑰

此外,所有 GKE 叢集都會啟用「應用程式層 Secret 加密」,保護機密資料 (例如 Kubernetes Secret 物件,這類物件儲存在 etcd 中)。即使攻擊者取得 etcd 資料儲存所在的基礎磁碟區存取權,這些資料也會經過加密。

建立叢集時,您可以在 --database-encryption-kms-key-arn 參數中提供 Azure Key Vault 金鑰。這組金鑰用於加密應用程式資料。如果您在建立叢集時未提供金鑰,GKE on Azure 會自動為叢集建立金鑰。這個資源欄位不可變更,叢集建立後就無法修改。

您也可以手動建立 Key Vault 金鑰,或使用硬體安全模組 (HSM) 自備金鑰 (BYOK)。詳情請參閱「自備金鑰」一文。

應用程式層級加密的運作方式

Kubernetes 提供應用程式層級的加密機制,也就是所謂的「信封加密」。系統會使用通常稱為「資料加密金鑰 (DEK)」的本機金鑰,加密 Secret。然後,DEK 本身會使用第二個金鑰 (稱為「金鑰加密金鑰 (KEK)」) 進行加密。Kubernetes 不會儲存 KEK。建立新的 Kubernetes Secret 時,叢集會執行下列操作:

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

  2. Kubernetes API 伺服器會在本機使用 DEK 加密 Secret。

  3. Kubernetes API 伺服器會將 DEK 傳送至 Azure Key Vault 進行加密。

  4. Azure Key Vault 會使用預先產生的 KEK 加密 DEK,並將加密的 DEK 傳回 Kubernetes API 伺服器的 Azure Key Vault 外掛程式。

  5. Kubernetes API 伺服器會將加密過的 Secret 和加密過的 DEK 儲存至 etcd。但不會將純文字 DEK 儲存在磁碟中。

  6. Kubernetes API 伺服器會建立記憶體內快取項目,將加密的 DEK 對應至純文字 DEK。這樣一來,API 伺服器就能解密最近存取的密鑰,而不必查詢 Azure Key Vault。

用戶端向 Kubernetes API 伺服器要求 Secret 時,會發生以下情況:

  1. Kubernetes API 伺服器會從 etcd 擷取加密過的 Secret 和加密過的 DEK。

  2. Kubernetes API 伺服器會檢查快取中是否有現有對應項目,如果有的話,就會使用該項目解密 Secret。

  3. 如果沒有相符的快取項目,API 伺服器會將 DEK 傳送至 Azure Key Vault,以 KEK 解密。然後使用解密的 DEK 解密密鑰。

  4. 最後,Kubernetes API 伺服器會將解密後的 Secret 傳回給用戶端。

使用 Key Vault 防火牆設定加密

如果您傳遞用於加密的公開金鑰,服務主體不需要加密權限,但需要管理角色指派的權限。最簡單的方法是將 Azure User Access Administrator 內建角色指派給服務主體。

如要進一步保護 Azure Key Vault,可以啟用 Azure Key Vault 防火牆。然後,Azure 上的 GKE 就能使用公開金鑰進行加密,並避免網路存取金鑰保存庫。

如要設定防火牆,請使用 Azure CLI 下載 Key Vault 金鑰。使用 Google Cloud CLI 建立叢集時,請將金鑰傳遞至 --config-encryption-public-key

您仍須為叢集使用的所有子網路啟用 Key Vault 的服務端點。詳情請參閱「Azure Key Vault 的虛擬網路服務端點」。

金鑰輪替

與憑證輪替不同,金鑰輪替是指變更金鑰加密金鑰 (KEK) 中包含的基礎加密編譯內容。這項作業可自動觸發 (排定輪替作業時),或手動觸發 (通常是在發生安全事件後,因為金鑰可能已遭盜用)。金鑰輪替只會替換金鑰中包含原始加密/解密金鑰資料的單一欄位。

詳情請參閱「金鑰輪替」。

叢集信任

所有叢集通訊都會使用傳輸層安全標準 (TLS)。每個叢集都會佈建下列主要自簽根憑證授權單位 (CA):

  • 叢集根 CA 用於驗證傳送至 API 伺服器的要求。
  • etcd 根 CA 用於驗證傳送至 etcd 副本的要求。

每個叢集都有專屬的根 CA。如果某個叢集的 CA 遭駭,其他叢集的 CA 不會受到影響。所有根 CA 的效期都是 30 年。

節點安全性

GKE on Azure 會將工作負載部署至 Azure VM 執行個體的節點集區。以下章節說明節點的安全功能。

Ubuntu

節點會執行最佳化版本的 Ubuntu OS,以執行 Kubernetes 控制層和節點。詳情請參閱 Ubuntu 說明文件中的「安全防護功能」。

GKE 叢集會實作多項安全防護功能,包括:

Ubuntu 還有其他安全指南,例如:

保護工作負載

Kubernetes 可讓使用者快速佈建、調度資源及更新以容器為基礎的工作負載。本節說明可用的策略,以避免執行中的容器對叢集和 Google Cloud 服務造成副作用。

限制 Pod 容器程序權限

限制容器化程序權限對叢集安全至關重要。您可以透過安全環境設定安全性相關選項。這些設定可讓您變更程序的安全設定,例如:

  • 執行程序的使用者和群組
  • 可用的 Linux 功能
  • 權限提升

Azure 上的預設 GKE 節點作業系統 Ubuntu 會針對所有容器使用預設的 Docker AppArmor 安全政策。您可在 GitHub 上檢視設定檔範本。此外,這個設定檔會拒絕在容器執行下列功能:

  • 直接在程序 ID 目錄 (/proc/) 中寫入檔案
  • 寫入不在 /proc/ 中的檔案
  • 將檔案寫入 /proc/sys (而非 /proc/sys/kernel/shm*)
  • 掛接檔案系統

限制工作負載自行修改的能力

特定 Kubernetes 工作負載 (尤其是系統工作負載) 有權自行修改。舉例來說,部分工作負載會自動垂直擴充。雖然方便,但如果攻擊者已入侵節點,就能在叢集中進一步擴大影響範圍。舉例來說,攻擊者可能會讓節點上的工作負載變更,以同一個命名空間中權限較高的服務帳戶身分執行。

理想情況下,工作負載不應獲得修改自身的權限。如果必須自行修改,您可以安裝 Policy ControllerGatekeeper,並套用限制 (例如開放原始碼 Gatekeeper 程式庫中的 NoUpdateServiceAccount),藉此限制權限。這個程式庫提供多項實用的安全性政策。

部署政策時,通常需要允許管理叢集生命週期的控制器略過政策。這是必要步驟,因為控制器需要變更叢集,例如套用叢集升級。舉例來說,如果您在 Azure 上的 GKE 部署 NoUpdateServiceAccount 政策,就必須在 Constraint 中設定下列參數:

parameters:
  allowedGroups: []
  allowedUsers:
  - service-PROJECT_NUMBER@gcp-sa-gkemulticloud.iam.gserviceaccount.com

PROJECT_NUMBER 替換為叢集所在專案的編號 (而非 ID)。

在專屬節點集區中隔離工作負載

您可以使用 Kubernetes taint 和容許條件,指定特定節點集區執行特定類型的工作負載。舉例來說,您可以指示 Azure 上的 GKE 將使用者工作負載排程在大多數系統管理的工作負載之外,或將具有不同信任等級的工作負載放在不同的節點集區。

使用 taint 和容許條件隔離工作負載並非有保障的安全措施。請務必搭配使用這項功能與 GKE on Azure 提供的其他強化措施。

詳情請參閱「在專屬節點集區中隔離工作負載」。

後續步驟