1、概述
- Core metrics(核心指標):從 Kubelet、cAdvisor 等獲取度量數據,再由metrics-server提供給 kube-scheduler、HPA、 控制器等使用。
- Custom Metrics(自定義指標):由Prometheus Adapter提供API custom.metrics.k8s.io,由此可支持任意Prometheus采集到的指標。
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

創建一個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
- 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)同樣的效果。