一、介绍
1、曾经
原先版本是用heapster来收集资源指标才能看,但是现在heapster废弃了。从k8s v1.8开始后,引入了新的功能,即把资源指标引入api;
在使用heapster时,获取资源指标是由heapster自已获取的,heapster有自已的获取路径,没有通过apiserver,后来k8s引入了资源指标API(Metrics API),于是资源指标的数据就从k8s的api中的直接获取,不必再通过其它途径。
k8s中很多组件是依赖于资源指标API的功能 ,比如kubectl top 、hpa,如果没有一个资源指标API接口,这些组件是没法运行的;Heapster只能根据CPU来进行HPA。
2、目前
metrics-server:它也是一种API Server,提供了核心的Metrics API,就像k8s组件kube-apiserver提供了很多API群组一样,但它不是k8s组成部分,而是托管运行在k8s之上的Pod。metrics-server是一个服务于资源指标的api server,收集cpu利用率、内存利用率等。
为了让用户无缝的使用metrics-server当中的API,还需要把这类自定义的API,通过聚合器(kube-aggregator)聚合到核心API组里,然后可以把此API当作是核心API的一部分,通过kubectl api-versions可直接查看。
Metrics server通过kubernetes聚合器(kube-aggregator)注册到主API server之上,然后基于kubelet的summary api收集每个节点上的指标数据,并将它们存储于内存中然后以指标API格式提供。
核心资源指标Core metrics:metrics-server
自定义指标Custom Metrics:不是标准的内建的指标。Prometheus,k8s-prometheus-adapter(把prometheus采集的数据转为K8S能解析的格式)
3、新一代架构
核心指标流水线:由kubelet、metrics-server以及由API server提供的api组成;cpu累计利用率、内存实时利用率、pod的资源占用率及容器的磁盘占用率;
监控流水线:用于从系统收集各种指标数据并提供终端用户、存储系统以及HPA,他们包含核心指标以及许多非核心指标。非核心指标不能被k8s所解析。
二、部署
1、卸载之前部署的Heapster相关:
[root@master ~]# cd manifests/metrics/heapster/ [root@master heapster]# kubectl delete -f ./
2、部署metrics-server
(1)准备工作
参考:
https://github.com/kubernetes-incubator/metrics-server
https://github.com/kubernetes/kubernetes/tree/master/cluster/addons/metrics-server
下载yaml文件:
[root@master metrics-server]# for file in aggregated-metrics-reader.yaml auth-delegator.yaml auth-reader.yaml metrics-apiservice.yaml metrics-server-deployment.yaml metrics-server-service.yaml resource-reader.yaml;do wget https://raw.githubusercontent.com/kubernetes-incubator/metrics-server/master/deploy/1.8%2B/$file; done
修改资源清单内容:
修改镜像路径,因为国内网络下载谷歌镜像加载不下来。修改存储卷类型,因为默认用的时emptyDir,Pod挂掉数据就丢失了。
[root@master metrics-server]# vim metrics-server-deployment.yaml [root@master metrics-server]# sed -i "s/k8s.gcr.io/registry.aliyuncs.com\/google_containers/g" *
(2)应用:
[root@master metrics-server]# kubectl apply -f ./ [root@master metrics-server]# kubectl get pod -n kube-system | grep metrics [root@master metrics-server]# kubectl get svc -n kube-system | grep metrics [root@master metrics-server]# kubectl api-versions | grep metrics
(3)问题排查:
问题1:
unable to fully collect metrics: [unable to fully scrape metrics from source kubelet_summary:node1: unable to fetch metrics from Kubelet node1 (node1): Get https://node1:10250/stats/summary/: dial tcp: i/o timeout, unable to fully scrape metrics from source kubelet_summary:master: unable to fetch metrics from Kubelet master (master): Get https://master:10250/stats/summary/: dial tcp: i/o timeout
问题原因:
由于metrics-server默认使用节点hostname通过kubelet 10250端口获取数据,但是coredns里面没有该数据无法解析,所以可在metrics server启动命令添加参数 --kubelet-preferred-address-types=InternalIP 直接使用节点IP地址获取数据;
解决方法:
# 在配置文件metrics-server/deploy/1.8+/metrics-server-deployment.yaml添加启动参数 command: - /metrics-server - --metric-resolution=30s - --kubelet-preferred-address-types=InternalIP,Hostname,InternalDNS,ExternalDNS,ExternalIP
[root@master metrics-server]# kubectl apply -f metrics-server-deployment.yaml
问题2:
[root@master metrics-server]# kubectl logs metrics-server-646fc6465b-srtl2 -n kube-system 报错详情:unable to fully collect metrics: [unable to fully scrape metrics from source kubelet_summary:node2: unable to fetch metrics from Kubelet node2 (192.168.42.130): Get https://192.168.42.130:10250/stats/summary/: x509: cannot validate certificate for 192.168.42.130 because it doesn't contain any IP SANs, unable to fully scrape metrics from source kubelet_summary:node1:
问题原因:由于kubelet 的10250端口使用的是https协议,连接需要验证tls证书。可以在metrics server启动命令添加参数--kubelet-insecure-tls不验证客户端证书。
解决方法:
# 在配置文件metrics-server/deploy/1.8+/metrics-server-deployment.yaml中启动命令添加--kubelet-insecure-tls不验证客户端证书。故,最终最终启动参数如下: command: - /metrics-server - --metric-resolution=30s - --kubelet-insecure-tls - --kubelet-preferred-address-types=InternalIP,Hostname,InternalDNS,ExternalDNS,ExternalIP
[root@master metrics-server]# kubectl apply -f metrics-server-deployment.yaml
问题3:
如果Pod和Service都运行正常,pod日志也没有报错,但就是kubectl top nodes就是报【Error from server (ServiceUnavailable): the server is currently unable to handle the request (get pods.metrics.k8s.io)】请排查网络,节点到svc,到pod网络,端口是否能通。
(4)验证
Pod运行日志没有报错。
Kubectl top能够获取到资源指标
[root@master ~]# kubectl top nodes
[root@master metrics-server]# kubectl top pods -n kube-system
通过api也能获取到资源指标
[root@master ~]# kubectl proxy --port=8001 [root@master ~]# curl http://localhost:8001/apis/metrics.k8s.io/v1beta1/nodes
3、部署prometheus
Prometheus是一个有状态应用。自身就是一个时间序列数据库。
(1)介绍
Metric-server只能监控cpu和内存,对于其他指标如用户自定义的监控指标,metrics就无法监控到了。这时就需要另外一个组件叫prometheus。
PromQL相当于sql语句来查询数据;
node-exporter:prometheus的agent端,收集Node级别的监控数据。
prometheus:监控服务端,从node-exporter拉数据并存储为时序数据。
kube-state-metrics: 将prometheus中可以用PromQL查询到的指标数据转换成k8s对应的数据格式,即转换成【Custerom Metrics API】接口格式的数据,但是它不能聚合进apiserver中的功能。
k8s-prometheus-adpater:聚合apiserver,即提供了一个apiserver【cuester-metrics-api】,自定义APIServer通常都要通过Kubernetes aggregator聚合到apiserver。
grafana:展示prometheus获取到的metrics。导入grafana模板。
kubernetes中prometheus的项目地址:https://github.com/kubernetes/kubernetes/tree/master/cluster/addons/prometheus
马哥的prometheus项目地址:https://github.com/ikubernetes/k8s-prom
(2)准备工作
本次实验使用马哥改造过的prometheus,建议从官方网站上下载资源清单进行部署。
把项目clone下来:
[root@master prometheus]# cd /root/manifests/metrics/prometheus [root@master prometheus]# git clone https://github.com/ikubernetes/k8s-prom
(3)部署
创建namespace
[root@master k8s-prom]# kubectl apply -f namespace.yaml
部署node_exporter
[root@master prometheus]# cd k8s-prom/node_exporter/ [root@master node_exporter]# kubectl apply -f ./
部署prometheus-server
[root@master prometheus]# cd k8s-prom/prometheus/ [root@master prometheus]# kubectl apply -f ./ [root@master prometheus]# kubectl get all -n prom -o wide
[root@master prometheus]# kubectl describe pod/prometheus-server-75cf46bdbc-5wv68 -n prom
[root@master prometheus]# vim prometheus-deploy.yaml #修改deploy资源清单,注释Memory资源limits [root@master prometheus]# kubectl logs prometheus-server-56949896b5-rndjf -n prom #验证部署
浏览器访问:
http://192.168.42.129:30090/metrics
部署kube-state-metrics
image: registry.cn-shanghai.aliyuncs.com/yy_k8s/kube-state-metrics-amd64:v1.4.0 #更改镜像位置,不然拉取不下来。 [root@master kube-state-metrics]# kubectl apply -f ./
部署k8s-prometheus-adapter
k8s-prometheus-adapter需要基于https提供服务,需要提供一个证书,以确保能供应为https,并且这个证书必须要为k8s集群认可的CA签发的。证书一定要叫cm-adapter-serving-certs这个名字,否则就需要改资源清单。
自签证书:
[root@master prometheus]# cd /etc/kubernetes/pki/ [root@master pki]# (umask 077;openssl genrsa -out serving.key 2048) [root@master pki]# openssl req -new -key serving.key -out serving.csr -subj "/CN=serving" [root@master pki]# openssl x509 -req -in serving.csr -CA ./ca.crt -CAkey ./ca.key -CAcreateserial -out serving.crt -days 3650 [root@master pki]# kubectl create secret generic cm-adapter-serving-certs --from-file=serving.crt=./serving.crt --from-file=serving.key=./serving.key -n prom
部署:
[root@master k8s-prometheus-adapter]# kubectl apply -f ./
未能正常启动:
查看日志:
[root@master k8s-prometheus-adapter]# kubectl describe pod custom-metrics-apiserver-6bb45c6978-psdd8 -n prom [root@master k8s-prometheus-adapter]# kubectl logs custom-metrics-apiserver-6bb45c6978-psdd8 -n prom
问题原因是启动命令里有一个选项,不能被识别。可能是版本兼容性问题,因为默认拖下来的镜像是latest标签。
尝试解决方法二:从github上去下载新的deployment资源清单来重新部署。也需要configMap的配置文件。
[root@master k8s-prometheus-adapter]# wget https://raw.githubusercontent.com/DirectXMan12/k8s-prometheus-adapter/master/deploy/manifests/custom-metrics-apiserver-deployment.yaml [root@master k8s-prometheus-adapter]# wget https://raw.githubusercontent.com/DirectXMan12/k8s-prometheus-adapter/master/deploy/manifests/custom-metrics-config-map.yaml 修改刚刚下载资源清单的namespace,从custom-metrics改为prom,因为我们之前的资源都在这个名称空间: [root@master k8s-prometheus-adapter]# vim custom-metrics-apiserver-deployment.yaml [root@master k8s-prometheus-adapter]# vim custom-metrics-config-map.yaml [root@master k8s-prometheus-adapter]# kubectl apply -f custom-metrics-config-map.yaml [root@master k8s-prometheus-adapter]# kubectl apply -f custom-metrics-apiserver-deployment.yaml
[root@master ~]# kubectl proxy --port=8001
[root@master k8s-prometheus-adapter]# curl http://localhost:8001/apis/custom.metrics.k8s.io/v1beta1/
现在已经可以获取很多的指标数据了。
Tips:建议直接去GitHub上获取最新的清单来部署(https://github.com/DirectXMan12/k8s-prometheus-adapter),并且不能为了部署而部署,应该好好看看资源清单的内容,不然排错都不知道咋查。
部署grafana,整合prometheus
上一次部署Heapster时使用的grafana.yaml刚好拿来使用,只是需要修改名称空间(deployment和service都需要改)和数据源(注释掉influxDB相关的环境变量即可,不注释应该也可以)。
[root@master k8s-prom]# kubectl apply -f grafana.yaml
浏览器访问:http://192.168.42.128:32571/?orgId=1
在web界面修改数据源为prometheus。
导入一些prometheus一些自带的监控指标的dashboard。
找到dashboard,可以看到大部分没有数据,但还是有些数据的,可以证明接入没有问题。
可以在grafana网站上去下载prometheus相关Kubernetes的监控模板,然后导入使用,但定制化还是需要了解监控模板的配置,告警的配置等。
三、HPA
1、介绍
HPA:Horizontal Pod Autoscaling,是Kubernetes中实现POD水平自动伸缩的功能。它可以根据CPU使用率或应用自定义metrics自动扩展Pod数量(支持 replication controller、deployment 和 replica set),支持应用规模的自动伸缩。目前HPA只支持两个版本,其中v1版本只支持核心指标的定义。
HPA(Horizontal Pod Autoscaling,Pod横向自动扩容):通过追踪分析RC控制的所有Pod的负载变化情况,来确认是否需要针对性的调整目标Pod的副本数量。
HPA的Pod调度指标:
- CpuUtilizationPercentage
- 应用程序自定义的度量指标(TPS或QPS等)
需要使用核心指标伸缩的资源一定要定义resources.requests
hpa v1版本只能根据cpu利用率括水平自动扩展pod。 hpa v2可以根据CPU,内存,自定义指标利用率来水平扩展pod。
[root@master k8s-prom]# kubectl explain hpa [root@master k8s-prom]# kubectl explain hpa.spec
文档:https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status
2、核心指标自动伸缩
创建deployment:
[root@master hpa]# kubectl run myapp --image=ikubernetes/myapp:v1 --replicas=1 --requests='cpu=50m,memory=256Mi' --limits='cpu=50m,memory=256Mi' --labels='app=myapp' --expose --port=80
让这个deployment能够自动伸缩,其实就是创建一个HPA控制器:
[root@master hpa]# kubectl autoscale deployment myapp --min=1 --max=4 --cpu-percent=60 # 使用命令创建的hpa默认为v1版本
Hpa一直获取不到CPU数据,不知道为啥?需解决。(不清楚是不是因为annotation没有配置,一般pod需要prometheus去采集需要配置)
压测:
压测需要能够外网访问,所以需要把对应的svc改为NodePort模式。
[root@master hpa]# kubectl patch svc myapp -p '{"spec":{"type":"NodePort"}}'
下载压测工具:
[root@master hpa]# yum install httpd-tools –y 测试: [root@master hpa]# ab -c 1000 -n 500000 http://192.168.42.128:31913/index.html [root@master manifests]# kubectl get pod –w # 动态观察pod数量变化
3、自定义指标自动伸缩
hpa v2可以根据cpu和内存使用率进行伸缩Pod个数,还可以根据其他参数进行pod处理,如http并发量。
[root@master hpa]# kubectl explain hpa --api-version='autoscaling/v2beta1' [root@master hpa]# kubectl explain hpa --api-version='autoscaling/v2beta2'
# autoscaling的v1,v2beta1,v2beta2版本的资源清单定义都不一样,只能一个个看。
autoscaling/v2beta1:
autoscaling/v2beta2:
和核心指标一样,v2beta1和v2beta2版本都采集不到数据,需要排查。