本頁面說明如何使用核發登錄檔憑證的憑證授權機構 (CA) 公開金鑰,允許在 Google Kubernetes Engine (GKE) 中執行的工作負載存取私人映像檔登錄檔。
本文適用於負責管理機構工作負載存取權的安全專家。如要進一步瞭解 Google Cloud 內容中提及的常見角色和範例工作,請參閱常見的 GKE Enterprise 使用者角色和工作。
閱讀本頁面之前,請先熟悉 Secret Manager。
存取私人登錄檔的運作方式
您可以在 Secret Manager 中儲存用於核發私有登錄檔憑證的 CA 公開金鑰,並設定哪些登錄檔的完整網域名稱 (FQDN) 會使用該公開金鑰進行憑證驗證。GKE 會在節點啟動期間自動擷取金鑰,並更新容器執行階段登錄設定。部署使用私人登錄檔容器映像檔的工作負載時,會發生下列步驟:
- 節點上的 kubelet 會嘗試從私人登錄檔提取映像檔。
- 登錄檔會提供伺服器端 TLS 憑證。
- 容器執行階段會以密碼編譯方式驗證登錄檔憑證,並確保完整網域名稱與您指定的內容相符。
- 如果驗證通過,GKE 會提取映像檔並排定工作負載。
優點
這種存取私有登錄檔的方法有以下優點:
- 提升容器執行階段設定的可靠性:使用 DaemonSet 等方法設定 containerd 設定時,可能會發生競爭條件,導致其他 DaemonSet 在設定 DaemonSet 之前執行。
- 降低權限提升攻擊的風險:不必執行修改容器執行階段設定的具備權限 DaemonSet。
- 減少管理負擔:您可以使用 Secret Manager 將 CA 公開金鑰儲存在中央位置,並透過 IAM 管理金鑰存取權,以及實作版本控管和註解。詳情請參閱 Secret Manager 產品總覽。
- 提升稽核能力:Cloud Logging 已收集記錄,包括憑證新增至叢集的時間,以及 GKE 節點提取映像檔的時間。
定價
本文使用下列 Google Cloud計費元件:
- GKE
- Secret Manager
- 記錄: GKE 會為這項功能產生「管理員活動」稽核記錄,並在啟用時產生「資料存取」稽核記錄。如要瞭解不同類型的稽核記錄,請參閱 GKE 稽核記錄。
如要根據預測用量估算費用,請使用 Pricing Calculator。
事前準備
開始之前,請確認你已完成下列工作:
- 啟用 Google Kubernetes Engine API。 啟用 Google Kubernetes Engine API
- 如要使用 Google Cloud CLI 執行這項工作,請安裝並初始化 gcloud CLI。如果您先前已安裝 gcloud CLI,請執行
gcloud components update
,取得最新版本。
Enable the Secret Manager API.
您必須已擁有私人登錄檔和私人 CA 憑證,才能存取登錄檔。本指南不包含設定私人登錄檔或建立憑證的內容。
需求條件
如要使用私有 CA 公開金鑰存取私有登錄檔,必須符合下列條件:
- 叢集必須使用 GKE 1.27.3-gke.1700 以上版本。
- 您必須使用搭載 containerd 的 Container-Optimized OS 節點映像檔 (所有 GKE 叢集的預設映像檔),或是搭載 containerd 的 Ubuntu 節點映像檔 (版本為 1.33.0 以上)。不支援 Windows Server 節點映像檔。
- 節點集區必須具備節點的
cloud-platform
存取範圍,節點才能下載憑證。詳情請參閱「GKE 中的預設存取權範圍」。本文說明如何在建立叢集或節點集區時設定存取範圍。
限制
請注意下列限制:
- 在 1.33.0 之前的版本中,您無法在 Ubuntu 節點映像檔中使用私有 CA 憑證。
- 您無法在 Windows Server 節點中使用私有 CA 憑證。
- 每個叢集最多支援五個私人 CA 憑證,適用於私人登錄檔。
- 每個憑證最多可有 25 個完整網域名稱 (FQDN)。
- 每個網域只能用於單一憑證檔案。但支援憑證套裝組合。
- 憑證必須經過 PEM 編碼。
- 伺服器不會自動輪替憑證。詳情請參閱本文的「輪替私有 CA 憑證」一節。
- FQDN 具有下列限制:
- 完整網域名稱長度上限為 255 個字元,包括特殊字元。
- FQDN 只能使用英文字母、數字和破折號 (-)。
- 系統不支援 Punycode。
- 不支援萬用字元。
從設定 DaemonSet 遷移
在 GKE Standard 叢集中,您可以部署具備權限的 DaemonSet,修改容器執行階段設定。這個方法會直接修改每個節點上的 containerd 設定。
如果您使用具備特殊權限的 DaemonSet 設定私人登錄檔的存取權,請先考慮下列事項,再使用本文:
- 在 Secret Manager 中儲存私有 CA 公開金鑰,只會設定私有登錄檔的存取權。系統不支援其他登錄相關設定。
啟用這項功能後,叢集會使用 containerd 的 CRI hostpath 設定模型,與先前的設定模型不相容。如果您有任何會修改 containerd 主機設定的 DaemonSet,例如不安全的私人登錄檔、鏡像或 Proxy,請更新 DaemonSet,改用 CRI hostpath 模型。
如要瞭解 CRI hostpath 模型中的可用欄位,請參閱 containerd GitHub 存放區中的「登錄設定」。
啟用這項功能後,GKE 會將 CRI hostpath 設定模型套用至叢集中的新節點。現有節點會繼續使用先前的設定模型,直到在升級等事件期間重新建立為止。
更新 DaemonSet,同時支援兩種設定模型
為降低設定 DaemonSet 無法在支援特定設定模型的節點上運作的風險,請確保 DaemonSet 會根據節點上的 containerd 設定檔,有條件地使用特定設定模型。如需實作這項條件式邏輯的 DaemonSet 範例,請參閱 GoogleCloudPlatform/k8s-node-tools
GitHub 存放區中的 insecure-registry-config.yaml 資訊清單。
將 CA 公開金鑰儲存在 Secret Manager 中
將核發私有登錄檔憑證的私有 CA 公開金鑰,以密鑰形式儲存在 Secret Manager 中。如需操作說明,請參閱 Secret Manager 文件中的「建立密鑰」。
設定從 GKE 存取 Secret Manager 的權限
為確保叢集的 IAM 服務帳戶具備從 Secret Manager 提取密鑰的必要權限,請要求管理員將密鑰的下列 IAM 角色授予叢集的 IAM 服務帳戶:
-
存取密鑰內容:
Secret Manager 密鑰存取者 (
roles/secretmanager.secretAccessor
) -
存取密碼中繼資料:
Secret Manager 檢視者 (
roles/secretmanager.viewer
)
如要進一步瞭解如何授予角色,請參閱「管理專案、資料夾和機構的存取權」。
這些預先定義的角色具備從 Secret Manager 提取密鑰所需的權限。如要查看確切的必要權限,請展開「必要權限」部分:
所需權限
如要從 Secret Manager 提取密鑰,您必須具備下列權限:
-
resourcemanager.projects.get
-
resourcemanager.projects.list
-
secretmanager.secrets.get
-
secretmanager.secrets.list
-
secretmanager.versions.get
-
secretmanager.versions.list
-
secretmanager.versions.access
管理員或許還可透過自訂角色或其他預先定義的角色,將這些權限授予叢集的 IAM 服務帳戶。
如果您未將自訂 IAM 服務帳戶與叢集或節點集區建立關聯 (建議您這麼做),叢集會使用 Compute Engine 預設服務帳戶。
建議您盡可能使用最低權限的 IAM 服務帳戶,設定叢集和節點集區。如需操作說明,請參閱「使用最低權限的服務帳戶」。
建立執行階段設定檔
如要在 GKE 中啟用私人登錄檔的私人 CA 憑證,請建立 YAML 檔案來修改 containerd 設定。
取得 Google Cloud 專案編號:
gcloud projects describe PROJECT_ID \ --format="value(projectNumber)"
輸出內容是專案編號 (數字)。
將下列設定儲存為
containerd-configuration.yaml
:privateRegistryAccessConfig: certificateAuthorityDomainConfig: - gcpSecretManagerCertificateConfig: secretURI: "projects/PROJECT_NUMBER/secrets/SECRET_NAME/versions/SECRET_VERSION" fqdns: - "FQDN1" - "FQDN2" enabled: true
更改下列內容:
PROJECT_NUMBER
:您在上一個步驟中取得的專案編號。SECRET_VERSION
:Secret Manager 中密鑰的版本號碼。您可以選擇使用版本別名,但建議使用版本號碼,以免管理作業過於複雜。FQDN1
、FQDN2
:私有登錄檔的完整網域名稱。如果憑證是針對 IPv4 位址核發,您也可以使用該位址,但我們不建議這麼做。
如需這些欄位的說明,請參閱「Available containerd configuration options」(可用的 containerd 設定選項) 表格中的「privateRegistryAccessConfig」。
將 containerd 設定套用至新叢集
本節說明如何建立新的 GKE 叢集時,套用 containerd 設定檔。
執行下列指令:
gcloud container clusters create-autoCLUSTER_NAME
\ --location=LOCATION
\ --scopes="cloud-platform" \ --containerd-config-from-file="PATH_TO_CONFIG_FILE
"
更改下列內容:
CLUSTER_NAME
:新叢集的名稱。LOCATION
:新叢集的 Compute Engine 位置。PATH_TO_CONFIG_FILE
:您建立的設定檔路徑,例如~/containerd-configuration.yaml
。
如要在新的 Standard 叢集上啟用私人登錄設定,請使用相同選項執行 gcloud container clusters create
指令。
將 containerd 設定套用至現有叢集
本節說明如何將 containerd 設定套用至現有叢集和節點。
檢查存取權範圍
現有叢集必須具備 cloud-platform
存取範圍,才能使用這項功能。本節說明如何檢查存取範圍,以及如何使用新的或修改過的私人登錄設定檔更新現有叢集。
如要瞭解新叢集的預設存取權範圍,請參閱「GKE 中的存取權範圍」。
檢查 Autopilot 存取權範圍
執行下列指令:
gcloud container clusters describeCLUSTER_NAME
\ --location=LOCATION
\ --flatten=nodeConfig \ --format='csv[delimiter="\\n",no-heading](oauthScopes)'
如果叢集沒有 https://www.googleapis.com/auth/cloud-platform
存取權範圍,請建立具有這個存取權範圍的新叢集。
檢查標準存取權範圍
如要檢查 Standard 叢集存取範圍,請檢查節點集區:
gcloud container node-pools describeNODE_POOL_NAME
\ --cluster=CLUSTER_NAME
\ --location=LOCATION
\ --flatten=nodeConfig \ --format='csv[delimiter="\\n",no-heading](oauthScopes)'
將 NODE_POOL_NAME
替換為節點集區的名稱。
如果叢集沒有 https://www.googleapis.com/auth/cloud-platform
存取範圍,請建立具有 cloud-platform
存取範圍的新節點集區,並刪除現有節點集區。
更新叢集以使用設定檔
執行下列指令:
gcloud container clusters updateCLUSTER_NAME
\ --location=LOCATION
\ --containerd-config-from-file="PATH_TO_CONFIG_FILE
"
在標準叢集中重新建立節點
如果您的標準叢集未使用自動升級功能,則必須手動重新建立節點集區,才能套用新設定。如要手動重建節點,請將叢集升級至目前使用的 GKE 版本。
gcloud container clusters upgradeCLUSTER_NAME
\ --location=LOCATION
\ --cluster-version=VERSION
將 VERSION
替換為叢集已使用的 GKE 修補程式版本。
確認叢集可以存取私人登錄檔
執行下列指令:
gcloud container clusters describe CLUSTER_NAME \
--location=LOCATION \
--flatten="nodePoolDefaults.nodeConfigDefaults.containerdConfig"
輸出結果會與下列內容相似:
containerdConfig:
privateRegistryAccessConfig:
certificateAuthorityDomainConfig:
- fqdns:
- 203.0.113.105
gcpSecretManagerCertificateConfig:
secretUri: projects/123456789012/secrets/example-secret-name/versions/1
enabled: true
部署可存取私有映像檔的工作負載
在本節中,您將部署靜態 Pod,並參照私人登錄檔中的映像檔。
將下列資訊清單儲存為
private-registry-pod.yaml
:apiVersion: v1 kind: Pod metadata: name: private-registry-pod spec: containers: - name: private-image image: IMAGE_NAME
將
IMAGE_NAME
替換成您的私人映像檔名稱。部署 Pod:
kubectl create -f private-registry-pod.yaml
輪替私人 CA 憑證
Secret Manager 和 GKE 無法自動輪替 Secret Manager 中的私有 CA 憑證。如要執行憑證輪替,請按照下列步驟操作。您必須重新建立現有節點兩次,才能完成這些步驟。建議您在排定的停機期間執行憑證輪替,盡量減少工作負載中斷造成的影響。
- 建立 PEM 編碼憑證組合,其中包含舊憑證和新憑證。
- 在 Secret Manager 中,將套件新增為新的密鑰版本。
- 使用新的密碼版本號碼更新執行階段設定檔
secretURI
欄位。 - 更新叢集以使用新的密鑰版本。
取得更新作業的時間戳記:
gcloud container operations list \ --filter="operationType ~ UPDATE_CLUSTER AND targetLink ~ CLUSTER_NAME" \ --sort-by=startTime \ --limit=1 \ --format='value(endTime)'
輸出結果會與下列內容相似:
2024-01-31T09:27:30.864308964Z
找出更新作業結束前建立的節點:
kubectl get nodes -o json | jq ".items[] | select(.metadata.creationTimestamp | fromdateiso8601 < $(date -d CLUSTER_UPDATE_TIMESTAMP +%s)) | .metadata.name"
將
CLUSTER_UPDATE_TIMESTAMP
替換為上一步的時間戳記。輸出內容是節點名稱清單,這些節點尚未以更新後的設定重新建立。如果輸出內容為空白,請繼續下一個步驟。
在 Secret Manager 中建立新的密鑰版本,其中只包含新憑證。
重複上述步驟更新叢集、取得作業時間戳記,並確認節點使用新的密鑰版本。
從 Secret Manager 刪除舊的密鑰版本。
在 Logging 中查看稽核記錄
本節說明如何使用 Logging 檢查 GKE 是否在節點上安裝密碼版本。
前往 Google Cloud 控制台的「Logs Explorer」頁面:
指定下列查詢:
resource.type="gce_instance" textPayload:"Installed certificate \\\"projects/PROJECT_NUMBER/secrets/SECRET_NAME/versions/SECRET_VERSION\\\""
如果憑證安裝成功,輸出內容會類似以下內容:
"Installed certificate "projects/PROJECT_NUMBER/secrets/SECRET_NAME/versions/SECRET_VERSION""
如果憑證安裝失敗,輸出內容會類似於以下內容:
"Failed to install certificate "projects/PROJECT_NUMBER/secrets/SECRET_NAME/versions/SECRET_VERSION""
最佳做法
使用這項功能時,建議您採取下列最佳做法:
- 請勿使用別名做為 Secret Manager 密鑰版本。每個密鑰版本都會自動產生版本號碼,別名可能會隨著時間指向不同的憑證版本,導致追蹤工作負載使用的特定版本時發生複雜情況。
- 使用維護期間和排除項目,控制 GKE 何時可重新建立節點,以套用更新的 containerd 設定。
- 在密碼層級提供密碼存取權,而非專案層級。
停用 containerd 設定選項
如要移除自訂設定,請按照下列步驟操作:
-
更新設定檔,在要停用的設定項目中指定
enabled: false
,並刪除項目中的所有其他欄位,如下列範例所示:privateRegistryAccessConfig: enabled: false
- 將更新後的設定檔套用至叢集。如需操作說明,請參閱「將 containerd 設定套用至現有叢集」。
疑難排解
如需疑難排解步驟,請參閱「排解容器執行階段問題」。