准入 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 就會產生深入分析和建議:
K8S_ADMISSION_WEBHOOK_UNAVAILABLE:GKE 叢集有一或多個 Webhook 回報沒有可用的端點。請按照操作說明,查看回報沒有可用端點的 Webhook。K8S_ADMISSION_WEBHOOK_UNSAFE:GKE 叢集有一或多個 Webhook,根據攔截的資源,這些 Webhook 被視為不安全。請按照操作說明檢查不安全的 Webhook。下列 Webhook 視為不安全:- Webhook 攔截
kube-system命名空間中的資源,包括 Pod 和租約。 - Webhook 攔截
kube-node-lease命名空間中的租約。 - Webhook 攔截叢集範圍內的系統資源,包括
Nodes、TokenReviews、SubjectAccessReviews和CertificateSigningRequests。
- Webhook 攔截
排解偵測到的 Webhook 問題
下列各節說明如何排解 GKE 偵測到可能設定錯誤的 Webhook。
按照操作說明正確設定 Webhook 後,系統會在 24 小時內解決建議,且不會再顯示於控制台。
如果不想採行最佳化建議,可以關閉建議。
Webhook 回報沒有可用端點
如果 Webhook 回報沒有可用端點,表示支援 Webhook 端點的 Service 有一或多個 Pod 未運作。如要讓 Webhook 端點可供使用,請按照操作說明,找出並排解支援這個 Webhook 端點的 Service Pod 問題:
查看洞察和建議,一次選擇一項洞察進行疑難排解。GKE 會為每個叢集產生一項深入分析,列出一或多個端點損壞、必須調查的 Webhook。針對每個 Webhook,洞察也會說明服務名稱、損壞的端點,以及上次呼叫端點的時間。
找出與 Webhook 相關聯的 Service 服務 Pod:
控制台
在洞察的側欄面板中,查看設定錯誤的 Webhook 表格。按一下服務名稱。
kubectl
執行下列指令來說明 Service:
kubectl describe svc SERVICE_NAME -n SERVICE_NAMESPACE將 SERVICE_NAME 和 SERVICE_NAMESPACE 分別替換為服務的名稱和命名空間。
如果在 Webhook 中找不到列出的服務名稱,可能是因為設定中列出的名稱與服務的實際名稱不符,導致端點無法使用。如要修正端點可用性,請更新 Webhook 設定中的 Service 名稱,使其與正確的 Service 物件相符。
檢查這個 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,避免攔截這些資源。
- 請按照操作說明查看洞察和建議,一次選擇一項洞察進行疑難排解。GKE 只會為每個叢集產生一項深入分析,這項深入分析會列出一或多個 Webhook 設定,每項設定都會列出一或多個 Webhook。針對列出的每個 Webhook 設定,洞察會說明設定標記的原因。
檢查 Webhook 設定:
控制台
在洞察的側欄面板中查看表格。每列都會顯示 Webhook 設定的名稱,以及這項設定遭標記的原因。
如要檢查各項設定,請按一下名稱,前往 GKE 物件瀏覽器資訊主頁中的設定。
kubectl
執行下列
kubectl指令來取得 Webhook 設定,並將 CONFIGURATION_NAME 替換為 Webhook 設定的名稱:kubectl get validatingwebhookconfigurations CONFIGURATION_NAME -o yaml如果這個指令未傳回任何內容,請再次執行指令,並將
validatingwebhookconfigurations替換為mutatingwebhookconfigurations。webhooks區段會列出一或多個 Webhook。根據 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 分配至不同的故障網域。