本文介紹使用工作負載伸縮功能(包括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的資料來源的情況。返回的樣本資料如下。
如果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"
方法二:通過在指定工作負載的模板中添加以下Annotation,可以在應用發布開始階段跳過設定的預熱時間段。
#工作負載的spec.template.metadata.annotations加入Annotation,在應用發布開始階段跳過設定的預熱的時間段。 HPAScaleUpDelay: 3m # 3m僅為樣本,具體時間段請按需設定
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如下。
為什麼HPA審計日誌數值未達閾值但擴縮了?
問題原因
Pod水平自動擴縮控制器根據當前指標和期望指標來計算擴縮比例,期望副本數 = ceil(當前副本數 × (當前指標 / 期望指標))
。
從這個公式可以看出,期望副本數的準確度是由當前副本數、當前指標和期望指標的準確度來保證的。以HPA中應用廣泛的資源指標為例,HPA擷取當前副本數時,是先擷取scaleTargetRef
所定義的對象的scale
子資源(subResources
),然後將scale
的status
的Selector
的值轉化為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
怎麼辦?
請按照以下操作解決。
執行
kubectl describe hpa <hpa_name>
,確認HPA失效的原因。如果
Conditions
欄位提示AbleToScale
為False
,請確認Deployment是否正常部署。如果
Conditions
欄位提示ScalingActive
為False
,請繼續執行下一步。
執行
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訪問日誌分析與監控。
確認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方式採集容器日誌。