使用 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 中列出的服務名稱,可能是因為設定中列出的名稱與服務的實際名稱不符,導致端點無法使用。如要修正端點可用性,請更新 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 設定:

    控制台

    在洞察資料的側邊面板中,查看表格。每一列都會顯示 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。在這個範例中,values 中只能有 blue-system,因為 operatorIn

    排除相符資源

    如果資源下列出 nodestokenreviewssubjectaccessreviewscertificatesigningrequests,系統也會將 Webhook 標示為有問題,如下例所示:

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

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

後續步驟