容器监控实践—Custom Metrics

6次阅读

共计 3900 个字符,预计需要花费 10 分钟才能阅读完成。

概述
上文 metric-server 提到,kubernetes 的监控指标分为两种:

Core metrics(核心指标):从 Kubelet、cAdvisor 等获取度量数据,再由 metrics-server 提供给 Dashboard、HPA 控制器等使用。
Custom Metrics(自定义指标):由 Prometheus Adapter 提供 API custom.metrics.k8s.io,由此可支持任意 Prometheus 采集到的指标。

核心指标只包含 node 和 pod 的 cpu、内存等,一般来说,核心指标作 HPA 已经足够,但如果想根据自定义指标: 如请求 qps/5xx 错误数来实现 HPA,就需要使用自定义指标了,目前 Kubernetes 中自定义指标一般由 Prometheus 来提供,再利用 k8s-prometheus-adpater 聚合到 apiserver,实现和核心指标(metric-server) 同样的效果。
以下是官方 metrics 的项目介绍:
Resource Metrics API(核心 api)

Heapster
Metrics Server

Custom Metrics API:

Prometheus Adapter
Microsoft Azure Adapter
Google Stackdriver
Datadog Cluster Agent

部署
Prometheus 可以采集其它各种指标,但是 prometheus 采集到的 metrics 并不能直接给 k8s 用,因为两者数据格式不兼容,因此还需要另外一个组件 (kube-state-metrics),将 prometheus 的 metrics 数据格式转换成 k8s API 接口能识别的格式,转换以后,因为是自定义 API,所以还需要用 Kubernetes aggregator 在主 API 服务器中注册,以便直接通过 /apis/ 来访问。
文件清单:

node-exporter:prometheus 的 export,收集 Node 级别的监控数据

prometheus:监控服务端,从 node-exporter 拉数据并存储为时序数据。

kube-state-metrics:将 prometheus 中可以用 PromQL 查询到的指标数据转换成 k8s 对应的数

k8s-prometheus-adpater:聚合进 apiserver,即一种 custom-metrics-apiserver 实现
开启 Kubernetes aggregator 功能(参考上文 metric-server)

k8s-prometheus-adapter 的部署文件:
其中创建了一个叫做 cm-adapter-serving-certs 的 secret,包含两个值: serving.crt 和 serving.key,这是由 apiserver 信任的证书。kube-prometheus 项目中的 gencerts.sh 和 deploy.sh 脚本可以创建这个 secret
包括 secret 的所有资源,都在 custom-metrics 命名空间下,因此需要 kubectl create namespace custom-metrics
以上组件均部署成功后,可以通过 url 获取指标

基于自定义指标的 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

#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
关于 k8s-prometheus-adapter
其实 k8s-prometheus-adapter 既包含自定义指标,又包含核心指标,即如果按照了 prometheus,且指标都采集完整,k8s-prometheus-adapter 可以替代 metrics server。
在 1.6 以上的集群中,k8s-prometheus-adapter 可以适配 autoscaling/v2 的 HPA
因为一般是部署在集群内,所以 k8s-prometheus-adapter 默认情况下,使用 in-cluster 的认证方式,以下是主要参数:

lister-kubeconfig: 默认使用 in-cluster 方式
metrics-relist-interval: 更新 metric 缓存值的间隔,最好大于等于 Prometheus 的 scrape interval,不然数据会为空
prometheus-url: 对应连接的 prometheus 地址
config:一个 yaml 文件,配置如何从 prometheus 获取数据,并与 k8s 的资源做对应,以及如何在 api 接口中展示。

config 文件的内容示例 (参考文档)
rules:
– seriesQuery: ‘{__name__=~”^container_.*”,container_name!=”POD”,namespace!=””,pod_name!=””}’
seriesFilters: []
resources:
overrides:
namespace:
resource: namespace
pod_name:
resource: pod
name:
matches: ^container_(.*)_seconds_total$
as: “”
metricsQuery: sum(rate(<<.Series>>{<<.LabelMatchers>>,container_name!=”POD”}[1m])) by (<<.GroupBy>>)
– seriesQuery: ‘{__name__=~”^container_.*”,container_name!=”POD”,namespace!=””,pod_name!=””}’
seriesFilters:
– isNot: ^container_.*_seconds_total$
resources:
overrides:
namespace:
resource: namespace
pod_name:
resource: pod
name:
matches: ^container_(.*)_total$
as: “”
metricsQuery: sum(rate(<<.Series>>{<<.LabelMatchers>>,container_name!=”POD”}[1m])) by (<<.GroupBy>>)
– seriesQuery: ‘{__name__=~”^container_.*”,container_name!=”POD”,namespace!=””,pod_name!=””}’
seriesFilters:
– isNot: ^container_.*_total$
resources:
overrides:
namespace:
resource: namespace
pod_name:
resource: pod
name:
matches: ^container_(.*)$
as: “”
metricsQuery: sum(<<.Series>>{<<.LabelMatchers>>,container_name!=”POD”}) by (<<.GroupBy>>)
问题
为什么我看不到自定义的 metric

检查下 config 配置文件,是否有选择你的 metric
检查下采集的信息是否正确,如 foo{namespace=”somens”,deployment=”bar”},foo 这个名称的数据来自于 somens 的命名空间 +bar 这个部署
启动的时候加上 –v=6,可以打出 adapter 实际的 query 信息

参考 k8s-prometheus-adapter,可以实现自己的 adapter,比如获取已有监控系统的指标,汇聚到 api-server 中,k8s-prometheus-adapter 的实现逻辑会在后续文章中专门来讲。
本文为容器监控实践系列文章,完整内容见:container-monitor-book

正文完
 0