全部產品
Search
文件中心

Container Service for Kubernetes:工作負載伸縮FAQ

更新時間:Oct 30, 2024

本文介紹使用工作負載伸縮功能(包括HPA、CronHPA等)時可能遇到的常見問題及解決方案。

索引

HPA的監控資料current欄位為何顯示為unknown

當HPA的監控資料的current欄位顯示為unknown時,表示kube-controller-manager無法訪問監控資料來源擷取對應的監控資料,HPA擴縮容時會失敗。

Name:                                                  kubernetes-tutorial-deployment
Namespace:                                             default
Labels:                                                <none>
Annotations:                                           <none>
CreationTimestamp:                                     Mon, 10 Jun 2019 11:46:48  0530
Reference:                                             Deployment/kubernetes-tutorial-deployment
Metrics:                                               ( current / target )
  resource cpu on pods  (as a percentage of request):  <unknown> / 2%
Min replicas:                                          1
Max replicas:                                          4
Deployment pods:                                       1 current / 0 desired
Conditions:
  Type           Status  Reason                   Message
  ----           ------  ------                   -------
  AbleToScale    True    SucceededGetScale        the HPA controller was able to get the target's current scale
  ScalingActive  False   FailedGetResourceMetric  the HPA was unable to compute the replica count: unable to get metrics for resource cpu: unable to fetch metrics from resource metrics API: the server is currently unable to handle the request (get pods.metrics.k8s.io)
Events:
  Type     Reason                   Age                      From                       Message
  ----     ------                   ----                     ----                       -------
  Warning  FailedGetResourceMetric  3m3s (x1009 over 4h18m)  horizontal-pod-autoscaler  unable to get metrics for resource cpu: unable to fetch metrics from resource metrics API: the server is currently unable to handle the request (get pods.metrics.k8s.io)

原因一:Resource Metrics資料來源無法使用

請先執行命令kubectl top pod檢查是否返回資料。如果所有的Pod都無資料,請執行kubectl get apiservice檢查當前提供Resource Metrics的資料來源的情況。返回的樣本資料如下。

展開查看返回的樣本資料

NAME                                   SERVICE                      AVAILABLE   AGE
v1.                                    Local                        True        29h
v1.admissionregistration.k8s.io        Local                        True        29h
v1.apiextensions.k8s.io                Local                        True        29h
v1.apps                                Local                        True        29h
v1.authentication.k8s.io               Local                        True        29h
v1.authorization.k8s.io                Local                        True        29h
v1.autoscaling                         Local                        True        29h
v1.batch                               Local                        True        29h
v1.coordination.k8s.io                 Local                        True        29h
v1.monitoring.coreos.com               Local                        True        29h
v1.networking.k8s.io                   Local                        True        29h
v1.rbac.authorization.k8s.io           Local                        True        29h
v1.scheduling.k8s.io                   Local                        True        29h
v1.storage.k8s.io                      Local                        True        29h
v1alpha1.argoproj.io                   Local                        True        29h
v1alpha1.fedlearner.k8s.io             Local                        True        5h11m
v1beta1.admissionregistration.k8s.io   Local                        True        29h
v1beta1.alicloud.com                   Local                        True        29h
v1beta1.apiextensions.k8s.io           Local                        True        29h
v1beta1.apps                           Local                        True        29h
v1beta1.authentication.k8s.io          Local                        True        29h
v1beta1.authorization.k8s.io           Local                        True        29h
v1beta1.batch                          Local                        True        29h
v1beta1.certificates.k8s.io            Local                        True        29h
v1beta1.coordination.k8s.io            Local                        True        29h
v1beta1.events.k8s.io                  Local                        True        29h
v1beta1.extensions                     Local                        True        29h
...
[v1beta1.metrics.k8s.io                 kube-system/metrics-server   True        29h]
...
v1beta1.networking.k8s.io              Local                        True        29h
v1beta1.node.k8s.io                    Local                        True        29h
v1beta1.policy                         Local                        True        29h
v1beta1.rbac.authorization.k8s.io      Local                        True        29h
v1beta1.scheduling.k8s.io              Local                        True        29h
v1beta1.storage.k8s.io                 Local                        True        29h
v1beta2.apps                           Local                        True        29h
v2beta1.autoscaling                    Local                        True        29h
v2beta2.autoscaling                    Local                        True        29h

如果v1beta1.metrics.k8s.io所對應的API Service不是kube-system/metrics-server,檢查是否由於安裝Prometheus Operator覆蓋導致。如果是覆蓋導致的問題,可以通過部署以下的YAML模板進行恢複。

apiVersion: apiregistration.k8s.io/v1beta1
kind: APIService
metadata:
  name: v1beta1.metrics.k8s.io
spec:
  service:
    name: metrics-server
    namespace: kube-system
  group: metrics.k8s.io
  version: v1beta1
  insecureSkipTLSVerify: true
  groupPriorityMinimum: 100
  versionPriority: 100

如果非上述問題,請確認已在叢集的營運管理>組件管理頁面安裝了metrics-server組件。更多資訊,請參見metrics-server

原因二:滾動發布或擴容時無法擷取資料

預設metrics-server的採集周期是1 min。剛擴容或更新完成後,metrics-server會有一段時間無法擷取監控資料。請於擴容或更新後2 min左右進行查看。

原因三:未配置request欄位

HPA預設是通過實際的利用率/request作為利用率的數值,因此可以檢查Pod的resource欄位中是否包含request欄位。

原因四:指標名填寫錯誤

請檢查指標名(包括大小寫)是否正確。例如,如果將HPA支援的cpu指標誤寫為CPU,監控資料current欄位會顯示為unknown

HPA擴縮容失敗,指標擷取異常怎麼辦?

HPA擴縮容失敗可能是因為指標擷取異常,HPA的監控資料current欄位將顯示為unknown。此時,HPA將無法擷取用於決策擴縮容的指標,也就無法調整Pod數量。請參見節點自動調整FAQ排查問題原因,並採取對應的解決措施。

為何HPA在滾動時擴容出了多餘的Pod?

社區Controller Manager在滾動發布時,對於沒有監控資料的Pod,進行監控資料的補零操作,從而有一定的機率出現擴容出多餘的Pod現象(多彈現象)。您可以通過以下配置防止多彈。

叢集維度配置

您可以通過升級ACK提供的最新版metrics-server,並在metrics-server的啟動參數上開啟開關以防止多彈。

這是全域開關,設定後對叢集內所有相關負載生效。

# 在metrics-server的啟動參數中加入以下選項。
--enable-hpa-rolling-update-skipped=true  

工作負載維度配置

如果只想對指定的工作負載開啟防止多彈,您可以使用以下兩種方法防止多彈。

  • 方法一:通過在指定工作負載的模板中添加以下Annotation,可以在滾動發布時臨時暫停HPA的判斷生效。

    #工作負載的spec.template.metadata.annotations加入Annotation,滾動發布時臨時暫停HPA的判斷生效。
    HPARollingUpdateSkipped: "true"

    展開查看範例程式碼詳情

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment-basic
      labels:
        app: nginx
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: nginx
        template:
            metadata:
              labels:
                app: nginx
              annotations:
                HPARollingUpdateSkipped: "true"  # 跳過滾動發布時的HPA的效果。
            spec:
              containers:
              - name: nginx
                image: nginx:1.7.9
                ports:
                - containerPort: 80
  • 方法二:通過在指定工作負載的模板中添加以下Annotation,可以在應用發布開始階段跳過設定的預熱時間段。

    #工作負載的spec.template.metadata.annotations加入Annotation,在應用發布開始階段跳過設定的預熱的時間段。
    HPAScaleUpDelay: 3m # 3m僅為樣本,具體時間段請按需設定

    展開查看範例程式碼詳情

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment-basic
      labels:
        app: nginx
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: nginx
        template:
            metadata:
              labels:
                app: nginx
              annotations:
                HPAScaleUpDelay: 3m  # m代表分鐘,表示HPA在Pod建立3分鐘後開始生效,可選單位為[s(秒),m(分)]。
            spec:
              containers:
              - name: nginx
                image: nginx:1.7.9
                ports:
                - containerPort: 80

HPA到達閾值為何不進行擴縮容?

HPA的擴縮容的觸發條件不僅是CPU使用率或記憶體使用量率超過閾值與低於閾值,需要額外考慮的是如果擴容或者縮容後,是否會再次觸發縮容或者擴容,減少震蕩的情境。

例如當您的擴容閾值設定為80%,如果有兩個Pod的CPU目前使用率都是70%,這種情況下就不會縮容。因為縮容後可能單個Pod的CPU使用率高於80%,就會觸發擴容,這樣就會來回擴縮容出現震蕩。

HPA採集周期如何配置?

對版本號碼大於v0.2.1-b46d98c-aliyun的metric-server,在metric-server的啟動參數中設定--metric-resolution,例如--metric-resolution=15s即可。

CronHPA是否相容HPA?如何相容HPA?

CronHPA可以相容HPA。阿里雲Container ServiceACK將CronHPA中的scaleTargetRef設定為HPA對象,然後通過HPA對象來尋找真實的scaleTargetRef,從而讓CronHPA感知HPA的目前狀態。CronHPA不會直接調整Deployment的副本數目,而是通過HPA來操作Deployment,這樣可以避免HPA和CronHPA的衝突問題。關於CronHPA相容HPA的更多資訊,請參見實現CronHPA與HPA的協同

如何解決HPA啟動時CPU或記憶體飆高造成擴容出多餘Pod的多彈現象?

對於Java等需要預熱的語言與架構而言,在容器剛啟動的時候,有可能會出現分鐘層級的CPU、記憶體飆高,可能會造成HPA的誤觸發。您可以通過將ACK提供的metrics-server組件升級至0.3.9.6版本以上,並在Pod的Annotation上增加開關防止誤觸發,解決此問題。關於如何升級metrics-server組件,請參見升級叢集至v1.12版本前升級metrics-server組件

增加開關防止誤觸發部署樣本YAML如下。

展開查看樣本YAML詳情

## 以Deployment為例
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment-basic
  labels:
    app: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
      annotations:
        HPAScaleUpDelay: 3m # m代表分鐘,表示HPA在Pod建立3分鐘後開始生效,可選單位為[s(秒),m(分)]。
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9 # Replace it with your exactly <image_name:tags>.
        ports:
        - containerPort: 80 

為什麼HPA審計日誌數值未達閾值但擴縮了?

問題原因

Pod水平自動擴縮控制器根據當前指標和期望指標來計算擴縮比例,期望副本數 = ceil(當前副本數 × (當前指標 / 期望指標))

從這個公式可以看出,期望副本數的準確度是由當前副本數、當前指標和期望指標的準確度來保證的。以HPA中應用廣泛的資源指標為例,HPA擷取當前副本數時,是先擷取scaleTargetRef所定義的對象的scale子資源(subResources),然後將scalestatusSelector的值轉化為labelselector,以此作為條件去匹配擷取Pod。如果某個時刻,用這個條件擷取到的Pod並不完全屬於scaleTargetRef中定義的對象,那以此計算出的期望副本數就很可能不符合預期(比如即時指標低於閾值卻擴容了)。

常見可能導致匹配Pod數目不準確的原因:

  • 滾動發布。

  • 給其他不屬於scaleTargetRef中對象的Pod打標了相同Label。執行如下命令,可判斷是否有其他Pod。

    kubectl get pods -n {命名空間名字} -l {scale子資源的status.Selector的值}

解決方案

  • 針對滾動發布,解決方案請參見節點自動調整FAQ

  • 針對給其他不屬於scaleTargetRef中對象的Pod打上了相同Label。定位出這類Pod,如果還需要使用則更換為不同Label,如果不再需要,刪除即可。

HPA縮容時,能夠決定Pod縮容的順序嗎?

不能。HPA可以根據定義的指標自動增加或減少Pod的數量,但並不能決定哪些Pod應該首先被終止。Pod終止的順序、優雅退出時間等特性均由管理Pod的Controller決定。

HPA使用率指標單位的含義是什嗎?

使用率指標通常為無單位的整數值或以m為單位的整數值,換算比例為1000m=1。例如,當tcp_connection_counts為70000m時,等同於70。

如果執行kubectl get hpa後發現target一欄為unknown怎麼辦?

請按照以下操作解決。

  1. 執行kubectl describe hpa <hpa_name>,確認HPA失效的原因。

    • 如果Conditions欄位提示AbleToScaleFalse,請確認Deployment是否正常部署。

    • 如果Conditions欄位提示ScalingActiveFalse,請繼續執行下一步。

  2. 執行kubectl get --raw "/apis/external.metrics.k8s.io/v1beta1/"。如果返回為Error from server (NotFound): the server could not find the requested resource,請確認alibaba-cloud-metrics-adapter的啟動狀態。

    如alibaba-cloud-metrics-adapter狀態正常,請確認HPA指標是否是Ingress相關指標。如果是Ingress相關指標,您需要提前部署Log Service組件。更多資訊,請參見Nginx Ingress訪問日誌分析與監控

  3. 確認HPA指標填寫正確。sls.ingress.route的值格式為<namespace>-<svc>-<port>

    • namespace:Ingress所在的命名空間。

    • svc:Ingress對應的Service名稱。

    • port:Ingress對應Service的連接埠名稱。

如何尋找HPA支援的指標名稱?

請參見阿里雲HPA指標,以下列舉為常用指標。

指標名稱

描述

附加參數

sls_ingress_qps

指定的IngressRoute每秒查詢率

sls.ingress.route

sls_alb_ingress_qps

ALB資料的IngressRoute每秒查詢率

sls.ingress.route

sls_ingress_latency_avg

所有請求的延遲

sls.ingress.route

sls_ingress_latency_p50

50%請求的延遲

sls.ingress.route

sls_ingress_latency_p95

95%請求的延遲

sls.ingress.route

sls_ingress_latency_p99

99%請求的延遲

sls.ingress.route

sls_ingress_latency_p9999

99.99%請求的延遲

sls.ingress.route

sls_ingress_inflow

Ingress的流入頻寬

sls.ingress.route

自訂了Nginx Ingress日誌格式後如何進行適配操作?

您可以參見基於阿里雲組件指標的容器水平伸縮瞭解如何使用SLS Ingress指標進行容器水平伸縮,需要您開啟並正確配置叢集中Nginx Ingress日誌接入阿里雲Log Service。

  • 建立叢集時,Log Service預設開啟。當您保持預設值不變,叢集建立成功後,您可以在Log Service控制台查看Nginx Ingress的訪問日誌分析報表和監控Nginx Ingress即時狀態。

  • 在建立叢集時,若您手動關閉了Log Service,叢集建立完成後,如果想要使用SLS Ingress指標進行容器水平伸縮,請重新開啟或配置Log Service。詳細資料,請參見Nginx Ingress訪問日誌分析與監控

  • 當您需要自訂Nginx Ingress日誌格式時,由於叢集中初次開啟Log Service部署AliyunLogConfig的CRD只針對ACK預設Ingress Controller中的日誌格式生效,若您修改過Ingress Controller的訪問日誌格式,請修改CRD配置中的Regex提取processor_regex部分。具體操作,請參見通過DaemonSet-CRD方式採集容器日誌