舍得

V1

2022/05/02阅读:12主题:橙心

实战:prometheus监控k8s集群里的容器和apiserver-2022.5.2(测试成功)

image-20220430221830106
image-20220430221830106

目录

实验环境

k8s:v1.22.2(1 master,2 node)
containerd: v1.5.5
prometneus: docker.io/prom/prometheus:v2.34.0

实验软件

链接:https://pan.baidu.com/s/1JkltHSHqRHSVMHvoMuf3VA?pwd=on8e 提取码:on8e

2022.5.2-prometheus监控k8s集群里的容器和apiserver-code

image-20220502100926703
image-20220502100926703

前置条件

  • 具有 k8s 环境;
  • 已经把 prometheus 应用部署到 k8s 环境里;

关于如何将prometheus应用部署到k8s环境里,请查看我的另一篇文章,获取完整的部署方法!。

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

image-20220430105630811
image-20220430105630811
image-20220430105722637
image-20220430105722637

实践 1:容器监控

基础知识

说到容器监控我们自然会想到 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 p8s-example/ [root@master1 p8s-example]#vim prometheus-cm.yaml

# prometheus-cm.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: prometheus-config
  namespace: monitor
data:
  prometheus.yml: |
    global:
      scrape_interval: 15s
      scrape_timeout: 15s

    scrape_configs:
    - job_name: 'prometheus'
      static_configs:
        - targets: ['localhost:9090']

    - job_name: 'coredns'
      static_configs:
        - targets: ['10.244.0.8:9153', '10.244.0.10:9153']

    - job_name: 'redis'
      static_configs:
        - targets: ['redis:9121']

    - job_name: 'nodes'
      kubernetes_sd_configs:
      - role: node
      relabel_configs:
      - source_labels: [__address__]
        regex: '(.*):10250'
        replacement: '${1}:9100'
        target_label: __address__
        action: replace
      - action: labelmap
        regex: __meta_kubernetes_node_label_(.+)

    - job_name: 'kubelet'
      kubernetes_sd_configs:
      - role: node
      scheme: https
      tls_config:
        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
        insecure_skip_verify: true
      bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
      relabel_configs:
      - action: labelmap
        regex: __meta_kubernetes_node_label_(.+)


    - job_name: 'kubernetes-cadvisor'
      kubernetes_sd_configs:
      - role: node
      scheme: https
      tls_config:
        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
        insecure_skip_verify: true
      bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
      relabel_configs:
      - action: labelmap
        regex: __meta_kubernetes_node_label_(.+)
image-20220501090525782
image-20220501090525782

上面的配置和我们之前配置 node-exporter 的时候几乎是一样的,区别是我们这里使用了 https 的协议。

另外需要注意的是配置了 ca.cart 和 token 这两个文件,这两个文件是 Pod 启动后自动注入进来的

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

发现和 kubelet 监控并没什么不同:

image-20220501090848329
image-20220501090848329

2、方法 1:直接配置__metrics_path选项

来看下Service Discovery,现在需求是把这里的__metrics_path 路径要替换成:/metrics/cadvisor 即可:

image-20220501091016938
image-20220501091016938

该如何替换呢?

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

image-20220501091217384
image-20220501091217384
  • 配置 prometheus 配置文件

[root@master1 ~]#cd p8s-example/ [root@master1 p8s-example]#vim prometheus-cm.yaml

# prometheus-cm.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: prometheus-config
  namespace: monitor
data:
  prometheus.yml: |
    global:
      scrape_interval: 15s
      scrape_timeout: 15s

    scrape_configs:
    - job_name: 'prometheus'
      static_configs:
        - targets: ['localhost:9090']

    - job_name: 'coredns'
      static_configs:
        - targets: ['10.244.0.8:9153', '10.244.0.10:9153']

    - job_name: 'redis'
      static_configs:
        - targets: ['redis:9121']

    - job_name: 'nodes'
      kubernetes_sd_configs:
      - role: node
      relabel_configs:
      - source_labels: [__address__]
        regex: '(.*):10250'
        replacement: '${1}:9100'
        target_label: __address__
        action: replace
      - action: labelmap
        regex: __meta_kubernetes_node_label_(.+)

    - job_name: 'kubelet'
      kubernetes_sd_configs:
      - role: node
      scheme: https
      tls_config:
        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
        insecure_skip_verify: true
      bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
      relabel_configs:
      - action: labelmap
        regex: __meta_kubernetes_node_label_(.+)


    - job_name: 'kubernetes-cadvisor'
      kubernetes_sd_configs:
      - role: node
      metrics_path: /metrics/cadvisor
      scheme: https
      tls_config:
        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
        insecure_skip_verify: true
      bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
      relabel_configs:
      - action: labelmap
        regex: __meta_kubernetes_node_label_(.+)
image-20220501130618763
image-20220501130618763
  • 更新并执行 reload 操作:
[root@master1 p8s-example]#kubectl apply -f prometheus-cm.yaml
configmap/prometheus-config configured
[root@master1 p8s-example]# curl -X POST "http://172.29.9.51:32700/-/reload"
  • 验证
image-20220501130312929
image-20220501130312929

可以看到,直接配置属性值也是可以生效的!😘

:warning: 当然,你直接访问,肯定是访问不到的,需要 token:

image-20220501130526242
image-20220501130526242

3、方法 2:使用relabel功能

  • 这里重新配置下 prometheus 配置文件

[root@master1 p8s-example]#pwd /root/p8s-example [root@master1 p8s-example]#vim prometheus-cm.yaml

# prometheus-cm.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: prometheus-config
  namespace: monitor
data:
  prometheus.yml: |
    global:
      scrape_interval: 15s
      scrape_timeout: 15s

    scrape_configs:
    - job_name: 'prometheus'
      static_configs:
        - targets: ['localhost:9090']

    - job_name: 'coredns'
      static_configs:
        - targets: ['10.244.0.8:9153', '10.244.0.10:9153']

    - job_name: 'redis'
      static_configs:
        - targets: ['redis:9121']

    - job_name: 'nodes'
      kubernetes_sd_configs:
      - role: node
      relabel_configs:
      - source_labels: [__address__]
        regex: '(.*):10250'
        replacement: '${1}:9100'
        target_label: __address__
        action: replace
      - action: labelmap
        regex: __meta_kubernetes_node_label_(.+)

    - job_name: 'kubelet'
      kubernetes_sd_configs:
      - role: node
      scheme: https
      tls_config:
        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
        insecure_skip_verify: true
      bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
      relabel_configs:
      - action: labelmap
        regex: __meta_kubernetes_node_label_(.+)


    - job_name: 'kubernetes-cadvisor'
      kubernetes_sd_configs:
      - role: node
     # metrics_path: /metrics/cadvisor
      scheme: https
      tls_config:
        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
        insecure_skip_verify: true
      bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
      relabel_configs:
      - action: labelmap
        regex: __meta_kubernetes_node_label_(.+)
      - source_labels: [__meta_kubernetes_node_name]
        regex: (.+)
        replacement: /metrics/cadvisor    # <nodeip>/metrics -> <nodeip>/metrics/cadvisor
        target_label: __metrics_path__
image-20220501131219911
image-20220501131219911
  • 更新并执行 reload 操作:
[root@master1 p8s-example]#kubectl apply -f prometheus-cm.yaml
configmap/prometheus-config configured
[root@master1 p8s-example]# curl -X POST "http://172.29.9.51:32700/-/reload"
  • 验证:
image-20220501131502459
image-20220501131502459

也是可以实现和上面一样的效果!

:warning: 注意:下面的这种方式是不推荐的!

image-20220501131629265
image-20220501131629265
- job_name: 'kubernetes-cadvisor'
  kubernetes_sd_configs:
  - role: node
  scheme: https
  tls_config:
    ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
  bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
  relabel_configs:
  - action: labelmap
    regex: __meta_kubernetes_node_label_(.+)
  replacement: $1
  - source_labels: [__meta_kubernetes_node_name]
    regex: (.+)
    replacement: /metrics/cadvisor    # <nodeip>/metrics -> <nodeip>/metrics/cadvisor
    target_label: __metrics_path__
  # 下面的方式不推荐使用
  # - target_label: __address__
  #   replacement: kubernetes.default.svc:443
  # - source_labels: [__meta_kubernetes_node_name]
  #   regex: (.+)
  #   target_label: __metrics_path__
  #   replacement: /api/v1/nodes/${1}/proxy/metrics/cadvisor
prometheus webui cadvisor
prometheus webui cadvisor

4、标签查询

  • 查询
container_memory_usage_bytes
image-20220501191817592
image-20220501191817592

可以看到有狠多年的实例,因为这里列出了集群里的所有容器。

  • 过滤
container_memory_usage_bytes{namespace="monitor",instance="node1"#这里会自动提示的!
image-20220501192021224
image-20220501192021224

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

image-20220501192537905
image-20220501192537905
image-20220501192553074
image-20220501192553074

测试结束。😘

实践 2:监控 apiserver

基础知识

apiserver 作为 Kubernetes 最核心的组件,当然他的监控也是非常有必要的。

1、查看集群 apiserver

对于 apiserver 的监控我们可以直接通过 kubernetes 的 Service 来获取:

➜ kubectl get svc
NAME             TYPE           CLUSTER-IP       EXTERNAL-IP             PORT(S)          AGE
kubernetes       ClusterIP      10.96.0.1        <none>                  443/TCP          33d

上面这个 Service 就是我们集群的 apiserver 在集群内部的 Service 地址,要自动发现 Service 类型的服务,我们就需要用到 role 为 Endpoints 的 kubernetes_sd_configs

image-20220501193932248
image-20220501193932248

2、在 ConfigMap 对象中添加上一个 Endpoints 类型的服务的监控任务

  • 我们可以在 ConfigMap 对象中添加上一个 Endpoints 类型的服务的监控任务:

[root@master1 ~]#cd p8s-example/ [root@master1 p8s-example]#vim prometheus-cm.yaml

- job_name: 'kubernetes-apiservers'
  kubernetes_sd_configs:
  - role: endpoints

本 yaml 完整代码如下:

# prometheus-cm.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: prometheus-config
  namespace: monitor
data:
  prometheus.yml: |
    global:
      scrape_interval: 15s
      scrape_timeout: 15s

    scrape_configs:
    - job_name: 'prometheus'
      static_configs:
        - targets: ['localhost:9090']

    - job_name: 'coredns'
      static_configs:
        - targets: ['10.244.0.8:9153', '10.244.0.10:9153']

    - job_name: 'redis'
      static_configs:
        - targets: ['redis:9121']

    - job_name: 'nodes'
      kubernetes_sd_configs:
      - role: node
      relabel_configs:
      - source_labels: [__address__]
        regex: '(.*):10250'
        replacement: '${1}:9100'
        target_label: __address__
        action: replace
      - action: labelmap
        regex: __meta_kubernetes_node_label_(.+)

    - job_name: 'kubelet'
      kubernetes_sd_configs:
      - role: node
      scheme: https
      tls_config:
        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
        insecure_skip_verify: true
      bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
      relabel_configs:
      - action: labelmap
        regex: __meta_kubernetes_node_label_(.+)


    - job_name: 'kubernetes-cadvisor'
      kubernetes_sd_configs:
      - role: node
     # metrics_path: /metrics/cadvisor
      scheme: https
      tls_config:
        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
        insecure_skip_verify: true
      bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
      relabel_configs:
      - action: labelmap
        regex: __meta_kubernetes_node_label_(.+)
      - source_labels: [__meta_kubernetes_node_name]
        regex: (.+)
        replacement: /metrics/cadvisor    # <nodeip>/metrics -> <nodeip>/metrics/cadvisor
        target_label: __metrics_path__

    - job_name: 'kubernetes-apiservers'
      kubernetes_sd_configs:
      - role: endpoints

上面这个任务是定义的一个类型为 endpoints 的 kubernetes_sd_configs ,添加到 Prometheus 的 ConfigMap 的配置文件中.

  • 然后更新配置:
[root@master1 p8s-example]#kubectl apply -f prometheus-cm.yaml
configmap/prometheus-config configured

# 隔一会儿执行reload操作
[root@master1 p8s-example]# curl -X POST "http://172.29.9.51:32700/-/reload"
  • 更新完成后,我们再去查看 Prometheus 的 Dashboard 的 target 页面:
image-20220501203047141
image-20220501203047141

我们可以看到 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 证书配置上,如下所示:

image-20220501203304600
image-20220501203304600
  • 配置如下

[root@master1 p8s-example]#pwd /root/p8s-example [root@master1 p8s-example]#vim prometheus-cm.yaml

- job_name: 'kubernetes-apiservers'
  kubernetes_sd_configs:
  - role: endpoints
  scheme: https
  tls_config:
    ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
    insecure_skip_verify: true
  bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
  relabel_configs:
  - source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
    action: keep
    regex: default;kubernetes;https

完整 yaml 如下:

# prometheus-cm.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: prometheus-config
  namespace: monitor
data:
  prometheus.yml: |
    global:
      scrape_interval: 15s
      scrape_timeout: 15s

    scrape_configs:
    - job_name: 'prometheus'
      static_configs:
        - targets: ['localhost:9090']

    - job_name: 'coredns'
      static_configs:
        - targets: ['10.244.0.8:9153', '10.244.0.10:9153']

    - job_name: 'redis'
      static_configs:
        - targets: ['redis:9121']

    - job_name: 'nodes'
      kubernetes_sd_configs:
      - role: node
      relabel_configs:
      - source_labels: [__address__]
        regex: '(.*):10250'
        replacement: '${1}:9100'
        target_label: __address__
        action: replace
      - action: labelmap
        regex: __meta_kubernetes_node_label_(.+)

    - job_name: 'kubelet'
      kubernetes_sd_configs:
      - role: node
      scheme: https
      tls_config:
        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
        insecure_skip_verify: true
      bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
      relabel_configs:
      - action: labelmap
        regex: __meta_kubernetes_node_label_(.+)


    - job_name: 'kubernetes-cadvisor'
      kubernetes_sd_configs:
      - role: node
     # metrics_path: /metrics/cadvisor
      scheme: https
      tls_config:
        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
        insecure_skip_verify: true
      bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
      relabel_configs:
      - action: labelmap
        regex: __meta_kubernetes_node_label_(.+)
      - source_labels: [__meta_kubernetes_node_name]
        regex: (.+)
        replacement: /metrics/cadvisor    # <nodeip>/metrics -> <nodeip>/metrics/cadvisor
        target_label: __metrics_path__

    - job_name: 'kubernetes-apiservers'
      kubernetes_sd_configs:
      - role: endpoints
      scheme: https
      tls_config:
        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
        insecure_skip_verify: true
      bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
      relabel_configs:
      - source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
        action: keep
        regex: default;kubernetes;https

4、验证

  • 现在重新更新配置文件、重新加载 Prometheus,切换到 Prometheus 的 Targets 路径下查看:
[root@master1 p8s-example]#kubectl apply -f prometheus-cm.yaml
configmap/prometheus-config configured

[root@master1 p8s-example]# curl -X POST "http://172.29.9.51:32700/-/reload"
image-20220501205220594
image-20220501205220594

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

prometheus apiserver rate
prometheus apiserver rate

这样我们就完成了对 Kubernetes APIServer 的监控。

:warning: 注意:

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

关于我

我的博客主旨:

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

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

    image-20211002141739664
    image-20211002141739664
  3. 个人 csdn

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

    image-20211002092344616
    image-20211002092344616
  4. 个人已开源干货 😘

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

    image-20220423100718009
    image-20220423100718009
  5. 个人网站:(计划 ing)

最后

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

image-20220501211853234
image-20220501211853234

分类:

后端

标签:

后端

作者介绍

舍得
V1