Prometheus

55479
下载
Prometheus 是一个开源的监控和告警系统,专注于时间序列数据的采集与存储。由 SoundCloud 开发,配备高级查询语言PromQL,便于数据挖掘与分析,并无缝对接多种可视化平台。

理解和使用 Multi-target Exporter 模式


本指南将为你介绍 Multi-target Exporter(多 Target Exporter)模式。为了实现这一目标,我们将:

  • 描述 Multi-target Exporter 模式及其用途,
  • blackbox exporter 为例,说明该模式的用法,
  • 配置自定义查询模块用于 blackbox exporter,
  • 让 blackbox exporter 对 Prometheus 网站执行基本指标查询,
  • 探索配置 Prometheus 抓取 Exporter 时使用的主流模式。

Multi-target Exporter 模式?

我们所说的 Multi-target Exporter 模式是指一种特定设计,其中:

  • Exporter 通过网络协议获取 Target 的指标。
  • Exporter 不必在从其收集指标的机器上运行。
  • Exporter 通过 Prometheus 的 GET 请求接收 Target 和查询配置字符串作为参数。
  • Exporter 在接收到 Prometheus 的 GET 请求后开始抓取,并在抓取完成后完成响应。
  • Exporter 可以查询多个 Target。

这种模式仅适用于某些 Exporter,例如 blackboxSNMP exporter。这是因为我们要么无法在采集 Target 上运行 Exporter(例如使用 SNMP 的网络设备),要么我们明确感兴趣的是访问的距离(例如网站从特定点外网的延迟和可达性,这是 blackbox exporter 的一个常见用例)。

运行 Multi-target Exporter

Multi-target Exporter 在运行环境方面具有灵活性,可以以多种方式运行。在容器中作为常规程序,在裸金属上和虚拟机上作为后台服务均可。因为它们通过网络被查询,所以使用时需要开放适当的端口。否则的话,它们的资源消耗量将会更少。

现在让我们来试一试,使用 Docker 启动一个 blackbox exporter 容器。在终端中运行以下命令:

Terminal window
docker run -p 9115:9115 prom/blackbox-exporter

你应该看到几条日志,如果一切顺利的话,最后一条应提示 “Listening on address”,如下所示:

level=info ts=2018-10-17T15:41:35.4997596Z caller=main.go:324 msg="Listening on address" address=:9115

Multi-target Exporter 的基本查询

有二种方式查询:

  1. 查询 Exporter 本身。它有自己的指标,通常可从/metrics端点访问。
  2. 查询 Exporter 以抓取另一个 Target。这通常可以在例如/probe的描述性端点(descriptive endpoint)上访问。当使用 Multi-target Exporter 时,这可能是你主要感兴趣的数据查询方式。

你可以手动使用 curl 在另一个终端中尝试第一种类型的查询,或者使用此链接访问:http://localhost:9115/metrics

Terminal window
curl 'localhost:9115/metrics'

得到响应应该是这样的:

# HELP blackbox_exporter_build_info A metric with a constant '1' value labeled by version, revision, branch, and goversion from which blackbox_exporter was built.
# TYPE blackbox_exporter_build_info gauge
blackbox_exporter_build_info{branch="HEAD",goversion="go1.10",revision="4a22506cf0cf139d9b2f9cde099f0012d9fcabde",version="0.12.0"} 1
# HELP go_gc_duration_seconds A summary of the GC invocation durations.
# TYPE go_gc_duration_seconds summary
go_gc_duration_seconds{quantile="0"} 0
go_gc_duration_seconds{quantile="0.25"} 0
go_gc_duration_seconds{quantile="0.5"} 0
go_gc_duration_seconds{quantile="0.75"} 0
go_gc_duration_seconds{quantile="1"} 0
go_gc_duration_seconds_sum 0
go_gc_duration_seconds_count 0
# HELP go_goroutines Number of goroutines that currently exist.
# TYPE go_goroutines gauge
go_goroutines 9
[…]
# HELP process_cpu_seconds_total Total user and system CPU time spent in seconds.
# TYPE process_cpu_seconds_total counter
process_cpu_seconds_total 0.05
# HELP process_max_fds Maximum number of open file descriptors.
# TYPE process_max_fds gauge
process_max_fds 1.048576e+06
# HELP process_open_fds Number of open file descriptors.
# TYPE process_open_fds gauge
process_open_fds 7
# HELP process_resident_memory_bytes Resident memory size in bytes.
# TYPE process_resident_memory_bytes gauge
process_resident_memory_bytes 7.8848e+06
# HELP process_start_time_seconds Start time of the process since unix epoch in seconds.
# TYPE process_start_time_seconds gauge
process_start_time_seconds 1.54115492874e+09
# HELP process_virtual_memory_bytes Virtual memory size in bytes.
# TYPE process_virtual_memory_bytes gauge
process_virtual_memory_bytes 1.5609856e+07

这些是 Prometheus 格式的指标。它们来自 Exporter 的仪表化过程,并且告诉我们 Exporter 运行时的状态。这个过程被称为白箱监控,对于日常操作实践非常有用。如果你对此感兴趣,请查阅我们的如何自定义应用程序的指南,了解如何监控自己的应用。

对于第二种类型的查询,我们需要在 HTTP GET 请求中提供 Target 和模块作为参数。Target 是一个 URI 或 IP 地址,而模块必须在 Exporter 的配置中定义。blackbox exporter 容器带有一个有用的默认配置。我们将使用 Target prometheus.io和预定义的模块http_2xx。它告诉 Exporter 像浏览器访问prometheus.io时一样发起GET请求,并期望收到一个200 OK 响应。

现在,你可以在终端中使用 curl 告诉你的 blackbox exporter 查询prometheus.io

Terminal window
curl 'localhost:9115/probe?target=prometheus.io&module=http_2xx'

这将返回大量指标:

# HELP probe_dns_lookup_time_seconds Returns the time taken for probe dns lookup in seconds
# TYPE probe_dns_lookup_time_seconds gauge
probe_dns_lookup_time_seconds 0.061087943
# HELP probe_duration_seconds Returns how long the probe took to complete in seconds
# TYPE probe_duration_seconds gauge
probe_duration_seconds 0.065580871
# HELP probe_failed_due_to_regex Indicates if probe failed due to regex
# TYPE probe_failed_due_to_regex gauge
probe_failed_due_to_regex 0
# HELP probe_http_content_length Length of http content response
# TYPE probe_http_content_length gauge
probe_http_content_length 0
# HELP probe_http_duration_seconds Duration of http request by phase, summed over all redirects
# TYPE probe_http_duration_seconds gauge
probe_http_duration_seconds{phase="connect"} 0
probe_http_duration_seconds{phase="processing"} 0
probe_http_duration_seconds{phase="resolve"} 0.061087943
probe_http_duration_seconds{phase="tls"} 0
probe_http_duration_seconds{phase="transfer"} 0
# HELP probe_http_redirects The number of redirects
# TYPE probe_http_redirects gauge
probe_http_redirects 0
# HELP probe_http_ssl Indicates if SSL was used for the final redirect
# TYPE probe_http_ssl gauge
probe_http_ssl 0
# HELP probe_http_status_code Response HTTP status code
# TYPE probe_http_status_code gauge
probe_http_status_code 0
# HELP probe_http_version Returns the version of HTTP of the probe response
# TYPE probe_http_version gauge
probe_http_version 0
# HELP probe_ip_protocol Specifies whether probe ip protocol is IP4 or IP6
# TYPE probe_ip_protocol gauge
probe_ip_protocol 6
# HELP probe_success Displays whether or not the probe was a success
# TYPE probe_success gauge
probe_success 0

注意事项

可以发现,几乎所有的指标值都是0。最后一个读取到的是probe_success 0。这意味着探针无法成功访问prometheus.io。原因在名为probe_ip_protocol的指标中,其值为6。默认情况下,探针默认使用 IPv6。但是,Docker 守护进程默认阻止了 IPv6 流量。因此,运行在 Docker 容器中的 blackbox exporter 无法通过 IPv6 进行连接。

我们现在可以要么告诉 Docker 允许使用 IPv6,要么让 blackbox exporter 使用 IPv4。在实际情况中,这两者都有可能适用,并且正如我们经常遇到的那样,“该怎么做?”的答案往往是“这取决于具体情况”。因为这是一个有关 Exporter 的指南,我们将更改 Exporter 的配置并利用这个机会配置自定义模块。

模块配置

模块可以在名为config.yml的文件中预定义,此文件位于 Docker 容器内部,是 GitHub 仓库中blackbox.yml文件的一个副本。

我们将复制这个文件,并根据我们的需求进行调整,然后告诉 Exporter 使用我们的配置文件而不是容器内自带的文件。首先,使用 curl 或浏览器下载文件:

Terminal window
curl -o blackbox.yml https://raw.githubusercontent.com/prometheus/blackbox_exporter/master/blackbox.yml

然后在编辑器中打开它,前几行看起来像这样:

modules:
http_2xx:
prober: http
http_post_2xx:
prober: http
http:
method: POST

YAML 使用空格缩进来表示层次结构,你可以从中识别出两个名为http_2xxhttp_post_2xx的模块,它们都具有http探针。对于其中一个,method被特别设置为POST。如果你想了解更多可用的探针和选项,请查看文档

接下来,我们需要告诉 blackbox exporter 使用我们刚刚修改过的文件。这可以通过--config.file="blackbox.yml"标志来实现。但由于我们正在使用 Docker,首先必须通过--mount命令使文件blackbox.yml在容器内部可用。注意:如果你使用的是 macOS,首先需要允许 Docker 守护程序访问存放blackbox.yml的目录。你可以通过点击菜单栏上的 Docker 小鲸鱼图标,然后选择Preferences->File Sharing->+来完成配置。之后按Apply & Restart

首先停止旧的容器:可以切换到它的终端并按ctrl+c。之后,确保你位于包含blackbox.yml的目录中,运行下面这个命令。它有点长,我们将会详细解释:

Terminal window
docker run -p 9115:9115 --mount type=bind,source="$(pwd)"/blackbox.yml,target=/blackbox.yml,readonly prom/blackbox-exporter --config.file="/blackbox.yml"

这个命令告诉docker

  1. run一个容器,将外部端口9115映射到容器内的端口9115
  2. mount从当前目录($(pwd)表示打印工作目录)将文件blackbox.yml以只读模式挂载到/blackbox.yml
  3. 使用 Docker hub 中的prom/blackbox-exporter镜像。
  4. 运行 blackbox exporter,并通过--config.file标志告诉它使用/blackbox.yml作为配置文件。

如果都输入正确,你应该看到类似这样的输出:

level=info ts=2018-10-19T12:40:51.650462756Z caller=main.go:213 msg="Starting blackbox_exporter" version="(version=0.12.0, branch=HEAD, revision=4a22506cf0cf139d9b2f9cde099f0012d9fcabde)"
level=info ts=2018-10-19T12:40:51.653357722Z caller=main.go:220 msg="Loaded config file"
level=info ts=2018-10-19T12:40:51.65349635Z caller=main.go:324 msg="Listening on address" address=:9115

现在,你可以在终端中尝试使用新的 IPv4 的模块http_2xx

Terminal window
curl 'localhost:9115/probe?target=prometheus.io&module=http_2xx'

这应该返回 Prometheus 指标,如下所示:

# HELP probe_dns_lookup_time_seconds Returns the time taken for probe dns lookup in seconds
# TYPE probe_dns_lookup_time_seconds gauge
probe_dns_lookup_time_seconds 0.02679421
# HELP probe_duration_seconds Returns how long the probe took to complete in seconds
# TYPE probe_duration_seconds gauge
probe_duration_seconds 0.461619124
# HELP probe_failed_due_to_regex Indicates if probe failed due to regex
# TYPE probe_failed_due_to_regex gauge
probe_failed_due_to_regex 0
# HELP probe_http_content_length Length of http content response
# TYPE probe_http_content_length gauge
probe_http_content_length -1
# HELP probe_http_duration_seconds Duration of http request by phase, summed over all redirects
# TYPE probe_http_duration_seconds gauge
probe_http_duration_seconds{phase="connect"} 0.062076202999999996
probe_http_duration_seconds{phase="processing"} 0.23481845699999998
probe_http_duration_seconds{phase="resolve"} 0.029594103
probe_http_duration_seconds{phase="tls"} 0.163420078
probe_http_duration_seconds{phase="transfer"} 0.002243199
# HELP probe_http_redirects The number of redirects
# TYPE probe_http_redirects gauge
probe_http_redirects 1
# HELP probe_http_ssl Indicates if SSL was used for the final redirect
# TYPE probe_http_ssl gauge
probe_http_ssl 1
# HELP probe_http_status_code Response HTTP status code
# TYPE probe_http_status_code gauge
probe_http_status_code 200
# HELP probe_http_uncompressed_body_length Length of uncompressed response body
# TYPE probe_http_uncompressed_body_length gauge
probe_http_uncompressed_body_length 14516
# HELP probe_http_version Returns the version of HTTP of the probe response
# TYPE probe_http_version gauge
probe_http_version 1.1
# HELP probe_ip_protocol Specifies whether probe ip protocol is IP4 or IP6
# TYPE probe_ip_protocol gauge
probe_ip_protocol 4
# HELP probe_ssl_earliest_cert_expiry Returns earliest SSL cert expiry in unixtime
# TYPE probe_ssl_earliest_cert_expiry gauge
probe_ssl_earliest_cert_expiry 1.581897599e+09
# HELP probe_success Displays whether or not the probe was a success
# TYPE probe_success gauge
probe_success 1
# HELP probe_tls_version_info Contains the TLS version used
# TYPE probe_tls_version_info gauge
probe_tls_version_info{version="TLS 1.3"} 1

你可以看到探针运行成功并且获得了许多有用的指标,如各阶段的延迟、状态码、SSL 状态或证书到期时间的 Unix 时间戳。blackbox exporter 还提供了一个小型的 Web 界面,地址为http://localhost:9115,可以供你检查最近的几次探针信息、加载的配置和调试信息。它甚至提供了探测prometheus.io的探针,这在当你想知道为什么某些配置不起作用时非常方便。

使用 Prometheus 查询 Multi-target Exporter

如果到目前为止,如果一切顺利,那么恭喜自己吧。blackbox exporter 已经可以正常工作,并且可以让它去查询远程 Target。目前你已经接近完成整个流程,现在你需要告诉 Prometheus 为我们自动执行查询。

以下是 Prometheus 配置的最小示例,它使用curl 'localhost:9115/metrics'的方式,告诉 Prometheus 自己抓取 Exporter 本身:

注意: 如果你使用的是 Docker for Mac 或 Docker for Windows,则在最后的行中不能使用localhost:9115,而必须使用host.docker.internal:9115。这与在这些操作系统上实现 Docker 所使用的虚拟机有关。在生产环境中不要使用此配置。

Linuxprometheus.yml文件:

global:
scrape_interval: 5s
scrape_configs:
- job_name: blackbox # 用于获取 Exporter 本身的指标
metrics_path: /metrics
static_configs:
- targets:
- localhost:9115

macOS 和 Windowsprometheus.yml 文件:

global:
scrape_interval: 5s
scrape_configs:
- job_name: blackbox # 用于获取 Exporter 本身的指标
metrics_path: /metrics
static_configs:
- targets:
- host.docker.internal:9115

现在运行 Prometheus 容器,并告诉它从指定的目录加载我们的配置文件。由于宿主机的网络地址在不同的环境中稍有差异,因此 Linux 上的命令与 MacOS 和 Windows 上的命令略有不同:

运行 Prometheus

Linux(不要在生产环境中使用--network="host"):

Terminal window
docker run --network="host" --mount type=bind,source="$(pwd)"/prometheus.yml,target=/prometheus.yml,readonly prom/prometheus --config.file="/prometheus.yml"

MacOS 和 Windows

Terminal window
docker run -p 9090:9090 --mount type=bind,source="$(pwd)"/prometheus.yml,target=/prometheus.yml,readonly prom/prometheus --config.file="/prometheus.yml"

这个命令类似于使用配置文件运行 blackbox exporter 的过程。

如果一切正常,你应该能够通过访问 localhost:9090/targets,看到blackbox下端点的状态为绿色的UP。如果你看到的是红色的DOWN,请确保你之前启动的 blackbox exporter 仍在运行。如果没有显示任何内容或黄色的UNKNOWN,你可能需要给浏览器重新加载一下试试。

要告诉 Prometheus 查询 "localhost:9115/probe?target=prometheus.io&module=http_2xx",你需要在 Prometheus 配置文件prometheus.yml中添加另一个采集任务blackbox-http,设置metrics_path/probe,并设置params:部分的参数:

配置 Prometheus

global:
scrape_interval: 5s
scrape_configs:
- job_name: blackbox # 用于获取 Exporter 本身的指标
metrics_path: /metrics
static_configs:
- targets:
- localhost:9115 # 对于 MacOS 和 Windows,请替换为 - host.docker.internal:9115
- job_name: blackbox-http # 用于获取 Exporter Target 的指标
metrics_path: /probe
params:
module: [http_2xx]
target: [prometheus.io]
static_configs:
- targets:
- localhost:9115 # 对于 MacOS 和 Windows,请替换为 - host.docker.internal:9115

保存配置文件后,切换到 Prometheus 容器的终端并停止容器(按 ctrl+C),然后重新启动容器以加载配置。

终端应返回消息"Server is ready to receive web requests.",几秒钟后你将开始看到丰富的图表出现在你的 Prometheus 上。

这种方法可以正常工作,但有几个缺点:

  1. 实际的 Target 出现在参数配置中,这非常不寻常且难以理解。
  2. instance标签包含 blackbox exporter 地址的值,从技术上来说这是正确的,但我们对此不感兴趣。
  3. 我们无法看到我们探测的 URL。如果我们要探测多个 URL,这将导致不同指标混在一起。

为了解决这些问题,我们将使用 relabel_config(relabel 即重标签)。relabel_config 在这里很有用,因为 Prometheus 在后台的许多东西都使用内部标签进行配置。详细的信息比较复杂,超出了本指南的讨论范畴。因此我们在这里只讨论必要的部分。但如果你想了解更多,请参阅这个演讲。目前只需理解以下这些信息就足够了:

  • 所有以__开头的标签在抓取后都会被丢弃。大多数内部标签都以__开始。
  • 你可以配置称为__param_<name>的内部标签,用于在抓取请求中设置键为<name>的 URL 参数。
  • 有一个内部标签__address__,由static_configs下的targets设置,并用于抓取请求的值。默认情况下,稍后用于设置附加到每个指标的标签instance的值,该标签告诉你指标来自何处。

以下是用于执行此操作的配置。我们将逐步解释:

global:
scrape_interval: 5s
scrape_configs:
- job_name: blackbox # 用于获取 Exporter 本身的指标
metrics_path: /metrics
static_configs:
- targets:
- localhost:9115 # 对于 MacOS 和 Windows,请替换为 - host.docker.internal:9115
- job_name: blackbox-http # 用于获取 Exporter Target 的指标
metrics_path: /probe
params:
module: [http_2xx]
static_configs:
- targets:
- http://prometheus.io # 要探测的 http Target
- https://prometheus.io # 要探测的 https Target
- http://example.com:8080 # 要探测的 http Target(端口 8080)
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- target_label: __address__
replacement: localhost:9115 # blackbox exporter 的真实主机名:端口。对于 MacOS 和 Windows,请替换为 - host.docker.internal:9115

与上一配置相比,这里有什么新东西?

params不再包含target,而是我们在static_configs下的targets添加实际的 Target。我们现在也可以这样做:

params:
module: [http_2xx]
static_configs:
- targets:
- http://prometheus.io # 要探测的 http Target
- https://prometheus.io # 要探测的 https Target
- http://example.com:8080 # 要探测的 http Target(端口 8080)

relabel_configs包含新的重标签规则:

relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- target_label: __address__
replacement: localhost:9115 # blackbox exporter的真实主机名:端口。对于 MacOS 和 Windows,请替换为 - host.docker.internal:9115

在应用重标签规则之前,Prometheus 发出请求的 URI 看起来是这样的:"http://prometheus.io/probe?module=http_2xx". 应用重标签规则之后,它看起来会变成这样:“http://localhost:9115/probe?target=http://prometheus.io&module=http_2xx"

让我们来看看每个规则是如何实现这一转换的:

首先,我们从标签__address__(包含targets的值)中提取值,并将其写入新的标签__param_target,这会在 Prometheus 抓取请求中添加参数target

relabel_configs:
- source_labels: [__address__]
target_label: __param_target

经过这一步,我们想象中的 Prometheus 请求 URI 现在有了 Target 参数:"http://prometheus.io/probe?target=http://prometheus.io&module=http_2xx"

然后,我们从标签__param_target中提取值,并创建一个具有这些值的instance标签。

relabel_configs:
- source_labels: [__param_target]
target_label: instance

请求本身不会被改变,但从我们的请求返回的指标值现在会携带一个标签instance="http://prometheus.io"

接下来,我们将值localhost:9115(我们的 Exporter 的 URI)写入标签__address__。这将被用于 Prometheus 抓取请求用到的主机名和端口,以使得 Prometheus 查询 Exporter 而不是直接查询指向 Target 的 URI。

relabel_configs:
- target_label: __address__
replacement: localhost:9115 # blackbox exporter的真实主机名:端口。对于Windows和macOS,请替换为 - host.docker.internal:9115

此时,我们的请求变为:"localhost:9115/probe?target=http://prometheus.io&module=http_2xx"。通过这种方式,我们可以在知道实际的 Target,使用它们作为instance的标签值,同时让 Prometheus 向 blackbox exporter 发起请求。

通常人们会结合特定的服务发现策略。欲了解更多信息,请参阅配置文档。使用服务发现也没有任何问题,因为这些与static_configs下的targets一样,都会写入到__address__标签中。

以上就是本指南的全部内容。重启 Prometheus Docker 容器,查看你的指标。注意你选择的时间段应该是实际收集到数据的时期。

概述

在这篇指南中,你学习了 Multi-target Exporter 模式的原理,如何运行带有自定义模块的 blackbox exporter,以及如何通过使用重标签来配置 Prometheus 以使用探针标签抓取指标值。

该文档基于 Prometheus 官方文档翻译而成。


observability.cn Authors 2024 | Documentation Distributed under CC-BY-4.0
Copyright © 2017-2024, Alibaba. All rights reserved. Alibaba has registered trademarks and uses trademarks.
浙ICP备2021005855号-32