Fork me on GitHub
Fork me on GitHub

资源指标API及自定义指标API

Kubernetes资源指标

官方文档的changelog中讲从1.11版本开始,开始将监控体系,指标数据获取机制移向新一代的监控模型。对于k8s来讲,现在有两种资源指标被使用:
1、资源指标
2、自定义指标
heapster提供的指标收集和存储的功能,并支持多个数据接收器,或者说是sink,比如说influxdb。每个存储后端的代码都驻留在heapster代码仓库中。意思是说heapster为了支持多种各种各样的存储后端,不得不去适配和驱动每一个不同的后端。这每一个适配器都是第三方组织研发的,第三方组织哪一天没兴趣了,就不维护了。以至于heapster为了适配很多存储后端,整合了近十几个后端存储的适配器,有些适配器自从整合进heapster以后在也没改动过,但heapster为此就不得不付出代码量很庞大的局面,所以这就意味着heapster里的设计架构不适用于这种云原生。所以要设计新一代的监控架构。k8s本身如此强大,一个方面就在于很多功能是可以基于addons来实现,非常灵活。而且现在版本中的k8s还支持开发人员轻松自己定义自己的api服务器,来扩展核心api服务。意思是如果用户觉得现有的资源类型,比如service、pod,不能够解决我们自己的问题,我们可以根据自己实际的需要扩展k8s系统所支持的资源类型。
传统heapster时代,大多数功能都是通过apiserver获取的,除了一个功能不是,就是要想获取资源指标数据,得专门部署一个addon,叫heapster。能不能干脆把资源指标这样的数据也直接整合进apiserver。让用户能通过apiserver获取所有数据,包括指标。
从1.8以后引入了资源指标API。另外,k8s从1.6引入了自定义指标。很多系统级的组件都是依赖于这些指标API的功能的,比如kubectl top。没有资源指标供给,是没办法运行的。另外像HPA,水平Pod自动伸缩器。这也是必须根据获取当前Pod使用的资源量,比如CPU负载80%已经很高了,可以额外加几个Pod。如果Pod的CPU使用率一直低于5%,可以删除几个,腾出一些资源和空间,留给其他Pod使用。Pod无论运行与否,requests一直会预留给这个Pod使用,这些资源放那不用,不运行,很可惜。可以移除一些这样的Pod,腾出空间给其他Pod使用。这些组件都是依赖资源指标工作的,早期都是依赖heapster来实现的。新一代的资源指标API获取的主要方式是靠metric-server实现的。

资源指标: metrics-server
自定义指标: prometheus, k8s-prometheus-adapter。 prometheus要想把它的监控的采集数据转成指标格式,需要一个特殊的组件来实现,k8s-prometheus-adapter。这是早期的版本,还没来得及看现有版本是否有了改进。prometheus已经被CNCF收录进去了,是个强大的监控系统。

新一代架构

核心指标流水线: 由kubelet、metrics-server以及由API server提供的api组成;
主要提供CPU累积使用率(这个程序累计使用CPU多长时间占整个CPU时长多大比例)、内存实时使用率、Pod的资源占用率及容器的磁盘占用率。
除了这些指标,可能你还需要评估网络、连接数量、可用网络带宽等等,这些度量标准一般而言就需要用第三方组件了。核心指标是不适合第三方来提供的,因为这些核心指标将会被系统中的很多组件使用。
监控流水线: 在系统上部署一个监控系统,用于从系统收集各种指标数据并提供终端用户、存储系统以及HPA,它们包含核心指标及许多非核心指标,并不仅限于CPU、内存、Pod的资源占用率及容器的磁盘占用率等数据。所以HPA既能够使用核心指标,也可以使用监控流水线中的扩展指标。监控流水线提供的指标我们称为非核心指标,但它通常也包括核心指标。
非核心指标本身不能被k8s所解析。比如prometheus采集到的数据,那是prometheus语境中保存的,prometheus能理解没问题,但是k8s理解不了,这就是为什么需要一个叫k8s-prometheus-adapter的原因。

metrics-server

metrics-server 是一个外部的API服务器,它是提供资源指标服务的。metrics-server本身不是k8s的组成部分,它是托管运行在k8s之上的一个Pod。
k8s apiserver该怎么运行怎么运行,除此之外我们又运行了一个metrics-server,它提供另外一组API,我们需要把这两组API合并成一个使用,在它两个之间加一个代理,这个代理称为kube-aggregator,聚合器。相当于把来自多个地方的API聚合成一个来使用。不光光能聚合这两个,还能聚合第三方用户定义的API server。而这个聚合器提供的资源指标将通过apis下的一个群组叫 /apis/metrics.k8s.io/v1beta1 来获取。在没部署metrics-server之前,通过kubectl api-versions是获取不到这个群组的,部署完后是可以获取到的。以后通过这个聚合器kube-aggregator既可以访问apiserver下的群组,也可以访问metrics-server下的群组。
heapster被废了,因此metrics-server已经成为k8s多个核心组件的先决条件,没有它就没办法运行。比如kubectl top,HPA等。

部署metrics-server

打开metrics-server在github上的主页:https://github.com/kubernetes-incubator/metrics-server

点击进入deploy目录下,我这里k8s集群是1.14.1,所以点击进入1.8+目录,把这些yaml文件下载下来执行:

1
2
3
4
5
[root@spark32 manifests]# mkdir metrics-server
[root@spark32 manifests]# cd metrics-server
[root@spark32 metrics-server]# for file in auth-delegator.yaml auth-reader.yaml metrics-apiservice.yaml metrics-server-deployment.yaml metrics-server-service.yaml resource-reader.yaml aggregated-metrics-reader.yaml; do wget ht
tps://raw.githubusercontent.com/kubernetes-incubator/metrics-server/master/deploy/1.8%2B/$file; done
[root@spark32 metrics-server]# kubectl apply -f .

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[root@spark32 metrics-server]# kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
canal-p9v5f 2/2 Running 0 22d
canal-sksfk 2/2 Running 0 22d
canal-zchqq 2/2 Running 0 22d
canal-zgwsq 2/2 Running 0 22d
coredns-fb8b8dccf-t2xj8 1/1 Running 0 180d
coredns-fb8b8dccf-xdjkx 1/1 Running 0 180d
etcd-spark32 1/1 Running 1 180d
kube-apiserver-spark32 1/1 Running 0 180d
kube-controller-manager-spark32 1/1 Running 0 180d
kube-flannel-ds-amd64-2mcd2 1/1 Running 0 22d
kube-flannel-ds-amd64-jsx8s 1/1 Running 0 22d
kube-flannel-ds-amd64-kk8cx 1/1 Running 0 22d
kube-flannel-ds-amd64-vdjn4 1/1 Running 0 22d
kube-proxy-czhfc 1/1 Running 0 180d
kube-proxy-gzhqw 1/1 Running 0 64d
kube-proxy-rfxjw 1/1 Running 0 180d
kube-proxy-xmkxq 1/1 Running 0 180d
kube-scheduler-spark32 1/1 Running 0 180d
kubernetes-dashboard-5f7b999d65-ngrr7 1/1 Running 0 24d
metrics-server-7967c9877f-m4jl8 1/1 Running 0 21d

但是查看pod日志,一直在报错:

1
unable to fully collect metrics: [unable to fully scrape metrics from source kubelet_summary:<hostname>: unable to fetch metrics from Kubelet <hostname> (<hostname>): Get https://<hostname>:10250/stats/summary/: dial tcp: lookup <hostname> on 10.96.0.10:53: no such host

解决:https://github.com/kubernetes-incubator/metrics-server/issues/143

1
2
[root@spark32 metrics-server]# kubectl delete -f .
[root@spark32 metrics-server]# vim metrics-server-deployment.yaml


1
[root@spark32 metrics-server]# kubectl apply -f .


部署完后,如果metrics-server已经收集到数据了,我们就可以使用curl命令去获取数据了。

1
[root@spark32 metrics-server]# curl http://localhost:8080/apis/metrics.k8s.io/v1beta1



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
[root@spark32 metrics-server]# kubectl top nodes
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
hadoop16 148m 7% 4470Mi 58%
spark17 86m 2% 4824Mi 63%
spark32 282m 3% 16629Mi 69%
ubuntu31 130m 1% 2724Mi 17%
[root@spark32 metrics-server]# kubectl top pods
NAME CPU(cores) MEMORY(bytes)
initcontainer-myapp-pod 0m 1Mi
myapp-deploy-675558bfc5-4sn9w 0m 2Mi
myapp-deploy-675558bfc5-7qn59 0m 3Mi
myapp-deploy-675558bfc5-jww2c 0m 2Mi
pod-demo 0m 4Mi
[root@spark32 metrics-server]# kubectl top pods -n kube-system
NAME CPU(cores) MEMORY(bytes)
canal-p9v5f 16m 31Mi
canal-sksfk 30m 47Mi
canal-zchqq 16m 33Mi
canal-zgwsq 28m 49Mi
coredns-fb8b8dccf-t2xj8 4m 18Mi
coredns-fb8b8dccf-xdjkx 3m 19Mi
etcd-spark32 31m 361Mi
kube-apiserver-spark32 37m 436Mi
kube-controller-manager-spark32 20m 65Mi
kube-flannel-ds-amd64-2mcd2 3m 21Mi
kube-flannel-ds-amd64-jsx8s 2m 15Mi
kube-flannel-ds-amd64-kk8cx 3m 22Mi
kube-flannel-ds-amd64-vdjn4 2m 13Mi
kube-proxy-czhfc 1m 20Mi
kube-proxy-gzhqw 2m 13Mi
kube-proxy-rfxjw 1m 25Mi
kube-proxy-xmkxq 3m 26Mi
kube-scheduler-spark32 2m 21Mi
kubernetes-dashboard-5f7b999d65-ngrr7 1m 21Mi
metrics-server-7967c9877f-m4jl8 1m 17Mi

Prometheus

Prometheus介绍

Prometheus是个监控系统,和zabbix一样,都是server-agent模式。在每个节点上都要部署agent,node_exporter,但是这个组件只是用来采集当前节点的系统级指标数据的,如果要采集其他指标数据,比如采集mysql的,还需要部署mysql的exporter,还有很多重量级服务的专用exporter。
要去采集Pod的话,Pod在k8s上本身就有获取采集数据的接口,倒也不一定非得额外去部署,更何况其实每个容器的日志都在节点上。 这些日志信息是通过对应的接口输出出来的。简单来讲,prometheus是通过metrics-url来到各Pod获取数据的。

1
2
[root@spark32 ~]# cd /var/log/containers/
[root@spark32 containers]# ll


采集以后,如何看呢?prometheus提供一个非常强大的接口叫PromQL。mysql有个查询语句叫sql。PromQL支持非常强大的restful风格接口的查询条件表达式。但是这种数据是不能被apiserver解析的,数据格式不兼容。因此如果期望能够让这些数据通过k8s的apiserver,像在apiserver中请求获取数据一样来获取指标数据,那么必须把PromQL所查询到的数据格式转为k8s的api查询接口的格式。这就需要k8s-prometheus-adapter,这是第三方开发的。这个k8s-prometheus-adapter能够用PromQL语句完成从prometheus这里查询到一些指标数据,并转为k8s apiserver上的格式的数据。

部署Prometheus

建议将prometheus放到单独的名称空间里去。