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


本頁面說明如何診斷及解決問題,避免叢集自動調度器無法縮減 Google Kubernetes Engine (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. 選用:如要查看這個事件的記錄,請按一下「記錄」。這項動作會將您帶往記錄檔總管,並預先填入查詢內容,協助您進一步調查縮放事件。如要進一步瞭解縮減事件的運作方式,請參閱「查看叢集自動配置器事件」。

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

查看活動中的錯誤

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

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

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

    前往 Kubernetes 叢集

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

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

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

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

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

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

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

情境

一週前,您查看 GKE Enterprise 資訊主頁時,發現叢集只用了 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,因此已封鎖縮減作業。 封鎖 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 團隊聯絡,以進行深入調查。

進行進一步調查

下列各節提供指引,說明如何使用記錄檔探索工具和 gcpdiag,進一步瞭解錯誤。

在記錄檔探索工具中調查錯誤

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

  1. 前往 Google Cloud 控制台的「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 命名空間中的 Pod 沒有 Pod 中斷預算,因此已封鎖縮減作業。

事件

"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。如要進一步瞭解如何手動為 Pod 新增 PodDisruptionBudget kube-system,請參閱 Kubernetes 叢集自動配置器常見問題

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

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

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

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

  1. 前往 Google Cloud 控制台的「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。這個 PodDisruptionBudget 中的 maxUnavailable: 0 設定規定所有副本都必須隨時保持可用狀態。此外,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 會使用這個服務帳戶管理專案的資源。如要瞭解如何執行這項操作,請參閱 IAM 說明文件中的「授予或撤銷單一角色」一節。

後續步驟