Kubernetes自定義監控指標 —— Prometheus Adapter


1、概述

Kubernetes的監控指標分為兩種:
  • Core metrics(核心指標):從 Kubelet、cAdvisor 等獲取度量數據,再由metrics-server提供給 kube-scheduler、HPA、 控制器等使用。
  • Custom Metrics(自定義指標):由Prometheus Adapter提供API custom.metrics.k8s.io,由此可支持任意Prometheus采集到的指標。

核心指標只包含node和pod的cpu、內存, 一般來說,核心指標作HPA已經足夠,但如果想根據自定義指標:如請求qps/5xx錯誤數來實現HPA,就需要使用自定義指標了,目前Kubernetes中自定義指標一般由Prometheus來提供,再利用Prometheus-adpater(自定義apiserver)聚合到原生Kubernetes apiserver,實現和核心指標(metric-server)同樣的效果。聚合自定義apiserver請參考《 Kubernetes核心指標監控——Metrics Server 》這篇博文,本文不再贅余。

2、部署​Prometheus-Adapter

Prometheus可以采集其它各種指標,但是Prometheus采集到的metrics並不能直接給Kubernetes用,因為兩者數據格式不兼容,因此還需要另外一個組件Prometheus-Adapter,將Prometheus的metrics數據格式轉換成k8s API接口能識別的格式。由於prometheus-adapter是自定義API Service,所以還需要用Kubernetes aggregator在主API服務器中注冊,以便直接通過/apis/來訪問。

Prometheus-Adapter項目地址:https://github.com/kubernetes-sigs/prometheus-adapter

2.1 使用helm部署

helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm install my-release prometheus-community/prometheus-adapter

2.2 使用yaml文件形式部署

除了可以通過helm形式部署,也可以通過kubectl apply形式進行部署。

kubectl create namespace monitoring # 如果需要將prometheus-adapter部署到其他命名空間下,需要手動修改manifests底下的yaml配置文件
kubectl create -f manifests/ # 下載最新穩定版本源碼,並進入到prometheus-adapter/deploy目錄下進行prometheus-adapter組件安裝

Prometheus-Adapter組件部署文件清單:

注意 1:不管是使用helm安裝,還是使用yaml文件形式進行安裝,安裝Prometheus-Adapter前,需要提前裝好Prometheus,並保證Prometheus中已經拉取並保存了所需的自定義指標數據,這時通過安裝Prometheus-Adapter組件,可以將用PromQL查詢到的指標數據轉換成k8s API接口能識別的格式。

注意 2:不管是使用helm安裝,還是使用yaml文件形式進行安裝,配置文件都需要按需修改,比如修改custom-metrics-apiservice.yaml配置文件,將服務地址改成實際的prometheus-adapter組件地址。

apiVersion: apiregistration.k8s.io/v1
kind: APIService
metadata:
  annotations:
    meta.helm.sh/release-name: prometheus-adapter
    meta.helm.sh/release-namespace: monitoring-system
  creationTimestamp: "2023-03-20T01:50:17Z"
  labels:
    app.kubernetes.io/component: metrics
    app.kubernetes.io/instance: prometheus-adapter
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: prometheus-adapter
    app.kubernetes.io/part-of: prometheus-adapter
    app.kubernetes.io/version: v0.10.0
    helm.sh/chart: prometheus-adapter-4.1.1
  name: v1beta1.custom.metrics.k8s.io
spec:
  group: custom.metrics.k8s.io
  groupPriorityMinimum: 100
  insecureSkipTLSVerify: true
  service:  							
    name: prometheus-adapter
    namespace: monitoring
    port: 443
  version: v1beta1
  versionPriority: 100

​Prometheus-Adapter組件以及其依賴組件(Prometheus等)均部署成功后,客戶端便可以通過​Prometheus-Adapter提供的 RESTful 接口獲取指標(需要保障Prometeus中已經拉取並保存了所需的自定義指標數據)。

3、通過​Prometheus-Adapter獲取自定義指標

在第二章節部署Prometheus-Adapter組件的時候通過創建對應APIService資源對象把Prometheus-Adapter組件作為自定義Apiserver注冊到原生的Apiserver上,因此可以通過訪問原生K8s Apiserver來訪問Prometheus-Adapter組件。

假設注冊的 APIService為custom.metrics.k8s.io/v1beta1,其中/apis/custom.metrics.k8s.io/v1beta1 接口用於獲取已定義的自定義指標的值。另外 metrics 的 API path 是分為 namespaced 和 non-namespaced 類型的。

3.1 namespaced類型

獲取指定 namespace 下指定 object 類型和名稱的 metrics。

kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/namespaces/{namespace-name}/{object-type}/{object-name}/{metric-name...}" | jq .

如獲取 monitor 命名空間下名為 grafana 的 pod 的start_time_seconds metric。

kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/namespaces/monitor/pods/grafana/start_time_seconds" | jq .

獲取指定 namespace 下所有特定 object 類型的 metrics。

kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/namespaces/{namespace-name}/pods/*/{metric-name...}" | jq .

如獲取 monitor 命名空間下名為所有 pod 的 start_time_seconds metric。

kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/namespaces/monitor/pods/*/start_time_seconds" | jq .

使用 labelSelector 可以選擇帶有特定 label 的 object。

kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/namespaces/{namespace-name}/{object-type}/{object-name}/{metric-name...}?labelSelector={label-name}" | jq .   
kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/namespaces/{namespace-name}/pods/*/{metric-name...}?labelSelector={label-name}" | jq .   

示例 1:

通過Prometheus Adapter組件獲取custom-metrics-ns-zpz-0625命名空間下所有Pod的http_requests_count5xx指標。

kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/namespaces/custom-metrics-ns-zpz-0625/pods/*/http_requests_count5xx"
{
	"kind": "MetricValueList",
	"apiVersion": "custom.metrics.k8s.io/v1beta1",
	"metadata": {},
	"items": [{
		"describedObject": {
			"kind": "Pod",
			"namespace": "custom-metrics-ns-zpz-0625",
			"name": "custom-metrics-5xx-deploy-5f55d579fb-djqrw",
			"apiVersion": "/v1"
		},
		"metricName": "http_requests_count5xx",
		"timestamp": "2023-07-06T07:08:48Z",
		"value": "0",
		"selector": null
	}, {
		"describedObject": {
			"kind": "Pod",
			"namespace": "custom-metrics-ns-zpz-0625",
			"name": "custom-metrics-deploy-0626-1-v1-69b89f5c97-dmx2d",
			"apiVersion": "/v1"
		},
		"metricName": "http_requests_count5xx",
		"timestamp": "2023-07-06T07:08:48Z",
		"value": "0",
		"selector": null
	}]
}

3.2 non-namespaced類型

non-namespaced 和 namespaced 的類似,主要有 node,namespace,PersistentVolume 等。non-namespaced 訪問有些與 custom metrics API 描述不一致

訪問 object 為 namespace 的方式如下如下。

kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/namespaces/{namespace-name}/metrics/{metric-name...}" | jq .   
kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/namespaces/*/metrics/{metric-name...}" | jq .   

訪問 node 的方式如下。

kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/nodes/{node-name}/{metric-name...}" | jq .   

示例 1:

kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/nodes/node1/kubelet_pleg_relist_duration_seconds_count"
{
	"kind": "MetricValueList",
	"apiVersion": "custom.metrics.k8s.io/v1beta1",
	"metadata": {},
	"items": [{
		"describedObject": {
			"kind": "Node",
			"name": "node1",
			"apiVersion": "/v1"
		},
		"metricName": "kubelet_pleg_relist_duration_seconds_count",
		"timestamp": "2023-07-06T07:20:41Z",
		"value": "2312911",
		"selector": null
	}]
}

3、基於自定義指標的HPA

使用Prometheus后,pod有一些自定義指標,如http_request請求數
 

創建一個HPA,當請求數超過每秒10次時進行自動擴容

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

查看HPA:

$ kubectl get hpa
NAME      REFERENCE            TARGETS     MINPODS   MAXPODS   REPLICAS   AGE
podinfo   Deployment/podinfo   899m / 10   2         10        2          1m

對Pod試壓:

#install hey
$ go get -u github.com/rakyll/hey<   br >
#do 10K requests rate limited at 25 QPS
$ hey -n 10000 -q 5 -c 5 http://PODINFO_SVC_IP:9898/healthz

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

4、關於Prometheus-Adapter

其實Prometheus-Adapter既包含自定義指標,又包含核心指標,即如果安裝了Prometheus,且指標都采集完整,Prometheus-Adapter可以替代metrics server。
在1.6以上的集群中,Prometheus-Adapter可以適配autoscaling/v2的HPA。
因為一般是部署在集群內,所以Prometheus-Adapter默認情況下,使用in-cluster的認證方式,以下是主要參數:
  • lister-kubeconfig: 默認使用in-cluster方式
  • metrics-relist-interval: 更新metric緩存值的間隔,最好大於等於Prometheus 的scrape interval,不然數據會為空
  • Prometheus-url: 對應連接的Prometheus地址
  • config: 一個yaml文件,配置如何從Prometheus獲取數據,並與k8s的資源做對應,以及如何在api接口中展示。

5、總結

Kubernetes自定義監控指標Prometheus-Adapter一般通過Prometheus來提供監控指標數據(其他自定義監控指標采集工具還包括Microsoft Azure Adapter、

Google Stackdriver等),一般來說,核心指標作HPA已經足夠,但如果想根據自定義指標:如請求qps/5xx錯誤數來實現HPA,這時候就需要在集群中部署

Prometheus-Adapter了,通過將Prometheus-adpater(自定義apiserver)聚合到原生Kubernetes apiserver,實現和核心指標(metric-server)同樣的效果。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM