本文介紹使用工作負載伸縮功能(包括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"
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。阿里云容器服務ACK將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如下。
## 以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
),然后將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
一欄為unknow
怎么辦?
請按照以下操作解決。
執行
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相關指標,您需要提前部署日志服務組件。更多信息,請參見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日志接入阿里云日志服務。
創建集群時,日志服務默認開啟。當您保持默認值不變,集群創建成功后,您可以在日志服務控制臺查看Nginx Ingress的訪問日志分析報表和監控Nginx Ingress實時狀態。
在創建集群時,若您手動關閉了日志服務,集群創建完成后,如果想要使用SLS Ingress指標進行容器水平伸縮,請重新開啟或配置日志服務。詳細信息,請參見Nginx Ingress訪問日志分析與監控。
當您需要自定義Nginx Ingress日志格式時,由于集群中初次開啟日志服務部署AliyunLogConfig的CRD只針對ACK默認Ingress Controller中的日志格式生效,若您修改過Ingress Controller的訪問日志格式,請修改CRD配置中的正則表達式提取
processor_regex
部分。具體操作,請參見通過DaemonSet-CRD方式采集容器日志。