排解水平自動調度 Pod 資源問題

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

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

如果您是設定 HorizontalPodAutoscaler 物件的應用程式開發人員,且需要確保應用程式能正確擴縮,請務必詳閱本文。此外,平台管理員和營運人員也能透過這項功能,排解影響所有自動調整規模工作負載的指標管道或叢集設定問題。如要進一步瞭解 Cloud de Confiance by S3NS 內容中提及的常見角色和範例工作,請參閱「常見的 GKE 使用者角色和工作」。

事前準備

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

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

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

  • 設定 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:您的 Cloud de Confiance by S3NS 專案 ID。

診斷 HorizontalPodAutoscaler 問題

如要診斷 HorizontalPodAutoscaler 的問題,請使用 kubectl 指令或 Cloud de Confiance 主控台檢查狀態和設定。

說明 HorizontalPodAutoscaler

如要查看即時計算結果和最近的調整規模決策,請使用 kubectl describe hpa 指令:

kubectl describe hpa HPA_NAME -n NAMESPACE_NAME

更改下列內容:

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

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

Name:                                                  php-apache-hpa
Namespace:                                             default
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:顯示目前指標值與目標的比較結果。<unknown> 指標值表示 HorizontalPodAutoscaler 尚未擷取指標,或指標管道已中斷。
  • Conditions:顯示 HorizontalPodAutoscaler 是否可以擷取指標 (AbleToScale) 及執行調整計算 (ScalingActive)。如果這些條件中有任何一個的狀態為 False,表示失敗。
  • Events:記錄 HorizontalPodAutoscaler 控制器的近期調度動作、警告和錯誤。您通常可以在這裡找到特定錯誤訊息或原因,例如 FailedGetScaleFailedGetResourceMetric

檢查 HorizontalPodAutoscaler 資訊清單

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

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

控制台

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

    前往物件瀏覽器

  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 設定要調整的 workload (例如 Deployment)。
    • minReplicasmaxReplicas:副本設定的最小值和最大值。
    • metrics:為擴充功能設定的指標 (例如 CPU 使用率或自訂指標)。
  • status (HorizontalPodAutoscaler 的即時狀態)
    • currentMetrics:HorizontalPodAutoscaler 最近觀察到的指標值。
    • currentReplicasdesiredReplicas:目前的 Pod 數量,以及 HorizontalPodAutoscaler 想要調整的數量。
    • conditions:顯示 HorizontalPodAutoscaler 的健康狀態:
      • AbleToScale:指出 HorizontalPodAutoscaler 是否能找到目標和指標。
      • ScalingActive:顯示 HorizontalPodAutoscaler 是否可計算及執行資源調度。
      • ScalingLimited:顯示 HorizontalPodAutoscaler 是否要擴大,但受到 minReplicasmaxReplicas 設定的限制。

查看事件記錄

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

  • 在 Cloud Logging 中查看 HorizontalPodAutoscaler 事件:使用記錄篩選器找出特定叢集的所有 HorizontalPodAutoscaler 事件。例如:

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

      前往 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 資源事件:這些記錄提供結構化且人類可讀的記錄,說明 HorizontalPodAutoscaler 如何計算建議,讓您深入分析其決策過程。

排解 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 因設定問題而無法計算所需副本,其 Events 區段會顯示 FailedComputeMetricsReplicas 原因,並顯示類似下列內容的訊息:

invalid metrics (1 invalid out of 1)

原因

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

解析度

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

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

不允許使用指標標籤

問題

您會看到下列錯誤:

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 的狀態中沒有特定的 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 物件名稱。

排解工作負載和服務錯誤

以下各節將說明目標工作負載或相關聯的服務所造成的錯誤,而非 HorizontalPodAutoscaler 物件本身。

缺少用於計算縮放比例的資源要求

問題

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

the HorizontalPodAutoscaler was unable to compute the replica count

原因

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

解析度

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

apiVersion: v1
kind: Pod
metadata:
  name: example-pod
# Multiple lines are omitted here
spec:
  containers:
  - name: example-container
    resources:
      requests:
        cpu: "100m"
        memory: "128Mi"

無法擷取 Pod 指標

問題

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

unable to fetch pod metrics for pod

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

原因

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

解析度

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

多個服務選取相同目標

問題

您會看到下列錯誤:

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 的目標 Deployment 名稱。
    • 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 欄位中新增不重複的標籤,讓目標服務的選取器成為唯一。然後,更新預期 Service 的 one spec.selector 欄位,加入這個新標籤。
    • 變更所有其他衝突服務的 spec.selector 欄位,使其他服務選取器更具限制性,不再與工作負載的 Pod 相符。
  4. 套用變更:

    kubectl apply -f MANIFEST_NAME
    

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

排解指標 API 和資料可用性問題

以下各節有助於解決 HorizontalPodAutoscaler 嘗試與指標 API 通訊或查詢指標後端時發生的錯誤。

排解自訂和外部指標問題

如果 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 的輸入流量 (位於 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 等監控工具,確認指標存在且名稱和標籤正確。

找不到指標版本或轉接程式無法使用

問題

您會發現下列錯誤:

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. 在 Cloud de Confiance 控制台中,查看叢集的健康狀態和狀態。

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

        前往 Kubernetes 叢集

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

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

    4. 查看 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. 確認應用程式活動:確認負責指標的應用程式在發生 HorizontalPodAutoscaler 警告的時間範圍期間運作正常,並嘗試將資料傳送至 Cloud Monitoring。
  4. 調查錯誤:檢查同一時間範圍內的應用程式記錄,找出與指標發布相關的明確錯誤,例如連線失敗、無效憑證或格式問題。

排解健康狀態良好但擴縮行為異常的問題

以下各節說明 HorizontalPodAutoscaler 設定有效且指標可用,但擴縮操作未如預期執行的情況。

HorizontalPodAutoscaler 運作正常,但不會調度資源

問題

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

原因

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

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

解析度

請嘗試下列解決方法:

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

HorizontalPodAutoscaler 無法縮減資源配置

問題

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

原因

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

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

解析度

請嘗試下列解決方法:

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

    kubectl describe hpa HPA_NAME -n NAMESPACE_NAME
    

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

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

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

後續步驟