您可以停用控制層虛擬機器 (VM) 執行個體的外部 IP 位址,提升 Google Kubernetes Engine (GKE) 控制層的安全性。本文件說明安全工程師如何控管 Kubernetes API 伺服器的輸出流量,以及如何避免准入 Webhook 發生潛在的中斷問題。
您應該已熟悉下列項目:
限制層級
建立或更新叢集時,您可以指定下列其中一個限制等級:
- 沒有流量 (
NONE):停用每個控制層 VM 執行個體的外部 IP 位址,並將所有 API 伺服器輸出流量路由至黑洞。這項限制層級會產生下列影響:- GKE 會封鎖從 API 伺服器到叢集外部執行的許可控制器 Webhook 伺服器的直接外送流量。凡是使用網址或 IP 位址與 Webhook 伺服器通訊的許可控制 Webhook,都會受到影響。
- GKE 會封鎖 API 伺服器直接傳送至外部服務 (包括網際網路和Google Cloud 服務) 的任何輸出流量。GKE 驗證和中繼資料伺服器等系統元件的流量不受影響。
- 其他類型的輸出流量 (例如重要系統流量或節點流量) 不會受到影響。
- GKE 會使用 ValidatingAdmissionPolicy 拒絕建立或更新使用
clientConfig.url欄位的 ValidatingWebhookConfigurations 或 MutatingWebhookConfigurations。
- 所有流量 (
VIA_CONTROL_PLANE):保留每個控制層執行個體的外部 IP 位址,並允許 API 伺服器將該 IP 位址用於輸出流量。這是 GKE 的預設選項。
限制
如果將限制等級設為 NONE 來停用輸出流量,叢集就無法使用私人的公開 IP (PUPI) 位址。
事前準備
開始之前,請確認您已完成下列工作:
- 啟用 Google Kubernetes Engine API。 啟用 Google Kubernetes Engine API
- 如要使用 Google Cloud CLI 執行這項工作,請安裝並初始化 gcloud CLI。如果您先前已安裝 gcloud CLI,請執行
gcloud components update指令,取得最新版本。較舊的 gcloud CLI 版本可能不支援執行本文件中的指令。
- 確認您擁有執行 1.35.1-gke.1396000 以上版本的 GKE Autopilot 或 Standard 叢集。您也可以建立 Autopilot 叢集。
- 如果您有任何外部 Webhook 伺服器,請確認您使用服務參照與這些伺服器聯絡。停用 API 伺服器的輸出流量後,任何使用網址聯絡 Webhook 伺服器的 Webhook 都會失敗。GKE 管理的 Webhook 不受影響。
自訂 API 伺服器的輸出流量
建立或更新叢集時,您可以自訂 API 伺服器輸出流量的限制等級。如要更新現有叢集,請使用 --control-plane-egress 標記:
gcloud container clusters update CLUSTER_NAME \
--location=CONTROL_PLANE_LOCATION \
--control-plane-egress=CONTROL_PLANE_EGRESS_MODE
更改下列內容:
CLUSTER_NAME:叢集名稱。CONTROL_PLANE_LOCATION:叢集控制層的區域或可用區,例如us-central1或us-central1-a。CONTROL_PLANE_EGRESS_MODE:API 伺服器輸出流量的限制等級。請使用下列其中一個值:NONE:停用控制層 VM 執行個體的外部 IP 位址,並封鎖 API 伺服器的所有非重要輸出流量。GKE 會禁止建立使用clientConfig.url欄位的新 Webhook 設定。VIA_CONTROL_PLANE:保留控制層 VM 執行個體的外部 IP 位址,並允許 API 伺服器傳送輸出流量。這是預設值。
確認輸出流量限制
如要檢查 GKE 是否封鎖 API 伺服器的輸出流量,請使用下列任一方法:
檢查叢集設定:
gcloud container clusters describe CLUSTER_NAME \ --location=CONTROL_PLANE_LOCATION \ --format='value(controlPlaneEgress)'輸出內容如下:
NONE:輸出流量受到限制。VIA_CONTROL_PLANE:輸出流量不受限制。
如要驗證變更對新 Webhook 的影響,請嘗試建立使用
clientConfig.url欄位的 Webhook 設定:cat <<EOF | kubectl apply -f - apiVersion: admissionregistration.k8s.io/v1 kind: MutatingWebhookConfiguration metadata: name: test-webhook-config webhooks: - name: my-webhook.example.com clientConfig: url: "https://my-webhook.example.com:9443/my-webhook-path"輸出結果會與下列內容相似:
ValidatingAdmissionPolicy 'gke-restrict-webhook-url' denied request: Egress traffic from the API server through the control plane is disabled. As a result, direct API server calls to external webhook servers are blocked. To connect to external webhooks, update any webhook configurations that use clientConfig.url to use clientConfig.service instead.這項輸出內容表示 GKE ValidatingAdmissionPolicy 會禁止您使用
clientConfig.url欄位建立或更新 Webhook 設定。如果刪除 ValidatingAdmissionPolicy,您可以建立或更新設定,但准入要求不會傳送至 Webhook 伺服器。如要驗證變更對叢集中現有 Webhook 的影響,請嘗試將直接要求傳送至叢集外部的 IP 位址:
- 為叢集啟用
API_SERVER記錄。 刪除
gke-restrict-webhook-urlValidatingAdmissionPolicy:kubectl delete validatingadmissionpolicy gke-restrict-webhook-url刪除 ValidatingAdmissionPolicy 後,您可以使用
clientConfig.url欄位建立或更新 Webhook 設定。叢集會自動重新建立 ValidatingAdmissionPolicy,因此這項略過作業是暫時性的。在 ValidatingWebhookConfiguration 或 MutatingWebhookConfiguration 的
clientConfig.url欄位中,指定要將要求傳送至的 IP 位址或網址。您可以使用範例值,例如http://example.com或203.0.113.100。檢查 API 伺服器記錄,找出類似下列內容的錯誤訊息:
Error from server (InternalError): error when creating "STDIN": Internal error occurred: failed calling webhook WEBHOOK_NAME": failed to call webhook: Post "WEBHOOK_URL": proxyconnect tcp: dial tcp: lookup master-internet-access-unavailable.localhost on 169.254.169.254:53: no such host這項輸出內容表示即使 ValidatingAdmissionPolicy 已刪除,准入要求也無法透過伺服器 IP 位址或網址連上 Webhook 伺服器。
- 為叢集啟用
停用控制層 VM 執行個體的外部 IP 位址後,GKE 會封鎖傳送至任何網路掛鉤的流量,這些網路掛鉤會使用網址與外部網路掛鉤伺服器聯絡。您必須使用 webhook 設定中的 clientConfig.service 欄位,為 API 伺服器設定替代路徑。詳情請參閱「外部 Webhook 設定」。