Prometheus service discovery mechanism in the Kubernetes

Prometheus as the de facto standard in the field of vessel monitoring, with the rise of the core of the cloud to Kubernetes native boom, has been widely deployed. Flexible service discovery mechanism is the basis of both Prometheus and Kubernetes to be connected, this part of this article will be introduced, allowing the reader to understand how Kubernetes Prometheus cluster itself and applications running on it effectively monitored.

1. Prometheus Overview

Before officially entered the theme, it is necessary to conduct a comprehensive understanding of Prometheus. As shown below, Prometheus Server is the core component of the ecological Prometheus. It will be configured with a static or dynamic service discovery, crawl to find a series of objects, which we call target, Prometheus Server periodically pulls data from the target sequence, the later part of this will be described in detail. For constantly crawl to the time-series data, Prometheus Server will be aggregated and stored locally on the default database TSDB in timing. It can be queried via HTTP interface and built-in query language PromQL Prometehus Server for time-series data stored TSDB and other tools on display through Grafana. At the same time, we can define a set of alarm rules, Prometheus Server will check periodically TSDB to determine whether an alarm is triggered, the alarm if the message is pushed to the Alert Manager. Alert Manager alerting message will be polymerized, a complex series of operations to re-like, if necessary the alarm message notifies the user via Email or the like.

arch

2. static configuration

When the fixed object needs to capture, and when a smaller number, it is written directly Prometehus profile is the best choice. In fact, Prometheus Server as an application, it is also their operating data has been collected and a standard way of external exposure. Therefore, we can use monitoring Prometheus Prometheus. At this point, Prometheus configuration file as follows, known Prometheus Server 9090 runs in a local port:

global:
  scrape_interval:     15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
  evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute. # scrape_timeout is set to the global default (10s). # A scrape configuration containing exactly one endpoint to scrape: # Here it's Prometheus itself. scrape_configs: # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config. - job_name: 'prometheus' # scheme: http # metrics_path: /metric static_configs: - targets: ['127.0.0.1:9090']

上述配置文件的scrape_configs中包含一个名为prometheusjob。在Prometheus中一个job代表多个配置类似的target的集合,例如它们都可以通过http或者https协议进行访问,访问路径都为/metrics等等。在上述prometheus这个job中,仅仅包含一个地址为127.0.0.1:9090的target。简单地说,Prometheus Server会每隔scrape_interval就对target的URLhttp://127.0.0.1:9090进行访问获取时序数据。

3. Prometheus抓取机制

在Prometheus内部,target的发现和抓取分别是由Scrape Discovery Manager和Scrape Manager独立实现的。两者通过如下所示的channel进行连接:

chan map[string][]*targetgroup.Group

可以看到,上述管道传输的是map,其中的每个key和value对应的就是一个job名以及它所包含的一系列target group。事实上,在Prometheus内部一个target是用一系列的labels来描述的,每个label就是一个键值对,而一个target group就是共享某些labels的target集合。在下文中我们会了解到,一个Pod往往就和一个target group相对应。

每当从上述channel获取最新的target列表之后,Scrape Manager会进行重载。为每个job创建一个Scrape Pool,再为job中的每个target创建一个Scrape Loop。Scrape Pool会根据job的配置,创建一个http client供其中的各个Scrape Loop使用,而Scrape Loop则利用该http client具体完成对目标target的时序数据抓取工作。整体结构如下所示:

  • Scrape Manager
    • Scrape Pool 1
      • Scrape Loop for target 1
      • Scrape Loop for target 2
      • [...]
      • Scrape Loop for target n
    • Scrape Pool 2
      • [...]
    • [...]
    • Scrape Pool n
      • [...]

在Scrape Discovery Manager端同样会根据job进行划分。每个job中可以包含多种的服务发现,基于File,基于Kubernetes,基于Consul等等。对于各种服务发现方式,我们统一用provider对象进行封装,类似地,provider通过channel:

chan<- []*targetgroup.Group

定期向Scrape Discovery Manager推送最新的一系列target group。Scrape Discovery Manager则会将各个provider推送的target group进行聚合并向Scrape Manager推送。

事实上,对于静态配置的target,我们可以将它看作一种特殊的服务发现机制并且同样用provider进行封装,不同的是它只会用channel推送一次用户在配置文件中写好的target group,之后就会将channel关闭。

4. Kubernetes下的服务发现

在Kubernetes环境下,要做到对系统本身,特别是运行其上的各种应用的完整监控,静态配置的方式显然是无法满足需求的。因此,基于Kubernetes本身的服务发现能力,Prometheus实现了对于Kubernetes集群,包括系统组件,Pod,Service,Ingress等各个维度的动态监控。本文将以针对Pod的服务发现作为例子,对于其他维度,其实现机制是类似的。

若要实现对于集群中的Pod的动态监控,则Prometheus的配置文件中需要加入以下job:

- job_name: "kubernetes-pods"
  kubernetes_sd_configs:
  - role: pod # api_server: <host> # basic_auth: XXX # tls_config: XXX relabel_configs: - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape] action: keep regex: true - source_labels: [__meta_kubernetes_namespace] action: replace target_label: kubernetes_namespace - source_labels: [__meta_kubernetes_pod_name] action: replace target_label: kubernetes_pod_name

其中的kubernetes_sd_configs表示基于Kubernetes进行服务发现,而其中的role字段为pod,表示针对Kubernetes中的pod资源对象,进行具体的服务发现操作。role字段其余的合法值包括nodeserviceendpointsingress

之后Prometheus会创建Kubernetes Client对role中指定的资源对象进行监听。一般Prometheus部署在Kubernetes集群中的话,Prometheus可以直接利用指定的Service Account对Kubernetes API进行访问。若Prometheus在Kubernetes集群之外,则kubernetes_sd_configs还需指定监控集群的API Server的URL以及相关的认证信息,从而能够创建对应集群的Client。

和Kubernetes内置的各种Controller类似,当目标资源对象为Pod时,Prometheus会对Kubernetes中的Pod进行List & Watch。每当集群中新增一个Pod,Prometheus就会对其进行处理,根据其配置创建一个target group。之后,Prometheus会遍历Pod中的每个Container:若Container没有暴露端口,则将一个Container作为一个target并将该target的__address__直接设置为Pod的IP地址;若Container暴露了一个或多个端口,则将每个端口设置为一个target且target的__address设置为Pod IP加对应端口的组合。如上文所述,一个target group中的targets会共享某些labels,当target group对应的是一个pod时,Prometheus会将Pod的基本信息作为共享labels。例如:__meta_kubernetes_namespace对应Pod所在的namespace,__meta_kubernetes_pod_name对应pod name,以及pod的ip,labels和annotations都会作为共享labels写入。

最终,这些自发现的target groups都将通过管道传递给Scrape Manager,由它来创建对于各个target的抓取实例并实现数据的抓取。

5. Targets的过滤机制

从上文可知,若配置了对于Kubernetes中Pod资源对象的服务发现,Prometheus会默认将每个Pod IP + Pod Port的组合作为一个taget。显然,并不是每个Pod都会暴露符合Prometheus标准的监控数据,即使暴露了,也不太可能在它的每个容器的每个端口进行暴露。因此,通过上述服务发现机制获取到的大部分targets都将是无效的。已知targets本质上是一系列的labels,因此我们可以根据labels是否符合某些规则实现对targets的过滤,在Prometheus中,这一机制叫做relabel。

Prometheus配置文件中的relabel_configs就包含了对于relabel规则的描述。我们可以同时定义多条relabels规则,它们会在Scrape Manager创建target实例并抓取之前,依次对targets实现过滤和修改。例如,上一节中的配置文件包含了三条relabel规则。第一条规则表示,若targets的labels中存在__meta_kubernetes_pod_annotation_prometheus_io_scrape且该label的值为true,则对应的target保留。这条规则就要求我们在定义Pod的配置时,若期望该Pod的监控数据被Prometheus抓取,则需要为它添加prometheus.io/scrape:true这样一个annotation,其余Pod生成的target都将被丢弃。

另外,我们还可以利用relabel实现对targets中labels的修改。一般来说,以__作为前缀的labels都只在内部使用,在relabels之后会统一删除。若想要保留其中的某些labels,我们可以如第二,三条规则所示,将名为__meta_kubernetes_namespace__meta_kubernetes_pod_name的labels重命名为kubernetes_namespacekubernetes_pod_name。这样一来,这两个label就能得到保留并出现在target最终的labels中,而对应的target抓取的所有指标都将额外添加kubernetes_namespacekubernetes_pod_name这两个labels。

这里我们只是对Prometheus的relabel机制进行了简单的介绍,事实上可以利用多条relabel规则的组合实现对于targets的复杂的过滤和修改,在此不再赘述。另外,Scrape Manager会在对target进行relabel之前,根据配置文件额外添加job__metrics_path____scheme__这三个label,而在relabel之后,若target中没有instance这个label,则会向其添加instance这个label,值为__address__这个label的值。

6. 总结

Prometheus provides services based on their ability to find other targets Kubernetes grab objects from a monitoring system discovery mechanism whereby enormous flexibility is its ability to become a de facto standard for the era of cloud native surveillance of one of the important reasons. By the above description, we can know, grab a target, that target, in Prometheus is a series of labels to describe the global configuration file describes the common configuration of certain targets, and service discovery and other system capabilities Kubernetes Prometheus was provided most of the configuration information of targets. In the end, we can modify the filtering mechanism targets by relabel the object, in order to achieve an effective target for the crawl. As for the target crawl, essentially through the target __scheme__, __address__and __metrcis_path__these label, piece together a URL, for example http://10.32.0.2/metrics, the URL to initiate a GET request to obtain monitoring data.

references

Guess you like

Origin www.cnblogs.com/YaoDD/p/11391310.html