使用 Webhook 時確保控制層穩定性

許可 Webhook (或 Kubernetes 中的「Webhook」) 是一種許可控制器,可用於 Kubernetes 叢集,在要求持續存在之前,驗證或變更對控制層的要求。第三方應用程式通常會使用在系統重要資源和命名空間中運作的 Webhook。設定錯誤的 Webhook 可能會影響控制層的效能和穩定性。舉例來說,第三方應用程式建立的 Webhook 設定有誤,可能會導致 GKE 無法在代管的 kube-system 命名空間中建立及修改資源,進而影響叢集功能。

Google Kubernetes Engine (GKE) 會監控叢集,並使用 Recommender 服務提供指引,協助您最佳化平台使用情形。為確保叢集保持穩定且效能良好,請參閱 GKE 針對下列情境提供的建議:

  • 運作中但沒有可用端點的 Webhook。
  • Webhook 會對重要的系統資源和命名空間執行作業,因此被視為不安全。

這份指南提供相關操作說明,協助您檢查可能設定錯誤的 Webhook,並視需要更新。

如要進一步瞭解如何管理 Recommenders 的深入分析和建議,請參閱「運用深入分析和建議,最佳化 GKE 用量」。

找出可能影響叢集的設定錯誤 Webhook

如要取得洞察資料,找出可能影響叢集效能和穩定性的 Webhook,請按照這篇文章的說明查看洞察資料和建議。 您可以透過下列方式取得洞察:

  • 使用 Google Cloud 控制台。
  • 使用 Google Cloud CLI 或 Recommender API,並以子類型 K8S_ADMISSION_WEBHOOK_UNSAFEK8S_ADMISSION_WEBHOOK_UNAVAILABLE 進行篩選。

透過洞察資料找出網路鉤後,請按照說明排解偵測到的網路鉤問題

GKE 偵測到設定錯誤的 Webhook 時

如果叢集符合下列任一條件,GKE 就會產生洞察資料和建議:

排解偵測到的 Webhook 問題

下列各節提供操作說明,協助您排解 GKE 偵測到的潛在設定錯誤 Webhook。

按照指示操作並正確設定 Webhook 後,建議會在 24 小時內解決,且不會再顯示在控制台中。

如不想採用最佳化建議,可以略過

Webhook 回報沒有可用端點

如果 Webhook 回報沒有可用端點,表示支援 Webhook 端點的服務有一或多個 Pod 未執行。如要取得 Webhook 端點,請按照操作說明找出並排解支援這個 Webhook 端點的服務 Pod 問題:

  1. 查看洞察資料和建議,一次選擇一項洞察資料進行疑難排解。GKE 會為每個叢集產生一項洞察,並列出一或多個端點中斷的 Webhook,供您調查。針對每個這類 Webhook,洞察資訊也會指出服務名稱、中斷的端點,以及上次呼叫端點的時間。

  2. 找出與 Webhook 相關聯的服務放送 Pod:

    控制台

    在洞察資料的側邊欄面板中,查看設定錯誤的 Webhook 表格。 按一下服務名稱。

    kubectl

    執行下列指令來描述 Service:

    kubectl describe svc SERVICE_NAME -n SERVICE_NAMESPACE
    

    SERVICE_NAMESERVICE_NAMESPACE 分別替換為服務的名稱和命名空間。

    如果找不到 webhook 中列出的服務名稱,可能是因為設定中列出的名稱與服務的實際名稱不符,導致端點無法使用。如要修正端點可用性,請更新網路鉤子設定中的服務名稱,使其與正確的服務物件相符。

  3. 檢查這項服務的服務 Pod:

    控制台

    在「服務詳細資料」的「提供服務的 Pod」下方,查看支援這項服務的 Pod 清單。

    kubectl

    列出 Deployment 或 Pod,找出未執行的 Pod:

    kubectl get deployment -n SERVICE_NAMESPACE
    

    或者執行下列指令:

    kubectl get pods -n SERVICE_NAMESPACE -o wide
    

    如果 Pod 未執行,請檢查 Pod 記錄,瞭解原因。如需 Pod 常見問題的相關說明,請參閱「排解已部署工作負載的問題」。

被視為不安全的 Webhook

如果 Webhook 攔截系統管理命名空間中的任何資源,或特定類型的資源,GKE 會將此視為不安全行為,並建議您更新 Webhook,避免攔截這些資源。

  1. 按照說明查看洞察資料和最佳化建議,一次選擇一項洞察資料進行疑難排解。GKE 每個叢集只會產生一項洞察,這項洞察會列出一或多個 Webhook 設定,而每項設定會列出一或多個 Webhook。針對列出的每個 Webhook 設定,洞察資訊會說明設定遭到標記的原因。
  2. 檢查 Webhook 設定:

    控制台

    在洞察資料的側邊面板中,查看表格。每一列都會顯示網路鉤子設定的名稱,以及這項設定遭到標記的原因。

    如要檢查各項設定,請按一下名稱,前往 GKE 物件瀏覽器資訊主頁中的這項設定。

    kubectl

    執行下列 kubectl 指令來取得 Webhook 設定,並將 CONFIGURATION_NAME 替換為 Webhook 設定的名稱:

    kubectl get validatingwebhookconfigurations CONFIGURATION_NAME -o yaml
    

    如果這項指令沒有傳回任何內容,請再次執行指令,並將 validatingwebhookconfigurations 替換為 mutatingwebhookconfigurations

    webhooks」部分會列出一或多個 Webhook。

  3. 根據系統標記 Webhook 的原因編輯設定:

    排除 kube-system 和 kube-node-lease 命名空間

    如果 scope*,系統會標記 Webhook。或者,如果範圍是 Namespaced,且符合下列任一條件,系統就會標記 Webhook:

    • operator 條件為 NotIn,且 values 會省略 kube-systemkube-node-lease,如下列範例所示:

      webhooks:
      - admissionReviewVersions:
        ...
        namespaceSelector:
          matchExpressions:
          - key: kubernetes.io/metadata.name
            operator: NotIn
            values:
            - blue-system
        objectSelector: {}
        rules:
        - apiGroups:
          ...
          scope: '*'
        sideEffects: None
        timeoutSeconds: 3
      

      請務必將 scope 設為 Namespaced,而非 *,這樣 webhook 才會只在特定命名空間中運作。此外,請確認如果 operatorNotIn,您會在 values 中加入 kube-systemkube-node-lease (在本範例中,使用 blue-system)。

    • operator 條件為 In,且 values 包含 kube-systemkube-node-lease,如下列範例所示:

      namespaceSelector:
          matchExpressions:
          - key: kubernetes.io/metadata.name
            operator: In
            values:
            - blue-system
            - kube-system
            - kube-node-lease
      

      請務必將 scope 設為 Namespaced,而非 *,這樣 webhook 就只會在特定命名空間中運作。請確認如果 operatorIn,則 values 中不包含 kube-systemkube-node-lease。在本範例中,只有 blue-system 應位於 values 中,因為 operatorIn

    排除相符資源

    如果資源下列出 nodestokenreviewssubjectaccessreviewscertificatesigningrequests,系統也會標記 Webhook,如下例所示:

    - admissionReviewVersions:
    ...
      resources:
      - 'pods'
      - 'nodes'
      - 'tokenreviews'
      - 'subjectaccessreviews'
      - 'certificatesigningrequests'
      scope: '*'
    sideEffects: None
    timeoutSeconds: 3
    

    從資源部分移除 nodestokenreviewssubjectaccessreviewscertificatesigningrequests。你可以將 pods 保留在 resources 中。

會封鎖系統重要元件的 Webhook

如果 Webhook 攔截建立或更新 ClusterRolesClusterRoleBindings 的要求,可能會干擾控制層協調這些重要系統資源的能力。舉例來說,在叢集升級期間,kube-apiserver 可能需要更新系統角色。如果無法使用或設定錯誤的 Webhook 封鎖這項更新,kube-apiserver 就無法正常運作,叢集升級作業也會因此受阻。

GKE 不會偵測 Webhook 是否攔截 ClusterRolesClusterRoleBindings,因此不會針對這種情況產生深入分析。

以下範例顯示會攔截 ClusterRoles 的問題 Webhook 設定:

-   admissionReviewVersions:
  ...
  resources:
  -   'clusterroles'
  -   'clusterrolebindings'
  scope: '*'
sideEffects: None
timeoutSeconds: 3

為避免發生這種情況,請確保 Webhook 不會攔截具有 system: prefix 設定的 ClusterRolesClusterRoleBindings 要求。

入學僵局

如果將 Webhook 設為失敗即關閉,可能會導致叢集無法自動復原。舉例來說,如果叢集中的所有節點都遭到刪除,Webhook 也會停止運作。由於新增節點需要進行許可驗證,因此 Webhook 必須可用於核准要求。這會建立循環依附元件,導致叢集的控制層無法復原。

GKE 不會偵測准入死結情境,因此不會針對這類情境產生深入分析。不過,如果 Webhook Pod 停止運作,可能會發生准入死結,此時 GKE 會偵測到 Webhook 沒有可用的端點,並產生 K8S_ADMISSION_WEBHOOK_UNAVAILABLE Insights。

如要解決這個問題,請刪除 ValidatingWebhookConfiguration,打破循環依附元件,讓叢集恢復運作。

叢集控制層可用性

如果將 Webhook 設為「失敗時關閉」,Kubernetes 控制層的可用性就會取決於 Webhook 的可用性。如要提升控制層的可用性,請考慮下列事項:

GKE 不會偵測 Webhook 導致的叢集控制層可用性問題,因此不會針對這個情境產生洞察資訊。

  • 限制 Webhook 的範圍:您可以免除 Webhook 驗證重要資源,防止 Webhook 干擾敏感程序。您可以排除命名空間或特定種類的資源。不過,請注意不明顯的依附元件。舉例來說,ConfigMap 可以是 Kubernetes 中領導者選舉的重要資源。

  • 強化 Webhook 部署作業:在多個 Pod 中執行 Webhook 可提高韌性和正常運作時間。您可以使用節點選取器,將 Pod 分散到不同的故障網域。

後續步驟