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

前置条件

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

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

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

image-20220430105630811

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

上面的配置和我们之前配置 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

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

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

image-20220501091016938

该如何替换呢?

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

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

  • 更新并执行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

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

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

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

  • 更新并执行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-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

4、标签查询

  • 查询
container_memory_usage_bytes

image-20220501191817592

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

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

image-20220501192021224

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

image-20220501192537905

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

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

我们可以看到 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

  • 配置如下

[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

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

prometheus apiserver rate

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

⚠️ 注意:

另外如果我们要来监控其他系统组件,比如 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

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

    image-20211002141739664

  3. 个人csdn

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

    image-20211002092344616

  4. 个人已开源干货😘

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

    image-20220423100718009

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

最后

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

image-20220501211853234

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐