通過自定義prometheus資料實現k8s hpa
核心指標管道
從 Kubernetes 1.8 開始,資源使用指標(如容器 CPU 和記憶體使用率)通過 Metrics API 在 Kubernetes 中獲取。
這些指標可以直接被使用者訪問(例如通過使用 kubectl top 命令),或由叢集中的控制器使用(例如,Horizontal Pod Autoscale
可以使用這些指標作出決策)。
Resource Metrics API
通過 Metrics API,您可以獲取指定 node 或 pod 當前使用的資源量。這個 API 不儲存指標值,
因此想要獲取某個指定 node 10 分鐘前的資源使用量是不可能的。
Metrics API 和其他的 API 沒有什麼不同:
它可以通過與 /apis/metrics.k8s.io/
路徑下的其他 Kubernetes API 相同的端點來發現
它提供了相同的安全性、可擴充套件性和可靠性保證
Metrics API 在 k8s.io/metrics 倉庫中定義。您可以在這裡找到關於Metrics API 的更多資訊。
注意: Metrics API 需要在叢集中部署 Metrics Server。否則它將不可用。
Metrics Server
Metrics Server 實現了Resource Metrics API
Metrics Server 是叢集範圍資源使用資料的聚合器。
從 Kubernetes 1.8 開始,它作為一個 Deployment 物件預設部署在由 kube-up.sh 指令碼建立的叢集中。
如果您使用了其他的 Kubernetes 安裝方法,您可以使用 Kubernetes 1.7+ (請參閱下面的詳細資訊)
中引入的
Metrics Server 從每個節點上的 Kubelet 公開的 Summary API 中採集指標資訊。
通過在主 API server 中註冊的 Metrics Server Kubernetes 聚合器 來採集指標資訊, 這是在 Kubernetes 1.7 中引入的。
在 設計文件 中可以瞭解到有關 Metrics Server 的更多資訊。
custom metrics api
該API允許消費者訪問任意度量描述Kubernetes資源。
API的目的是通過監測管道供應商,在其度量儲存解決方案之上實現。
如果你想實現這個API API伺服器,請參閱
其中包含設定這樣一個API伺服器所需的基本基礎設施。
Import Path: k8s.io/metrics/pkg/apis/custom_metrics.
custom metrics apiserver
HPA
自動伸縮是一種根據資源使用情況自動伸縮工作負載的方法。
自動伸縮在Kubernetes中有兩個維度:cluster Autoscaler處理節點擴容操作和Horizontal Pod Autoscaler自動縮放rs或rc中的pod。
cluster Autoscaler和Horizontal Pod Autoscaler一起可用於動態調整的計算能力以及並行性的水平,你的系統需要滿足sla。
雖然cluster Autoscaler高度依賴於託管叢集的雲提供商的底層功能,但是HPA可以獨立於您的IaaS/PaaS提供商進行操作。
在Kubernetes v1.1中首次引入了hpa特性,自那時起已經有了很大的發展。
hpa第一個版本基於觀察到的CPU利用率,後續版本支援基於記憶體使用。
在Kubernetes 1.6中引入了一個新的API自定義指標API,它允許HPA訪問任意指標。
Kubernetes 1.7引入了聚合層,允許第三方應用程式通過註冊為API附加元件來擴充套件Kubernetes API。
自定義指標API以及聚合層使得像Prometheus這樣的監控系統可以向HPA控制器公開特定於應用程式的指標。
hpa 實現了一個控制環,可以週期性的從資源指標API查詢特定應用的CPU/MEM資訊。
實戰
以下是關於Kubernetes 1.9或更高版本的HPA v2配置的分步指南。您將安裝提供核心指標的度量伺服器附加元件,
然後您將使用一個演示應用程式來展示基於CPU和記憶體使用的pod自動伸縮。在指南的第二部分,
您將部署Prometheus和一個自定義API伺服器。您將使用聚合器層註冊自定義API伺服器,然後使用演示應用程式提供的自定義度量配置HPA。
前提
cd $GOPATH
git clone https://github.com/stefanprodan/k8s-prom-hpa
安裝 Metrics Server
Kubernetes Metrics Server是一個叢集範圍的資源使用資料聚合器,是Heapster的繼承者。
metrics伺服器通過從kubernet.summary_api收集資料收集節點和pod的CPU和記憶體使用情況。
summary API是一個記憶體有效的API,用於將資料從Kubelet/cAdvisor傳遞到metrics server。
如果在v1版本的HPA中,您將需要Heapster提供CPU和記憶體指標,在HPA v2和Kubernetes 1.8中,
只有度量伺服器是需要的,而水平-pod-autoscaler-use-rest-客戶機是開啟的。
在Kubernetes 1.9中預設啟用HPA rest客戶端。GKE 1.9附帶了預先安裝的指標伺服器。
在kube-system
名稱空間總部署metrics-server
kubectl create -f ./metrics-server
一分鐘後,度量伺服器開始報告節點和莢的CPU和記憶體使用情況。
檢視nodes指標
kubectl get --raw "/apis/metrics.k8s.io/v1beta1/nodes" | jq .
檢視pod指標
kubectl get --raw "/apis/metrics.k8s.io/v1beta1/pods" | jq .
基於CPU和記憶體使用的自動縮放
你將使用一個基於golang的小程式測試hpa.
部署podinfo到預設名稱空間
kubectl create -f ./podinfo/podinfo-svc.yaml,./podinfo/podinfo-dep.yaml
在http://<K8S_PUBLIC_IP>:31198
通過nodeport訪問podinfo
接下來定義一個HPA,保持最小兩個副本和最大十個如果CPU平均超過80%或如果記憶體超過200mi。
apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
name: podinfo
spec:
scaleTargetRef:
apiVersion: extensions/v1beta1
kind: Deployment
name: podinfo
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
targetAverageUtilization: 80
- type: Resource
resource:
name: memory
targetAverageValue: 200Mi
建立HPA
kubectl create -f ./podinfo/podinfo-hpa.yaml
幾秒鐘之後,HPA控制器與metrics server聯絡,然後取出CPU和記憶體使用情況。
kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
podinfo Deployment/podinfo 2826240 / 200Mi, 15% / 80% 2 10 2 5m
為了提高CPU使用率、執行rakyll/hey
進行壓力測試
#install hey
go get -u github.com/rakyll/hey
#do 10K requests
hey -n 10000 -q 10 -c 5 http://<K8S_PUBLIC_IP>:31198/
你可以通過以下命令獲取HPA event
$ kubectl describe hpa
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfulRescale 7m horizontal-pod-autoscaler New size: 4; reason: cpu resource utilization (percentage of request) above target
Normal SuccessfulRescale 3m horizontal-pod-autoscaler New size: 8; reason: cpu resource utilization (percentage of request) above target
先將podinfo
移除一會兒,稍後將再次部署:
kubectl delete -f ./podinfo/podinfo-hpa.yaml,./podinfo/podinfo-dep.yaml,./podinfo/podinfo-svc.yaml
安裝Custom Metrics Server
為了根據custom metrics進行擴充套件,您需要有兩個元件。一個從應用程式中收集指標並將其儲存為Prometheus時間序列資料庫的元件。
第二個元件將Kubernetes自定義指標API擴充套件到由收集的k8s-prometheus-adapter提供的指標。
您將在專用名稱空間中部署Prometheus和adapter。
建立monitoring
名稱空間
kubectl create -f ./namespaces.yaml
將 Prometheus v2部署到monitoring
名稱空間:
如果您部署到GKE,您可能會得到一個錯誤:從伺服器(禁止)中出錯:建立這個錯誤將幫助您解決這個問題:RBAC on GKE。
kubectl create -f ./prometheus
生成由Prometheus adapter所需的TLS證書:
make certs
部署Prometheus自定義api介面卡
kubectl create -f ./custom-metrics-api
列出由prometheus提供的自定義指標:
kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1" | jq .
獲取monitoring
名稱空間中所有pod的FS資訊:
kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/namespaces/monitoring/pods/*/fs_usage_bytes" | jq .
基於自定義指標的自動擴容
建立podinfo nodeport服務並在default名稱空間中部署:
kubectl create -f ./podinfo/podinfo-svc.yaml,./podinfo/podinfo-dep.yaml
podinfo
應用程式的暴露了一個自定義的度量http_requests_total。普羅米修斯介面卡刪除_total
字尾標記度量作為一個計數器度量
從自定義度量API獲取每秒的總請求數:
kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/namespaces/default/pods/*/http_requests" | jq .
{
"kind": "MetricValueList",
"apiVersion": "custom.metrics.k8s.io/v1beta1",
"metadata": {
"selfLink": "/apis/custom.metrics.k8s.io/v1beta1/namespaces/default/pods/%2A/http_requests"
},
"items": [
{
"describedObject": {
"kind": "Pod",
"namespace": "default",
"name": "podinfo-6b86c8ccc9-kv5g9",
"apiVersion": "/__internal"
},
"metricName": "http_requests",
"timestamp": "2018-01-10T16:49:07Z",
"value": "901m"
},
{
"describedObject": {
"kind": "Pod",
"namespace": "default",
"name": "podinfo-6b86c8ccc9-nm7bl",
"apiVersion": "/__internal"
},
"metricName": "http_requests",
"timestamp": "2018-01-10T16:49:07Z",
"value": "898m"
}
]
}
m
代表milli-units
,例如,901m
意味著milli-requests
。
建立一個HPA,如果請求數超過每秒10當將擴大podinfo數量:
apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
name: podinfo
spec:
scaleTargetRef:
apiVersion: extensions/v1beta1
kind: Deployment
name: podinfo
minReplicas: 2
maxReplicas: 10
metrics:
- type: Pods
pods:
metricName: http_requests
targetAverageValue: 10
在default
名稱空間部署podinfo
HPA:
kubectl create -f ./podinfo/podinfo-hpa-custom.yaml
過幾秒鐘HPA從標準的API取得http_requests
的值:
kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
podinfo Deployment/podinfo 899m / 10 2 10 2 1m
用25每秒請求數給podinfo
服務加壓
#install hey
go get -u github.com/rakyll/hey
#do 10K requests rate limited at 25 QPS
hey -n 10000 -q 5 -c 5 http://<K8S-IP>:31198/healthz
幾分鐘後,HPA開始擴大部署。
kubectl describe hpa
Name: podinfo
Namespace: default
Reference: Deployment/podinfo
Metrics: ( current / target )
"http_requests" on pods: 9059m / 10
Min replicas: 2
Max replicas: 10
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfulRescale 2m horizontal-pod-autoscaler New size: 3; reason: pods metric http_requests above target
以每秒當前的請求速率,部署將永遠無法達到10個莢的最大值。三副本足以讓RPS在10每pod.
負載測試結束後,HPA向下擴充套件部署到初始副本。
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfulRescale 5m horizontal-pod-autoscaler New size: 3; reason: pods metric http_requests above target
Normal SuccessfulRescale 21s horizontal-pod-autoscaler New size: 2; reason: All metrics below target
你可能已經注意到,自動定標器不使用峰值立即做出反應。預設情況下,指標每30秒同步一次,
並且擴充套件/收縮當3-5分鐘沒有重新擴充套件發生變化時。在這種方式中,HPA防止快速執行並保留了指標生效時間
總結
不是所有的系統都可以依靠CPU/記憶體使用指標單獨滿足SLA,大多數Web和移動後端需要以每秒請求處理任何突發流量進行自動縮放。
對於ETL應用程式,可能會由於作業佇列長度超過某個閾值而觸發自動縮放,等等。
通過prometheus檢測你應用程式的正確指,併為自動是很所提供正確指標,您可以微調您的應用程式更好地處理突發和確保高可用性。
參考
歡迎加入QQ群:k8s開發與實踐(482956822)一起交流k8s技術