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

准入 Webhook (或 Kubernetes 中的 Webhook) 是一種准入控制器,可在 Kubernetes 叢集中使用,在要求保存之前,驗證或變更傳送至控制層的要求。第三方應用程式通常會使用在系統重要資源和命名空間上運作的 Webhook。如果 Webhook 設定錯誤,可能會影響控制層的效能和穩定性。舉例來說,如果第三方應用程式建立的 Webhook 設定不正確,GKE 可能無法在代管的 kube-system 命名空間中建立及修改資源,進而降低叢集的功能。

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

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

您可以按照這份指南的操作說明,檢查可能設定錯誤的 Webhook,並視需要更新。

如要進一步瞭解如何管理建議工具提供的深入分析和建議,請參閱「運用深入分析和建議,充分發揮 GKE 的效益」。

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

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

  • 使用 Google Cloud 控制台。
  • 使用 Google Cloud CLI 或 Recommender API,並依子類型 K8S_ADMISSION_WEBHOOK_UNSAFE 和 K8S_ADMISSION_WEBHOOK_UNAVAILABLE 篩選。

透過深入分析找出 Webhook 後,請按照操作說明排解偵測到的 Webhook 問題。

GKE 偵測到設定錯誤的 Webhook 時

如果叢集符合下列任一條件,GKE 就會產生深入分析和建議:

排解偵測到的 Webhook 問題

下列各節說明如何排解 GKE 偵測到可能設定錯誤的 Webhook。

按照操作說明正確設定 Webhook 後,系統會在 24 小時內解決建議,且不會再顯示於控制台。

如果不想採行最佳化建議,可以關閉建議。

Webhook 回報沒有可用端點

如果 Webhook 回報沒有可用端點,表示支援 Webhook 端點的 Service 有一或多個 Pod 未運作。如要讓 Webhook 端點可供使用,請按照操作說明,找出並排解支援這個 Webhook 端點的 Service Pod 問題:

  1. 查看洞察和建議,一次選擇一項洞察進行疑難排解。GKE 會為每個叢集產生一項深入分析,列出一或多個端點損壞、必須調查的 Webhook。針對每個 Webhook,洞察也會說明服務名稱、損壞的端點,以及上次呼叫端點的時間。

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

    控制台

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

    kubectl

    執行下列指令來說明 Service:

    kubectl describe svc SERVICE_NAME -n SERVICE_NAMESPACE
    

    將 SERVICE_NAME 和 SERVICE_NAMESPACE 分別替換為服務的名稱和命名空間。

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

  3. 檢查這個 Service 的服務 Pod:

    控制台

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

    kubectl

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

    kubectl get deployment -n SERVICE_NAMESPACE
    

    或者,執行下列指令:

    kubectl get pods -n SERVICE_NAMESPACE -o wide
    

    如果 Pod 未執行,請檢查 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-system 和 kube-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 就只會在特定命名空間中運作。此外,如果 operator 為 NotIn,請務必在 values 中加入 kube-system 和 kube-node-lease (在本例中為 blue-system)。

    • operator 條件為 In,values 包含 kube-system 和 kube-node-lease,如以下範例所示:

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

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

    排除相符的資源

    如果資源中列出 nodes、tokenreviews、subjectaccessreviews 或 certificatesigningrequests,Webhook 也會標記,如下例所示:

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

    從資源部分移除 nodes、tokenreviews、subjectaccessreviews 和 certificatesigningrequests。你可以在 resources 中保留 pods。

封鎖系統重要元件的 Webhook

如果 Webhook 攔截了建立或更新 ClusterRoles 和 ClusterRoleBindings 的要求,可能會干擾控制層協調這些重要系統資源的能力。舉例來說,在叢集升級期間,kube-apiserver 可能需要更新系統角色。如果無法使用或設定錯誤的 Webhook 封鎖這項更新,kube-apiserver 就無法恢復健康狀態,進而導致叢集升級作業遭到封鎖。

GKE 不會偵測 Webhook 是否攔截 ClusterRoles 和 ClusterRoleBindings,因此不會針對這種情況產生洞察。

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

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

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

許可死結

如果 Webhook 設定為失敗時關閉,可能會導致叢集無法自動復原。舉例來說,如果刪除叢集中的所有節點,Webhook 也會停止運作。由於新增節點需要准入驗證,因此 Webhook 必須可用,才能核准要求。這會造成循環相依,導致叢集的控制層無法復原。

GKE 不會偵測准入死結情況,因此不會為這種情況產生洞察。不過,如果 Webhook Pod 停止運作,可能會發生准入死結,在這種情況下,GKE 會偵測到 Webhook 沒有可用的端點,並產生 K8S_ADMISSION_WEBHOOK_UNAVAILABLE 深入分析。

如要解決這個問題,可以刪除 ValidatingWebhookConfiguration,中斷循環相依關係,讓叢集復原。

叢集控制層可用性

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

GKE 不會偵測 Webhook 造成的叢集控制層可用性問題,因此不會針對這種情況產生深入分析。

  • 限制 Webhook 的範圍:您可以豁免重要資源,不讓 Webhook 驗證,以免 Webhook 干擾機密程序。您可以豁免命名空間或特定種類的資源。不過,請留意不明顯的依附元件。舉例來說,ConfigMap 可能是 Kubernetes 中選取領導者的重要資源。

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

後續步驟