1. 程式人生 > >通過自定義prometheus資料實現k8s hpa

通過自定義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+ (請參閱下面的詳細資訊)
中引入的

deployment yamls 檔案來部署。

Metrics Server 從每個節點上的 Kubelet 公開的 Summary API 中採集指標資訊。

通過在主 API server 中註冊的 Metrics Server Kubernetes 聚合器 來採集指標資訊, 這是在 Kubernetes 1.7 中引入的。

設計文件 中可以瞭解到有關 Metrics Server 的更多資訊。

custom metrics api

該API允許消費者訪問任意度量描述Kubernetes資源。

API的目的是通過監測管道供應商,在其度量儲存解決方案之上實現。

如果你想實現這個API API伺服器,請參閱

kubernetes-incubator/custom-metrics-apiserver庫,其中包含需要建立這樣一個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技術