排解水平 Pod 自動調度問題

如果 Google Kubernetes Engine (GKE) 中的 Pod 水平自動調度資源功能無法正常運作,工作負載可能就無法正確調度資源。這個問題可能會導致應用程式無法處理負載,進而造成效能問題或中斷。您可能會發現 CPU 使用率偏高,但 Pod 數量並未增加;HorizontalPodAutoscaler 狀態顯示的指標值為 <unknown>;或完全沒有發生調度作業。

本頁面說明如何診斷及解決水平 Pod 自動調度資源的常見問題,包括 HorizontalPodAutoscaler 物件的初始設定錯誤,以及指標管道中較複雜的故障。按照這些疑難排解步驟操作,有助於確保應用程式能根據需求有效率且可靠地調度資源,充分運用水平 Pod 自動調度器資源。

應用程式開發人員設定 HorizontalPodAutoscaler 物件時,需要確保應用程式能正確擴縮,因此這項資訊非常重要。此外,平台管理員和營運人員也能藉此排解指標管道或叢集設定的問題,這些問題會影響所有自動調整規模的工作負載。如要進一步瞭解我們在 Google Cloud 內容中提及的常見角色和範例工作,請參閱「常見的 GKE 使用者角色和工作」。

如果已出現症狀或看到錯誤訊息,請參閱下表,瞭解如何解決問題:

問題 可能的解決方法
未調整,但 HorizontalPodAutoscaler 條件為 True 排解運作正常但沒有回應的 HorizontalPodAutoscaler
您在 HorizontalPodAutoscaler 事件中看到特定錯誤訊息 排解常見的水平 Pod 自動調度資源錯誤
指標 <unknown> 排解自訂指標和外部指標的問題
未縮減 排解水平 Pod 自動調度資源功能無法縮減的問題

事前準備

  • 請務必搭配可調度的工作負載 (例如 Deployment 和 StatefulSet),使用 HorizontalPodAutoscaler 物件。您無法將水平 Pod 自動調度資源功能與無法調度資源的工作負載 (例如 DaemonSet) 搭配使用。
  • 如要取得在 GKE 中排解 Pod 水平自動調度問題所需的權限 (包括檢查 HorizontalPodAutoscaler 物件和查看叢集記錄),請要求管理員在專案中授予您下列 IAM 角色:

    • 檢查 GKE 資源: GKE 檢視者 (roles/container.viewer)
    • 查看叢集記錄: 「記錄檢視器」 (roles/logging.viewer)

    如要進一步瞭解如何授予角色,請參閱「管理專案、資料夾和機構的存取權」。

    您或許還可透過自訂角色或其他預先定義的角色取得必要權限。

  • 設定 kubectl 指令列工具,與 GKE 叢集通訊:

    gcloud container clusters get-credentials CLUSTER_NAME \
        --location LOCATION \
        --project PROJECT_ID
    

    更改下列內容:

    • CLUSTER_NAME:叢集名稱。
    • LOCATION:叢集的 Compute Engine 區域或可用區 (例如 us-central1us-central1-a)。
    • PROJECT_ID:您的 Google Cloud 專案 ID。

驗證水平 Pod 自動調度資源狀態和設定

請先檢查 HorizontalPodAutoscaler 物件的健康狀態和設定,再開始排解問題。這項初步檢查有助於找出並解決基本設定錯誤,這類錯誤是造成擴充問題的常見根本原因。

說明 HorizontalPodAutoscaler

如要查看 HorizontalPodAutoscaler 的即時計算結果和最近的調整大小決策,請使用 kubectl describe hpa 指令。這項指令會提供 HorizontalPodAutoscaler 物件的摘要,以及有助於診斷問題的 Events 記錄:

kubectl describe hpa HPA_NAME -n NAMESPACE_NAME

更改下列內容:

  • HPA_NAME:HorizontalPodAutoscaler 物件的名稱。
  • NAMESPACE_NAME:HorizontalPodAutoscaler 物件的命名空間。

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

Name:                                                  php-apache-hpa
Reference:                                             Deployment/php-apache
Metrics: ( current / target )
  resource cpu on pods (as a percentage of request):   1% (1m) / 50%
Min replicas:                                          1
Max replicas:                                          10
Conditions:
  Type            Status  Reason              Message
  ----            ------  ------              -------
  AbleToScale     True    ReadyForNewScale    recommended size matches current size
  ScalingActive   True    ValidMetricFound    the HorizontalPodAutoscaler was able to successfully calculate a replica count
Events:
  Type     Reason              Age   From                       Message
  ----     ------              ----  ----                       -------
  Normal   SuccessfulRescale   39m   horizontal-pod-autoscaler  New size: 4; reason: cpu resource utilization...
  Normal   SuccessfulRescale   26m   horizontal-pod-autoscaler  New size: 1; reason: cpu resource utilization...

輸出內容中的下列三個部分有助於診斷問題:

  • Metrics:這個部分會顯示目前的指標值,並與目標值比較。請在此處確認 HorizontalPodAutoscaler 是否收到資料。 <unknown> 指標值表示 HorizontalPodAutoscaler 尚未擷取指標,或指標管道已中斷。
  • Conditions:這項高階健康檢查會顯示 HorizontalPodAutoscaler 是否能擷取指標 (AbleToScale) 並執行資源調度計算 (ScalingActive)。如果這些條件中有任何一項的狀態為 False,表示發生故障。
  • Events:這個部分會記錄 HorizontalPodAutoscaler 控制器的近期調度動作、警告和錯誤。您通常可以在這裡找到特定錯誤訊息或原因,例如 FailedGetScaleFailedGetResourceMetric,有助於找出問題來源。

在 Deployment 中檢查 HorizontalPodAutoscaler 狀態

如要檢查與 Deployment 搭配使用的 HorizontalPodAutoscaler 物件狀態,請使用 Google Cloud 控制台:

  1. 前往 Google Cloud 控制台的「Workloads」(工作負載) 頁面。

    前往「Workloads」(工作負載)

  2. 按一下 Deployment 的名稱。

  3. 前往「詳細資料」分頁,然後找到「自動調度資源」部分。

  4. 查看「狀態」列中的值:

    • 綠色勾號表示 HorizontalPodAutoscaler 已設定完成,且可以讀取指標。
    • 黃色三角形表示已設定 HorizontalPodAutoscaler,但系統無法讀取指標。這是自訂或外部指標的常見問題。如要解決這個問題,請診斷指標無法使用的原因。詳情請參閱「排解自訂和外部指標的疑難」一節。

如為其他工作負載類型 (例如 StatefulSet),或如需更多詳細資料,請查看 HorizontalPodAutoscaler 物件的資訊清單。

檢查 HorizontalPodAutoscaler 的資訊清單

您可以透過 HorizontalPodAutoscaler 物件的 YAML 資訊清單,查看設定和目前狀態的相關資訊。

如要查看 YAML 資訊清單,請選取下列任一選項:

控制台

  1. 前往 Google Cloud 控制台的「物件瀏覽器」頁面。

    前往物件瀏覽器

  2. 在「物件種類」清單中,選取「HorizontalPodAutoscaler」核取方塊,然後按一下「確定」

  3. 前往 autoscaling API 群組,然後按一下「HorizontalPodAutoscaler」的展開箭頭。

  4. 按一下要檢查的 HorizontalPodAutoscaler 物件名稱。

  5. 查看「YAML」YAML部分,其中會顯示 HorizontalPodAutoscaler 物件的完整設定。

kubectl

執行下列指令:

kubectl get hpa HPA_NAME -n NAMESPACE_NAME -o yaml

更改下列內容:

  • HPA_NAME:HorizontalPodAutoscaler 物件的名稱。
  • NAMESPACE_NAME:HorizontalPodAutoscaler 物件的命名空間。

擷取資訊清單後,請尋找下列重要部分:

  • spec (您的設定)
    • scaleTargetRef:HorizontalPodAutoscaler 應調整的工作負載 (例如 Deployment)。
    • minReplicasmaxReplicas:副本設定的最小值和最大值。
    • metrics:您為調整大小設定的指標 (例如 CPU 使用率或自訂指標)。
  • status (HorizontalPodAutoscaler 的即時狀態)
    • currentMetrics:HorizontalPodAutoscaler 最近觀察到的指標值。
    • currentReplicasdesiredReplicas:目前的 Pod 數量,以及 HorizontalPodAutoscaler 想要擴充的數量。
    • conditions:這是最有價值的疑難排解區段。這個部分會顯示 HorizontalPodAutoscaler 的健康狀態:
      • AbleToScale:指出 HorizontalPodAutoscaler 是否能找到目標和指標。
      • ScalingActive:顯示 HorizontalPodAutoscaler 是否可計算及執行資源調度。
      • ScalingLimited:顯示 HorizontalPodAutoscaler 想要擴展,但受到 minReplicasmaxReplicas 設定限制。

使用進階記錄功能

如要深入瞭解 HorizontalPodAutoscaler 物件,請使用下列類型的記錄:

  • 在 Cloud Logging 中查看水平 Pod 自動配置器事件:使用記錄篩選器找出特定叢集的所有水平 Pod 自動配置器事件。例如:

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

      前往記錄檔探索工具

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

      resource.type="k8s_cluster"
      resource.labels.cluster_name="CLUSTER_NAME"
      resource.labels.location="LOCATION"
      logName="projects/PROJECT_ID/logs/events"
      jsonPayload.involvedObject.kind="HorizontalPodAutoscaler"`
      

      更改下列內容:

      • CLUSTER_NAME:HorizontalPodAutoscaler 所屬的叢集名稱。
      • LOCATION:叢集的 Compute Engine 區域或可用區 (例如 us-central1us-central1-a)。
      • PROJECT_ID:您的專案 ID。
    3. 按一下「執行查詢」並查看輸出內容。

  • 查看水平自動調度 Pod 資源事件:這些記錄提供結構化且容易解讀的記錄,說明水平自動調度 Pod 資源如何計算建議,並深入瞭解其決策程序。

排解健康狀態良好但沒有回應的 HorizontalPodAutoscaler

本節有助於診斷 HorizontalPodAutoscaler 可能未觸發任何調整動作的原因,即使該工具看似運作正常,且狀態或事件中未回報任何錯誤。

症狀

HorizontalPodAutoscaler 狀態良好,條件會回報 True,且事件中沒有任何錯誤。不過,系統仍不會採取任何縮放動作。

原因

造成這項預期行為的因素包括:

  • 副本限制:目前的副本數量已達到 HorizontalPodAutoscaler 設定中 minReplicasmaxReplicas 欄位設定的界線。
  • 容許範圍:Kubernetes 預設會使用 10% 的容許範圍,避免因指標的微小波動而進行資源調度。只有在目前指標與目標指標的比率超出 0.9 至 1.1 範圍時,系統才會進行擴充。舉例來說,如果目標是 85% 的 CPU,目前使用率為 93%,則比率約為 1.094 (93/85≈1.094)。由於這個值小於 1.1,因此水平 Pod 自動調度器不會向上調度資源。
  • 未就緒的 Pod:水平 Pod 自動調度器只會將狀態為 Ready 的 Pod 納入資源調度計算。如果 Pod 卡在 Pending 狀態,或因健康狀態檢查失敗或資源問題而未變成 Ready,系統會忽略這些 Pod,並可能導致無法擴充。
  • 同步處理週期延遲:HorizontalPodAutoscaler 控制器會定期檢查指標。指標超過門檻與啟動調整規模動作之間,有 15 到 30 秒的延遲是正常現象。
  • 新指標延遲時間:當 HorizontalPodAutoscaler 首次使用新的自訂指標時,可能會出現幾分鐘的延遲。發生延遲的原因是,監控系統 (例如 Cloud Monitoring) 必須在寫入第一個資料點時建立新的時間序列。
  • 計算多個指標:設定多個指標時,Horizontal Pod Autoscaler 會分別計算每個指標所需的備用資源數量,然後選擇最高的計算值做為最終的備用資源數量。因此,工作負載會根據需求最高的指標進行調整,舉例來說,如果 CPU 指標計算出需要 9 個副本,但每秒要求數指標計算出需要 15 個副本,則水平 Pod 自動調度器會將 Deployment 擴充至 15 個副本。

解決方法

請嘗試下列解決方案:

  • 副本限制:檢查 HorizontalPodAutoscaler 資訊清單或 kubectl describe 指令輸出中的 minReplicasmaxReplicas 值。如果這些限制阻礙了必要的擴充作業,請調整限制。
  • 容許範圍:如果需要在預設容許範圍內縮放,請設定不同的容許值。 否則,請等待指標移出 0.9 至 1.1 的比率範圍。
  • 未就緒的 Pod:調查 Pod 為 Pending 或非 Ready 的原因,並解決根本問題 (例如資源限制、就緒探查失敗)。如需疑難排解提示,請參閱 Kubernetes 說明文件中的「偵錯 Pod」。
  • 同步處理期間延遲和新指標延遲時間:這些延遲時間為正常現象。 等待同步處理週期完成,或建立新的自訂指標時間序列。
  • 計算多項指標:這是預期行為。如果擴充是根據某項指標 (例如每秒要求數) 進行,系統會正確地覆寫另一項指標的較低計算結果 (例如 CPU)。

排解常見的水平 Pod 自動調度資源錯誤

以下各節提供特定錯誤訊息和事件原因的解決方法,這些訊息和原因可能會在您檢查 HorizontalPodAutoscaler 的狀態時出現。這些訊息通常會顯示在 kubectl describe hpa 指令輸出內容的 Events 區段中。

排解水平 Pod 自動調度資源設定錯誤

HorizontalPodAutoscaler 資訊清單設定錯誤 (例如欄位輸入錯誤或設定衝突),會導致這個部分發生錯誤。

錯誤:指標無效

如果 HorizontalPodAutoscaler 內的指標設定語法有誤或不一致,您可能會看到這項錯誤。

症狀

如果 HorizontalPodAutoscaler 因設定問題而無法計算所需副本,其 Events 區段會顯示 FailedComputeMetricsReplicas 原因,並顯示類似下列的訊息:

invalid metrics (1 invalid out of 1)

原因

這項錯誤通常表示指標 type 與您在 HorizontalPodAutoscaler 資訊清單中定義的 target 不符。舉例來說,您可能已指定 typeUtilization,但提供的目標值卻是 averageValue,而非 averageUtilization

解決方法

修正 HorizontalPodAutoscaler 資訊清單,讓 target 欄位的值與指標 type 一致:

  • 如果 typeUtilization,則 target 欄位中的值必須為 averageUtilization
  • 如果 typeAverageValue,則 target 欄位中的值必須為 averageValue

錯誤:多個服務選取相同目標

使用以流量為準的自動調度功能時,如果 HorizontalPodAutoscaler 的服務設定有誤,可能會看到這項錯誤。

症狀

您會發現下列錯誤:

multiple services selecting the same target of HPA_NAME: SERVICE_NAME

這項輸出內容包含下列值:

  • HPA_NAME:HorizontalPodAutoscaler 的名稱。
  • SERVICE_NAME:服務名稱。

原因

已設定以流量為準的自動調度資源,但有多個 Kubernetes 服務以 HorizontalPodAutoscaler 的 scaleTargetRef 欄位為目標。以流量為準的自動調整功能僅支援服務與自動調整工作負載之間的一對一關係。

解決方法

如要修正這個問題,請確認只有一個 Service 的標籤選取器與工作負載的 Pod 相符:

  1. 找出工作負載的 Pod 標籤:

    kubectl get deployment HPA_TARGET_DEPLOYMENT \
        -n NAMESPACE \
        -o jsonpath='{.spec.template.metadata.labels}'
    

    更改下列內容:

    • HPA_TARGET_DEPLOYMENT:HorizontalPodAutoscaler 的目標部署作業名稱。
    • NAMESPACE:Deployment 的命名空間。

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

    {"app":"my-app", "env":"prod"}
    
  2. 查看命名空間中所有服務的 spec.selector 欄位,找出符合這些標籤的所有服務。

    kubectl get services -n NAMESPACE -o yaml
    

    找出選取器與上一步驟標籤相符的所有 Service。舉例來說,{"app": "my-app"}{"app": "my-app", "env": "prod"} 都會符合範例 Pod 標籤。

  3. 請選擇下列其中一個選項,解決衝突:

    • 在 Deployment 的 spec.template.metadata.labels 欄位中新增專屬標籤,讓目標服務的選取器成為專屬選取器。然後更新預期服務的 spec.selector 欄位,加入這個新標籤。
    • 變更所有衝突其他服務的 spec.selector 欄位,使其他服務選取器更具限制性,不再與工作負載的 Pod 相符。
  4. 套用變更:

    kubectl apply -f MANIFEST_NAME
    

    MANIFEST_NAME 替換為包含更新後服務或 Deployment 資訊清單的 YAML 檔案名稱。

錯誤:不允許使用標籤

症狀

您會發現下列錯誤:

unable to fetch metrics from external metrics API: googleapi: Error 400: Metric label: 'LABEL_NAME' is not allowed

在這個輸出內容中,LABEL_NAME 是不正確標籤的名稱。

原因

HorizontalPodAutoscaler 資訊清單的 metric.selector.matchLabels 區段指定了無效的標籤鍵,而 Cloud Monitoring 無法辨識或允許將這個鍵用於指標。

解決方法

如要解決這個問題,請按照下列步驟操作:

  1. 從錯誤訊息中找出遭拒的標籤名稱。
  2. 請在 HorizontalPodAutoscaler 資訊清單的 metric.selector.matchLabels 區段中移除或修正這個標籤鍵。
  3. 請參閱該指標的 Cloud Monitoring 說明文件,找出可供篩選的有效標籤鍵。

問題:多個 HorizontalPodAutoscaler 指向相同的工作負載

設定多個 HorizontalPodAutoscaler 物件來管理相同的工作負載,會導致資源調度行為衝突且無法預測。

症狀

HorizontalPodAutoscaler 的狀態中沒有特定的 ConditionReason 會直接指出這項衝突。不過,您可能會發現下列症狀:

  • 工作負載的副本數量可能會意外波動。
  • 資源調度決策可能與任何單一 HorizontalPodAutoscaler 中定義的指標不符。
  • 查看事件時,您可能會看到來自不同 HorizontalPodAutoscaler 物件的交替或矛盾事件。SuccessfulRescale

原因

如果同一命名空間內有多個 HorizontalPodAutoscaler 物件,且這些物件在 spec.scaleTargetRef 欄位中指定完全相同的工作負載,就會發生這個問題。每個 HorizontalPodAutoscaler 都會獨立計算備用資源數量,並根據自身的一組指標和目標嘗試調整工作負載。Kubernetes 不會封鎖這項設定,但會導致擴縮調整不穩定,因為 HorizontalPodAutoscaler 會彼此競爭。

解決方法

為避免發生衝突,請在單一 HorizontalPodAutoscaler 物件中定義所有縮放指標。每個 HorizontalPodAutoscaler 都會根據自己的 spec.metrics 欄位計算調度資源需求,因此合併這些欄位可讓所選的 HorizontalPodAutoscaler 物件一併考量所有因素,例如 CPU 和每秒要求數:

  1. 如要找出以相同工作負載為目標的 HorizontalPodAutoscaler,請取得每個 HorizontalPodAutoscaler 物件的 YAML 資訊清單。請密切注意輸出內容中的 spec.scaleTargetRef 欄位。

    kubectl get hpa -n NAMESPACE_NAME -o yaml
    

    NAMESPACE_NAME 替換為 HorizontalPodAutoscaler 物件的命名空間。

    找出任何 HorizontalPodAutoscaler 資源,這些資源在 scaleTargetRef 欄位中,apiVersionkindname 的值相同。

  2. 將指標合併為單一 HorizontalPodAutoscaler 物件:

    1. 選擇要保留的 HorizontalPodAutoscaler 物件。您要修改的 HorizontalPodAutoscaler 就是這個。
    2. 檢查以相同工作負載為目標的其他 HorizontalPodAutoscaler 物件資訊清單中的 spec.metrics 區段。
    3. 從重複的 HorizontalPodAutoscaler 物件的 spec.metrics 區段中,複製要保留的指標定義。
    4. 將複製的指標定義貼到您決定保留的 HorizontalPodAutoscaler 的 spec.metrics 陣列中。
  3. 套用變更:

    kubectl apply -f MANIFEST_NAME
    

    MANIFEST_NAME 替換為您決定保留的 HorizontalPodAutoscaler 資訊清單名稱。

  4. 刪除以相同工作負載為目標的其他 HorizontalPodAutoscaler 物件:

    kubectl delete hpa DUPLICATE_MANIFEST_NAME -n NAMESPACE_NAME
    

    DUPLICATE_MANIFEST_NAME 替換為要刪除的多餘 HorizontalPodAutoscaler 物件名稱。

排解工作負載和目標錯誤

這個區段中的錯誤是由於 Deployment、StatefulSet 或 Pod 正在調整,而非 HorizontalPodAutoscaler 物件本身。

錯誤:無法取得目標的目前比例

如果 HorizontalPodAutoscaler 找不到或無法存取應要擴展的工作負載,您可能會看到這則錯誤訊息。

症狀

Events 區段的條件為 FailedGetScale,訊息類似於:

the HorizontalPodAutoscaler controller was unable to get the target's current scale: WORKLOAD_TYPE.apps "TARGET_WORKLOAD" not found

這項輸出內容包含下列值:

  • WORKLOAD_TYPE:工作負載類型,例如 DeploymentStatefulSet
  • TARGET_WORKLOAD:工作負載的名稱。

原因

HorizontalPodAutoscaler 控制器找不到設定要管理的工作負載 (例如 Deployment 或 StatefulSet)。這個問題是由 HorizontalPodAutoscaler 資訊清單中的 scaleTargetRef 欄位所致。指定的資源可能不存在、已遭刪除,或有拼字錯誤。

解決方法

請嘗試下列解決方案:

  1. 驗證 HorizontalPodAutoscaler 資訊清單的 scaleTargetRef 欄位:確認 scaleTargetRef 欄位中的 namekindapiVersion 值,與目標工作負載的對應中繼資料完全相符。如果工作負載名稱有誤,請更新 HorizontalPodAutoscaler 的 scaleTargetRef 欄位,指向正確名稱。
  2. 確認工作負載存在:確認目標工作負載與 HorizontalPodAutoscaler 位於相同命名空間。您可以使用 kubectl get deployment DEPLOYMENT_NAME 等指令檢查此結果。如果您有意刪除工作負載,請刪除對應的 HorizontalPodAutoscaler 物件,以清除叢集。如果需要重新建立工作負載,HorizontalPodAutoscaler 會在工作負載可用時自動找到,並解決錯誤。
  3. 確認 HorizontalPodAutoscaler 和工作負載位於相同命名空間:HorizontalPodAutoscaler 和目標工作負載必須位於相同命名空間。如果使用 kubectl 指令建立物件時忘記指定命名空間,Kubernetes 會將物件放在 default 命名空間。如果 HorizontalPodAutoscaler 位於 default 命名空間,而工作負載位於其他命名空間,或反過來,就可能導致不符。檢查兩個物件的命名空間,並確認兩者相符。

HorizontalPodAutoscaler 成功找到目標後,條件 AbleToScale 會變成 True,訊息也會變更為 the HorizontalPodAutoscaler controller was able to get the target's current scale

錯誤:無法計算副本數量

當 HorizontalPodAutoscaler 需要根據資源使用率計算調度作業,但缺少 Pod 的必要基準資訊時,可能會出現這項錯誤。

症狀

ScalingActive 條件為 FalseReasonFailedGetResourceMetric。您通常也會看到類似下列內容的訊息:

the HorizontalPodAutoscaler was unable to compute the replica count

原因

Horizontal Pod Autoscaler 需要計算資源使用率百分比,才能調度工作負載,但由於 Pod 規格中至少有一個容器缺少相應資源 (cpumemory) 的 resources.requests 定義,因此無法執行這項計算。

解決方法

如要解決這個問題,請更新 Deployment、StatefulSet 或其他控制器中的 Pod 資訊清單,加入資源 (cpumemory) 的 resources.requests 欄位,HorizontalPodAutoscaler 會嘗試擴充 Pod 中所有容器的資源。例如:

apiVersion: v1
kind: Pod
metadata:
  name: example-pod
spec:
  containers:
  - name: example-container
...
    resources:
      requests:
        cpu: "100m"
        memory: "128Mi"

錯誤:無法擷取 Pod 的 Pod 指標

如果系統無法擷取 HorizontalPodAutoscaler 做出擴縮決策所需的指標,您可能會看到這則錯誤訊息。這通常與 Pod 資源定義有關。

症狀

您會看到類似下列內容的持續性訊息:

unable to fetch pod metrics for pod

指標伺服器啟動時,暫時顯示這則訊息是正常現象。

原因

如要根據資源使用率百分比 (例如 cpumemory) 調整資源配置,HorizontalPodAutoscaler 物件鎖定的 Pod 內每個容器,都必須為該特定資源定義 resources.requests 欄位。否則,HorizontalPodAutoscaler 無法執行所需計算,也不會針對該指標採取任何動作。

解決方法

如果這些錯誤訊息持續顯示,且您發現 Pod 未針對工作負載進行擴縮,請確認您已為工作負載中的每個容器指定資源要求

排解指標 API 和資料可用性錯誤

以下各節有助於解決 HorizontalPodAutoscaler 嘗試從指標 API 擷取資料時發生的錯誤。這些問題包括內部叢集通訊失敗 (導致指標 API 無法使用),以及指標供應商拒絕的無效查詢 (通常會顯示為 400 級別的 HTTP 錯誤)。

錯誤:找不到可用的指標版本

症狀

您會發現下列錯誤:

unable to fetch metrics from custom metrics API: no known available metric versions found

原因

這項錯誤表示叢集內的通訊中斷,而非指標來源 (例如 Cloud Monitoring) 有問題。常見原因包括:

  • Kubernetes API 伺服器暫時無法使用 (例如在叢集升級或控制層修復期間)。
  • 指標介面卡 Pod (例如 custom-metrics-stackdriver-adapter) 狀況不佳、未執行,或未向 API 伺服器正確註冊。

解決方法

這個問題通常只是暫時性的。如果問題仍未解決,請嘗試下列解決方案:

  1. 檢查 Kubernetes 控制層的健康狀態

    1. 在 Google Cloud 控制台中,查看叢集的健康狀態和狀態。

      1. 前往「Kubernetes clusters」(Kubernetes 叢集) 頁面

        前往 Kubernetes 叢集

      2. 檢查叢集的「狀態」和「通知」欄。

      3. 按一下「通知」,查看是否有正在進行的作業,例如升級或維修。在這些時間,API 伺服器可能會暫時無法使用。

    2. 查看 Cloud 稽核記錄,瞭解是否有與控制平面元件相關的錯誤。如要瞭解如何查看這些記錄,請參閱 GKE 稽核記錄資訊

  2. 檢查指標轉接器 Pod 的健康狀態和記錄:確認指標轉接器 Pod 處於 Running 狀態,且近期未重新啟動:

    kubectl get pods -n custom-metrics,kube-system -o wide
    

    如果 Pod 的狀態不是 Running,或是重新啟動次數過多,請調查 Pod 以找出根本原因。如需疑難排解提示,請參閱 Kubernetes 說明文件的「偵錯 Pod」一節。

  3. 確認指標 API 已註冊並可供使用

    kubectl get apiservice | grep metrics.k8s.io
    

    如果指標 API 運作正常,輸出結果會與下列內容相似:

    NAME                            SERVICE                                             AVAILABLE   AGE
    v1beta1.custom.metrics.k8s.io   custom-metrics/custom-metrics-stackdriver-adapter   True        18d
    v1beta1.external.metrics.k8s.io custom-metrics/custom-metrics-stackdriver-adapter   True        18d
    v1beta1.metrics.k8s.io          kube-system/metrics-server                          True        18d
    

    如果 AVAILABLE 欄的值為 False,完整 APIService 資訊清單中的 Message 欄可能會提供更多詳細資料。

    您可以使用下列指令查看完整資訊清單:

    kubectl get apiservice API_SERVICE_NAME -o yaml
    

    API_SERVICE_NAME 改為 APIService 物件的名稱,例如 v1beta1.custom.metrics.k8s.io

錯誤:查詢不會傳回任何時間序列

症狀

您會發現下列錯誤:

unable to fetch metrics from custom or external metrics API: googleapi: Error
400: The supplied filter [...] query will not return any time series

原因

傳送至 Cloud Monitoring 的查詢有效,但未傳回任何資料。這表示沒有符合篩選條件的資料點 (這與找到值為 0 的指標不同)。造成這個問題最可能的原因是,負責產生自訂指標的應用程式或工作負載,在回報錯誤期間未將資料寫入 Cloud Monitoring。

解決方法

請嘗試下列解決方案:

  1. 驗證設定:確認 HorizontalPodAutoscaler 物件中的指標名稱和標籤,與應用程式發出的指標名稱和標籤完全相符。
  2. 檢查權限:確認應用程式已正確設定必要權限和 API 端點,可將指標發布至 Cloud Monitoring。
  3. 確認應用程式活動:確認負責指標的應用程式在發生 Horizontal Pod Autoscaler 警告的時間範圍內,是否正常運作並嘗試將資料傳送至 Cloud Monitoring。
  4. 調查錯誤:檢查同一時間範圍內的應用程式記錄,找出與指標發布相關的明確錯誤,例如連線失敗、憑證無效或格式問題。

排解自訂和外部指標問題

如果 HorizontalPodAutoscaler 依據的指標來自預設 CPU 或記憶體以外的來源,自訂或外部指標管道可能會發生問題。這個管道包含 HorizontalPodAutoscaler 控制器、Kubernetes 指標 API 伺服器、指標轉接器和指標來源 (例如 Cloud Monitoring 或 Prometheus),如下圖所示:

HPA 指標管道,顯示元件:HPA 控制器、Kubernetes API 伺服器、指標介面卡和指標來源。

本節將詳細說明如何偵錯這個管道,從指標介面卡到指標來源。

症狀

指標管道發生問題時,最常見的症狀如下:

  • 指標值會顯示為 <unknown>
  • HorizontalPodAutoscaler 事件會顯示 FailedGetExternalMetricFailedGetCustomMetric 等錯誤。

原因

自訂或外部指標管道發生問題。

解決方法

請按照下列步驟偵錯管道:

  1. 檢查指標介面卡是否已註冊並可供使用:指標介面卡必須向主要的 Kubernetes API 伺服器註冊,才能提供指標。這是最直接的方法,可查看轉接程式是否正在執行,以及 API 伺服器是否可連上轉接程式:

    kubectl get apiservice | grep -E 'NAME|metrics.k8s.io'
    

    輸出內容應會顯示 v1beta1.custom.metrics.k8s.iov1beta1.external.metrics.k8s.io 項目,以及 Available 欄中的 True 值。例如:

    NAME                   SERVICE                      AVAILABLE   AGE
    v1beta1.metrics.k8s.io kube-system/metrics-server   True        18d
    
    • 如果「Available」欄中的值為 False 或遺失,您的轉接程式可能已當機或設定錯誤。在 kube-systemcustom-metrics 命名空間中,檢查介面卡的 Pod 記錄,找出與權限、指標來源的網路連線,或指出找不到指標的訊息相關的錯誤。

    • 如果值為 True,請繼續下一個步驟。

  2. 直接查詢指標 API:如果轉接器可用,請略過 HorizontalPodAutoscaler,直接向 Kubernetes API 索取指標。這項指令會測試整個管道,包括 API 伺服器、指標介面卡和資料來源。

    如要查詢外部指標,請執行下列指令:

    kubectl get --raw "/apis/external.metrics.k8s.io/v1beta1/namespaces/NAMESPACE_NAME/METRIC_NAME" | jq .
    

    如要查詢自訂 Pod 指標,請執行下列指令:

    kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/namespaces/NAMESPACE_NAME/pods/*/METRIC_NAME" | jq .
    

    更改下列內容:

    • NAMESPACE_NAME:Pod 執行的命名空間。
    • METRIC_NAME:您要查詢的自訂或外部指標名稱。例如 requests_per_secondqueue_depth
  3. 分析指令輸出內容:先前指令的結果會指出問題所在。請選擇與輸出內容相符的情境:

    • JSON 回應成功並傳回值:指標管道運作正常。問題可能出在 HorizontalPodAutoscaler 資訊清單的設定。檢查指標名稱是否有錯字,或 matchLabels 是否不正確。
    • Error: Error from server (Service Unavailable):這項錯誤通常表示網路連線問題,如果叢集使用網路隔離,通常是防火牆問題。

      1. 找出指標轉接器服務。通常位於 custom-metricskube-system 命名空間:

        kubectl get service -n custom-metrics,kube-system | grep -E 'adapter|metrics'
        
      2. 找出轉接程式監聽的通訊埠:

        kubectl get service ADAPTER_SERVICE -n ADAPTER_NAMESPACE -o yaml
        

        更改下列內容:

        • ADAPTER_SERVICE:與您部署的指標介面卡相關聯的 Kubernetes Service 名稱。這個 Service 是您在上一個步驟中找到的 Service。這項服務會將介面卡的函式庫公開給叢集其他部分,包括 Kubernetes API 伺服器。
        • ADAPTER_NAMESPACE:轉接程式服務所在的命名空間 (例如 custom-metricskube-system)。
      3. 找出叢集控制層的傳入防火牆規則:

        gcloud compute firewall-rules list \
            --filter="name~gke-CLUSTER_NAME-[0-9a-z]*-master"
        

        CLUSTER_NAME 換成叢集名稱。

      4. 將轉接程式的 targetPort 新增至規則:

        1. 說明目前的規則,查看現有允許的通訊埠:

          gcloud compute firewall-rules describe FIREWALL_RULE_NAME
          

          請將 FIREWALL_RULE_NAME 替換為防火牆規則的名稱,該規則會控管 Kubernetes 叢集控制平面的網路流量。

        2. 更新規則,將轉接器連接埠新增至清單:

          gcloud compute firewall-rules update FIREWALL_RULE_NAME \
              --allow tcp:443,tcp:10250,tcp:ADAPTER_PORT
          

          ADAPTER_PORT 替換為指標轉接程式監聽的網路連接埠。

      5. 確認 Kubernetes 網路政策未封鎖傳送至指標介面卡 Pod 的流量:

        kubectl get networkpolicy -n custom-metrics,kube-system
        

        檢查所有政策,確保允許從控制層或 API 伺服器到 ADAPTER_SERVICE 的 Ingress 流量 (位於 ADAPTER_PORT 上)。

    • 空白清單 []:這項輸出內容表示配接器正在執行,但無法擷取特定指標,這表示配接器設定或指標來源本身有問題。

      • 介面卡 Pod 問題:檢查指標介面卡 Pod 或 Pod 的記錄,找出與 API 呼叫、驗證或指標擷取相關的錯誤。如要檢查記錄,請執行下列操作:

        1. 找出轉接器 Pod 的名稱:

          kubectl get pods -n ADAPTER_NAMESPACE
          
        2. 查看記錄:

          kubectl logs ADAPTER_POD_NAME \
              -n ADAPTER_NAMESPACE
          

          更改下列內容:

          • ADAPTER_POD_NAME:您在上一步中識別的轉接程式 Pod 名稱。
          • ADAPTER_NAMESPACE:轉接程式 Pod 所在的命名空間 (例如 custom-metricskube-system)。
      • 來源沒有資料:來源系統中可能沒有該指標。使用監控工具 (例如 Metrics Explorer),確認指標存在且名稱和標籤正確無誤。

排解水平 Pod 自動配置器無法縮減的問題

本節說明 HorizontalPodAutoscaler 可能無法如預期縮減工作負載的原因。

症狀

HorizontalPodAutoscaler 成功調度工作負載,但即使 CPU 使用率等指標偏低,也無法調度回來。

原因

這項設計是為了避免快速擴大/縮減或根據不完整資訊縮減規模。主要原因有二:

  • 使用多個指標:水平 Pod 自動調度器會根據最多備用資源的指標進行調度。如有多項指標,除非所有指標都指出需要減少副本數量,否則工作負載不會縮減。即使其他指標偏低,只要有一個指標需要大量副本,系統就不會縮減副本數量。
  • 無法使用的指標:如果任何指標無法使用 (通常會顯示為 <unknown>),水平 Pod 自動調度器會保守地拒絕縮減工作負載。這項功能無法判斷指標是否遺失,是因為使用量確實為零,還是指標管道發生問題。以速率為準的自訂指標 (例如 messages_per_second) 經常會發生這個問題,因為這類指標在沒有活動時會停止回報資料,導致水平 Pod 自動調度器將指標視為無法使用,並停止縮減作業。
  • 資源調度政策的縮減延遲:HorizontalPodAutoscaler 的 behavior 欄位可讓您設定資源調度政策。縮減的預設政策包含 300 秒 (五分鐘) 的穩定期。在這段期間,即使指標值低於目標門檻,HorizontalPodAutoscaler 也不會減少副本數量。這個時間範圍可避免快速波動,但縮減規模的速度可能會比預期慢。

解決方法

請嘗試下列解決方案:

  1. 如果有多個指標或指標無法使用,請診斷造成問題的指標:

    kubectl describe hpa HPA_NAME -n NAMESPACE_NAME
    

    在輸出結果中,查看 Metrics 區段中狀態為 <unknown> 的指標,以及 Events 區段中類似 FailedGetCustomMetricFailedGetExternalMetric 的警告。如要詳細瞭解如何偵錯管道,請參閱「排解自訂和外部指標的疑難」一節。

  2. 如果指標在流量偏低時無法使用 (以比率為準的指標通常會發生這種情況),請嘗試下列其中一種解決方案:

    • 請盡可能使用以計量表為準的指標,而非以速率為準的指標。量規指標 (例如佇列中的訊息總數,如 subscriptionnum_undelivered_messages) 會持續回報值,即使該值為 0 也是如此,因此水平 Pod 自動調度器可以根據這些指標做出可靠的調度決策。
    • 確認指標來源回報零值。如果您控管自訂指標,請將指標設為在閒置期間發布 0,而不是完全不傳送資料。
  3. 如要縮短資源調度政策的縮減延遲時間,如果縮減的預設五分鐘穩定時間範圍太長,請自訂該時間範圍。檢查 HorizontalPodAutoscaler 資訊清單的 spec.behavior.scaleDown 區段。您可以降低 stabilizationWindowSeconds,讓自動調度器在指標下降後更快縮減規模。如要進一步瞭解如何設定這些政策,請參閱 Kubernetes 說明文件中的「擴縮政策」。

後續步驟