Prometheus
Prometheus

目录
[toc]
Prometheus基础
1.简介
我们知道监控是保证系统运行必不可少的功能,特别是对于 Kubernetes 这种比较庞大的系统来说,监控报警更是不可或缺,我们需要时刻了解系统的各种运行指标,也需要时刻了解我们的 Pod 的各种指标,更需要在出现问题的时候有报警信息通知到我们。
在早期的版本中 Kubernetes 提供了 heapster、influxDB、grafana 的组合来监控系统,在现在的版本中已经移除掉了 heapster。现在更加流行的监控工具是 Prometheus,Prometheus 是 Google 内部监控报警系统的开源版本,是 Google SRE 思想在其内部不断完善的产物,它的存在是为了更快和高效的发现问题,快速的接入速度,简单灵活的配置都很好的解决了这一切,而且是已经毕业的 CNCF 项目。
2.特点
Prometheus 最初是 SoundCloud 构建的开源系统监控和报警工具,是一个独立的开源项目,于2016年加入了 CNCF 基金会,作为继 Kubernetes 之后的第二个托管项目。Prometheus 相比于其他传统监控工具主要有以下几个特点:
- 具有由 metric 名称和键/值对标识的时间序列数据的多维数据模型
- 有一个灵活的查询语言
- 不依赖分布式存储,只和本地磁盘有关
- 通过 HTTP 的服务拉取时间序列数据
- 也支持推送的方式来添加时间序列数据
- 还支持通过服务发现或静态配置发现目标
- 多种图形和仪表板支持
3.架构
Prometheus 由多个组件组成,但是其中有些组件是可选的:
Prometheus Server:用于抓取指标、存储时间序列数据exporter:暴露指标让任务来抓pushgateway:push 的方式将指标数据推送到该网关alertmanager:处理报警的报警组件adhoc:用于数据查询
大多数 Prometheus 组件都是用 Go 编写的,因此很容易构建和部署为静态的二进制文件。下图是 Prometheus 官方提供的架构及其一些相关的生态系统组件:

整体流程比较简单,Prometheus 直接接收或者通过中间的 Pushgateway 网关被动获取指标数据,在本地存储所有的获取的指标数据,并对这些数据进行一些规则整理,用来生成一些聚合数据或者报警信息,Grafana 或者其他工具用来可视化这些数据。
注意:prometheus的数据可以也可以存储在ceph里,但不能存储在nfs里。测试环境,你可以用nfs,prometheus是可以跑起来的。但生产环境一定不能用nfs,否则重建之后,以前的历史数据可其他能会被损坏!
💘 实战:prometheus部署(测试成功)-2022.4.29

实验环境
1centos7
2prometheus-2.35.0
实验软件
链接:https://pan.baidu.com/s/1A1ZLbqxz4JSwbg0elPKRNQ?pwd=fv3a
提取码:fv3a
prometheus-2.35.0.linux-amd64.tar.gz

1、下载prometheus二进制安装包
由于 Prometheus 是 Golang 编写的程序,所以要安装的话也非常简单,只需要将二进制文件下载下来直接执行即可,前往地址:https://prometheus.io/download 下载最新版本即可。
直接下载相应系统安装包:

2、启动prometheus
将二进制软件包上传到linux下,并解压:
1[root@master1 ~]#ll -h prometheus-2.35.0.linux-amd64.tar.gz
2-rw-rw-rw- 1 root root 77M Apr 28 12:38 prometheus-2.35.0.linux-amd64.tar.gz
3[root@master1 ~]#tar -xf prometheus-2.35.0.linux-amd64.tar.gz
4[root@master1 ~]#cd prometheus-2.35.0.linux-amd64/
5[root@master1 prometheus-2.35.0.linux-amd64]#ll
6total 198236
7drwxr-xr-x 2 3434 3434 38 Apr 21 17:59 console_libraries #2个与prometheus dashboard相关的
8drwxr-xr-x 2 3434 3434 173 Apr 21 17:59 consoles
9-rw-r--r-- 1 3434 3434 11357 Apr 21 17:59 LICENSE
10-rw-r--r-- 1 3434 3434 3773 Apr 21 17:59 NOTICE
11-rwxr-xr-x 1 3434 3434 105576684 Apr 21 17:55 prometheus #二进制文件
12-rw-r--r-- 1 3434 3434 934 Apr 21 17:59 prometheus.yml
13-rwxr-xr-x 1 3434 3434 97394322 Apr 21 17:58 promtool #校验相关的
- 启动prometheus
Prometheus 是通过一个 YAML 配置文件来进行启动的,如果我们使用二进制的方式来启动的话,可以使用下面的命令:
1./prometheus
2或者
3./prometheus --config.file=prometheus.yml

其中 prometheus.yml 文件的基本配置如下:
1global:
2 scrape_interval: 15s
3 evaluation_interval: 15s #评估频率
4
5rule_files: #告警规则文件
6 # - "first.rules"
7 # - "second.rules"
8
9scrape_configs:
10 - job_name: prometheus
11 static_configs:
12 - targets: ['localhost:9090']
上面这个配置文件中包含了3个模块:global、rule_files 和 scrape_configs。
global模块控制Prometheus Server的全局配置:scrape_interval:表示 prometheus 抓取指标数据的频率,默认是15s,我们可以覆盖这个值evaluation_interval:用来控制评估规则的频率,prometheus 使用规则产生新的时间序列数据或者产生警报
rule_files:指定了报警规则所在的位置,prometheus 可以根据这个配置加载规则,用于生成新的时间序列数据或者报警信息,当前我们没有配置任何报警规则。scrape_configs用于控制 prometheus 监控哪些资源。
由于 prometheus 通过 HTTP 的方式来暴露的它本身的监控数据,prometheus 也能够监控本身的健康情况。在默认的配置里有一个单独的 job,叫做 prometheus,它采集 prometheus 服务本身的时间序列数据。这个 job 包含了一个单独的、静态配置的目标:监听 localhost 上的 9090 端口。prometheus 默认会通过目标的 /metrics 路径采集 metrics。所以,默认的 job 通过 URL:http://localhost:9090/metrics 采集 metrics。收集到的时间序列包含 prometheus 服务本身的状态和性能。如果我们还有其他的资源需要监控的话,直接配置在 scrape_configs 模块下面就可以了。
3、验证
在浏览器里输入链接:http://172.29.9.51:9090/即可打开prometheus页面了

- Graph图表:

Status/Configuration:



http://172.29.9.51:9090/metrics

注意:有的应用可能不希望自己的应用的/metrics暴露在外面,prometheus这里是可以加上auth认证的!


实验结束。😘
💘 实战:prometheus部署到k8s-2022.4.29(测试成功)

实验环境
1k8s:v1.22.2,containerd:1.5.5
2prometheus:prom/prometheus:v2.34.0
实验软件
链接:https://pan.baidu.com/s/12jfLts2wtJQUvT3WrD9EJg?pwd=rbvo
提取码:rbvo
2022.4.29-prometheus综合应用demo-code

前置条件
1具有k8s环境:k8s:v1.22.2,containerd:1.5.5
将Prometheus应用部署在k8s里
但是由于我们这里是要运行在 Kubernetes 系统中,所以我们直接用 Docker 镜像的方式运行。
1.创建monitor命名空间
- 为了方便管理,我们将监控相关的所有资源对象都安装在
monitor这个 namespace 下面,没有的话可以提前创建。
1[root@master1 ~]#kubectl create ns monitor
2namespace/monitor created
2.将 prometheus.yml 文件用 ConfigMap 的形式进行管理
本次实验目录如下:
1[root@master1 ~]#mkdir prometheus-example
2[root@master1 ~]#cd prometheus-example/
- 为了能够方便的管理配置文件,我们这里将
prometheus.yml文件用 ConfigMap 的形式进行管理:
[root@master1 prometheus-example]#vim prometheus-cm.yaml
1# prometheus-cm.yaml
2apiVersion: v1
3kind: ConfigMap
4metadata:
5 name: prometheus-config
6 namespace: monitor
7data:
8 prometheus.yml: |
9 global:
10 scrape_interval: 15s
11 scrape_timeout: 15s
12 scrape_configs:
13 - job_name: 'prometheus'
14 static_configs:
15 - targets: ['localhost:9090']
注意:

3.创建prometheus 的 Pod 资源
现在我们来创建 prometheus 的 Pod 资源:
[root@master1 prometheus-example]#vim prometheus-deploy.yaml
1# prometheus-deploy.yaml
2apiVersion: apps/v1
3kind: Deployment
4metadata:
5 name: prometheus
6 namespace: monitor
7 labels:
8 app: prometheus
9spec:
10 selector:
11 matchLabels:
12 app: prometheus
13 template:
14 metadata:
15 labels:
16 app: prometheus
17 spec:
18 serviceAccountName: prometheus
19 containers:
20 - image: prom/prometheus:v2.34.0
21 name: prometheus
22 args:
23 - "--config.file=/etc/prometheus/prometheus.yml"
24 - "--storage.tsdb.path=/prometheus" # 指定tsdb数据路径
25 - "--storage.tsdb.retention.time=24h" #保存时间
26 - "--web.enable-admin-api" # 控制对admin HTTP API的访问,其中包括删除时间序列等功能
27 - "--web.enable-lifecycle" # 支持热更新,直接执行localhost:9090/-/reload立即生效
28 ports:
29 - containerPort: 9090
30 name: http
31 volumeMounts:
32 - mountPath: "/etc/prometheus"
33 name: config-volume
34 - mountPath: "/prometheus"
35 name: data
36 resources:
37 requests:
38 cpu: 100m
39 memory: 512Mi
40 limits:
41 cpu: 100m
42 memory: 512Mi
43 volumes:
44 - name: data #tsdb数据路径:/prometheus,这里使用的是pvc
45 persistentVolumeClaim:
46 claimName: prometheus-data
47 - configMap: #
48 name: prometheus-config
49 name: config-volume
1…… #上面突然写成那种我还看不懂了哈哈……老铁,没毛病!
2 volumes: #这里要再次熟悉下关于volumes/volumeMounts数据卷挂载的使用方法!!!
3 - name: data #tsdb数据路径:/prometheus,这里使用的是pvc
4 persistentVolumeClaim:
5 claimName: prometheus-data
6 - name: config-volume
7 configMap: #
8 name: prometheus-config
另外为了 prometheus 的性能和数据持久化我们这里是直接将通过一个 LocalPV 来进行数据持久化的,通过 --storage.tsdb.path=/prometheus 指定数据目录。
4.创建prometheus的pv/pvc资源
创建如下所示的一个 PVC 资源对象,注意是一个 LocalPV,和 node1 节点具有亲和性:
- 先在宿主机node1节点上上创建这个下面LocalPV要使用到的本地目录:
1[root@master1 ~]#ssh node1
2Last login: Fri Apr 29 09:57:06 2022 from master1
3[root@node1 ~]#mkdir -p /data/k8s/prometheus
- 创建prometheus-pvc.yaml文件:
[root@master1 prometheus-example]#vim prometheus-pvc.yaml
1#prometheus-pvc.yaml
2apiVersion: v1
3kind: PersistentVolume
4metadata:
5 name: prometheus-local
6 labels:
7 app: prometheus
8spec:
9 accessModes:
10 - ReadWriteOnce
11 capacity:
12 storage: 20Gi
13 storageClassName: local-storage
14 local:
15 path: /data/k8s/prometheus #一定要先在宿主机上创建这个目录!!!
16 nodeAffinity: #pv也是可以配置节点亲和性的哦!!!
17 required:
18 nodeSelectorTerms:
19 - matchExpressions:
20 - key: kubernetes.io/hostname
21 operator: In
22 values:
23 - node1 #这里是自己的node1节点
24 persistentVolumeReclaimPolicy: Retain
25---
26apiVersion: v1
27kind: PersistentVolumeClaim
28metadata:
29 name: prometheus-data
30 namespace: monitor
31spec:
32 selector:
33 matchLabels:
34 app: prometheus
35 accessModes:
36 - ReadWriteOnce
37 resources:
38 requests:
39 storage: 20Gi
40 storageClassName: local-storage
5.创建prometheus的rbac资源
由于 prometheus 可以访问 Kubernetes 的一些资源对象,所以需要配置 rbac 相关认证,这里我们使用了一个名为 prometheus 的 serviceAccount 对象:
[root@master1 prometheus-example]#vim prometheus-rbac.yaml
1# prometheus-rbac.yaml
2apiVersion: v1
3kind: ServiceAccount #创建一个ServiceAccount
4metadata:
5 name: prometheus
6 namespace: monitor
7---
8apiVersion: rbac.authorization.k8s.io/v1
9kind: ClusterRole
10metadata:
11 name: prometheus
12rules:
13- apiGroups:
14 - ""
15 resources:
16 - nodes
17 - services
18 - endpoints
19 - pods
20 - nodes/proxy
21 verbs:
22 - get
23 - list
24 - watch
25- apiGroups:
26 - "extensions"
27 resources:
28 - ingresses
29 verbs:
30 - get
31 - list
32 - watch
33- apiGroups:
34 - ""
35 resources:
36 - configmaps
37 - nodes/metrics
38 verbs:
39 - get
40- nonResourceURLs:
41 - /metrics
42 verbs:
43 - get
44---
45apiVersion: rbac.authorization.k8s.io/v1
46kind: ClusterRoleBinding
47metadata:
48 name: prometheus
49roleRef:
50 apiGroup: rbac.authorization.k8s.io
51 kind: ClusterRole
52 name: prometheus
53subjects:
54- kind: ServiceAccount
55 name: prometheus
56 namespace: monitor
由于我们要获取的资源信息,在每一个 namespace 下面都有可能存在,所以我们这里使用的是 ClusterRole 的资源对象。
值得一提的是我们这里的权限规则声明中有一个 nonResourceURLs 的属性,是用来对非资源型 metrics 进行操作的权限声明,这个在以前我们很少遇到过。
6.创建以上资源
- 创建prometheus.yml
我们这里暂时只配置了对 prometheus本身的监控,直接创建该资源对象:
1[root@master1 prometheus-example]#kubectl apply -f prometheus-cm.yaml
2configmap/prometheus-config created
配置文件创建完成了,以后如果我们有新的资源需要被监控,我们只需要将上面的 ConfigMap 对象更新即可。
- 创建prometheus-pv-pvc.yaml
1[root@master1 prometheus-example]#kubectl apply -f prometheus-pvc.yaml
2persistentvolume/prometheus-local created
3persistentvolumeclaim/prometheus-data created
4
5#验证
6[root@master1 prometheus-example]#kubectl get pvc -nmonitor
7NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
8prometheus-data Bound prometheus-local 20Gi RWO local-storage 33s
9[root@master1 prometheus-example]#kubectl get pv
10NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
11prometheus-local 20Gi RWO Retain Bound monitor/prometheus-data local-storage 35s

- 创建prometheus-rbac.yaml
1[root@master1 prometheus-example]#kubectl apply -f prometheus-rbac.yaml
2serviceaccount "prometheus" created
3clusterrole.rbac.authorization.k8s.io "prometheus" created
4clusterrolebinding.rbac.authorization.k8s.io "prometheus" created
- 现在我们就可以添加 promethues 的资源对象了:
1[root@master1 prometheus-example]#kubectl apply -f prometheus-deploy.yaml
2deployment.apps/prometheus created
3
4[root@master1 prometheus-example]#kubectl get pods -n monitor
5NAME READY STATUS RESTARTS AGE
6prometheus-58f59fd485-7hncv 0/1 CrashLoopBackOff 2 (24s ago) 112s
7
8[root@master1 prometheus-example]#kubectl logs prometheus-58f59fd485-7hncv -nmonitor
9ts=2022-04-29T04:42:09.982Z caller=main.go:516 level=info msg="Starting Prometheus" version="(version=2.34.0, branch=HEAD, revision=881111fec4332c33094a6fb2680c71fffc427275)"
10ts=2022-04-29T04:42:09.982Z caller=main.go:521 level=info build_context="(go=go1.17.8, user=root@121ad7ea5487, date=20220315-15:18:00)"
11ts=2022-04-29T04:42:09.982Z caller=main.go:522 level=info host_details="(Linux 3.10.0-957.el7.x86_64 #1 SMP Thu Nov 8 23:39:32 UTC 2018 x86_64 prometheus-58f59fd485-7hncv (none))"
12ts=2022-04-29T04:42:09.982Z caller=main.go:523 level=info fd_limits="(soft=65536, hard=65536)"
13ts=2022-04-29T04:42:09.982Z caller=main.go:524 level=info vm_limits="(soft=unlimited, hard=unlimited)"
14ts=2022-04-29T04:42:09.983Z caller=query_logger.go:90 level=error component=activeQueryTracker msg="Error opening query log file" file=/prometheus/queries.active err="open /prometheus/queries.active: permission denied"
15panic: Unable to create mmap-ed active query log
16
17goroutine 1 [running]:
18github.com/prometheus/prometheus/promql.NewActiveQueryTracker({0x7ffe09113e00, 0xb}, 0x14, {0x3637a40, 0xc0002032c0})
19 /app/promql/query_logger.go:120 +0x3d7
20main.main()
21 /app/cmd/prometheus/main.go:569 +0x6049

创建 Pod 后,我们可以看到并没有成功运行,出现了 open /prometheus/queries.active: permission denied 这样的错误信息,这是因为我们的 prometheus 的镜像中是使用的 nobody 这个用户,然后现在我们通过 LocalPV 挂载到宿主机上面的目录的 ownership 却是 root:
1[root@node1 ~]#ls -la /data/k8s
2total 0
3drwxr-xr-x 3 root root 24 Apr 29 09:57 .
4drwxr-xr-x 3 root root 17 Apr 29 09:57 ..
5drwxr-xr-x 2 root root 6 Apr 29 09:57 prometheus
所以当然会出现操作权限问题了,这个时候我们就可以通过 securityContext 来为 Pod 设置下 volumes 的权限,通过设置 runAsUser=0 指定运行的用户为 root;也可以通过设置一个 initContainer 来修改数据目录权限(本次使用后面这种方法):
1[root@master1 prometheus-example]#vim prometheus-deploy.yaml
2......
3initContainers:
4- name: fix-permissions
5 image: busybox
6 command: [chown, -R, "nobody:nobody", /prometheus]
7 volumeMounts:
8 - name: data
9 mountPath: /prometheus

完整代码如下:
1# prometheus-deploy.yaml
2apiVersion: apps/v1
3kind: Deployment
4metadata:
5 name: prometheus
6 namespace: monitor
7 labels:
8 app: prometheus
9spec:
10 selector:
11 matchLabels:
12 app: prometheus
13 template:
14 metadata:
15 labels:
16 app: prometheus
17 spec:
18 serviceAccountName: prometheus
19 initContainers:
20 - name: fix-permissions
21 image: busybox
22 command: [chown, -R, "nobody:nobody", /prometheus]
23 volumeMounts:
24 - name: data
25 mountPath: /prometheus
26 containers:
27 - image: prom/prometheus:v2.34.0
28 name: prometheus
29 args:
30 - "--config.file=/etc/prometheus/prometheus.yml"
31 - "--storage.tsdb.path=/prometheus" # 指定tsdb数据路径
32 - "--storage.tsdb.retention.time=24h" #保存时间
33 - "--web.enable-admin-api" # 控制对admin HTTP API的访问,其中包括删除时间序列等功能
34 - "--web.enable-lifecycle" # 支持热更新,直接执行localhost:9090/-/reload立即生效
35 ports:
36 - containerPort: 9090
37 name: http
38 volumeMounts:
39 - mountPath: "/etc/prometheus"
40 name: config-volume
41 - mountPath: "/prometheus"
42 name: data
43 resources:
44 requests:
45 cpu: 100m
46 memory: 512Mi
47 limits:
48 cpu: 100m
49 memory: 512Mi
50 volumes: #这里要再次熟悉下关于volumes/volumeMounts数据卷挂载的使用方法!!!
51 - name: data #tsdb数据路径:/prometheus,这里使用的是pvc
52 persistentVolumeClaim:
53 claimName: prometheus-data
54 - configMap: #
55 name: prometheus-config
56 name: config-volume
- 这个时候我们重新更新下 prometheus:
1[root@master1 prometheus-example]#kubectl apply -f prometheus-deploy.yaml
2deployment.apps/prometheus configured
3#注意:这里下载镜像要耐心等待一会儿!!!74M大小!
4
5[root@master1 prometheus-example]#kubectl get pods -n monitor
6NAME READY STATUS RESTARTS AGE
7prometheus-849c8456c7-dz6rt 1/1 Running 0 54s
8
9
10[root@master1 prometheus-example]#kubectl logs prometheus-849c8456c7-dz6rt -nmonitor
11……
12ts=2022-04-29T05:00:09.184Z caller=main.go:1142 level=info msg="Loading configuration file" filename=/etc/prometheus/prometheus.yml
13ts=2022-04-29T05:00:09.185Z caller=main.go:1179 level=info msg="Completed loading of configuration file" filename=/etc/prometheus/prometheus.yml totalDuration=1.128855ms db_storage=1.302µs remote_storage=5.18µs web_handler=721ns query_engine=2.705µs scrape=773.91µs scrape_sd=66.725µs notify=1.443µs notify_sd=2.966µs rules=4.859µs tracing=20.118µs
14ts=2022-04-29T05:00:09.185Z caller=main.go:910 level=info msg="Server is ready to receive web requests."

7.创建prometheus的svc资源
- Pod 创建成功后,为了能够在外部访问到 prometheus 的 服务,我们还需要创建一个 Service 对象:
[root@master1 prometheus-example]#vim prometheus-svc.yaml
1# prometheus-svc.yaml
2apiVersion: v1
3kind: Service
4metadata:
5 name: prometheus
6 namespace: monitor
7 labels:
8 app: prometheus
9spec:
10 selector:
11 app: prometheus
12 type: NodePort
13 ports:
14 - name: web
15 port: 9090
16 targetPort: http
- 为了方便测试,我们这里创建一个
NodePort类型的服务,当然我们可以创建一个Ingress对象,通过域名来进行访问:
1[root@master1 prometheus-example]#kubectl apply -f prometheus-svc.yaml
2service/prometheus created
3
4[root@master1 prometheus-example]#kubectl get svc -nmonitor
5NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
6prometheus NodePort 10.108.47.93 <none> 9090:30092/TCP 9s
8.测试
- 现在我们就可以通过
http://任意节点IP:30980访问 prometheus 的 webui 服务了:

- 现在我们可以查看当前监控系统中的一些监控目标(Status -> Targets):


由于我们现在还没有配置任何的报警信息,所以 Alerts 菜单下面现在没有任何数据,隔一会儿,我们可以去 Graph 菜单下面查看我们抓取的 prometheus 本身的一些监控数据了,其中 - insert metrics at cursor -下面就有我们搜集到的一些监控指标数据:

- 比如我们这里就选择
scrape_duration_seconds这个指标,然后点击Execute,就可以看到类似于下面的图表数据了:

测试结束。😘
除了简单的直接使用采集到的一些监控指标数据之外,这个时候也可以使用强大的 PromQL 工具,PromQL 其实就是 prometheus 便于数据聚合展示开发的一套 adhoc 查询语言的,你想要查什么找对应函数取你的数据好了。
💘 实战:prometheus监控测试-2022.7.23(测试成功)
比如我们在本地启动一些样例来让 Prometheus 采集。Go 客户端库包含一个示例,该示例为具有不同延迟分布的三个服务暴露 RPC 延迟。
实验环境
前置条件
1具有prometheus环境:prometheus-2.35.0
2具有go环境:go1.16.2
1、下载 Prometheus 的 Go 客户端库并运行示例
- 首先确保已经安装了 Go 环境并启用 go modules,下载 Prometheus 的 Go 客户端库并运行这三个示例:
至于,如何在linux上安装go环境,可以查看我的另一篇文章:
https://blog.csdn.net/weixin_39246554/article/details/124495828?spm=1001.2014.3001.5502


1(1)下载源代码
2[root@master1 ~]#git clone https://github.com/prometheus/client_golang.git
3[root@master1 ~]#cd client_golang/examples/random/
4[root@master1 random]#ls
5main.go
6
7(2)编译生成二进制文件
8[root@master1 random]#go build
9go: downloading github.com/beorn7/perks v1.0.1
10go: downloading github.com/cespare/xxhash/v2 v2.1.2
11go: downloading github.com/golang/protobuf v1.5.2
12go: downloading github.com/prometheus/client_model v0.2.0
13go: downloading github.com/prometheus/common v0.33.0
14go: downloading github.com/prometheus/procfs v0.7.3
15go: downloading google.golang.org/protobuf v1.28.0
16go: downloading github.com/matttproud/golang_protobuf_extensions v1.0.1
17go: downloading golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886
18[root@master1 random]#ll -h
19total 12M
20-rw-r--r-- 1 root root 4.5K Apr 28 16:52 main.go
21-rwxr-xr-x 1 root root 12M Apr 28 16:56 random
- 然后在3个独立的终端里面运行3个服务:
1./random -listen-address=:8080
2./random -listen-address=:8081
3./random -listen-address=:8082
这个时候我们可以得到3个不同的监控接口:http://localhost:8080/metrics、http://localhost:8081/metrics 和 http://localhost:8082/metrics。
2、配置prometheus server的prometheus.yml文件
现在我们配置 Prometheus 来采集这些新的目标,让我们将这三个目标分组到一个名为 example-random 的任务。假设前两个端点(即:http://localhost:8080/metrics、http://localhost:8081/metrics )都是生产级目标应用,第三个端点(即:http://localhost:8082/metrics )为金丝雀实例。要在 Prometheus 中对此进行建模,我们可以将多组端点添加到单个任务中,为每组目标添加额外的标签。
在此示例中,我们将 group =“production” 标签添加到第一组目标,同时将 group=“canary”添加到第二组。将以下配置添加到 prometheus.yml 中的 scrape_configs 部分,然后重新启动 Prometheus 实例:
1[root@master1 ~]#cd prometheus-2.35.0.linux-amd64/
2[root@master1 prometheus-2.35.0.linux-amd64]#ls
3console_libraries consoles data LICENSE NOTICE prometheus prometheus.yml promtool
4
5[root@master1 prometheus-2.35.0.linux-amd64]#vim prometheus.yml
6scrape_configs:
7 - job_name: 'example-random'
8 # Override the global default and scrape targets from this job every 5 seconds.
9 scrape_interval: 5s
10 static_configs:
11 - targets: ['localhost:8080', 'localhost:8081']
12 labels:
13 group: 'production'
14 - targets: ['localhost:8082']
15 labels:
16 group: 'canary'
3、验证
修改完prometheus.yml配置文件后,我们重启下prometheus。以上就是添加监控配置最基本的配置方式了,非常简单,只需要提供一个符合 metrics 格式的可访问的接口配置给 Prometheus 就可以了。





实验结束。😘
💘 实战:prometheus应用监控-2022.4.30(测试成功)
(监控k8s集群的CoreDns和redis服务)

前面我们和大家介绍了 Prometheus 的数据指标是通过一个公开的 HTTP(S) 数据接口获取到的,我们不需要单独安装监控的 agent,只需要暴露一个 metrics 接口,Prometheus 就会定期去拉取数据;对于一些普通的 HTTP 服务,我们完全可以直接重用这个服务,添加一个 /metrics 接口暴露给 Prometheus;而且获取到的指标数据格式是非常易懂的,不需要太高的学习成本。
现在很多服务从一开始就内置了一个 /metrics 接口,比如 Kubernetes 的各个组件、istio 服务网格都直接提供了数据指标接口。有一些服务即使没有原生集成该接口,也完全可以使用一些 exporter 来获取到指标数据,比如 mysqld_exporter、node_exporter,这些 exporter 就有点类似于传统监控服务中的 agent,作为服务一直存在,用来收集目标服务的指标数据然后直接暴露给 Prometheus。
实验环境
1k8s:v1.22.2(1 master,2 node)
2containerd: v1.5.5
3prometneus: docker.io/prom/prometheus:v2.34.0
实验软件
链接:https://pan.baidu.com/s/1qngIIlrb_wZNefjK2C-EBw?pwd=i435
提取码:i435
2022.4.30-prometheus应用监控demo-code

前置条件
- 具有k8s环境;
- 已经把prometheus应用部署到k8s环境里;
关于如何将prometheus应用部署到k8s环境里,请查看我的另一篇文章,获取完整的部署方法!。
https://blog.csdn.net/weixin_39246554/article/details/124498172?spm=1001.2014.3001.5501


1.普通应用:监控k8s集群的CoreDns服务
对于普通应用只需要能够提供一个满足 prometheus 格式要求的 /metrics 接口就可以让 Prometheus 来接管监控。
1.查看CoreDns是否开启/metric接口
- 比如 Kubernetes 集群中非常重要的 CoreDNS 插件,一般默认情况下就开启了
/metrics接口:
1➜ kubectl get cm coredns -n kube-system -o yaml
2apiVersion: v1
3data:
4 Corefile: |
5 .:53 {
6 errors
7 health
8 ready
9 kubernetes cluster.local in-addr.arpa ip6.arpa {
10 pods insecure
11 fallthrough in-addr.arpa ip6.arpa
12 ttl 30
13 }
14 prometheus :9153
15 forward . /etc/resolv.conf
16 cache 30
17 loop
18 reload
19 loadbalance
20 }
21kind: ConfigMap
22metadata:
23 creationTimestamp: "2019-11-08T11:59:49Z"
24 name: coredns
25 namespace: kube-system
26 resourceVersion: "188"
27 selfLink: /api/v1/namespaces/kube-system/configmaps/coredns
28 uid: 21966186-c2d9-467a-b87f-d061c5c9e4d7
上面 ConfigMap 中 prometheus :9153 就是开启 prometheus 的插件。
- 查看下当前k8s集群的CoreDns pod信息
1[root@master1 prometheus-example]#kubectl get pods -n kube-system -l k8s-app=kube-dns -o wide
2NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
3coredns-7568f67dbd-2ztgw 1/1 Running 1 (100d ago) 148d 10.244.0.8 master1 <none> <none>
4coredns-7568f67dbd-9dls5 1/1 Running 1 (100d ago) 169d 10.244.0.10 master1 <none> <none>
- 我们可以先尝试手动访问下
/metrics接口,如果能够手动访问到那证明接口是没有任何问题的:
1[root@master1 prometheus-example]#curl http://10.244.0.8:9153/metrics
2# HELP coredns_build_info A metric with a constant '1' value labeled by version, revision, and goversion from which CoreDNS was built.
3# TYPE coredns_build_info gauge
4coredns_build_info{goversion="go1.16.4",revision="053c4d5",version="1.8.4"} 1
5# HELP coredns_cache_entries The number of elements in the cache.
6# TYPE coredns_cache_entries gauge
7coredns_cache_entries{server="dns://:53",type="denial"} 1
8coredns_cache_entries{server="dns://:53",type="success"} 0
9# HELP coredns_cache_misses_total The count of cache misses.
10# TYPE coredns_cache_misses_total counter
11……

我们可以看到可以正常访问到,从这里可以看到 CoreDNS 的监控数据接口是正常的了。
2.将CoreDns的/metrics接口配置到prometheus的ConfigMap
- 然后我们就可以将这个
/metrics接口配置到prometheus.yml中去了,直接加到默认的 prometheus 这个job下面:
注意:这里是直接加到上次实验环境里,将prometheus部署到k8s里的prometheus-cm.yamlconfigmap里。

csdn文章:https://blog.csdn.net/weixin_39246554/article/details/124498172?spm=1001.2014.3001.5501

[root@master1 ~]#cd prometheus-example/
[root@master1 prometheus-example]#vim prometheus-cm.yaml
1# prometheus-cm.yaml
2apiVersion: v1
3kind: ConfigMap
4metadata:
5 name: prometheus-config
6 namespace: monitor
7data:
8 prometheus.yml: |
9 global:
10 scrape_interval: 15s
11 scrape_timeout: 15s
12
13 scrape_configs:
14 - job_name: 'prometheus'
15 static_configs:
16 - targets: ['localhost:9090']
17
18 - job_name: 'coredns'
19 static_configs:
20 - targets: ['10.244.0.8:9153', '10.244.0.10:9153']
当然,我们这里只是一个很简单的配置,scrape_configs 下面可以支持很多参数,例如:
basic_auth和bearer_token:比如我们提供的/metrics接口需要 basic 认证的时候,通过传统的用户名/密码或者在请求的 header 中添加对应的 token 都可以支持kubernetes_sd_configs或consul_sd_configs:可以用来自动发现一些应用的监控数据
现在我们重新更新这个 ConfigMap 资源对象:
1[root@master1 prometheus-example]#kubectl apply -f prometheus-cm.yaml
2configmap/prometheus-config configured
现在 Prometheus 的配置文件内容已经更改了,隔一会儿被挂载到 Pod 中的 prometheus.yml 文件也会更新。
我们可以看下prometheus pd里面的数据是否已经发生了改变?
1[root@master1 prometheus-example]#kubectl exec prometheus-698b6858c9-5xgsm -n monitor -- cat /etc/prometheus/prometheus.yml


- 执行reload热更新操作
由于我们之前的 Prometheus 启动参数中添加了 --web.enable-lifecycle 参数,所以现在我们只需要执行一个 reload 命令即可让配置生效:

1[root@master1 prometheus-example]#kubectl get pods -n monitor -o wide
2NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
3prometheus-698b6858c9-5xgsm 1/1 Running 0 64m 10.244.1.86 node1 <none> <none>
4[root@master1 prometheus-example]#curl -X POST "http://10.244.1.86:9090/-/reload"
5[root@master1 prometheus-example]#
热更新
由于 ConfigMap 通过 Volume 的形式挂载到 Pod 中去的热更新需要一定的间隔时间才会生效,所以需要稍微等一小会儿。
3.验证
- 这个时候我们再去看 Prometheus 的 Dashboard 中查看采集的目标数据:

可以看到我们刚刚添加的 coredns 这个任务已经出现了。
然后同样的我们可以切换到 Graph 下面去,我们可以找到一些 CoreDNS 的指标数据,至于这些指标数据代表什么意义,一般情况下,我们可以去查看对应的 /metrics 接口,里面一般情况下都会有对应的注释。

到这里我们就在 Prometheus 上配置了第一个 Kubernetes 应用。
测试结束。😘
2.使用 exporter 监控:监控k8s集群的redis应用
上面我们也说过有一些应用可能没有自带 /metrics 接口供 Prometheus 使用,在这种情况下,我们就需要利用 exporter 服务来为 Prometheus 提供指标数据了。Prometheus 官方为许多应用就提供了对应的 exporter 应用,也有许多第三方的实现,我们可以前往官方网站进行查看:exporters,当然如果你的应用本身也没有 exporter 实现,那么就要我们自己想办法去实现一个 /metrics 接口了,只要你能提供一个合法的 /metrics 接口,Prometheus 就可以监控你的应用。


1.创建pod资源
比如我们这里通过一个 redis-exporter 的服务来监控 redis 服务,对于这类应用,我们一般会以 sidecar 的形式和主应用部署在同一个 Pod 中,比如我们这里来部署一个 redis 应用,并用 redis-exporter 的方式来采集监控数据供 Prometheus 使用,如下资源清单文件:
[root@master1 ~]#cd prometheus-example/
[root@master1 prometheus-example]#vim prometheus-redis.yaml
1# prometheus-redis.yaml
2apiVersion: apps/v1
3kind: Deployment
4metadata:
5 name: redis
6 namespace: monitor
7spec:
8 selector:
9 matchLabels:
10 app: redis
11 template:
12 metadata:
13 labels:
14 app: redis
15 spec:
16 containers:
17 - name: redis #redis不可能简单地写成多副本,因为它是有状态服务
18 image: redis:4
19 resources:
20 requests:
21 cpu: 100m
22 memory: 100Mi
23 ports:
24 - containerPort: 6379
25 - name: redis-exporter #它只会提供监控指标数据,主应用的metrics
26 image: oliver006/redis_exporter:latest
27 resources:
28 requests:
29 cpu: 100m
30 memory: 100Mi
31 ports:
32 - containerPort: 9121
33---
34kind: Service
35apiVersion: v1
36metadata:
37 name: redis
38 namespace: monitor
39spec:
40 selector:
41 app: redis
42 ports:
43 - name: redis
44 port: 6379
45 targetPort: 6379
46 - name: prom
47 port: 9121
48 targetPort: 9121
可以看到上面我们在 redis 这个 Pod 中包含了两个容器,一个就是 redis 本身的主应用,另外一个容器就是 redis_exporter。
- 创建应用
现在直接创建上面的应用:
1[root@master1 prometheus-example]#kubectl apply -f prometheus-redis.yaml
2deployment.apps/redis created
3service/redis created
- 创建完成后,我们可以看到 redis 的 Pod 里面包含有两个容器:
1[root@master1 prometheus-example]#kubectl get pods -n monitor
2NAME READY STATUS RESTARTS AGE
3prometheus-698b6858c9-5xgsm 1/1 Running 0 13h
4redis-7fb8ff6779-5ts8m 2/2 Running 0 48s
5
6[root@master1 prometheus-example]#kubectl get svc -n monitor
7NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
8prometheus NodePort 10.101.131.61 <none> 9090:32700/TCP 13h
9redis ClusterIP 10.99.36.173 <none> 6379/TCP,9121/TCP 56s

- 我们可以通过 9121 端口来校验是否能够采集到数据:
1➜ curl 10.99.36.173:9121/metrics
2# HELP go_gc_duration_seconds A summary of the GC invocation durations.
3# TYPE go_gc_duration_seconds summary
4go_gc_duration_seconds{quantile="0"} 0
5go_gc_duration_seconds{quantile="0.25"} 0
6go_gc_duration_seconds{quantile="0.5"} 0
7go_gc_duration_seconds{quantile="0.75"} 0
8go_gc_duration_seconds{quantile="1"} 0
9go_gc_duration_seconds_sum 0
10go_gc_duration_seconds_count 0
11......
12# HELP redis_up Information about the Redis instance
13# TYPE redis_up gauge
14redis_up 1
15# HELP redis_uptime_in_seconds uptime_in_seconds metric
16# TYPE redis_uptime_in_seconds gauge
17redis_uptime_in_seconds 100
踩坑:注意:我这里没有现象………………一直卡在这里……😥
故障现象:




解决过程:
参考链接:https://blog.csdn.net/a13568hki/article/details/107038136


1第一个警告
2将net.core.somaxconn = 1024添加到/etc/sysctl.conf中,然后执行sysctl -p生效配置。
3
4第二个警告
5将vm.overcommit_memory = 1添加到/etc/sysctl.conf中,然后执行sysctl -p生效配置。
6
7第三个警告
8将echo never > /sys/kernel/mm/transparent_hugepage/enabled添加到/etc/rc.local中,然后执行source /etc/rc.local生效配置。
验证:经实际测试后,发现要重启服务器的,重启就立马就有现象了!🤣

但是,后面再次测试时,发现有没有以上配置,redis都是可以正常提供/metrics接口的。😥(先搁置这里吧)
2.更新Prometheus 的配置文件
- 同样的,现在我们只需要更新 Prometheus 的配置文件:
注意:这里同样在上次的prometheus的configmap文件里更新配置:
[root@master1 prometheus-example]#pwd
/root/prometheus-example
[root@master1 prometheus-example]#vim prometheus-cm.yaml
1# prometheus-cm.yaml
2apiVersion: v1
3kind: ConfigMap
4metadata:
5 name: prometheus-config
6 namespace: monitor
7data:
8 prometheus.yml: |
9 global:
10 scrape_interval: 15s
11 scrape_timeout: 15s
12
13 scrape_configs:
14 - job_name: 'prometheus'
15 static_configs:
16 - targets: ['localhost:9090']
17
18 - job_name: 'coredns'
19 static_configs:
20 - targets: ['10.244.0.8:9153', '10.244.0.10:9153']
21
22 - job_name: 'redis'
23 static_configs:
24 - targets: ['redis:9121']

由于我们这里是通过 Service 去配置的 redis 服务,当然直接配置 Pod IP 也是可以的,因为和 Prometheus 处于同一个 namespace,所以我们直接使用 servicename 即可。
这样写也是可以的哦:

- 配置文件更新后,重新加载:
1[root@master1 prometheus-example]#kubectl apply -f prometheus-cm.yaml
2configmap/prometheus-config configured
3
4# 隔一会儿执行reload操作
5[root@master1 prometheus-example]# curl -X POST "http://10.244.1.86:9090/-/reload"

或者使用nodeIP:nodePort也是可以的哦

3.验证
- 这个时候我们再去看 Prometheus 的 Dashboard 中查看采集的目标数据:

可以看到配置的 redis 这个 job 已经生效了。
切换到 Graph 下面可以看到很多关于 redis 的指标数据,我们选择任意一个指标,比如 redis_exporter_scrapes_total,然后点击执行就可以看到对应的数据图表了:

实验结束。😘
关于我
我的博客主旨:我希望每一个人拿着我的博客都可以做出实验现象,先把实验做出来,然后再结合理论知识更深层次去理解技术点,这样学习起来才有乐趣和动力。并且,我的博客内容步骤是很完整的,也分享源码和实验用到的软件,希望能和大家一起共同进步!
各位小伙伴在实际操作过程中如有什么疑问,可随时联系本人免费帮您解决问题:
- 个人微信二维码:x2675263825 (舍得), qq:2675263825。

- 个人微信公众号:《云原生架构师实战》

- 个人csdn
https://blog.csdn.net/weixin_39246554?spm=1010.2135.3001.5421

- 个人已开源干货😘
不服来怼:宇宙中最好用的云笔记 & 其他开源干货:https://www.yuque.com/go/doc/73723298?#


- 个人网站:(计划ing)
最后
好了,关于本次实验就到这里了,感谢大家阅读,最后贴上我女神的photo,祝大家生活快乐,每天都过的有意义哦,我们下期见!

💘 实战:prometheus监控k8s集群里的node资源(测试成功)-2022.4.30

前置条件
1有k8s环境;
2已经把prometheus应用部署到k8s环境里;
关于如何将prometheus应用部署到k8s环境里,请查看我的另一篇文章,获取完整的部署方法!。
https://blog.csdn.net/weixin_39246554/article/details/124498172?spm=1001.2014.3001.5501


🍀 实验环境
1k8s:v1.22.2(1 master,2 node)
2containerd: v1.5.5
3prometneus: docker.io/prom/prometheus:v2.34.0
🍀 实验软件
链接:https://pan.baidu.com/s/1GdxitBmmH6JaTmcg8kFn2w?pwd=au4n
提取码:au4n
2022.4.30-prometheus监控k8s集群node资源-code

基础知识
监控集群节点
前面我们和大家学习了怎样用 Promethues 来监控 Kubernetes 集群中的应用,但是对于 Kubernetes 集群本身的监控也是非常重要的,我们需要时时刻刻了解集群的运行状态。
对于集群的监控一般我们需要考虑以下几个方面:
- Kubernetes 节点的监控:比如节点的 cpu、load、disk、memory 等指标
- 内部系统组件的状态:比如 kube-scheduler、kube-controller-manager、kubedns/coredns 等组件的详细运行状态
- 编排级的 metrics:比如 Deployment 的状态、资源请求、调度和 API 延迟等数据指标
Kubernetes 集群的监控方案目前主要有以下几种方案:
Heapster:Heapster 是一个集群范围的监控和数据聚合工具,以 Pod 的形式运行在集群中。 heapster 除了 Kubelet/cAdvisor 之外,我们还可以向 Heapster 添加其他指标源数据,比如 kube-state-metrics。需要注意的是 Heapster 已经被废弃了,后续版本中会使用 metrics-server 代替。- cAdvisor:cAdvisor 是 Google 开源的容器资源监控和性能分析工具,它是专门为容器而生,本身也支持 Docker 容器。
- kube-state-metrics:kube-state-metrics 通过监听 API Server 生成有关资源对象的状态指标,比如 Deployment、Node、Pod。需要注意的是 kube-state-metrics 只是简单提供一个 metrics 数据,并不会存储这些指标数据,所以我们可以使用 Prometheus 来抓取这些数据然后存储。
- metrics-server:metrics-server 也是一个集群范围内的资源数据聚合工具,是 Heapster 的替代品。同样的,metrics-server 也只是显示数据,并不提供数据存储服务。
不过 kube-state-metrics 和 metrics-server 之间还是有很大不同的,二者的主要区别如下:
- kube-state-metrics 主要关注的是业务相关的一些元数据,比如 Deployment、Pod、副本状态等。
- metrics-server 主要关注的是资源度量 API 的实现,比如 CPU、文件描述符、内存、请求延时等指标。
要监控节点其实我们已经有很多非常成熟的方案了,比如 Nagios、zabbix,甚至我们自己来收集数据也可以。
我们这里通过 Prometheus 来采集节点的监控指标数据,可以通过 node_exporter 来获取。顾名思义,node_exporter 就是抓取用于采集服务器节点的各种运行指标,目前 node_exporter 支持几乎所有常见的监控点,比如 conntrack,cpu,diskstats,filesystem,loadavg,meminfo,netstat 等,详细的监控点列表可以参考其 Github 仓库。
我们可以通过 DaemonSet 控制器来部署该服务,这样每一个节点都会自动运行一个这样的 Pod,如果我们从集群中删除或者添加节点后,也会进行自动扩展。
1、创建daemonset资源
- 在部署
node-exporter的时候有一些细节需要注意,如下资源清单文件:
[root@master1 prometheus-example]#pwd
/root/prometheus-example
[root@master1 prometheus-example]#vim prometheus-node-exporter.yaml
1# prometheus-node-exporter.yaml
2apiVersion: apps/v1
3kind: DaemonSet
4metadata:
5 name: node-exporter
6 namespace: monitor
7 labels:
8 app: node-exporter
9spec:
10 selector:
11 matchLabels:
12 app: node-exporter
13 template:
14 metadata:
15 labels:
16 app: node-exporter
17 spec:
18 hostPID: true
19 hostIPC: true
20 hostNetwork: true #因为这里用的是hostNetwortk模式,所以后面就不需要创建svc了!!!
21 nodeSelector:
22 kubernetes.io/os: linux
23 containers:
24 - name: node-exporter
25 image: prom/node-exporter:v1.3.1
26 args:
27 - --web.listen-address=$(HOSTIP):9100
28 - --path.procfs=/host/proc
29 - --path.sysfs=/host/sys
30 - --path.rootfs=/host/root
31 - --no-collector.hwmon # 禁用不需要的一些采集器
32 - --no-collector.nfs
33 - --no-collector.nfsd
34 - --no-collector.nvme
35 - --no-collector.dmi
36 - --no-collector.arp
37 - --collector.filesystem.ignored-mount-points=^/(dev|proc|sys|var/lib/containerd/.+|/var/lib/docker/.+|var/lib/kubelet/pods/.+)($|/)
38 - --collector.filesystem.ignored-fs-types=^(autofs|binfmt_misc|cgroup|configfs|debugfs|devpts|devtmpfs|fusectl|hugetlbfs|mqueue|overlay|proc|procfs|pstore|rpc_pipefs|securityfs|sysfs|tracefs)$
39 ports:
40 - containerPort: 9100
41 env:
42 - name: HOSTIP
43 valueFrom:
44 fieldRef:
45 fieldPath: status.hostIP #Downward API
46 resources:
47 requests:
48 cpu: 150m
49 memory: 180Mi
50 limits:
51 cpu: 150m
52 memory: 180Mi
53 securityContext:
54 runAsNonRoot: true
55 runAsUser: 65534
56 volumeMounts:
57 - name: proc
58 mountPath: /host/proc
59 - name: sys
60 mountPath: /host/sys
61 - name: root
62 mountPath: /host/root
63 mountPropagation: HostToContainer #这个是what??
64 readOnly: true
65 tolerations:
66 - operator: "Exists"
67 volumes:
68 - name: proc
69 hostPath:
70 path: /proc
71 - name: dev
72 hostPath:
73 path: /dev
74 - name: sys
75 hostPath:
76 path: /sys
77 - name: root
78 hostPath:
79 path: /
注意:这里是可以更改监听端口的。

由于我们要获取到的数据是主机的监控指标数据,而我们的 node-exporter 是运行在容器中的,所以我们在 Pod 中需要配置一些 Pod 的安全策略,这里我们就添加了 hostPID: true、hostIPC: true、hostNetwork: true 3个策略,用来使用主机的 PID namespace、IPC namespace 以及主机网络,这些 namespace 就是用于容器隔离的关键技术,要注意这里的 namespace 和集群中的 namespace 是两个完全不相同的概念。
另外我们还将主机的 /dev、/proc、/sys这些目录挂载到容器中,这些因为我们采集的很多节点数据都是通过这些文件夹下面的文件来获取到的,比如我们在使用 top 命令可以查看当前 cpu 使用情况,数据就来源于文件 /proc/stat。使用 free 命令可以查看当前内存使用情况,其数据来源是来自 /proc/meminfo 文件。
另外由于我们集群使用的是 kubeadm 搭建的,所以如果希望 master 节点也一起被监控,则需要添加相应的容忍。
🍀 部署资源
- 然后直接创建上面的资源对象:
1[root@master1 prometheus-example]#kubectl apply -f prometheus-node-exporter.yaml
2daemonset.apps/node-exporter created
3
4[root@master1 prometheus-example]#kubectl get pods -nmonitor -l app=node-exporter -o wide
5NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
6node-exporter-6z7dx 1/1 Running 0 39s 172.29.9.52 node1 <none> <none>
7node-exporter-bbsh6 1/1 Running 0 39s 172.29.9.51 master1 <none> <none>
8node-exporter-lm46b 1/1 Running 0 39s 172.29.9.53 node2 <none> <none>

部署完成后,我们可以看到在几个节点上都运行了一个 Pod,由于我们指定了 hostNetwork=true,所以在每个节点上就会绑定一个端口 9100。
- 我们可以通过这个端口去获取到监控指标数据:
1➜ curl 172.29.9.51:9100/metrics
2...
3node_filesystem_device_error{device="shm",fstype="tmpfs",mountpoint="/rootfs/var/lib/docker/containers/aefe8b1b63c3aa5f27766053ec817415faf8f6f417bb210d266fef0c2da64674/shm"} 1
4node_filesystem_device_error{device="shm",fstype="tmpfs",mountpoint="/rootfs/var/lib/docker/containers/c8652ca72230496038a07e4fe4ee47046abb5f88d9d2440f0c8a923d5f3e133c/shm"} 1
5node_filesystem_device_error{device="tmpfs",fstype="tmpfs",mountpoint="/dev"} 0
6node_filesystem_device_error{device="tmpfs",fstype="tmpfs",mountpoint="/dev/shm"} 0
7...

🍀 当然如果你觉得上面的手动安装方式比较麻烦,我们也可以使用 Helm 的方式来安装:
1helm upgrade --install node-exporter --namespace monitor stable/prometheus-node-exporter
2、prometheus的服务发现
由于我们这里每个节点上面都运行了 node-exporter 程序,如果我们通过一个 Service 来将数据收集到一起用静态配置的方式配置到 Prometheus 去中,就只会显示一条数据,我们得自己在指标数据中去过滤每个节点的数据。
当然我们也可以手动的把所有节点用静态的方式配置到 Prometheus 中去,但是以后要新增或者去掉节点的时候就还得手动去配置。
那么有没有一种方式可以让 Prometheus 去自动发现我们节点的 node-exporter 程序,并且按节点进行分组呢?这就是 Prometheus 里面非常重要的服务发现功能了。
在 Kubernetes 下,Promethues 通过与 Kubernetes API 集成,主要支持5种服务发现模式,分别是:Node、Service、Pod、Endpoints、Ingress。
- 我们通过 kubectl 命令可以很方便的获取到当前集群中的所有节点信息:
1[root@master1 prometheus-example]# kubectl get node
2NAME STATUS ROLES AGE VERSION
3master1 Ready control-plane,master 181d v1.22.2
4node1 Ready <none> 181d v1.22.2
5node2 Ready <none> 181d v1.22.2
1.部署prometheus ConfigMap配置文件
- 但是要让 Prometheus 也能够获取到当前集群中的所有节点信息的话,我们就需要利用 Node 的服务发现模式。同样的,在
prometheus.yml文件中配置如下的 job 任务即可:
[root@master1 prometheus-example]#pwd
/root/prometheus-example
[root@master1 prometheus-example]#vim prometheus-cm.yaml
1# prometheus-cm.yaml
2apiVersion: v1
3kind: ConfigMap
4metadata:
5 name: prometheus-config
6 namespace: monitor
7data:
8 prometheus.yml: |
9 global:
10 scrape_interval: 15s
11 scrape_timeout: 15s
12
13 scrape_configs:
14 - job_name: 'prometheus'
15 static_configs:
16 - targets: ['localhost:9090']
17
18 - job_name: 'coredns'
19 static_configs:
20 - targets: ['10.244.0.8:9153', '10.244.0.10:9153']
21
22 - job_name: 'redis'
23 static_configs:
24 - targets: ['redis:9121']
25
26 - job_name: 'nodes'
27 kubernetes_sd_configs:
28 - role: node
通过指定 kubernetes_sd_configs 的模式为 node,Prometheus 就会自动从 Kubernetes 中发现所有的 node 节点并作为当前 job 监控的目标实例,发现的节点 /metrics 接口是默认的 kubelet 的 HTTP 接口。
🍀 部署prometheus配置文件
- prometheus 的 ConfigMap 更新完成后,同样的我们执行 reload 操作,让配置生效:
1[root@master1 prometheus-example]#kubectl apply -f prometheus-cm.yaml
2configmap/prometheus-config configured
3
4[root@master1 prometheus-example]#kubectl exec prometheus-698b6858c9-5xgsm -nmonitor -- cat /etc/prometheus/prometheus.yml
可以看到prometheus pod的配置文件已经被更新了:

此时就可以执行reload操作了:
1[root@master1 prometheus-example]# curl -X POST "http://172.29.9.51:32700/-/reload"

看了下prometheus pod日志没什么报错:

- 另外需要注意一点的是:之前这边是已经部署了rbac.yaml了的:
[root@master1 prometheus-example]#vim prometheus-rbac.yaml


- 配置生效后,我们再去 prometheus 的 dashboard 中查看 Targets 是否能够正常抓取数据,访问
http://任意节点IP:32700:


- 我们可以看到上面的
nodes这个 job 任务已经自动发现了我们3个 node 节点,但是在获取数据的时候失败了,出现了类似于下面的错误信息:
1server returned HTTP status 400 Bad Request
这个是因为 prometheus 去发现 Node 模式的服务的时候,访问的端口默认是 10250,而默认是需要认证的 https 协议才有权访问的,但实际上我们并不是希望让去访问10250端口的 /metrics 接口,而是 node-exporter 绑定到节点的 9100 端口,所以我们应该将这里的 10250 替换成 9100,但是应该怎样替换呢?
2.使用 Prometheus 提供的 relabel_configs 中的 replace 能力
这里我们就需要使用到 Prometheus 提供的 relabel_configs 中的 replace 能力了,relabel 可以在 Prometheus 采集数据之前,通过 Target 实例的 Metadata 信息,动态重新写入 Label 的值。除此之外,我们还能根据 Target 实例的 Metadata 信息选择是否采集或者忽略该 Target 实例。比如我们这里就可以去匹配 __address__ 这个 Label 标签,然后替换掉其中的端口,如果你不知道有哪些 Label 标签可以操作的话,可以在 Service Discovery 页面获取到相关的元标签,这些标签都是我们可以进行 Relabel 的标签:


- 现在我们来替换掉端口,修改 ConfigMap:
[root@master1 prometheus-example]#pwd
/root/prometheus-example
[root@master1 prometheus-example]#vim prometheus-cm.yaml
1# prometheus-cm.yaml
2apiVersion: v1
3kind: ConfigMap
4metadata:
5 name: prometheus-config
6 namespace: monitor
7data:
8 prometheus.yml: |
9 global:
10 scrape_interval: 15s
11 scrape_timeout: 15s
12
13 scrape_configs:
14 - job_name: 'prometheus'
15 static_configs:
16 - targets: ['localhost:9090']
17
18 - job_name: 'coredns'
19 static_configs:
20 - targets: ['10.244.0.8:9153', '10.244.0.10:9153']
21
22 - job_name: 'redis'
23 static_configs:
24 - targets: ['redis:9121']
25
26 - job_name: 'nodes'
27 kubernetes_sd_configs:
28 - role: node
29 relabel_configs:
30 - source_labels: [__address__]
31 regex: '(.*):10250'
32 replacement: '${1}:9100'
33 target_label: __address__
34 action: replace

这里就是一个正则表达式,去匹配 __address__ 这个标签,然后将 host 部分保留下来,port 替换成了 9100。
- 现在我们重新更新配置文件,执行 reload 操作,然后再去看 Prometheus 的 Dashboard 的 Targets 路径下面 kubernetes-nodes 这个 job 任务是否正常了:
更新configmap文件:
1[root@master1 prometheus-example]#kubectl apply -f prometheus-cm.yaml
2configmap/prometheus-config configured

- 执行reload操作:
1[root@master1 prometheus-example]# curl -X POST "http://172.29.9.51:32700/-/reload"
- 查看prometheus web界面:

我们可以看到现在已经正常了。
3.通过 labelmap 属性来将 Kubernetes 的 Label 标签添加为 Prometheus 的指标数据的标签
但是还有一个问题就是我们采集的指标数据 Label 标签就只有一个节点的 hostname,这对于我们在进行监控分组分类查询的时候带来了很多不方便的地方,要是我们能够将集群中 Node 节点的 Label 标签也能获取到就很好了。
默认就是replace:

- 这里我们可以通过
labelmap这个属性来将 Kubernetes 的 Label 标签添加为 Prometheus 的指标数据的标签:
添加到prometheus-cm.yaml配置文件:
[root@master1 prometheus-example]#pwd
/root/prometheus-example
[root@master1 prometheus-example]#vim prometheus-cm.yaml
1……
2- job_name: 'kubernetes-nodes'
3 kubernetes_sd_configs:
4 - role: node
5 relabel_configs:
6 - source_labels: [__address__]
7 regex: '(.*):10250'
8 replacement: '${1}:9100'
9 target_label: __address__
10 action: replace
11 - action: labelmap
12 regex: __meta_kubernetes_node_label_(.+)

添加了一个 action 为 labelmap,正则表达式是 __meta_kubernetes_node_label_(.+) 的配置,这里的意思就是表达式中匹配都的数据也添加到指标数据的 Label 标签中去。
- 更新文件,稍等一会儿执行reload操作:
1[root@master1 prometheus-example]#kubectl apply -f prometheus-cm.yaml
2configmap/prometheus-config configured

- 执行reload操作:
1[root@master1 prometheus-example]# curl -X POST "http://172.29.9.51:32700/-/reload"
- 查看prometheus web界面:

符合预期。
🍀 对于 kubernetes_sd_configs 下面可用的元信息标签如下:
__meta_kubernetes_node_name:节点对象的名称_meta_kubernetes_node_label:节点对象中的每个标签_meta_kubernetes_node_annotation:来自节点对象的每个注释_meta_kubernetes_node_address:每个节点地址类型的第一个地址(如果存在)
关于 kubernets_sd_configs 更多信息可以查看官方文档:kubernetes_sd_config
4.把 kubelet 的监控任务也一并配置上
🍀 另外由于 kubelet 也自带了一些监控指标数据,就上面我们提到的 10250 端口,所以我们这里也把 kubelet 的监控任务也一并配置上:
添加到prometheus-cm.yaml配置文件:
[root@master1 prometheus-example]#pwd
/root/prometheus-example
[root@master1 prometheus-example]#vim prometheus-cm.yaml
1……
2- job_name: 'kubelet'
3 kubernetes_sd_configs:
4 - role: node
5 scheme: https
6 tls_config:
7 ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
8 insecure_skip_verify: true
9 bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
10 relabel_configs:
11 - action: labelmap
12 regex: __meta_kubernetes_node_label_(.+)

但是这里需要特别注意的是这里必须使用 https 协议访问,这样就必然需要提供证书,我们这里是通过配置 insecure_skip_verify: true 来跳过了证书校验。但是除此之外,要访问集群的资源,还必须要有对应的权限才可以,也就是对应的 ServiceAccount 棒的 权限允许才可以,我们这里部署的 prometheus 关联的 ServiceAccount 对象前面我们已经提到过了,这里我们只需要将 Pod 中自动注入的 /var/run/secrets/kubernetes.io/serviceaccount/ca.crt 和 /var/run/secrets/kubernetes.io/serviceaccount/token 文件配置上,就可以获取到对应的权限了。
1token就是pod里面内置的,每一个pod都有;serviceaccount -> secret -> token
2
3insecure_skip_verify: true #加上这个:只是为了不让他校验我们访问的ip;
4[root@master1 ~]#kubectl get po prometheus-698b6858c9-5xgsm -nmonitor -oyaml


以下不影响,是可以出效果的:

- 更新文件,稍等一会儿执行reload操作:
1[root@master1 prometheus-example]#kubectl apply -f prometheus-cm.yaml
2configmap/prometheus-config configured
- 执行reload操作:
1[root@master1 prometheus-example]# curl -X POST "http://172.29.9.51:32700/-/reload"
- 验证:
现在我们再去更新下配置文件,执行 reload 操作,让配置生效,然后访问 Prometheus 的 Dashboard 查看 Targets 路径:

现在可以看到我们上面添加的 kubernetes-kubelet 和 kubernetes-nodes 这两个 job 任务都已经配置成功了,而且二者的 Labels 标签都和集群的 node 节点标签保持一致了。
现在我们就可以切换到 Graph 路径下面查看采集的一些指标数据了,比如查询 node_load1 指标:

我们可以看到将几个节点对应的 node_load1 指标数据都查询出来了。
同样的,我们还可以使用 PromQL 语句来进行更复杂的一些聚合查询操作,还可以根据我们的 Labels 标签对指标数据进行聚合,比如我们这里只查询 node1 节点的数据,可以使用表达式 node_load1{instance="node1"} 来进行查询:

到这里我们就把 Kubernetes 集群节点使用 Prometheus 监控起来了,接下来我们再来和大家学习下怎样监控 Pod 或者 Service 之类的资源对象。
3、验证
💘 实战:prometheus监控容器-2022.5.2(测试成功)
实验环境
1k8s:v1.22.2(1 master,2 node)
2containerd: v1.5.5
3prometneus: docker.io/prom/prometheus:v2.34.0
实验软件
链接:https://pan.baidu.com/s/1JkltHSHqRHSVMHvoMuf3VA?pwd=on8e
提取码:on8e
2022.5.2-prometheus监控k8s集群里的容器和apiserver-code

前置条件
- 具有k8s环境;
- 已经把prometheus应用部署到k8s环境里;
关于如何将prometheus应用部署到k8s环境里,请查看我的另一篇文章,获取完整的部署方法!。
https://blog.csdn.net/weixin_39246554/article/details/124498172?spm=1001.2014.3001.5501


基础知识
说到容器监控我们自然会想到 cAdvisor,我们前面也说过 cAdvisor 已经内置在了 kubelet 组件之中,所以我们不需要单独去安装。
cAdvisor 的数据路径为 /api/v1/nodes/<node>/proxy/metrics,但是我们不推荐使用这种方式,因为这种方式是通过 APIServer 去代理访问的,对于大规模的集群比如会对 APIServer 造成很大的压力。
所以我们可以直接通过访问 kubelet 的 /metrics/cadvisor 这个路径来获取 cAdvisor 的数据, 同样我们这里使用 node 的服务发现模式,因为每一个节点下面都有 kubelet,自然都有 cAdvisor 采集到的数据指标。
1、使用node的服务发现实现对kubelet进行监控
[root@master1 ~]#cd prometheus-example/
[root@master1 prometheus-example]#vim prometheus-cm.yaml
1# prometheus-cm.yaml
2apiVersion: v1
3kind: ConfigMap
4metadata:
5 name: prometheus-config
6 namespace: monitor
7data:
8 prometheus.yml: |
9 global:
10 scrape_interval: 15s
11 scrape_timeout: 15s
12
13 scrape_configs:
14 - job_name: 'prometheus'
15 static_configs:
16 - targets: ['localhost:9090']
17
18 - job_name: 'coredns'
19 static_configs:
20 - targets: ['10.244.0.8:9153', '10.244.0.10:9153']
21
22 - job_name: 'redis'
23 static_configs:
24 - targets: ['redis:9121']
25
26 - job_name: 'nodes'
27 kubernetes_sd_configs:
28 - role: node
29 relabel_configs:
30 - source_labels: [__address__]
31 regex: '(.*):10250'
32 replacement: '${1}:9100'
33 target_label: __address__
34 action: replace
35 - action: labelmap
36 regex: __meta_kubernetes_node_label_(.+)
37
38 - job_name: 'kubelet'
39 kubernetes_sd_configs:
40 - role: node
41 scheme: https
42 tls_config:
43 ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
44 insecure_skip_verify: true
45 bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
46 relabel_configs:
47 - action: labelmap
48 regex: __meta_kubernetes_node_label_(.+)
49
50
51 - job_name: 'kubernetes-cadvisor'
52 kubernetes_sd_configs:
53 - role: node
54 scheme: https
55 tls_config:
56 ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
57 insecure_skip_verify: true
58 bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
59 relabel_configs:
60 - action: labelmap
61 regex: __meta_kubernetes_node_label_(.+)

上面的配置和我们之前配置 node-exporter 的时候几乎是一样的,区别是我们这里使用了 https 的协议。
另外需要注意的是配置了 ca.cart 和 token 这两个文件,这两个文件是 Pod 启动后自动注入进来的;
- 更新并执行reload操作:
1[root@master1 prometheus-example]#kubectl apply -f prometheus-cm.yaml
2configmap/prometheus-config configured
1[root@master1 ~]# curl -X POST "http://172.29.9.51:32700/-/reload"
- 验证:
发现和kubelet监控并没什么不同:

2、方法1:直接配置__metrics_path选项
来看下Service Discovery,现在需求是把这里的__metrics_path路径要替换成:/metrics/cadvisor即可:

该如何替换呢?
我们可以看到Configuration里面,这里有metrics_path选项,那我们直接把peometheus配置文件里的这个选线修改下,看是是否能满足需求呢?

- 配置prometheus配置文件
[root@master1 ~]#cd prometheus-example/
[root@master1 prometheus-example]#vim prometheus-cm.yaml
1# prometheus-cm.yaml
2apiVersion: v1
3kind: ConfigMap
4metadata:
5 name: prometheus-config
6 namespace: monitor
7data:
8 prometheus.yml: |
9 global:
10 scrape_interval: 15s
11 scrape_timeout: 15s
12
13 scrape_configs:
14 - job_name: 'prometheus'
15 static_configs:
16 - targets: ['localhost:9090']
17
18 - job_name: 'coredns'
19 static_configs:
20 - targets: ['10.244.0.8:9153', '10.244.0.10:9153']
21
22 - job_name: 'redis'
23 static_configs:
24 - targets: ['redis:9121']
25
26 - job_name: 'nodes'
27 kubernetes_sd_configs:
28 - role: node
29 relabel_configs:
30 - source_labels: [__address__]
31 regex: '(.*):10250'
32 replacement: '${1}:9100'
33 target_label: __address__
34 action: replace
35 - action: labelmap
36 regex: __meta_kubernetes_node_label_(.+)
37
38 - job_name: 'kubelet'
39 kubernetes_sd_configs:
40 - role: node
41 scheme: https
42 tls_config:
43 ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
44 insecure_skip_verify: true
45 bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
46 relabel_configs:
47 - action: labelmap
48 regex: __meta_kubernetes_node_label_(.+)
49
50
51 - job_name: 'kubernetes-cadvisor'
52 kubernetes_sd_configs:
53 - role: node
54 metrics_path: /metrics/cadvisor
55 scheme: https
56 tls_config:
57 ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
58 insecure_skip_verify: true
59 bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
60 relabel_configs:
61 - action: labelmap
62 regex: __meta_kubernetes_node_label_(.+)

- 更新并执行reload操作:
1[root@master1 prometheus-example]#kubectl apply -f prometheus-cm.yaml
2configmap/prometheus-config configured
1[root@master1 prometheus-example]# curl -X POST "http://172.29.9.51:32700/-/reload"
- 验证

可以看到,直接配置属性值也是可以生效的!😘
当然,你直接访问,肯定是访问不到的,需要token:

3、方法2:使用relabel功能
- 这里重新配置下prometheus配置文件
[root@master1 prometheus-example]#pwd
/root/prometheus-example
[root@master1 prometheus-example]#vim prometheus-cm.yaml
1# prometheus-cm.yaml
2apiVersion: v1
3kind: ConfigMap
4metadata:
5 name: prometheus-config
6 namespace: monitor
7data:
8 prometheus.yml: |
9 global:
10 scrape_interval: 15s
11 scrape_timeout: 15s
12
13 scrape_configs:
14 - job_name: 'prometheus'
15 static_configs:
16 - targets: ['localhost:9090']
17
18 - job_name: 'coredns'
19 static_configs:
20 - targets: ['10.244.0.8:9153', '10.244.0.10:9153']
21
22 - job_name: 'redis'
23 static_configs:
24 - targets: ['redis:9121']
25
26 - job_name: 'nodes'
27 kubernetes_sd_configs:
28 - role: node
29 relabel_configs:
30 - source_labels: [__address__]
31 regex: '(.*):10250'
32 replacement: '${1}:9100'
33 target_label: __address__
34 action: replace
35 - action: labelmap
36 regex: __meta_kubernetes_node_label_(.+)
37
38 - job_name: 'kubelet'
39 kubernetes_sd_configs:
40 - role: node
41 scheme: https
42 tls_config:
43 ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
44 insecure_skip_verify: true
45 bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
46 relabel_configs:
47 - action: labelmap
48 regex: __meta_kubernetes_node_label_(.+)
49
50
51 - job_name: 'kubernetes-cadvisor'
52 kubernetes_sd_configs:
53 - role: node
54 # metrics_path: /metrics/cadvisor
55 scheme: https
56 tls_config:
57 ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
58 insecure_skip_verify: true
59 bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
60 relabel_configs:
61 - action: labelmap
62 regex: __meta_kubernetes_node_label_(.+)
63 - source_labels: [__meta_kubernetes_node_name]
64 regex: (.+)
65 replacement: /metrics/cadvisor # <nodeip>/metrics -> <nodeip>/metrics/cadvisor
66 target_label: __metrics_path__

- 更新并执行reload操作:
1[root@master1 prometheus-example]#kubectl apply -f prometheus-cm.yaml
2configmap/prometheus-config configured
1[root@master1 prometheus-example]# curl -X POST "http://172.29.9.51:32700/-/reload"
- 验证:

也是可以实现和上面一样的效果!
注意:下面的这种方式是不推荐的!

1- job_name: 'kubernetes-cadvisor'
2 kubernetes_sd_configs:
3 - role: node
4 scheme: https
5 tls_config:
6 ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
7 bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
8 relabel_configs:
9 - action: labelmap
10 regex: __meta_kubernetes_node_label_(.+)
11 replacement: $1
12 - source_labels: [__meta_kubernetes_node_name]
13 regex: (.+)
14 replacement: /metrics/cadvisor # <nodeip>/metrics -> <nodeip>/metrics/cadvisor
15 target_label: __metrics_path__
16 # 下面的方式不推荐使用
17 # - target_label: __address__
18 # replacement: kubernetes.default.svc:443
19 # - source_labels: [__meta_kubernetes_node_name]
20 # regex: (.+)
21 # target_label: __metrics_path__
22 # replacement: /api/v1/nodes/${1}/proxy/metrics/cadvisor

4、标签查询
- 查询
1container_memory_usage_bytes

可以看到有狠多年的实例,因为这里列出了集群里的所有容器。
- 过滤
1container_memory_usage_bytes{namespace="monitor",instance="node1"} #这里会自动提示的!

注意:这里的Discovered Labels是relabel之前的标签哦!


测试结束。😘
💘 实战:prometheus监控 apiserver-2022.5.2(测试成功)
实验环境
1k8s:v1.22.2(1 master,2 node)
2containerd: v1.5.5
3prometneus: docker.io/prom/prometheus:v2.34.0
实验软件
链接:https://pan.baidu.com/s/1JkltHSHqRHSVMHvoMuf3VA?pwd=on8e
提取码:on8e
2022.5.2-prometheus监控k8s集群里的容器和apiserver-code

前置条件
- 具有k8s环境;
- 已经把prometheus应用部署到k8s环境里;
关于如何将prometheus应用部署到k8s环境里,请查看我的另一篇文章,获取完整的部署方法!。
https://blog.csdn.net/weixin_39246554/article/details/124498172?spm=1001.2014.3001.5501


基础知识
apiserver 作为 Kubernetes 最核心的组件,当然他的监控也是非常有必要的。
1、查看集群apiserver
对于 apiserver 的监控我们可以直接通过 kubernetes 的 Service 来获取:
1➜ kubectl get svc
2NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
3kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 33d
上面这个 Service 就是我们集群的 apiserver 在集群内部的 Service 地址,要自动发现 Service 类型的服务,我们就需要用到 role 为 Endpoints 的 kubernetes_sd_configs。

2、在 ConfigMap 对象中添加上一个 Endpoints 类型的服务的监控任务
- 我们可以在 ConfigMap 对象中添加上一个 Endpoints 类型的服务的监控任务:
[root@master1 ~]#cd prometheus-example/
[root@master1 prometheus-example]#vim prometheus-cm.yaml
1- job_name: 'kubernetes-apiservers'
2 kubernetes_sd_configs:
3 - role: endpoints
本yaml完整代码如下:
1# prometheus-cm.yaml
2apiVersion: v1
3kind: ConfigMap
4metadata:
5 name: prometheus-config
6 namespace: monitor
7data:
8 prometheus.yml: |
9 global:
10 scrape_interval: 15s
11 scrape_timeout: 15s
12
13 scrape_configs:
14 - job_name: 'prometheus'
15 static_configs:
16 - targets: ['localhost:9090']
17
18 - job_name: 'coredns'
19 static_configs:
20 - targets: ['10.244.0.8:9153', '10.244.0.10:9153']
21
22 - job_name: 'redis'
23 static_configs:
24 - targets: ['redis:9121']
25
26 - job_name: 'nodes'
27 kubernetes_sd_configs:
28 - role: node
29 relabel_configs:
30 - source_labels: [__address__]
31 regex: '(.*):10250'
32 replacement: '${1}:9100'
33 target_label: __address__
34 action: replace
35 - action: labelmap
36 regex: __meta_kubernetes_node_label_(.+)
37
38 - job_name: 'kubelet'
39 kubernetes_sd_configs:
40 - role: node
41 scheme: https
42 tls_config:
43 ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
44 insecure_skip_verify: true
45 bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
46 relabel_configs:
47 - action: labelmap
48 regex: __meta_kubernetes_node_label_(.+)
49
50
51 - job_name: 'kubernetes-cadvisor'
52 kubernetes_sd_configs:
53 - role: node
54 # metrics_path: /metrics/cadvisor
55 scheme: https
56 tls_config:
57 ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
58 insecure_skip_verify: true
59 bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
60 relabel_configs:
61 - action: labelmap
62 regex: __meta_kubernetes_node_label_(.+)
63 - source_labels: [__meta_kubernetes_node_name]
64 regex: (.+)
65 replacement: /metrics/cadvisor # <nodeip>/metrics -> <nodeip>/metrics/cadvisor
66 target_label: __metrics_path__
67
68 - job_name: 'kubernetes-apiservers'
69 kubernetes_sd_configs:
70 - role: endpoints
上面这个任务是定义的一个类型为 endpoints 的 kubernetes_sd_configs ,添加到 Prometheus 的 ConfigMap 的配置文件中.
- 然后更新配置:
1[root@master1 prometheus-example]#kubectl apply -f prometheus-cm.yaml
2configmap/prometheus-config configured
3
4# 隔一会儿执行reload操作
5[root@master1 prometheus-example]# curl -X POST "http://172.29.9.51:32700/-/reload"
- 更新完成后,我们再去查看 Prometheus 的 Dashboard 的 target 页面:

我们可以看到 kubernetes-apiservers 下面出现了很多实例,这是因为这里我们使用的是 Endpoints 类型的服务发现,所以 Prometheus 把所有的 Endpoints 服务都抓取过来了。同样的,上面我们需要的服务名为 kubernetes 这个 apiserver 的服务也在这个列表之中,那么我们应该怎样来过滤出这个服务来呢?
3、使用relabel_configs里的keep动作
还记得前面的 relabel_configs 吗?没错,同样我们需要使用这个配置,只是我们这里不是使用 replace 这个动作了,而是 keep,就是只把符合我们要求的给保留下来,哪些才是符合我们要求的呢?
我们可以把鼠标放置在任意一个 target 上,可以查看到 Before relabeling里面所有的元数据,比如我们要过滤的服务是 default 这个 namespace 下面,服务名为 kubernetes 的元数据,所以这里我们就可以根据对应的 __meta_kubernetes_namespace 和 __meta_kubernetes_service_name 这两个元数据来 relabel。另外由于 kubernetes 这个服务对应的端口是 443,需要使用 https 协议,所以这里我们需要使用 https 的协议,对应的就需要将 ca 证书配置上,如下所示:

- 配置如下
[root@master1 prometheus-example]#pwd
/root/prometheus-example
[root@master1 prometheus-example]#vim prometheus-cm.yaml
1- job_name: 'kubernetes-apiservers'
2 kubernetes_sd_configs:
3 - role: endpoints
4 scheme: https
5 tls_config:
6 ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
7 insecure_skip_verify: true
8 bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
9 relabel_configs:
10 - source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
11 action: keep
12 regex: default;kubernetes;https
完整yaml如下:
1# prometheus-cm.yaml
2apiVersion: v1
3kind: ConfigMap
4metadata:
5 name: prometheus-config
6 namespace: monitor
7data:
8 prometheus.yml: |
9 global:
10 scrape_interval: 15s
11 scrape_timeout: 15s
12
13 scrape_configs:
14 - job_name: 'prometheus'
15 static_configs:
16 - targets: ['localhost:9090']
17
18 - job_name: 'coredns'
19 static_configs:
20 - targets: ['10.244.0.8:9153', '10.244.0.10:9153']
21
22 - job_name: 'redis'
23 static_configs:
24 - targets: ['redis:9121']
25
26 - job_name: 'nodes'
27 kubernetes_sd_configs:
28 - role: node
29 relabel_configs:
30 - source_labels: [__address__]
31 regex: '(.*):10250'
32 replacement: '${1}:9100'
33 target_label: __address__
34 action: replace
35 - action: labelmap
36 regex: __meta_kubernetes_node_label_(.+)
37
38 - job_name: 'kubelet'
39 kubernetes_sd_configs:
40 - role: node
41 scheme: https
42 tls_config:
43 ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
44 insecure_skip_verify: true
45 bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
46 relabel_configs:
47 - action: labelmap
48 regex: __meta_kubernetes_node_label_(.+)
49
50
51 - job_name: 'kubernetes-cadvisor'
52 kubernetes_sd_configs:
53 - role: node
54 # metrics_path: /metrics/cadvisor
55 scheme: https
56 tls_config:
57 ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
58 insecure_skip_verify: true
59 bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
60 relabel_configs:
61 - action: labelmap
62 regex: __meta_kubernetes_node_label_(.+)
63 - source_labels: [__meta_kubernetes_node_name]
64 regex: (.+)
65 replacement: /metrics/cadvisor # <nodeip>/metrics -> <nodeip>/metrics/cadvisor
66 target_label: __metrics_path__
67
68 - job_name: 'kubernetes-apiservers'
69 kubernetes_sd_configs:
70 - role: endpoints
71 scheme: https
72 tls_config:
73 ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
74 insecure_skip_verify: true
75 bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
76 relabel_configs:
77 - source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
78 action: keep
79 regex: default;kubernetes;https
4、验证
- 现在重新更新配置文件、重新加载 Prometheus,切换到 Prometheus 的 Targets 路径下查看:
1[root@master1 prometheus-example]#kubectl apply -f prometheus-cm.yaml
2configmap/prometheus-config configured
3
4[root@master1 prometheus-example]# curl -X POST "http://172.29.9.51:32700/-/reload"

现在可以看到 kubernetes-apiserver 这个任务下面只有 apiserver 这一个实例了,证明我们的 relabel 是成功的,现在我们切换到 Graph 路径下面查看下采集到的数据,比如查询 apiserver 的总的请求数:

这样我们就完成了对 Kubernetes APIServer 的监控。
注意:
另外如果我们要来监控其他系统组件,比如 kube-controller-manager、kube-scheduler 的话应该怎么做呢?由于 apiserver 服务 namespace 在 default 使用默认的 Service kubernetes,而其余组件服务在 kube-system 这个 namespace 下面,如果我们想要来监控这些组件的话,需要手动创建单独的 Service,其中 kube-sheduler 的指标数据端口为 10251,kube-controller-manager 对应的端口为 10252,大家可以尝试下自己来配置下这几个系统组件。
💘 实践:prometheus监控pod-2022.5.2(测试成功)

实验软件

prometheus-example.tar.gz
链接:https://pan.baidu.com/s/1JkltHSHqRHSVMHvoMuf3VA?pwd=on8e
提取码:on8e
1、配置一个任务用来专门发现普通类型的 Endpoint
上面的 apiserver 实际上就是一种特殊的 Endpoints,现在我们同样来配置一个任务用来专门发现普通类型的 Endpoint,其实就是 Service 关联的 Pod 列表:
[root@master1 ~]#cd prometheus-example/
[root@master1 prometheus-example]#vim prometheus-cm.yaml
1- job_name: 'kubernetes-endpoints'
2 kubernetes_sd_configs:
3 - role: endpoints
本次完整yaml如下:
1# prometheus-cm.yaml
2apiVersion: v1
3kind: ConfigMap
4metadata:
5 name: prometheus-config
6 namespace: monitor
7data:
8 prometheus.yml: |
9 global:
10 scrape_interval: 15s
11 scrape_timeout: 15s
12
13 scrape_configs:
14 - job_name: 'prometheus'
15 static_configs:
16 - targets: ['localhost:9090']
17
18 - job_name: 'coredns'
19 static_configs:
20 - targets: ['10.244.0.8:9153', '10.244.0.10:9153']
21
22 - job_name: 'redis'
23 static_configs:
24 - targets: ['redis:9121']
25
26 - job_name: 'nodes'
27 kubernetes_sd_configs:
28 - role: node
29 relabel_configs:
30 - source_labels: [__address__]
31 regex: '(.*):10250'
32 replacement: '${1}:9100'
33 target_label: __address__
34 action: replace
35 - action: labelmap
36 regex: __meta_kubernetes_node_label_(.+)
37
38 - job_name: 'kubelet'
39 kubernetes_sd_configs:
40 - role: node
41 scheme: https
42 tls_config:
43 ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
44 insecure_skip_verify: true
45 bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
46 relabel_configs:
47 - action: labelmap
48 regex: __meta_kubernetes_node_label_(.+)
49
50
51 - job_name: 'kubernetes-cadvisor'
52 kubernetes_sd_configs:
53 - role: node
54 # metrics_path: /metrics/cadvisor
55 scheme: https
56 tls_config:
57 ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
58 insecure_skip_verify: true
59 bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
60 relabel_configs:
61 - action: labelmap
62 regex: __meta_kubernetes_node_label_(.+)
63 - source_labels: [__meta_kubernetes_node_name]
64 regex: (.+)
65 replacement: /metrics/cadvisor # <nodeip>/metrics -> <nodeip>/metrics/cadvisor
66 target_label: __metrics_path__
67
68 - job_name: 'kubernetes-apiservers'
69 kubernetes_sd_configs:
70 - role: endpoints
71 scheme: https
72 tls_config:
73 ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
74 insecure_skip_verify: true
75 bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
76 relabel_configs:
77 - source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
78 action: keep
79 regex: default;kubernetes;https
80
81 - job_name: 'kubernetes-endpoints'
82 kubernetes_sd_configs:
83 - role: endpoints
- 更新配置并验证
1[root@master1 prometheus-example]#kubectl apply -f prometheus-cm.yaml
2configmap/prometheus-config configured
3
4#稍等一会儿
5[root@master1 prometheus-example]# curl -X POST "http://172.29.9.51:32700/-/reload"
- 验证

可以看到,这里把当前k8s集群下所有的ep都采集到了:

注意:Service Discovery这里的源标签的格式:


2、更新配置并再次验证
- 现在我们先将上面的配置更新,查看下效果:
[root@master1 ~]#cd prometheus-example/
[root@master1 prometheus-example]#vim prometheus-cm.yaml
1- job_name: 'kubernetes-endpoints'
2 kubernetes_sd_configs:
3 - role: endpoints
4
5 relabel_configs:
6 - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]
7 action: keep
8 regex: true
9 - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme]
10 action: replace
11 target_label: __scheme__
12 regex: (https?)
13 - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path]
14 action: replace
15 target_label: __metrics_path__
16 regex: (.+)
17 - source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port]
18 action: replace
19 target_label: __address__
20 regex: ([^:]+)(?::\d+)?;(\d+) # 这里的难点在正则这里,RE2 正则规则,+是一次多多次,?是0次或1次,其中?:表示非匹配组(意思就是不获取匹配结果)
21 replacement: $1:$2
22
23 - action: labelmap
24 regex: __meta_kubernetes_service_label_(.+)
25 - source_labels: [__meta_kubernetes_namespace]
26 action: replace
27 target_label: namespace
28 - source_labels: [__meta_kubernetes_service_name]
29 action: replace
30 target_label: service
31 - source_labels: [__meta_kubernetes_pod_name]
32 action: replace
33 target_label: pod
34 - source_labels: [__meta_kubernetes_node_name]
35 action: replace
36 target_label: node
本次完整yaml如下:
1# prometheus-cm.yaml
2apiVersion: v1
3kind: ConfigMap
4metadata:
5 name: prometheus-config
6 namespace: monitor
7data:
8 prometheus.yml: |
9 global:
10 scrape_interval: 15s
11 scrape_timeout: 15s
12
13 scrape_configs:
14 - job_name: 'prometheus'
15 static_configs:
16 - targets: ['localhost:9090']
17
18 - job_name: 'coredns'
19 static_configs:
20 - targets: ['10.244.0.8:9153', '10.244.0.10:9153']
21
22 - job_name: 'redis'
23 static_configs:
24 - targets: ['redis:9121']
25
26 - job_name: 'nodes'
27 kubernetes_sd_configs:
28 - role: node
29 relabel_configs:
30 - source_labels: [__address__]
31 regex: '(.*):10250'
32 replacement: '${1}:9100'
33 target_label: __address__
34 action: replace
35 - action: labelmap
36 regex: __meta_kubernetes_node_label_(.+)
37
38 - job_name: 'kubelet'
39 kubernetes_sd_configs:
40 - role: node
41 scheme: https
42 tls_config:
43 ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
44 insecure_skip_verify: true
45 bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
46 relabel_configs:
47 - action: labelmap
48 regex: __meta_kubernetes_node_label_(.+)
49
50
51 - job_name: 'kubernetes-cadvisor'
52 kubernetes_sd_configs:
53 - role: node
54 # metrics_path: /metrics/cadvisor
55 scheme: https
56 tls_config:
57 ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
58 insecure_skip_verify: true
59 bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
60 relabel_configs:
61 - action: labelmap
62 regex: __meta_kubernetes_node_label_(.+)
63 - source_labels: [__meta_kubernetes_node_name]
64 regex: (.+)
65 replacement: /metrics/cadvisor # <nodeip>/metrics -> <nodeip>/metrics/cadvisor
66 target_label: __metrics_path__
67
68 - job_name: 'kubernetes-apiservers'
69 kubernetes_sd_configs:
70 - role: endpoints
71 scheme: https
72 tls_config:
73 ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
74 insecure_skip_verify: true
75 bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
76 relabel_configs:
77 - source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
78 action: keep
79 regex: default;kubernetes;https
80
81 - job_name: 'kubernetes-endpoints'
82 kubernetes_sd_configs:
83 - role: endpoints
84
85 relabel_configs:
86 - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]
87 action: keep
88 regex: true
89 - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme]
90 action: replace
91 target_label: __scheme__
92 regex: (https?)
93 - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path]
94 action: replace
95 target_label: __metrics_path__
96 regex: (.+)
97 - source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port]
98 action: replace
99 target_label: __address__
100 regex: ([^:]+)(?::\d+)?;(\d+) # 这里的难点在正则这里,RE2 正则规则,+是一次多多次,?是0次或1次,其中?:表示非匹配组(意思就是不获取匹配结果)
101 replacement: $1:$2
102
103 - action: labelmap
104 regex: __meta_kubernetes_service_label_(.+)
105 - source_labels: [__meta_kubernetes_namespace]
106 action: replace
107 target_label: namespace
108 - source_labels: [__meta_kubernetes_service_name]
109 action: replace
110 target_label: service
111 - source_labels: [__meta_kubernetes_pod_name]
112 action: replace
113 target_label: pod
114 - source_labels: [__meta_kubernetes_node_name]
115 action: replace
116 target_label: node
注意我们这里在 relabel_configs 区域做了大量的配置,特别是第一个保留 __meta_kubernetes_service_annotation_prometheus_io_scrape 为 true 的才保留下来,这就是说要想自动发现集群中的 Endpoint,就需要我们在 Service 的 annotation 区域添加 prometheus.io/scrape=true 的声明.

注意这里的正则

- 更新配置并验证
1[root@master1 prometheus-example]#kubectl apply -f prometheus-cm.yaml
2configmap/prometheus-config configured
3
4#稍等一会儿
5[root@master1 prometheus-example]# curl -X POST "http://172.29.9.51:32700/-/reload"
- 验证

我们可以看到 kubernetes-endpoints 这一个任务下面只发现了两个服务,这是因为我们在 relabel_configs 中过滤了 annotation 有 prometheus.io/scrape=true 的 Service,而现在我们系统中只有这样一个 kube-dns 服务符合要求,该 Service 下面有两个实例,所以出现了两个实例:

3、修改redis监控信息
- 现在我们在之前创建的 redis 这个 Service 中添加上
prometheus.io/scrape=true这个 annotation:(prome-redis.yaml)
[root@master1 prometheus-example]#vim prometheus-redis.yaml
1kind: Service
2apiVersion: v1
3metadata:
4 name: redis
5 namespace: monitor
6 annotations:
7 prometheus.io/scrape: "true" #增加这2行信息
8 prometheus.io/port: "9121"
9spec:
10 selector:
11 app: redis
12 ports:
13 - name: redis
14 port: 6379
15 targetPort: 6379
16 - name: prom
17 port: 9121
18 targetPort: 9121
由于 redis 服务的 metrics 接口在 9121 这个 redis-exporter 服务上面,所以我们还需要添加一个 prometheus.io/port=9121 这样的 annotations。
- 然后更新这个 Service:
1[root@master1 prometheus-example]#kubectl apply -f prometheus-redis.yaml
2deployment.apps/redis unchanged
3service/redis configured
- 更新完成后,去 Prometheus 查看 Targets 路径,可以看到 redis 服务自动出现在了
kubernetes-endpoints这个任务下面:

4、整合剩余的监控应用
- 这样以后我们有了新的服务,服务本身提供了
/metrics接口,我们就完全不需要用静态的方式去配置了,到这里我们就可以将之前配置的 redis 的静态配置去掉了。同样,我也可以把prometheus自身在svc里打上annotations,然后通过自动服务发现监控起来,当然,之前配置的 prometheus 的静态配置去掉了。
[root@master1 prometheus-example]#vim prometheus-svc.yaml
1# prometheus-svc.yaml
2apiVersion: v1
3kind: Service
4metadata:
5 name: prometheus
6 namespace: monitor
7 annotations:
8 prometheus.io/scrape: "true"
9 prometheus.io/port: "9090"
10 labels:
11 app: prometheus
12spec:
13 selector:
14 app: prometheus
15 type: NodePort
16 ports:
17 - name: web
18 port: 9090
19 targetPort: http
更新prometheus-svc.yaml:
1[root@master1 prometheus-example]#kubectl apply -f prometheus-svc.yaml
2service/prometheus configured
验证:

最后,删除prometheus-cm.yaml里剩余的静态配置:
[root@master1 prometheus-example]#vim prometheus-cm.yaml
1# prometheus-cm.yaml
2apiVersion: v1
3kind: ConfigMap
4metadata:
5 name: prometheus-config
6 namespace: monitor
7data:
8 prometheus.yml: |
9 global:
10 scrape_interval: 15s
11 scrape_timeout: 15s
12
13 scrape_configs:
14 - job_name: 'nodes'
15 kubernetes_sd_configs:
16 - role: node
17 relabel_configs:
18 - source_labels: [__address__]
19 regex: '(.*):10250'
20 replacement: '${1}:9100'
21 target_label: __address__
22 action: replace
23 - action: labelmap
24 regex: __meta_kubernetes_node_label_(.+)
25
26 - job_name: 'kubelet'
27 kubernetes_sd_configs:
28 - role: node
29 scheme: https
30 tls_config:
31 ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
32 insecure_skip_verify: true
33 bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
34 relabel_configs:
35 - action: labelmap
36 regex: __meta_kubernetes_node_label_(.+)
37
38
39 - job_name: 'kubernetes-cadvisor'
40 kubernetes_sd_configs:
41 - role: node
42 # metrics_path: /metrics/cadvisor
43 scheme: https
44 tls_config:
45 ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
46 insecure_skip_verify: true
47 bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
48 relabel_configs:
49 - action: labelmap
50 regex: __meta_kubernetes_node_label_(.+)
51 - source_labels: [__meta_kubernetes_node_name]
52 regex: (.+)
53 replacement: /metrics/cadvisor # <nodeip>/metrics -> <nodeip>/metrics/cadvisor
54 target_label: __metrics_path__
55
56 - job_name: 'kubernetes-apiservers'
57 kubernetes_sd_configs:
58 - role: endpoints
59 scheme: https
60 tls_config:
61 ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
62 insecure_skip_verify: true
63 bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
64 relabel_configs:
65 - source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
66 action: keep
67 regex: default;kubernetes;https
68
69 - job_name: 'kubernetes-endpoints'
70 kubernetes_sd_configs:
71 - role: endpoints
72
73 relabel_configs:
74 - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]
75 action: keep
76 regex: true
77 - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme]
78 action: replace
79 target_label: __scheme__
80 regex: (https?)
81 - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path]
82 action: replace
83 target_label: __metrics_path__
84 regex: (.+)
85 - source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port]
86 action: replace
87 target_label: __address__
88 regex: ([^:]+)(?::\d+)?;(\d+) # 这里的难点在正则这里,RE2 正则规则,+是一次多多次,?是0次或1次,其中?:表示非匹配组(意思就是不获取匹配结果)
89 replacement: $1:$2
90
91 - action: labelmap
92 regex: __meta_kubernetes_service_label_(.+)
93 - source_labels: [__meta_kubernetes_namespace]
94 action: replace
95 target_label: namespace
96 - source_labels: [__meta_kubernetes_service_name]
97 action: replace
98 target_label: service
99 - source_labels: [__meta_kubernetes_pod_name]
100 action: replace
101 target_label: pod
102 - source_labels: [__meta_kubernetes_node_name]
103 action: replace
104 target_label: node
更新并reload:
1[root@master1 prometheus-example]#kubectl apply -f prometheus-cm.yaml
2configmap/prometheus-config configured
3
4[root@master1 prometheus-example]# curl -X POST "http://172.29.9.51:32700/-/reload"
验证:

🍀 注意:这里的unkonw状态为,prometheus还没把数据给抓取过来呢,抓取过来后才知道其对应的状态。

🍀 监控ingress资源

符合预期,完美。😘
💘 实战:kube-state-metrics-2022.5.2(测试成功)
它本身也相当于是一个exporter。
上面我们配置了自动发现 Endpoints 的监控,但是这些监控数据都是应用内部的监控,需要应用本身提供一个 /metrics 接口,或者对应的 exporter 来暴露对应的指标数据。但是在 Kubernetes 集群上 Pod、DaemonSet、Deployment、Job、CronJob 等各种资源对象的状态也需要监控,这也反映了使用这些资源部署的应用的状态。比如:
- 我调度了多少个副本?现在可用的有几个?
- 多少个 Pod 是
running/stopped/terminated状态? - Pod重启了多少次?
- 我有多少 job 在运行中等等
通过查看前面从集群中拉取的指标(这些指标主要来自 apiserver 和 kubelet 中集成的 cAdvisor),并没有具体的各种资源对象的状态指标。对于 Prometheus 来说,当然是需要引入新的 exporter 来暴露这些指标,Kubernetes 提供了一个kube-state-metrics 就是我们需要的。
1.与 metric-server 的对比
metric-server是从 APIServer 中获取cpu、内存使用率这种监控指标,并把他们发送给存储后端,如 influxdb 或云厂商,当前的核心作用是为 HPA 等组件提供决策指标支持。kube-state-metrics关注于获取 Kubernetes 各种资源的最新状态,如 deployment 或者 daemonset,metric-server仅仅是获取、格式化现有数据,写入特定的存储,实质上是一个监控系统。而 kube-state-metrics 是获取集群最新的指标。- 像 Prometheus 这种监控系统,并不会去用 metric-server 中的数据,他都是自己做指标收集、集成的,但 Prometheus 可以监控 metric-server 本身组件的监控状态并适时报警,这里的监控就可以通过
kube-state-metrics来实现,如 metric-server pod 的运行状态。
2.安装(测试成功)-2022.5.2
实验软件
prometheus-example-0505.tar.gz
链接:https://pan.baidu.com/s/1JkltHSHqRHSVMHvoMuf3VA?pwd=on8e
提取码:on8e

实验环境
1k8s:v1.22.2(1 master,2 node)
2containerd: v1.5.5
3prometneus: docker.io/prom/prometheus:v2.34.0
4kube-state-metrics:v2.4.2
前置条件
- 具有k8s环境;
- 已经把prometheus应用部署到k8s环境里;
关于如何将prometheus应用部署到k8s环境里,请查看我的另一篇文章,获取完整的部署方法!。
https://blog.csdn.net/weixin_39246554/article/details/124498172?spm=1001.2014.3001.5501


- 且已部署了前面的监控
0.查看版本兼容性
kube-state-metrics 已经给出了在 Kubernetes 部署的 manifest 定义文件,我们直接将代码 Clone 到集群中(能用 kubectl 工具操作就行),不过需要注意兼容的版本:

🍀 当前测试时间:2022年5月2日


1.下载代码
1git clone https://github.com/kubernetes/kube-state-metrics.git
2cd kube-state-metrics/examples/standard
默认的镜像为 gcr 的,这里我们可以将 deployment.yaml 下面的镜像替换成 cnych/kube-state-metrics:v2.4.2。此外我们上面为 Prometheus 配置了 Endpoints 的自动发现,所以我们可以给 kube-state-metrics 的 Service 配置上对应的 annotations 来自动被发现。
2.创建资源
将代码克隆后,我们来到kube-state-metrics/examples/standard目录:
先替换下deployment.yaml的镜像源以及在service.yaml里添加下annotations信息:
1[root@master1 standard]#cat deployment.yaml
2apiVersion: apps/v1
3kind: Deployment
4metadata:
5 labels:
6 app.kubernetes.io/component: exporter
7 app.kubernetes.io/name: kube-state-metrics
8 app.kubernetes.io/version: 2.4.2
9 name: kube-state-metrics
10 namespace: kube-system
11spec:
12 replicas: 1
13 selector:
14 matchLabels:
15 app.kubernetes.io/name: kube-state-metrics
16 template:
17 metadata:
18 labels:
19 app.kubernetes.io/component: exporter
20 app.kubernetes.io/name: kube-state-metrics
21 app.kubernetes.io/version: 2.4.2
22 spec:
23 automountServiceAccountToken: true
24 containers:
25 - image: cnych/kube-state-metrics:v2.4.2
26 livenessProbe:
27 httpGet:
28 path: /healthz
29 port: 8080
30 initialDelaySeconds: 5
31 timeoutSeconds: 5
32 name: kube-state-metrics
33 ports:
34 - containerPort: 8080
35 name: http-metrics
36 - containerPort: 8081
37 name: telemetry
38 readinessProbe:
39 httpGet:
40 path: /
41 port: 8081
42 initialDelaySeconds: 5
43 timeoutSeconds: 5
44 securityContext:
45 allowPrivilegeEscalation: false
46 capabilities:
47 drop:
48 - ALL
49 readOnlyRootFilesystem: true
50 runAsUser: 65534
51 nodeSelector:
52 kubernetes.io/os: linux
53 serviceAccountName: kube-state-metrics
54
55[root@master1 standard]#cat service.yaml
56apiVersion: v1
57kind: Service
58metadata:
59 annotations:
60 prometheus.io/scrape: "true"
61 prometheus.io/port: "8080"
62 labels:
63 app.kubernetes.io/component: exporter
64 app.kubernetes.io/name: kube-state-metrics
65 app.kubernetes.io/version: 2.4.2
66 name: kube-state-metrics
67 namespace: kube-system
68spec:
69 clusterIP: None
70 ports:
71 - name: http-metrics
72 port: 8080
73 targetPort: http-metrics
74 - name: telemetry
75 port: 8081
76 targetPort: telemetry
77 selector:
78 app.kubernetes.io/name: kube-state-metrics


- 部署
1[root@master1 standard]#pwd
2/root/kube-state-metrics/examples/standard
3[root@master1 standard]#ls
4cluster-role-binding.yaml cluster-role.yaml deployment.yaml service-account.yaml service.yaml
5
6[root@master1 standard]#kubectl apply -f .
7clusterrolebinding.rbac.authorization.k8s.io/kube-state-metrics created
8clusterrole.rbac.authorization.k8s.io/kube-state-metrics created
9deployment.apps/kube-state-metrics created
10serviceaccount/kube-state-metrics created
11service/kube-state-metrics created
3.验证
部署完成后正常就可以被 Prometheus 采集到指标了:

4.过滤



安装完成。😘
3.水平缩放(分片)
kube-state-metrics 已经内置实现了一些自动分片功能,可以通过 --shard 和 --total-shards 参数进行配置。现在还有一个实验性功能,如果将 kube-state-metrics 部署在 StatefulSet 中,它可以自动发现其命名位置,以便自动配置分片,这是一项实验性功能,可能以后会被移除。
要启用自动分片,必须运行一个 kube-state-metrics 的 StatefulSet,并且必须通过 --pod 和 --pod-namespace 标志将 pod 名称和名称空间传递给 kube-state-metrics 进程。可以参考 /examples/autosharding 目录下面的示例清单文件进行说明。
4.使用(测试成功)-2022.5.2
使用 kube-state-metrics 的一些典型场景:
- 存在执行失败的Job:
kube_job_status_failed - 集群节点状态错误:
kube_node_status_condition{condition="Ready", status!="true"}==1 - 集群中存在启动失败的 Pod:
kube_pod_status_phase{phase=~"Failed|Unknown"}==1 - 最近30分钟内有 Pod 容器重启:
changes(kube_pod_container_status_restarts_total[30m])>0
1.问题现象:采集到的标签冲突问题
现在有一个问题是前面我们做 endpoints 类型的服务发现的时候做了一次 labelmap,将 namespace 和 pod 标签映射到了指标中。但是由于 kube-state-metrics 暴露的指标中本身就包含 namespace 和 pod 标签,这就会产生冲突,这种情况会将映射的标签变成 exported_namespace 和 exported_pod,这变会对指标的查询产生影响,如下所示:




可以看到这里的exported前缀信息都是正确的,但是node,namespace,service等都是kube-state-metrics的信息,不符合预期。
2.解决办法:利用metric_relabel_configs功能
这个情况下我们可以使用 metric_relabel_configs 这 Prometheus 保存数据前的最后一步重新编辑标签,metric_relabel_configs 模块和 relabel_configs 模块很相似,metric_relabel_configs 一个很常用的用途就是可以将监控不需要的数据,直接丢掉,不在 Prometheus 中保存。比如我们这里可以重新配置 endpoints 类型的指标发现配置:
1- job_name: 'endpoints'
2 kubernetes_sd_configs:
3 - role: endpoints
4
5 metric_relabel_configs:
6 - source_labels: [__name__, exported_pod]
7 regex: kube_pod_info;(.+)
8 target_label: pod
9 - source_labels: [__name__, exported_namespace]
10 regex: kube_pod_info;(.+)
11 target_label: namespace
12 - source_labels: [__name__, exported_node]
13 regex: kube_pod_info;(.+)
14 target_label: node
15 - source_labels: [__name__, exported_service]
16 regex: kube_pod_info;(.+)
17 target_label: service
18
19 relabel_configs:
20 # ......
本次完整yaml如下:
1# prometheus-cm.yaml
2apiVersion: v1
3kind: ConfigMap
4metadata:
5 name: prometheus-config
6 namespace: monitor
7data:
8 prometheus.yml: |
9 global:
10 scrape_interval: 15s
11 scrape_timeout: 15s
12
13 scrape_configs:
14 - job_name: 'nodes'
15 kubernetes_sd_configs:
16 - role: node
17 relabel_configs:
18 - source_labels: [__address__]
19 regex: '(.*):10250'
20 replacement: '${1}:9100'
21 target_label: __address__
22 action: replace
23 - action: labelmap
24 regex: __meta_kubernetes_node_label_(.+)
25
26 - job_name: 'kubelet'
27 kubernetes_sd_configs:
28 - role: node
29 scheme: https
30 tls_config:
31 ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
32 insecure_skip_verify: true
33 bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
34 relabel_configs:
35 - action: labelmap
36 regex: __meta_kubernetes_node_label_(.+)
37
38
39 - job_name: 'kubernetes-cadvisor'
40 kubernetes_sd_configs:
41 - role: node
42 # metrics_path: /metrics/cadvisor
43 scheme: https
44 tls_config:
45 ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
46 insecure_skip_verify: true
47 bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
48 relabel_configs:
49 - action: labelmap
50 regex: __meta_kubernetes_node_label_(.+)
51 - source_labels: [__meta_kubernetes_node_name]
52 regex: (.+)
53 replacement: /metrics/cadvisor # <nodeip>/metrics -> <nodeip>/metrics/cadvisor
54 target_label: __metrics_path__
55
56 - job_name: 'kubernetes-apiservers'
57 kubernetes_sd_configs:
58 - role: endpoints
59 scheme: https
60 tls_config:
61 ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
62 insecure_skip_verify: true
63 bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
64 relabel_configs:
65 - source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
66 action: keep
67 regex: default;kubernetes;https
68
69 - job_name: 'kubernetes-endpoints'
70 kubernetes_sd_configs:
71 - role: endpoints
72
73 relabel_configs:
74 - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]
75 action: keep
76 regex: true
77 - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme]
78 action: replace
79 target_label: __scheme__
80 regex: (https?)
81 - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path]
82 action: replace
83 target_label: __metrics_path__
84 regex: (.+)
85 - source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port]
86 action: replace
87 target_label: __address__
88 regex: ([^:]+)(?::\d+)?;(\d+) # 这里的难点在正则这里,RE2 正则规则,+是一次多多次,?是0次或1次,其中?:表示非匹配组(意思就是不获取匹配结果)
89 replacement: $1:$2
90
91 - action: labelmap
92 regex: __meta_kubernetes_service_label_(.+)
93 - source_labels: [__meta_kubernetes_namespace]
94 action: replace
95 target_label: namespace
96 - source_labels: [__meta_kubernetes_service_name]
97 action: replace
98 target_label: service
99 - source_labels: [__meta_kubernetes_pod_name]
100 action: replace
101 target_label: pod
102 - source_labels: [__meta_kubernetes_node_name]
103 action: replace
104 target_label: node
105
106
107 metric_relabel_configs:
108 - source_labels: [__name__, exported_pod]
109 regex: kube_pod_info;(.+)
110 target_label: pod
111 - source_labels: [__name__, exported_namespace]
112 regex: kube_pod_info;(.+)
113 target_label: namespace
114 - source_labels: [__name__, exported_node]
115 regex: kube_node_info;(.+)
116 target_label: node
117 - source_labels: [__name__, exported_service]
118 regex: kube_service_info;(.+)
119 target_label: service
- 更新配置并reload
1[root@master1 prometheus-example]#kubectl apply -f prometheus-cm.yaml
2configmap/prometheus-config unchanged
3[root@master1 prometheus-example]# curl -X POST "http://172.29.9.51:32700/-/reload"
3.验证



注意:这里虽然是改过来了,但是感觉部分还是有问题的……很奇怪!搁置!
metric_relabel_configs 与 relabel_configs 虽然非常类似,但是还是有很大不同的,relabel_configs 是针对 target 指标采集前和采集中的筛选,而 metric_relabel_configs 是针对指标采集后的筛选,如果一个不起作用,那么我们可以随时尝试使用另一个!
Prometheus 需要知道要抓取什么,这就是服务发现和 relabel_configs 配置的地方,relabel_configs 允许你选择要抓取的目标以及目标标签是什么,所以如果你想抓取这种类型的机器而不是那种类型的机器,请使用relabel_configs。
metric_relabel_configs 相比之下,在抓取发生之后,但在数据被存储系统摄取之前应用,因此,如果你想要删除一些昂贵的指标,或者你想要操作来自抓取目标本身的标签(例如来自 /metrics 页面),那就用 metric_relabel_configs。
🍀
譬如下面的 relabel_configs drop 动作:
1relabel_configs:
2 - source_labels: [__meta_xxx_label_xxx]
3 regex: Example.*
4 action: drop
那么将不会收集这个指标,而 metric_relabel_configs 使用的时候指标已经采集过了:
1metric_relabel_configs:
2- source_labels: [__name__]
3 regex: '(container_tasks_state|container_memory_failures_total)'
4 action: drop
所以 metric_relabel_configs 相对来说,更加昂贵,因为指标已经采集了。
测试结束。😘
5.更多信息
关于 kube-state-metrics 的更多用法可以查看官方 GitHub 仓库:https://github.com/kubernetes/kube-state-metrics
关于我
我的博客主旨:
- 排版美观,语言精炼;
- 文档即手册,步骤明细,拒绝埋坑,提供源码;
- 本人实战文档都是亲测成功的,各位小伙伴在实际操作过程中如有什么疑问,可随时联系本人帮您解决问题,让我们一起进步!
- 个人微信二维码:x2675263825 (舍得), qq:2675263825。

- 个人微信公众号:《云原生架构师实战》

- 个人csdn
https://blog.csdn.net/weixin_39246554?spm=1010.2135.3001.5421

- 个人已开源干货😘
不服来怼:宇宙中最好用的云笔记 & 其他开源干货:https://www.yuque.com/go/doc/73723298?#

- 个人网站:(计划ing)
最后
好了,关于prometheus监控k8s集群里的容器和apiserver实验就到这里了,感谢大家阅读,最后贴上我女神的photo,祝大家生活快乐,每天都过的有意义哦,我们下期见!

FAQ
prometheus联邦
prometheus本身是比较耗内存的,因为它的一个热数据本身都是在内存当中。
如果你内存占用比较多的话,最好的方式就是,你prometheus本地数据不要保留太多。假如说你要查询1年前的数据,那它肯定要把1年多的数据都要加载到本地进行计算,那肯定资源占用的多啊,内存消耗特别大的。
一般来说,你本地数据不要保留太多,历史的数据存到远端。你需要时,你可以在远程做个计算,然后返回回来,这个方式比较好。
后面可以用这个thanos来解决这个问题。
prometheus效果图

关于我
我的博客主旨:
- 排版美观,语言精炼;
- 文档即手册,步骤明细,拒绝埋坑,提供源码;
- 本人实战文档都是亲测成功的,各位小伙伴在实际操作过程中如有什么疑问,可随时联系本人帮您解决问题,让我们一起进步!
🍀 微信二维码
x2675263825 (舍得), qq:2675263825。

🍀 微信公众号
《云原生架构师实战》

🍀 csdn
https://blog.csdn.net/weixin_39246554?spm=1010.2135.3001.5421

🍀 博客

🍀 知乎
https://www.zhihu.com/people/foryouone

🍀 语雀
https://www.yuque.com/books/share/34a34d43-b80d-47f7-972e-24a888a8fc5e?# 《云笔记最佳实践》


最后
好了,关于本次就到这里了,感谢大家阅读,最后祝大家生活快乐,每天都过的有意义哦,我们下期见!

1


文档导航
本页导航
- Prometheus
- 目录
- Prometheus基础
- 💘 实战:prometheus部署(测试成功)-2022.4.29
- 💘 实战:prometheus部署到k8s-2022.4.29(测试成功)
- 💘 实战:prometheus监控测试-2022.7.23(测试成功)
- 💘 实战:prometheus应用监控-2022.4.30(测试成功)
- 💘 实战:prometheus监控k8s集群里的node资源(测试成功)-2022.4.30
- 💘 实战:prometheus监控容器-2022.5.2(测试成功)
- 💘 实战:prometheus监控 apiserver-2022.5.2(测试成功)
- 💘 实践:prometheus监控pod-2022.5.2(测试成功)
- 💘 实战:kube-state-metrics-2022.5.2(测试成功)
- FAQ
- 关于我
- 最后