Prometheus服务发现基础、relabel基础及语法介绍和使用案例;

Prometheus服务发现基础-简介:

prometheus采用pull方式拉取指定目标实例的监控数据,也就是间隔固定的周期去目标实例上抓取metrics数据,每一个被抓取的目标实例都需要暴露一个数据指标API接口,prometheus通过这个暴露的接口就可以获取到其指标数据,这种方式需要由目标服务决定采集的指标有哪些,prometheus通过配置在scrape_configs中指定目标节点,static_configs(静态配置)无法动态感知新的节点,即如果后面增加了节点或者删除节点,就得手动修promrtheus的配置文件,并重启promethues,因此后期维护很不方便,所以出现了很多不同类型的service discovery即动态服务发现机制,动态服务发现能够使prometheus自动发现集群中的新目标,并对其进行数据采集,通过服务发现机制使Prometheus能自动获取到需要监控的Target列表,然后轮询这些Target获取监控数据。

Prometheus常用的服务发现类型:

  • kubernetes_sd_configs: #基于Kubernetes API实现的服务发现,让prometheus动态发现kubernetes中被监控的新目标
  • static_configs: #静态服务发现,基于prometheus配置文件指定的监控目标
  • dns_sd_configs: #DNS 服务发现监控目标
  • consul_sd_configs: #Consul 服务发现,基于consul服务动态发现监控目标
  • file_sd_configs: #基于指定的文件实现服务发现,基于指定的文件发现监控目标

官方服务发现配置地址:

https://prometheus.io/docs/prometheus/latest/configuration/configuration/#configuration-file

Service_Discovery_Architecture_Diagram

Prometheus服务发现基础-动态发现类型:

基于kubernetes_sd_config支持的动态服务发现类型:

  • node #node节点
  • service #发现svc
  • pod #发现pod
  • endpoints #基于svc发现endpoints(pod)
  • Endpointslice #对endpoint进行切片
  • ingress #发现ingress

kubernetes服务发现流程图1

kubernetes服务发现流程图2

Prometheus服务发现基础-relabeling:

promethues的relabeling(重新修改标签)功能很强大,它能够在抓取到目标实例之前把目标实例的元数据标签动态重新修改,动态添加或者覆盖标签。
Prometheus从Kubernetes API动态发现目标(targer)之后,在被发现的target实例中,都包含一些原始的Metadata标签信息,默认的标签有:

  1. __address__:以<host>:<port> 格式显示目标targets的地址
  2. __scheme__:采集的目标服务地址的Scheme形式,HTTP或者HTTPS
  3. __metrics_path__:采集的目标服务的访问路径
    ...........

Prometheus服务发现基础:

标签重写的两个阶段:

为了更好的识别监控指标,便于后期调用数据绘图、告警等需求,prometheus支持对发现之后的目标进行label修改,在两个阶段可以重新标记:

  1. relabel_configs : 在对target进行数据采集之前(比如在采集数据之前重新定义标签信息,如目的IP、目的端口等信息),可以使用relabel_configs添加、修改或删除一些标签、也可以只采集特定目标或过滤目标。
  2. metric_relabel_configs:在对target进行数据采集之后,即如果是已经抓取到指标数据时,可以使用metric_relabel_configs做最后的重新标记和过滤。

一般来说使用前者居多

修改标签的阶段图

label类型:

  1. source_labels:源标签,没有经过relabel处理之前的标签名字
  2. target_label:通过action处理之后的新的标签名字
  3. regex:给定的值或正则表达式匹配,匹配源标签的值
  4. replacement:通过分组替换后标签(target_label)对应的/()/() $1:$2

示例:

Prometheus-Server静态配置:

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

  - job_name: "prometheus-node"
    static_configs:
    - targets: ["10.2.0.21:9100","10.2.0.22:9100"]

基于kubernetes API Server的动态发现:

scrape_configs:
  - job_name: 'kubernetes-apiserver'     #job名称
    kubernetes_sd_configs: #基于kubernetes_sd_configs实现服务发现
    - role: endpoints #发现类型为endpoints
    scheme: https #当前jod使用的发现协议
    tls_config: #证书配置
      ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt #容器里的证书路径
    bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token #容器里的token路径
    relabel_configs: #重新re修改标签label配置configs
      - source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name] #源标签,即对哪些标签进行操作
        action: keep #action定义了relabel的具体动作,action支持多种
        regex: default;kubernetes;https #指定匹配条件、只发现default命名空间中的kubernetes服务后面的endpoint并且是https协议

kubernetes_API_Server_metrics

action简介:

  1. replace: #替换标签值,根据regex正则匹配到源标签的值,使用replacement来引用表达式匹配的分组。
  2. keep: #满足regex正则条件的实例进行采集,把source_labels中没有匹配到regex正则内容的Target实例丢掉,即只采集匹配成功的实例。
  3. drop: #满足regex正则条件的实例不采集,把source_labels中匹配到regex正则内容的Target实例丢掉,即只采集没有匹配到的实例。
  4. labelmap:#匹配regex所有标签名称,然后复制匹配标签的值进行分组,可以通过replacement分组引用(${1},${2},…)替代
  5. labelkeep:匹配regex所有标签名称,其它不匹配的标签都将从标签集中删除
  6. labeldrop:匹配regex所有标签名称,其它匹配的标签都将从标签集中删除
  7. hashmod:使用hashmod计算source_labels的Hash值并进行对比,基于自定义的模数取模,以实现对目标进行分类、重新赋值等功能:

查看prometheus server容器证书:

kubectl exec -it prometheus-server-7547cc665-gqzbx ls /var/run/secrets/kubernetes.io/serviceaccount/ -n monitoring
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND]instead.
ca.crt namespace token

对比容器的ca.crt 与宿主机/etc/kubernetes/ssl/ca.pem文件的md5值是一样的。

kubectl exec -it prometheus-server-5dc5969f8c-gqt4j -n monitoring md5sum /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
b51d8fc20171d02ecd087f80a18054dc  /var/run/secrets/kubernetes.io/serviceaccount/ca.crt

md5sum /etc/kubernetes/ssl/ca.pem
b51d8fc20171d02ecd087f80a18054dc  /etc/kubernetes/ssl/ca.pem

Prometheus服务发现示例 api-server:

scrape_configs:
  - job_name: 'kubernetes-apiserver'     #job名称
    kubernetes_sd_configs: #基于kubernetes_sd_configs实现服务发现
    - role: endpoints #发现类型为endpoints
    scheme: https #当前jod使用的发现协议
    tls_config: #证书配置
      ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt #容器里的证书路径
    bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token #容器里的token路径
    relabel_configs: #重新re修改标签label配置configs
      - source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name] #源标签,即对哪些标签进行操作
        action: keep #action定义了relabel的具体动作,action支持多种
        regex: default;kubernetes;https #指定匹配条件、只发现default命名空间中的kubernetes服务后面的endpoint并且是https协议

最终,匹配到api-server的地址:

root@k8s-master-1:~# kubectl get ep
NAME         ENDPOINTS                                   AGE
kubernetes   10.2.0.1:6443,10.2.0.2:6443,10.2.0.3:6443   94d

api-server的主要指标数据:

  1. Apiserver组件是k8s集群的入口,所有请求都是从apiserver进来的,所以对apiserver指标做监控可以用来判断集群的健康状况。
  2. apiserver_request_total:
    以下promQL语句为查询apiserver最近一分钟不同方法的请求数量统计,apiserver_request_total为请求各个服务的访问详细统计:
    sum(rate(apiserver_request_total[10m])) by (resource,subresource,verb)

apiserver最近一分钟不同方法的请求数量统计示例图

Prometheus服务发现示例-annotation:

关于annotation_prometheus_io_scrape及kubernetes_service_annotation_prometheus_io_port:
在k8s中,如果deployment的yaml文件指定了annotation_prometheus_io_scrape及kubernetes_service_annotation_prometheus_io_port,那么基于prometheus的发现规则,需要在被发现的目的target定义注解匹配annotation_prometheus_io_scrape的值为true和kubernetes_service_annotation_prometheus_io_port对应的端口号如9153,且必须匹配成功该注解才会保留监控target,然后再进行数据抓取并进行标签替换,主要用于精确匹配目的target(过滤掉不匹配的其它target)

scrape_configs:
  - job_name: 'kubernetes-service-endpoints' #job名称
    kubernetes_sd_configs: #sd_configs发现
    - role: endpoints #角色,endpoints 发现
    relabel_configs: #标签重写配置

    #匹配annotation_prometheus_io_scrape的值为true,保留标签然后再向下执行
    - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]
      action: keep
      regex: true

    #将__meta_kubernetes_service_annotation_prometheus_io_scheme修改为__scheme__
    - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme]
      action: replace
      target_label: __scheme__
      regex: (https?) #基于正则匹配协议http或https(?匹配全面的字符0次或一次),即其它协议不替换

    #将__meta_kubernetes_service_annotation_prometheus_io_path替换为__metrics_path__
    - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path]
      action: replace
      target_label: __metrics_path__
      regex: (.+) #匹配路径为1到任意长度(.为匹配除\n之外的任意单个字符,+为匹配一次或多次)

    #地址发现及标签重写
    - source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port]
      action: replace
      target_label: __address__
      regex: ([^:]+)(?::\d+)?;(\d+)
      replacement: $1:$2 #格式为地址:端口
    
    #匹配regex所匹配的标签,然后进行应用:
    - action: labelmap
      regex: __meta_kubernetes_service_label_(.+) #通过正则匹配名称

Prometheus服务发现示例 Kube-DNS:

kube-dns的服务发现:

root@k8s-master-1:~# kubectl describe svc kube-dns -n kube-system
Name:              kube-dns
Namespace:         kube-system
Labels:            addonmanager.kubernetes.io/mode=Reconcile
                k8s-app=kube-dns
                kubernetes.io/cluster-service=true
                kubernetes.io/name=CoreDNS
Annotations:       prometheus.io/port: 9153  #注解标签,用于prometheus匹配发现端口
                prometheus.io/scrape: true   #注解标签,用于prometheus匹配抓取数据
Selector:          k8s-app=kube-dns
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.100.0.2
IPs:               10.100.0.2
Port:              dns  53/UDP
TargetPort:        53/UDP
Endpoints:         10.200.182.97:53,10.200.76.139:53
Port:              dns-tcp  53/TCP
TargetPort:        53/TCP
Endpoints:         10.200.182.97:53,10.200.76.139:53
Port:              metrics  9153/TCP
TargetPort:        9153/TCP
Endpoints:         10.200.182.97:9153,10.200.76.139:9153
Session Affinity:  None
Events:            <none>

修改coredns的副本数,以让endpoint数量发生变化,验证能否自动发现新添加的Pod:

kube-dns-自动发现

Prometheus服务发现示例 node:

1、匹配的目的数据:

__meta_kubernetes_node_label_beta_kubernetes_io_arch="amd64"
__meta_kubernetes_node_label_beta_kubernetes_io_os="linux"
__meta_kubernetes_node_label_kubernetes_io_arch="amd64"
__meta_kubernetes_node_label_kubernetes_io_hostname="xx.xx.xx.xx"
__meta_kubernetes_node_label_kubernetes_io_os="linux"
__meta_kubernetes_node_label_kubernetes_io_role="node"

2、node发现配置:

scrape_configs:
  - job_name: 'kubernetes-node' #job名称
    kubernetes_sd_configs: #sd_configs发现
    - role: node #角色,node发现
    relabel_configs: #标签重写配置
    - source_labels: [__address__]
      regex: '(.*):10250'
      replacement: '${1}:9100'
      target_label: __address__
      action: replace
    - action: labelmap
      regex: __meta_kubernetes_node_label_(.+)

3、验证node节点发现:

kubernetes_sd_configs_nod

kubelet监听端口:

root@k8s-node-1:~# lsof -i:10250
COMMAND  PID USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
kubelet 1170 root   19u  IPv6   23958      0t0  TCP *:10250 (LISTEN)
kubelet 1170 root   21u  IPv6 5665486      0t0  TCP k8s-node-1:10250->10.2.0.2:30389 (ESTABLISHED)
kubelet 1170 root   22u  IPv6 5666075      0t0  TCP k8s-node-1:10250->10.2.0.2:25129 (ESTABLISHED)
kubelet 1170 root   23u  IPv6 5665732      0t0  TCP k8s-node-1:10250->10.2.0.2:35765 (ESTABLISHED)

root@k8s-master-1:~#  kubectl get node 10.2.0.4 -o yaml | grep 10250
  Port: 10250

node节点指标数据:

root@k8s-node1:~# curl http://10.2.0.4:9100/metrics
#HELP:解释当前指标的含义
#TYPE:说明当前指标的数据类型,如:
# HELP node_load1 1m load average.
# TYPE node_load1 gauge
node_load1 0.49
# HELP node_load15 15m load average.
# TYPE node_load15 gauge
node_load15 0.72
# HELP node_load5 5m load average.
# TYPE node_load5 gauge
node_load5 0.54

node节点常见监控指标:

  1. node_cpu_:CPU相关指标
  2. node_load1:load average #系统负载指标
    node_load5
    node_load15
  3. node_memory_:内存相关指标
  4. node_network_:网络相关指标
  5. node_disk_:磁盘IO相关指标
  6. node_filesystem_:文件系统相关指标
  7. node_boot_time_seconds:系统启动时间监控
  8. go_*:node exporte运行过程中go相关指标
  9. process_*:node exporter运行时进程内部进程指标

Prometheus服务发现示例 Cadvisor :

Prometheus job配置:

scrape_configs:
  - job_name: 'kubernetes-node-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_(.+)
    - 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

查看cadvisor数据:

curl --cacert /etc/kubernetes/ssl/ca.pem -H "Authorization: Bearer $TOKEN" https://10.2.0.1:6443/api/v1/nodes/10.2.0.4/proxy/metrics/cadvisor

Prometheus服务发现示例 Pod:

    - job_name: 'kubernetes-pods'
      kubernetes_sd_configs:
      - role: pod
        namespaces: #可选指定namepace,如果不指定就是发现所有的namespace中的Pod
          names:
          - myserver
          - monitoring
      relabel_configs:
      - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
        action: keep
        regex: true
      - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scheme]
        action: replace
        target_label: __scheme__
        regex: (https?)
      - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
        action: replace
        target_label: __address__
        regex: ([^:]+)(?::\d+)?;(\d+)
        replacement: $1:$2
      - action: labelmap
        regex: __meta_kubernetes_pod_label_(.+)
      - source_labels: [__meta_kubernetes_namespace]
        action: replace
        target_label: kubernetes_namespace
      - source_labels: [__meta_kubernetes_pod_name]
        action: replace
        target_label: kubernetes_pod_name
最后修改:2023 年 10 月 31 日
如果觉得我的文章对你有用,请随意赞赏