k8s学习笔记- 部署prometheus
1.Prometheus概述
Prometheus是一个开源监控系统,它前身是SoundCloud的警告工具包。从2012年开始,许多公司和组织开始使用Prometheus。
该项目的开发人员和用户社区非常活跃,越来越多的开发人员和用户参与到该项目中。
目前它是一个独立的开源项目,且不依赖与任何公司。 为了强调这点和明确该项目治理结构,Prometheus在2016年继Kurberntes之后,加入了Cloud Native Computing Foundation。
特征:
Prometheus的主要特征有:
- 多维度数据模型
- 灵活的查询语言
- 不依赖分布式存储,单个服务器节点是自主的
- 以HTTP方式,通过pull模型拉去时间序列数据
- 也通过中间网关支持push模型
- 通过服务发现或者静态配置,来发现目标服务对象
- 支持多种多样的图表和界面展示,grafana也支持它
组件
Prometheus生态包括了很多组件,它们中的一些是可选的:
- 主服务Prometheus Server负责抓取和存储时间序列数据
- 客户库负责检测应用程序代码
- 支持短生命周期的PUSH网关
- 基于Rails/SQL仪表盘构建器的GUI
- 多种导出工具,可以支持Prometheus存储数据转化为HAProxy、StatsD、Graphite等工具所需要的数据存储格式
- 警告管理器
- 命令行查询工具
- 其他各种支撑工具
多数Prometheus组件是Go语言写的,这使得这些组件很容易编译和部署。
如上图,每个被监控的主机都可以通过专用的exporter
程序提供输出监控数据的接口,并等待Prometheus
服务器周期性的进行数据抓取。如果存在告警规则,则抓取到数据之后会根据规则进行计算,满足告警条件则会生成告警,并发送到Alertmanager
完成告警的汇总和分发。当被监控的目标有主动推送数据的需求时,可以以Pushgateway
组件进行接收并临时存储数据,然后等待Prometheus
服务器完成数据的采集。
任何被监控的目标都需要事先纳入到监控系统中才能进行时序数据采集、存储、告警和展示,监控目标可以通过配置信息以静态形式指定,也可以让Prometheus通过服务发现的机制进行动态管理。下面是组件的一些解析:
- 监控代理程序:如node_exporter:收集主机的指标数据,如平均负载、CPU、内存、磁盘、网络等等多个维度的指标数据。
- kubelet(cAdvisor):收集容器指标数据,也是K8S的核心指标收集,每个容器的相关指标数据包括:CPU使用率、限额、文件系统读写限额、内存使用率和限额、网络报文发送、接收、丢弃速率等等。
- API Server:收集API Server的性能指标数据,包括控制队列的性能、请求速率和延迟时长等等
- etcd:收集etcd存储集群的相关指标数据
- kube-state-metrics:该组件可以派生出k8s相关的多个指标数据,主要是资源类型相关的计数器和元数据信息,包括制定类型的对象总数、资源限额、容器状态以及Pod资源标签系列等。
Prometheus 能够 直接 把 Kubernetes API Server 作为 服务 发现 系统 使用 进而 动态 发现 和 监控 集群 中的 所有 可被 监控 的 对象。
这里 需要 特别 说明 的 是, Pod 资源 需要 添加 下列 注解 信息 才 能被 Prometheus 系统 自动 发现 并 抓取 其 内建 的 指标 数据。
- 1) prometheus. io/ scrape: 用于 标识 是否 需要 被 采集 指标 数据, 布尔 型 值, true 或 false。
- 2) prometheus. io/ path: 抓取 指标 数据 时 使用 的 URL 路径, 一般 为/ metrics。
- 3) prometheus. io/ port: 抓取 指标 数据 时 使 用的 套 接 字 端口, 如 8080。
另外, 仅 期望 Prometheus 为 后端 生成 自定义 指标 时 仅 部署 Prometheus 服务器 即可, 它 甚至 也不 需要 数据 持久 功能。 但 若要 配置 完整 功能 的 监控 系统, 管理员 还需 要在 每个 主机 上 部署 node_ exporter、 按 需 部署 其他 特有 类型 的 exporter 以及 Alertmanager。
Prometheus服务,可以直接通过目标拉取数据,或者间接地通过中间网关拉取数据。它在本地存储抓取的所有数据,并通过一定规则进行清理和整理数据,并把得到的结果存储到新的时间序列中,PromQL和其他API可视化地展示收集的数据
适用场景
Prometheus在记录纯数字时间序列方面表现非常好。它既适用于面向服务器等硬件指标的监控,也适用于高动态的面向服务架构的监控。对于现在流行的微服务,Prometheus的多维度数据收集和数据筛选查询语言也是非常的强大。
Prometheus是为服务的可靠性而设计的,当服务出现故障时,它可以使你快速定位和诊断问题。它的搭建过程对硬件和服务没有很强的依赖关系。
不适用场景
Prometheus,它的价值在于可靠性,甚至在很恶劣的环境下,你都可以随时访问它和查看系统服务各种指标的统计信息。 如果你对统计数据需要100%的精确,它并不适用,例如:它不适用于实时计费系统
更对详细介绍参考文章
https://www.kancloud.cn/cdh0805010118/prometheus/719339
https://github.com/yunlzheng/prometheus-book
2.在K8S 上部署Prometheus
文件清单:
node-exporter:prometheus的export,收集Node级别的监控数据
prometheus:监控服务端,从node-exporter拉数据并存储为时序数据。
kube-state-metrics:能够采集绝大多数k8s内置资源的相关数据,例如pod、deploy状态等等。同时它也提供自己的数据,主要是资源采集个数和采集发生的异常次数统计
https://blog.csdn.net/zhangoic/article/details/82844356
k8s-prometheus-adpater:聚合进apiserver,即一种custom-metrics-apiserver实现
开启Kubernetes aggregator功能(参考上文metric-server)
这个适用于Prometheus
的Kubernetes Customm Metrics Adapter
是属于Github上的k8s-prometheus-adapter项目提供的。其原理图如下:
总结:
prometheus
本身就是一监控系统,也分为server
端和agent
端,server
端从被监控主机获取数据,而agent
端需要部署一个node_exporter
,主要用于数据采集和暴露节点的数据,那么 在获取Pod级别或者是mysql等多种应用的数据,也是需要部署相关的exporter
。
我们可以通过PromQL
的方式对数据进行查询,但是由于本身prometheus
属于第三方的 解决方案,原生的k8s系统并不能对Prometheus
的自定义指标进行解析,就需要借助于k8s-prometheus-adapter
将这些指标数据查询接口转换为标准的Kubernetes
自定义指标。
参考文章
https://yasongxu.gitbook.io/container-monitor/yi-.-kai-yuan-fang-an/di-1-zhang-cai-ji/cadvisor
由于官方的YAML部署方式需要使用到PVC,如果只是为了简单的演示可以通过马哥的方式部署
注意一点,安装这个之前,必须已经安装好metrics-server (详细参考上一篇文章)
查考文档:
https://www.cnblogs.com/linuxk/p/10582534.html
我这边按照官方文档安装:
https://github.com/kubernetes/kubernetes/tree/master/cluster/addons/prometheus
下载下来相应的文档
cd /data/k8s/prometheus
mkdir promtheus
mkdir kube-state-metrics
mkdir node-exporter
cd promtheus
for file in prometheus-configmap.yaml prometheus-rbac.yaml prometheus-service.yaml prometheus-statefulset.yaml ;do wget https://raw.githubusercontent.com/kubernetes/kubernetes/master/cluster/addons/prometheus/$file;done
cd ../node-exporter
for file in node-exporter-ds.yml node-exporter-service.yaml ;do wget https://raw.githubusercontent.com/kubernetes/kubernetes/master/cluster/addons/prometheus/$file;done
cd ../kube-state-metrics
for file in kube-state-metrics-deployment.yaml kube-state-metrics-rbac.yaml kube-state-metrics-service.yaml ;do wget https://raw.githubusercontent.com/kubernetes/kubernetes/master/cluster/addons/prometheus/$file;done
整个prometheus 我安装在一个名称空间,先创建个名称空间prom
kubectl create ns prom
部署node-export
最开始安装的是node-export,它的作用是收集节点的数据,被prometheus采集的。
官方提供的node-export的yaml文件都是安装在kube-system的名称空间,所以需要修改下名称空间为prom
还有一点注意,因为我们还要监控master相关的节点,所以最好在主节点安装一个ds,可以给pod增加toleration(容忍主节点污点)
具体修改如图
node-exporter-ds.yml
1.#priorityClassName: system-node-critical #这行注释,否则创建会报错,具体的原因我还没找到
2.master节点的污点容忍度,否则不会再master节点创建pod
tolerations:
- effect: NoSchedule
key: node-role.kubernetes.io/master
3.备注:
1.为了让容器里的node-exporter获取到主机上的网络、PID、IPC指标,这里设置了hostNetwork: true、hostPID: true、hostIPC: true,来与主机共用网络、PID、IPC这三个namespace。
2.此处在Service的annotations中定义标注prometheus.io/scrape: 'true',表明该Service需要被Promethues发现并采集数据。
cd node-exporter
kubectl apply -f .
[root@k8s-master k8s]# kubectl get pods -n prom -o wide |egrep node-expor
node-exporter-5hwcg 1/1 Running 0 19h 10.211.55.11 k8s-master <none> <none>
node-exporter-92rt2 1/1 Running 0 19h 10.211.55.12 k8s-node1 <none> <none>
node-exporter-ls72w 1/1 Running 0 19h 10.211.55.13 k8s-node2 <none> <none>
可以看到Master 也部署了Pod
部署prometheus
通过查看prometheus-statefulset.yaml文件内容可知 需要持久存储数据的,官方给的yaml文件中需要设置一个16G的大小的pv
这里面涉及到存储类名所以先注释掉,当然名称空间也改成prom
#storageClassName: standard
#priorityClassName: system-cluster-critical #这个也注释掉,要不启动不起
我们这里使用的是NFS,创建一个PV
在NFS 的服务器上面配置
mkdir /data/prometheus
vim /etc/exports
/data/prometheus 10.0.0.0/8(rw,no_root_squash)
service nfs restart
注意:node节点要执行 yum install nfs-utils ,否则会出现挂载不上的情况,因为没有nfs的文件类型
vim pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pvdata
namespace: prom
labels:
name: pv01
spec:
nfs:
path: /data/prometheus
server: k8s-nfs
accessModes: ["ReadWriteOnce","ReadWriteMany"]
capacity:
storage: 20Gi
[root@master volumes]# kubectl get pv|egrep pvdata
pvdata 20Gi RWO,RWX Retain Available 20s
解决了存储问题呢,下图是主要修改的地方:
cd prometheus
[root@k8s-master prometheus]# kubectl apply -f .
[root@k8s-master prometheus]# kubectl get pod -n prom |egrep prom
prometheus-0 2/2 Running 0 22h
这里在说明一下,为了方便在外部查看prometheus-service的状态,这里修改一下
prometheus-service.yaml
type: NodePort
[root@k8s-master prometheus]# kubectl get svc -n prom |egrep prometheus
prometheus NodePort 10.102.102.188 <none> 9090:32268/TCP 22h
prometheus 本身自己有web 页面,其也有很多生成的查询条件,也可以生产图形数据,这里不做太多了解
具体配置文件参考下面文章:
https://github.com/1046102779/prometheus/blob/master/operating/configuration.md
部署kube-state-metrics
https://github.com/kubernetes/kube-state-metrics
[root@ kube-state-metrics ]# kubectl get pods -n prom |egrep kube
kube-state-metrics-6f584f4b48-tsmm8 2/2 Running 0 4h26m
部署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接口中展示。
这个组件的作用是整合收集的数据到api
自定义APIServer通常都要通过Kubernetes aggregator聚合到apiserver提供了一个APIServer服务,名为 custom-metrics-apiserver,提供的API组: custom.metrics.k8s.io,它是自定义指标API(custom.metrics.k8s.io)的实现
下面是git地址:
https://github.com/kubernetes-sigs/prometheus-adapter
cd /data/prometheus/
https://github.com/kubernetes-sigs/prometheus-adapter
cd /data/prometheus/k8s-prometheus-adapter/deploy/manifests
同样修改的是名称空间
kubectl apply -f .
kubectl get pods -n prom |egrep metrics-api
custom-metrics-apiserver-667fd4fffd-8fw98 0/1 ContainerCreating 0 3m7s
发现容器一直处于这个状态,查看详细内容可以看到下面的错误
kubectl describe pod custom-metrics-apiserver-667fd4fffd-8fw98 -n prom
Warning FailedMount 70s (x8 over 2m14s) kubelet, wan19 MountVolume.SetUp failed for volume "volume-serving-cert" : secret "cm-adapter-serving-certs" not found
通过查看文件 custom-metrics-apiserver-deployment.yaml
创建这个secret :
[root@k8s-master pki]# (umask 077; openssl genrsa -out serving.key 2048)
[root@k8s-master pki]# openssl req -new -key serving.key -out serving.csr -subj "/CN=serving"
[root@k8s-master pki]# openssl x509 -req -in serving.csr -CA ./ca.crt -CAkey ./ca.key -CAcreateserial -out serving.crt -days 3650
[root@k8s-master pki]# kubectl create secret generic cm-adapter-serving-certs --from-file=serving.crt=./serving.crt --from-file=serving.key -n prom
[root@k8s-master pki]# kubectl get secret -n prom|egrep cm-adapter
cm-adapter-serving-certs Opaque 2 20s
cd /data/prometheus/k8s-prometheus-adapter/deploy/manifests
kubectl delete -f .
kubectl apply -f .
kubectl get pod -n prom |egrep custom
custom-metrics-apiserver-667fd4fffd-8fw98 1/1 Running 0 11m
kubectl api-versions |grep custom
custom.metrics.k8s.io/v1beta1
kubectl get apiservice
有这个api说明安装成功了
推荐用helm 安装
helm pull stable/prometheus-adapter
helm install custom-metrics . -n kube-system
可以起个代理测试下如下:
kubectl proxy --port=8080
curl http://localhost:8080/apis/custom.metrics.k8s.io/v1beta1
K8S 下面测试
kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1"
获取CPU
kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/namespaces/default/pods/*/cpu_usage"
获取内存
kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/namespaces/default/pods/*/memory_usage_bytes
增加一个自定义的规则
yum install jq -y
kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/namespaces/default/pods/*/http_requests" | jq .
会得到这样的错误提示"message": "the server could not find the metric http_requests for pods"
这个就跟你部署的那个deployment的具体镜像k8s-prometheus-adapter-amd64它使用的配置文件有关,也就是custom-metrics-config-map.yaml里面定义的rules,
文件中所有的seriesQuery项在prometheus中查询后的结果都没有http_request_totals指标,所以也就肯定找不到。
把下面的规则追加到cm文件里面。
建议还是吧里面的规则都删除了,只保留自定义的规则,因为这个接口服务本来是为自定义指标服务的,其他的用metrics服务获取,当然你也可以用这个服务取代metrics,
最终的cm文件
不过访问还是没发现,这是因为,我们prommetheus 还没有采集到Pod相关的指标
所以我们引入一个测试用例
https://www.qikqiak.com/post/k8s-hpa-usage/ 可以参考这个文章
测试用例的地址
https://github.com/stefanprodan/k8s-prom-hpa/tree/master/podinfo
kubectl create -f ./test/podinfo-svc.yaml,./test/podinfo-dep.yaml
kubectl create -f ./test/podinfo-hpa.yaml
现在看到有这个数据了
现在在运行,可以获取到我们需要的指标数据了
可以查看下面的连接了解详情:
https://blog.csdn.net/weixin_30300523/article/details/94924334
https://www.qikqiak.com/post/k8s-hpa-usage/
https://github.com/stefanprodan/k8s-prom-hpa (参考文档)
https://www.jianshu.com/p/9abb697cd833
这么需要注意一点,在安装压力测试工具的时候
go get -v -u github.com/rakyll/hey
github.com/rakyll/hey (download)
created GOPATH=/root/go; see 'go help gopath'
默认安装到你运行目录下面的的go目录里面
http://10.211.55.13:32268/targets 可以看到好多信息
哈哈,总于搞完了,可以看到需要的数据和自定义的数据都有了,下面我们把这些数据用图形化的工具展示出来
Grafana数据展示
这里面涉及到的一个grafana.yaml
源文件在这下载
我这里面修改的地方:名称空间
存储卷修改PVC
镜像用的是最新的镜像,所以mountPath 需要修改,因为从grafana 5.1版本以后
mkdir: cannot create directory '/var/lib/grafana/plugins': No such file or directory 会报这个错
具体参考这篇文章:
这是我修改的地方
下面就是具体的PVC 情况
注释下面的内容,因为没有用到,我们数据源不是这个:
基本修改都是上面,修改好的文件可以到这里下载
wget https://raw.githubusercontent.com/erlonglong/test/master/grafana.yaml
kubectl get pod -n prom |egrep grafana
monitoring-grafana-54f9dbdc6-4xrx7 1/1 Running 0 23s
kubectl get svc -n prom|egrep grafana
monitoring-grafana NodePort 10.111.238.73 <none> 80:31096/TCP 5h47m
在客户端通过浏览器访问31096 的端口
下面创建默认的元数据为prometheus
格式地址是 $svcname.$namespace.svc:9090
通过下面命令可以了解到
可以看到默认已经有源配置了
接下来是导入图形模版,下载模版的地方
https://grafana.com/dashboards?dataSource=prometheus&search=kube
下面基本都是导入相应的模版
在点击红色部分,把你下载好多json的模版导入进去
导入成功,会展示下面的数据
当然还有许多模版没数据,可能和版本或者查询的数据不一样,在Status->Targets 下面查看是否 有down 的标签,导致的
具体为什么不展示还需要自己去研究
可以看到引用的查询数据语句
更快捷的部署方案
https://github.com/coreos/kube-prometheus.git
https://www.jianshu.com/p/b2f1b58c8e7f(参考文档)
后期学习地址
https://juejin.im/post/6844903908251451406
https://github.com/coreos/kube-prometheus
https://www.kancloud.cn/huyipow/prometheus/527091
https://yunlzheng.gitbook.io/prometheus-book/
https://www.kubernetes.org.cn/3418.html
https://www.servicemesher.com/blog/prometheus-operator-manual/
https://github.com/dotbalo/k8s/tree/master/prometheus-operator
https://www.servicemesher.com/blog/prometheus-monitor-k8s-2/
报警规则可以参考下面的文章,这边不细讲了,看YAML 文件就能看懂,都是按指标去监控的,定义监控指标的范围
说明一下
round() 是四舍五入取整数的函数
Prometheus 可以使用 $value 变量将当前告警规则表达式的数值输出到告警信息里。但是有些浮点数值位数相当长,非常不便于阅读,对于强迫症患者来说更是不可接受的
格式化下告警规则中的 $value 变量,有三种格式化数值的方法:
比如,下面是保留2位小数的表示方法
{{ printf "%.2f" $value }}
或
{{ $value | printf "%.2f" }}
或
{{ humanize $value }}
触发报警的模板
https://www.cszhi.com/2019/09/12/Prometheus%E6%A0%BC%E5%BC%8F%E5%8C%96%E5%91%8A%E8%AD%A6%E6%95%B0%E5%80%BC/
https://awesome-prometheus-alerts.grep.to/rules
最终整理的配置文档
https://github.com/erlonglong/k8s/tree/master/k8s/prod/prometheus