跳到主要内容

Prometheus

最后更新于:

💘 实战: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个模块:globalrule_filesscrape_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监控测试-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_exporternode_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_authbearer_token:比如我们提供的 /metrics 接口需要 basic 认证的时候,通过传统的用户名/密码或者在请求的 header 中添加对应的 token 都可以支持
  • kubernetes_sd_configsconsul_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,然后点击执行就可以看到对应的数据图表了:

实验结束。😘

关于我

我的博客主旨:我希望每一个人拿着我的博客都可以做出实验现象,先把实验做出来,然后再结合理论知识更深层次去理解技术点,这样学习起来才有乐趣和动力。并且,我的博客内容步骤是很完整的,也分享源码和实验用到的软件,希望能和大家一起共同进步!

各位小伙伴在实际操作过程中如有什么疑问,可随时联系本人免费帮您解决问题:

  1. 个人微信二维码:x2675263825 (舍得), qq:2675263825。

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

  1. 个人csdn

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

  1. 个人已开源干货😘

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

  1. 个人网站:(计划ing)

最后

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

💘 实战: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监控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 中过滤了 annotationprometheus.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

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_namespaceexported_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_configsrelabel_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

关于我

我的博客主旨:

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

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

  1. 个人csdn

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

  1. 个人已开源干货😘

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

  1. 个人网站:(计划ing)

最后

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

最新文章

本页导航

文档导航