排解叢集自動配置器未縮減的問題

如果 Google Kubernetes Engine (GKE) 節點未如預期縮減,通常是因為叢集自動調度器無法移除節點,導致資源使用效率不彰,產生不必要的費用。

本頁說明如何診斷及解決常見問題,避免叢集自動調度器無法執行縮減作業。排解這些問題有助於確保叢集以符合成本效益的方式運作,並適應工作負載變化。

對於負責叢集效率、成本最佳化和資源管理的平台管理員和運算子而言,這項資訊非常重要。如果應用程式開發人員的工作負載設定 (例如 PodDisruptionBudgets 或節點選取器) 無意間導致節點無法移除,他們可能也需要這項資訊。如要進一步瞭解 Google Cloud 內容中提及的常見角色和範例工作,請參閱「常見的 GKE 使用者角色和工作」。

瞭解叢集自動配置器何時會縮減節點

繼續進行疑難排解步驟之前,建議先瞭解叢集自動配置器何時會嘗試縮減節點。叢集自動調度器可能不需要縮減規模,因此未縮減。

叢集自動配置器會計算使用率係數,判斷節點是否使用率過低,且符合縮減條件。使用率係數的計算方式,是將節點上 Pod 要求使用的 vCPU 和記憶體,除以節點上可分配的 vCPU 和記憶體。

叢集自動配置器每 10 秒會檢查節點的使用率,確認是否低於必要門檻。如果您使用balanced 自動調度資源設定檔,使用率因數閾值為 0.5。如果您使用 optimize-utilization 設定檔,利用率會有所不同。當 vCPU 和記憶體的使用率因數都低於必要門檻時,叢集自動配置器會將節點視為未充分運用。

如果節點使用率過低,叢集自動調度器會標記要移除的節點,並在接下來 10 分鐘內監控該節點,確保使用率維持在必要門檻以下。如果節點在 10 分鐘後仍未充分利用,叢集自動調度器應會移除該節點。

示例:計算使用率

您有一個已啟用叢集自動配置器的叢集,且正在使用 balanced 自動調度資源設定檔。這個叢集上的節點是使用 e2-standard-4 機型佈建,提供 4 個 vCPU 和 16 GB 記憶體。這個節點上的 Pod 要求 0.5 個 vCPU 和 10 GB 的記憶體,因此叢集自動調度器會計算下列使用率因素:

  • vCPU 使用率係數:0.5 個 vCPU / 4 個 vCPU = 0.125
  • 記憶體使用率係數:10 GB / 16 GB = 0.625

在這種情況下,叢集自動配置器不會將這個節點視為資源使用率過低,因為記憶體使用率係數 (0.625) 超過 0.5 的門檻。即使 vCPU 使用率偏低,記憶體用量較高仍會阻止縮減,確保 Pod 工作負載有足夠的可用資源。

檢查問題是否由限制所致

如果觀察到叢集使用率偏低超過 10 分鐘,但系統未縮減資源,請確認問題是否是由叢集自動調度資源功能的限制所導致。

查看錯誤

如果問題並非限制所致,通常只要查看錯誤訊息,即可診斷原因:

在通知中查看錯誤

如果觀察到的問題發生在 72 小時內,請在 Google Cloud 控制台中查看錯誤通知。這些通知可提供寶貴的洞察資訊,說明叢集自動配置器無法縮減的原因,並提供解決錯誤的建議,以及查看相關記錄以進行深入調查。

如要在 Google Cloud 控制台中查看通知,請完成下列步驟:

  1. 前往 Google Cloud 控制台的「Kubernetes clusters」(Kubernetes 叢集) 頁面。

    前往 Kubernetes 叢集

  2. 查看「通知」欄。下列通知與縮減問題相關:

    • Can't scale down nodes
    • Scale down blocked by pod
  3. 按一下相關通知,即可查看窗格,瞭解造成問題的原因,以及解決問題的建議做法。

  4. 選用:如要查看這項事件的記錄,請按一下「記錄」。這項動作會將您帶往 Logs Explorer,並預先填入查詢內容,協助您進一步調查資源調度事件。如要進一步瞭解縮減事件的運作方式,請參閱「查看叢集自動調度器事件」。

如果參閱通知中的建議後仍遇到問題,請參閱錯誤訊息表,取得進一步協助。

查看活動中的錯誤

如果觀察到的問題發生在 72 小時前,請在 Cloud Logging 中查看事件。發生錯誤時,系統通常會記錄在事件中。

如要在 Google Cloud 控制台中查看叢集自動調度器記錄,請完成下列步驟:

  1. 前往 Google Cloud 控制台的「Kubernetes clusters」(Kubernetes 叢集) 頁面。

    前往 Kubernetes 叢集

  2. 選取要調查的叢集名稱,即可查看「Cluster details」(叢集詳細資料) 頁面。

  3. 在「叢集詳細資料」頁面中,按一下「記錄」分頁標籤。

  4. 在「記錄」分頁中,按一下「自動調整規模記錄」分頁,即可查看記錄。

  5. 選用:如要套用更進階的篩選器來縮小結果範圍,請按一下頁面右側的箭頭按鈕,在 Logs Explorer 中查看記錄。

如要進一步瞭解縮減事件的運作方式,請參閱「查看叢集自動配置器事件」。如需使用 Cloud Logging 的範例,請參閱下列疑難排解範例

範例:排解超過 72 小時的問題

以下範例說明如何調查及解決叢集無法縮減的問題。

情境

一週前,您查看 GKE 資訊主頁時,發現叢集只使用了 10% 的 CPU 和記憶體。儘管使用率偏低,叢集自動配置器並未如預期刪除節點。現在查看資訊主頁時,問題似乎已解決,但您決定找出問題原因,避免再次發生。

調查

  1. 由於問題發生時間超過 72 小時,因此您使用 Cloud Logging 調查問題,而不是查看通知訊息。
  2. 在 Cloud Logging 中,您可以找到叢集自動調度資源事件的記錄詳細資料,如「查看事件中的錯誤」一文所述。
  3. 您在 nodesToBeRemoved 欄位中搜尋scaleDown 事件,這些事件包含您正在調查的叢集所屬節點。您可以篩選記錄項目,包括依特定 JSON 欄位值篩選。詳情請參閱「進階記錄查詢」。
  4. 找不到任何 scaleDown 事件。不過,如果找到 scaleDown 事件,可以搜尋包含相關 eventIdeventResult 事件。然後在 errorMsg 欄位中搜尋錯誤。
  5. 您決定繼續調查,方法是在節點欄位中搜尋包含您要調查節點的 noScaleDown 事件。

    您會發現 noScaleDown 事件,其中包含節點無法縮減的原因。郵件 ID 為 "no.scale.down.node.pod.not.backed.by.controller",且只有一個參數:"test-single-pod"

解決方法:

您查閱錯誤訊息表,發現這則訊息表示 Pod 不受控制器支援,因此已封鎖縮減作業。您發現其中一個解決方案是在 Pod 中加入 "cluster-autoscaler.kubernetes.io/safe-to-evict": "true" 註解。您調查 test-single-pod 後發現,同事新增了註解,且套用註解後,叢集自動調度器已正確縮減叢集。您決定在所有其他 Pod 中新增註解,確保不會再次發生這個問題。

解決縮減錯誤

找出錯誤後,請參閱下表,瞭解錯誤原因和解決方法。

ScaleDown 錯誤

您可以在對應的 eventResult 事件中,於 resultInfo.results[].errorMsg 欄位查看 scaleDown 事件的錯誤事件訊息。

事件訊息 詳細資料 參數 緩解措施
"scale.down.error.failed.to.mark.to.be.deleted" 無法將節點標示為待刪除。 失敗的節點名稱。 這則訊息應該是暫時性的。 如果問題仍未解決,請與 Cloud Customer Care 團隊聯絡, 以便進一步調查。
"scale.down.error.failed.to.evict.pods" 無法從節點中移出某些 Pod,因此叢集自動調整器無法縮減資源配置。 失敗的節點名稱。 查看 Pod 的 PodDisruptionBudget,並確保規則允許在可接受的情況下撤銷應用程式副本。如要瞭解詳情,請參閱 Kubernetes 說明文件中的「為應用程式指定中斷預算」。
"scale.down.error.failed.to.delete.node.min.size.reached" 叢集大小已達下限,無法刪除節點,因此叢集自動配置器無法縮減資源配置。 失敗的節點名稱。 查看為節點集區自動調度資源設定的最小值,並視需要調整設定。 詳情請參閱「錯誤:叢集中的節點已達到最小大小」。

noScaleDown 事件的原因

如果叢集自動配置器無法刪除節點,系統會定期傳送 noScaleDown 事件。noScaleDown 事件是盡力而為的結果,並未涵蓋所有可能情況。

NoScaleDown 頂層原因

noScaleDown 事件的頂層原因訊息會顯示在「noDecisionStatus.noScaleDown.reason」欄位中。這則訊息包含頂層原因,說明叢集自動配置器無法縮減叢集的原因。

事件訊息 詳細資料 緩解措施
"no.scale.down.in.backoff" 叢集自動調度器無法縮減資源,因為縮減作業處於輪詢期間 (暫時遭到封鎖)。

這則訊息應該是暫時性的,且可能是在近期發生擴充事件時出現。

如果訊息持續顯示,請與 Cloud Customer Care 團隊聯絡,進一步調查問題。

"no.scale.down.in.progress"

先前的縮減作業仍在執行,因此叢集自動配置器無法縮減資源。

這則訊息應該是暫時性的,因為 Pod 最終會移除。如果經常出現這則訊息,請檢查阻礙縮減的 Pod 終止寬限期。如要加快解決問題的速度,也可以刪除不再需要的 Pod。

NoScaleDown 節點層級原因

noScaleDown 事件的節點層級原因訊息會顯示在 noDecisionStatus.noScaleDown.nodes[].reason field 中。訊息會說明叢集自動配置器無法移除特定節點的原因。

事件訊息 詳細資料 參數 緩解措施
"no.scale.down.node.scale.down.disabled.annotation" 叢集自動調度器無法從節點集區移除節點,因為節點已使用 cluster-autoscaler.kubernetes.io/scale-down-disabled: true 註解。 不適用 叢集自動配置器會略過具有這項註解的節點,不會考量節點的用量,且無論節點的用量因素為何,系統都會記錄這則訊息。如要讓叢集自動調度器縮減這些節點,請移除註解。
"no.scale.down.node.node.group.min.size.reached"

節點群組大小未達下限,因此叢集自動配置器無法縮減資源。

這是因為移除節點會違反節點自動佈建設定中定義的整個叢集資源最低限制。

不適用 查看為節點集區自動調度資源設定的最小值。如要讓叢集自動調度器縮減這個節點,請調整最小值
"no.scale.down.node.minimal.resource.limits.exceeded"

叢集自動調度器無法縮減節點資源,因為這會違反整個叢集的資源最低限制。

這是為自動佈建節點功能設定的資源限制。

不適用 查看記憶體和 vCPU 的限制,然後 降低限制,讓叢集自動調度器縮減這個節點。
"no.scale.down.node.no.place.to.move.pods" 叢集自動調度器無法縮減資源,因為沒有可移動 Pod 的位置。 不適用 如果預期 Pod 應重新排程,請查看未充分運用節點上 Pod 的排程需求,判斷這些 Pod 是否可以移至叢集中的其他節點。詳情請參閱「錯誤:沒有可移動 Pod 的位置」。
"no.scale.down.node.pod.not.backed.by.controller"

Pod 不受控制器支援,因此已封鎖縮減作業。

具體來說,叢集自動調度器無法縮減未充分利用的節點,因為 Pod 缺少可辨識的控制器。允許的控制器包括 ReplicationController、DaemonSet、Job、StatefulSet 或 ReplicaSet。

封鎖 Pod 的名稱。 為 Pod 設定註解 "cluster-autoscaler.kubernetes.io/safe-to-evict": "true" ,或是定義可接受的控制器。
"no.scale.down.node.pod.not.safe.to.evict.annotation" 節點上的 Pod 具有 safe-to-evict=false 註解。 封鎖 Pod 的名稱。 如果可以安全地撤銷 Pod,請編輯 Pod 的資訊清單,並將註解更新為 "cluster-autoscaler.kubernetes.io/safe-to-evict": "true"
"no.scale.down.node.pod.kube.system.unmovable" Pod 並非 DaemonSet、並未建立鏡射,且 kube-system 命名空間中沒有 PodDisruptionBudget,因此已封鎖縮減作業。 封鎖 Pod 的名稱。

在 1.32.4-gke.1236000 之前的 GKE 版本中,叢集自動調度器不會移除 kube-system 命名空間中的 Pod。從 1.32.4-gke.1236000 版開始,叢集自動調整程式會在這些 Pod 建立一小時後,考慮移除這些 Pod。

如要解決這個問題,請為 kube-system Pod 新增 PodDisruptionBudget,或使用節點集區 Taint 和容許條件的組合,將 kube-system Pod 與應用程式 Pod 分開。詳情請參閱「錯誤:kube-system Pod 無法移動」。

"no.scale.down.node.pod.not.enough.pdb" Pod 中斷預算不足,因此已封鎖縮減作業。 封鎖 Pod 的名稱。 查看 Pod 的 PodDisruptionBudget,並考慮降低限制。詳情請參閱「錯誤:PodDisruptionBudget 不足」。
"no.scale.down.node.pod.controller.not.found" 找不到 Pod 控制器 (例如 Deployment 或 ReplicaSet),因此已封鎖縮減作業。 不適用 如要判斷在移除控制器後,哪些動作導致 Pod 繼續執行,請查看記錄。如要解決這個問題,請手動刪除 Pod。
"no.scale.down.node.pod.unexpected.error" 發生未預期的錯誤,因此 Pod 已封鎖縮減作業。 不適用 目前找不到發生這個錯誤的根本原因。 與 Cloud Customer Care 團隊聯絡, 進行深入調查。

進行進一步調查

下列各節提供指引,說明如何使用 Logs Explorer 和 gcpdiag,進一步瞭解錯誤。

在 Logs Explorer 中調查錯誤

如要進一步調查錯誤訊息,可以查看與錯誤相關的記錄:

  1. 前往 Google Cloud 控制台的「Logs Explorer」頁面。

    前往 Logs Explorer

  2. 查詢窗格中,輸入下列查詢:

    resource.type="k8s_cluster"
    log_id("container.googleapis.com/cluster-autoscaler-visibility")
    jsonPayload.resultInfo.results.errorMsg.messageId="ERROR_MESSAGE"
    

    ERROR_MESSAGE 替換為要調查的訊息。例如:scale.down.error.failed.to.delete.node.min.size.reached

  3. 點選「執行查詢」

使用 gcpdiag 偵錯部分錯誤

gcpdiag 是由技術工程師協助建立的開放原始碼工具。 Google Cloud這並非官方支援的 Google Cloud 產品。

如果遇到下列任一則錯誤訊息,請使用 gcpdiag 來排解問題:

  • scale.down.error.failed.to.evict.pods
  • no.scale.down.node.node.group.min.size.reached

如需所有 gcpdiag 工具旗標的清單和說明,請參閱 gcpdiag 使用說明

解決複雜的縮減錯誤

下列各節將提供指南,協助您解決需要多個緩解步驟的錯誤,以及沒有相關聯叢集自動調度器事件訊息的錯誤。

錯誤:叢集中的節點已達下限

如果看到下列錯誤,表示叢集自動配置器無法刪除節點,因為叢集中的節點數量已達下限:

通知

未充分運用節點的縮減作業已遭封鎖,因為叢集自動配置器已達到資源最低限制。

事件

"scale.down.error.failed.to.delete.node.min.size.reached"

如要解決這個問題,請查看並更新自動調度資源的最低限制:

  1. 在 Google Cloud 控制台中,前往「Kubernetes clusters」(Kubernetes 叢集) 頁面:

    前往 Kubernetes 叢集

  2. 按一下通知或 Cloud Logging 中識別的叢集名稱。

  3. 在「叢集詳細資料」頁面中,前往「節點」分頁。

  4. 查看「Number of nodes」(節點數量) 欄中的值,並與「Autoscaling」(自動調度資源) 欄中列出的節點數量下限進行比較。舉例來說,如果「自動調度資源」欄列出 4 到 6 個節點,而節點集區中的節點數量為 4,則節點集區的節點數量已達到下限,因此叢集自動配置器無法進一步縮減節點數量。

  5. 如果設定正確,且節點數量值等於為「自動調度資源」定義的最小值,叢集自動配置器就會正常運作。如果節點數量下限過高,不符合您的需求,請調低下限,讓節點可以縮減。

錯誤:沒有可移動 Pod 的位置

叢集自動調度器嘗試縮減節點,但節點上的 Pod 無法移至其他節點,因此無法縮減節點時,會發生下列錯誤:

通知

未充分運用的節點中有 Pod 無法移至叢集中的另一個節點,因此該節點的縮減作業已遭封鎖。

事件

"no.scale.down.node.no.place.to.move.pods"

如果不想重新安排這個 Pod 的時間,則會出現這則訊息,且不需要進行任何變更。如要重新排定 Pod 的時間,請在 Pod 的資訊清單中,調查 pod.spec block 的下列定義:

  • NodeAffinity:查看資源使用率偏低的節點上 Pod 的排程需求。您可以檢查 Pod 資訊清單,找出任何 NodeAffinity 或 NodeSelector 規則,藉此查看這些需求。如果 Pod 定義了 nodeSelector,且叢集中沒有其他節點 (來自其他節點集區) 符合這個選取器,叢集自動調度器就無法將 Pod 移至其他節點,進而無法移除任何未充分運用的節點。
  • maxPodConstraint:如果 maxPodConstraint 設定為 110 以外的號碼,請確認這項變更是否為預期。降低這個值會增加發生問題的機率。 如果叢集中的所有其他節點都已達到 maxPodConstraint 中定義的值,導致沒有空間可排定新的 Pod,叢集自動調度器就無法將 Pod 重新排定到其他節點。提高 maxPodConstraint 值可讓節點排程更多 Pod,叢集自動配置器也會有空間重新排程 Pod,並縮減使用率過低的節點。定義 maxPodConstraint 時,請注意每個節點上約有 10 個系統 Pod。
  • hostPort:為 Pod 指定 hostPort,表示該節點只能執行一個 Pod。如果節點的連接埠已在使用中,Pod 可能無法移至其他節點,因此叢集自動調整器可能難以減少節點數量。請放心,這是正常情況。
  • 臨時儲存空間:Pod 會使用臨時儲存空間儲存暫時資料。節點上的暫時性儲存空間不足,可能會阻礙 Pod 排程,並防止未充分運用的節點縮減。範例:如果 Pod 需要 6 GB 的臨時儲存空間,即使節點有足夠的 CPU 和記憶體資源,系統也不會將 Pod 排定在臨時儲存空間少於 6 GB 的節點上。如要減輕暫存空間限制,請增加節點的佈建暫存空間容量。確保 Pod 重新安置和資源調度作業有足夠的容量。

錯誤:kube-system Pod 無法移動

如果系統 Pod 阻止縮減作業,會發生下列錯誤:

通知

Pod 並非 DaemonSet、並未建立鏡射,且 kube-system 命名空間中沒有 PodDisruptionBudget,因此已封鎖縮減作業。

事件

"no.scale.down.node.pod.kube.system.unmovable"

kube-system 命名空間中的 Pod 視為系統 Pod。在 GKE 1.32.4-gke.1236000 以上版本中,叢集自動調度器可以撤除已執行至少一小時的系統 Pod,藉此縮減節點。在舊版 GKE 中,叢集自動調度器不會移除 kube-system 命名空間中的 Pod,這可能會無限期阻止縮減作業。

如要解決這項錯誤,請選擇下列任一解決方法:

  • kube-system Pod 新增 PodDisruptionBudget。如要進一步瞭解如何手動新增 PodDisruptionBudget Pod 的 kube-system,請參閱 Kubernetes 叢集自動調度資源常見問題

    建立 PodDisruptionBudget 可能會影響系統工作負載的可用性,導致叢集停機。叢集自動配置器會在縮減資源期間,將這些系統工作負載重新排定至其他工作站節點。

  • 結合使用節點集區 taint 和容許條件,將 kube-system Pod 與應用程式 Pod 分開。詳情請參閱「GKE 中的自動佈建節點功能」。

確認節點是否含有 kube-system Pod

如果不確定節點是否正在執行 kube-system Pod,並想進行驗證,請完成下列步驟:

  1. 前往 Google Cloud 控制台的「Logs Explorer」頁面。

    前往 Logs Explorer

  2. 按一下「查詢產生器」

  3. 使用下列查詢找出所有網路政策記錄:

    - resource.labels.location="CLUSTER_LOCATION"
    resource.labels.cluster_name="CLUSTER_NAME"
    logName="projects/PROJECT_ID/logs/container.googleapis.com%2Fcluster-autoscaler-visibility"
    jsonPayload.noDecisionStatus.noScaleDown.nodes.node.mig.nodepool="NODE_POOL_NAME"
    

    更改下列內容:

    • CLUSTER_LOCATION:叢集所在的區域。
    • CLUSTER_NAME:叢集名稱。
    • PROJECT_ID:叢集所屬專案的 ID。
    • NODE_POOL_NAME:節點集區的名稱。

    如果節點集區中正在執行 kube-system Pod,輸出內容會包含下列項目:

    "no.scale.down.node.pod.kube.system.unmovable"
    

錯誤:PodDisruptionBudget 不足

如果 PodDisruptionBudget 阻礙縮減規模,就會發生下列錯誤:

通知

未充分運用的節點含有因 Pod 中斷預算不足而無法移出的 Pod,因此該節點的縮減作業已遭封鎖。

事件

NoScaleDownNodePodNotEnoughPdb: "no.scale.down.node.pod.not.enough.pdb"

如要查看 PodDisruptionBudget 是否過於嚴格,請檢查其設定:

kubectl get pdb --all-namespaces

輸出結果會與下列內容相似:

NAMESPACE        NAME    MIN AVAILABLE   MAX UNAVAILABLE   ALLOWED DISRUPTIONS   AGE
example-app-one  one_pdb       N/A             1                 1               12d
example-app-two  two_pdb       N/A             0                 0               12d

在這個範例中,叢集自動配置器不會撤銷任何與 two_pdb 標籤選取器相符的 Pod。這個設定中的 maxUnavailable: 0 PodDisruptionBudget 會規定所有副本必須隨時保持可用狀態。此外,disruptionsAllowed: 0 禁止中斷這些 Pod。因此,執行這些 Pod 的節點無法縮減,否則會造成中斷並違反 PodDisruptionBudget

如果 PodDisruptionBudget 運作正常,則無須採取其他行動。如要調整 PodDisruptionBudget,以便移動使用率偏低的節點上的 Pod,請編輯 PodDisruptionBudget 的資訊清單。舉例來說,如果您已將 maxUnavailable 設為 0,可以將其變更為 1,讓叢集自動配置器縮減規模。

問題:節點處於封鎖狀態,且未移除

如果 Google 服務帳戶沒有編輯者角色,叢集自動配置器就無法縮減節點集區大小,並會發生類似下列的錯誤:

Required 'compute.instanceGroups.update' permission for 'INSTANCE_GROUP_NAME'.

這個問題的常見徵兆是叢集自動配置器嘗試縮減節點集區大小,但節點狀態沒有變更。

如要解決這個問題,請檢查預設服務帳戶 (PROJECT_NUMBER@cloudservices.gserviceaccount.com) 是否具有專案的「編輯者」角色 (roles/editor)。如果服務帳戶沒有這個角色,請新增。GKE 會使用這個服務帳戶管理專案的資源。如要瞭解如何執行這項操作,請參閱身分與存取權管理說明文件中的「授予或撤銷單一角色」。

後續步驟