介紹
Horizontal Pod Autoscaling(Pod 水平自動伸縮),簡稱HPA,HPA 通過監(jiān)控分析一些控制器控制的所有 Pod 的負載變化情況來確定是否需要調(diào)整 Pod 的副本數(shù)量纷闺,
應(yīng)對線上的各種復(fù)雜情況,我們需要能夠做到自動化去感知業(yè)務(wù),來自動進行擴縮容。
原理
HPA 控制器 定期查詢Resource Metrics API(Metrics Server)以獲取CPU內(nèi)存等核心指標和針對特定應(yīng)用程序指標的Custom Metrics API (Prometheus adapter)
擴縮容算法
desiredReplicas = ceil[currentReplicas * ( currentMetricValue / desiredMetricValue )]
即當前副本數(shù) * (當前指標值/期望的指標值)单鹿,將結(jié)果向上取整掀宋。
實踐
擴容的指標 CPU 深纲、內(nèi)存、TPS(自定義) 劲妙,系統(tǒng)將針對每種類型的指標都計算 Pod 副本的目標數(shù)量湃鹊,以最大值為準進行擴縮容操作。
apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
name: {{ metadata_name }} #APP Name
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: {{ spec_scaleTargetRef_name }} #APP Name
minReplicas: {{spec_minReplicas}} # 最小副本數(shù)
maxReplicas: {{spec_maxReplicas}} # 擴容最大副本數(shù)
metrics:
- type: Resource
resource:
name: cpu
targetAverageUtilization: {{metrics_resource_targetAverageUtilization}}
- type: Resource
resource:
name: memory
targetAverageValue: {{metrics_resource_targetAverageValue}}
- type: Pods
pods:
metric:
name: http_server_requests_seconds_count # k8s-prometheus-adapter configMap 配置
target:
type: AverageValue
averageValue: {{metrics_pods_target_averageValue}}
主要參數(shù)如下:
- scaleTargetRef:目標作用對象镣奋,可以是 Deployment币呵、ReplicationController 或 ReplicaSet。
- minReplicas 和 maxReplicas:Pod 副本數(shù)量的最小值和最大值侨颈,系統(tǒng)較臟這個范圍內(nèi)進行自動擴縮容操作余赢,并維持每個 Pod 的CPU 使用率為 50%。
- metrics:目標指標值哈垢。在 metrics 中通過參數(shù) type 定義指標的類型妻柒,通過參數(shù) target 定義相應(yīng)的指標目標值,系統(tǒng)將在指標數(shù)據(jù)達到目標值時(考慮容忍度的區(qū)間耘分,見前面算法部分的說明)觸發(fā)擴縮容操作举塔。
可以將 metrics 中的 type(指標類型)設(shè)置為以下四種绑警,可以設(shè)置一個或多個組合,如下所述央渣。
(1)Resource:基于資源的指標值计盒,可以設(shè)置的資源為 CPU 和內(nèi)存。
(2)Pods:基于 Pod 的指標芽丹,系統(tǒng)將對全部 Pod 副本的指標值進行平均計算北启。
(3)Object:基于某種資源對象(如 Ingress)的指標或應(yīng)用系統(tǒng)的任意自定義指標。
(4)External:基于外部指標值志衍,用戶使用了公有云服務(wù)商提供的消息服務(wù)或外部負載均衡器暖庄,希望基于這些外部服務(wù)的性能指標(如消息服務(wù)的隊列長度、負載均衡器的 QPS)對自己部署在 Kubernetes 中的服務(wù)進行自動擴縮容操作
規(guī)則
1.定義metric name 和 格式 比如統(tǒng)計TPS
http_server_requests_seconds_count{application=“hello-word”,env=“test”,instance=“10.142.22.9:9090”,job=“op-app-prometheus-prod-dayu”,method=“GET”,namespace=“base”,pod=“hello-word-7cdfc8bb48-nn5vf”}
Label 必須含有 env 楼肪,pod 培廓,namespace
2.接入prometheus
Java(spring boot 和 Eureka) 引入dayu starter (內(nèi)部編寫統(tǒng)一暴露metric sdk)
Go
Python
配置
k8s-prometheus-adapter configMap 部署adapter前需要配置adapter的rule,用于預(yù)處理metrics
- seriesQuery: 'http_server_requests_seconds_count{namespace !="", pod!="",,env="test"}'
resources:
overrides:
namespace: {resource: "namespace"}
pod: {resource: "pod"}
name:
matches: ""
as: ""
metricsQuery: 'sum(rate(<<.Series>>{<<.LabelMatchers>>}[1m])) by (<<.GroupBy>>)'
kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/namespaces/base/pods/*/http_server_requests_seconds_count" | jq .
http_server_requests_seconds_count custom metrics name 春叫,環(huán)境匹配當前的env
seriesQuery 可以根據(jù)標簽進行查找(如下)肩钠,也可以直接指定metric name查找
resources 設(shè)置metric與kubernetes resources的映射關(guān)系
name 用于將prometheus metrics名稱轉(zhuǎn)化為custom metrics API所使用的metrics名稱,但不會改變其本身的metric名稱
metricsQuery 處理調(diào)用custom metrics API獲取到的metrics的value 該值最終提供給HPA進行擴縮容
未來
1暂殖,當前custom metric 需要在k8s-prometheus-adapter 創(chuàng)建rules 价匠,如果custom metric 太多了 人工修改是一個低效的工作,考慮rules 根據(jù)業(yè)務(wù)自行定義
自行動態(tài)創(chuàng)建
2呛每,以上需要滿足不了 踩窖,自行實現(xiàn) custom-metric-apiserver
資料
https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/
https://github.com/kubernetes/metrics
https://github.com/DirectXMan12/k8s-prometheus-adapter
https://github.com/kubernetes-sigs/custom-metrics-apiserver