理解并使用多目标导出器模式
本指南将向您介绍多目标导出器模式。为了实现这一点,我们将:
- 描述多目标导出器模式及其使用原因,
- 运行 blackbox 导出器作为该模式的示例,
- 为 blackbox 导出器配置自定义查询模块,
- 让 blackbox 导出器针对 Prometheus 网站 运行基本指标查询,
- 探讨一种通过重写标签 (relabeling) 来配置 Prometheus 采集导出器的常用模式。
什么是多目标导出器模式?
我们所说的多目标 导出器 (exporter) 模式是指一种特定的设计,其中:
- 导出器通过网络协议获取目标的指标。
- 导出器不必运行在指标所在的机器上。
- 导出器将目标和一个查询配置字符串作为 Prometheus GET 请求的参数。
- 在收到 Prometheus 的 GET 请求后,导出器开始执行采集,并在采集完成后结束。
- 导出器可以查询多个目标。
此模式仅用于某些导出器,例如 blackbox 和 SNMP 导出器 。
其原因是我们要么无法在目标上运行导出器(例如使用 SNMP 的网络设备),要么我们明确关注距离,例如从网络外部的特定点访问网站的延迟和可达性,这是 blackbox 导出器的常见用例。
运行多目标导出器
多目标导出器在环境方面非常灵活,可以通过多种方式运行:作为常规程序、在容器中、作为后台服务、在裸机上或在虚拟机中。由于它们需要通过网络进行查询和被查询,因此需要开放适当的端口。除此之外,它们非常节省资源。
现在让我们亲自尝试一下!
使用 Docker 在终端运行以下命令来启动 blackbox 导出器容器。根据您的系统配置,可能需要在命令前加上 sudo。
docker run -p 9115:9115 prom/blackbox-exporter
您应该会看到几行日志,如果一切正常,最后一行应该显示 msg="Listening on address",如下所示:
level=info ts=2018-10-17T15:41:35.4997596Z caller=main.go:324 msg="Listening on address" address=:9115
多目标导出器的基本查询
有两种查询方式:
- 查询导出器本身。它有自己的指标,通常在
/metrics下可用。 - 查询导出器以采集另一个目标。通常在“描述性”端点(例如
/probe)下可用。这很可能是您在使用多目标导出器时主要感兴趣的内容。
您可以在另一个终端手动尝试第一种查询类型,或者使用此 链接 。
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 格式的指标。它们来自导出器自身的 插桩,告诉我们导出器在运行时自身的状态。这被称为白盒监控,在日常运维实践中非常有用。如果您感兴趣,可以尝试阅读我们关于如何插桩您自己的应用程序的指南。
对于第二种查询方式,我们需要在 HTTP GET 请求中提供目标 (target) 和模块 (module) 作为参数。目标是 URI 或 IP 地址,模块必须在导出器的配置中定义。blackbox 导出器容器附带了一个有意义的默认配置。我们将使用目标 prometheus.io 和预定义的模块 http_2xx。它告诉导出器像浏览器访问 prometheus.io 一样发出 GET 请求,并期望收到一个 200 OK 响应。
现在,您可以在终端中使用 curl 命令让 blackbox 导出器查询 prometheus.io:
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。原因隐藏在值为 6 的指标 probe_ip_protocol 中。默认情况下,探针会使用 IPv6 ,除非另有指定。但 Docker 守护进程默认会阻止 IPv6。因此,在 Docker 容器中运行的 blackbox 导出器无法通过 IPv6 连接。
我们现在可以告诉 Docker 允许 IPv6,或者让 blackbox 导出器使用 IPv4。在现实世界中,这两种方法都有意义,而且就像通常那样,对于“该怎么做?”这个问题的回答是“视情况而定”。因为这是一份导出器指南,我们将更改导出器,并借此机会配置一个自定义模块。
配置模块
这些模块是在 docker 容器内名为 config.yml 的文件中预定义的,它是 GitHub 仓库中 blackbox.yml 的副本。
我们将复制此文件,根据我们的需要进行 调整 ,并告诉导出器使用我们的配置文件,而不是容器中包含的那个。
首先使用 curl 或您的浏览器下载该文件。
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_2xx 和 http_post_2xx 的 modules,它们都有一个 http 探针,其中一个的方法值明确设置为 POST。现在,您将通过将 http 探针的 preferred_ip_protocol 显式设置为字符串 ip4 来更改 http_2xx 模块。
modules:
http_2xx:
prober: http
http:
preferred_ip_protocol: "ip4"
http_post_2xx:
prober: http
http:
method: POST
如果您想了解更多关于可用探针和选项的信息,请查看 文档 。
现在我们需要告诉 blackbox 导出器使用我们刚刚更改的文件。您可以使用标志 --config.file="blackbox.yml" 来实现。但是因为我们正在使用 Docker,所以必须先使用 --mount 命令使该文件在容器内 可用 。
注意如果您使用的是 macOS,则首先需要允许 Docker 守护进程访问包含blackbox.yml的目录。您可以通过单击菜单栏中的 Docker 小鲸鱼图标,然后单击Preferences->File Sharing->+来实现。之后,单击Apply & Restart。
首先进入旧容器的终端并按 ctrl+c 停止它。确保您位于包含 blackbox.yml 的目录中。然后运行此命令。该命令很长,我们将对其进行解释:
docker \
run -p 9115:9115 \
--mount type=bind,source="$(pwd)"/blackbox.yml,target=/blackbox.yml,readonly \
prom/blackbox-exporter \
--config.file="/blackbox.yml"
通过此命令,您告诉 docker:
run一个容器,将容器外的端口9115映射到容器内的端口9115。mount当前目录($(pwd)代表打印当前工作目录)中的blackbox.yml文件到/blackbox.yml,并以readonly模式挂载。- 使用来自 Docker hub 的镜像
prom/blackbox-exporter。 - 运行 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
现在您可以在终端中使用 curl 尝试我们的新 IPv4 模块 http_2xx:
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 导出器还在 localhost:9115 提供了一个小型的 Web 界面,供您查看最近几次探测、已加载的配置和调试信息。它甚至还提供了直接探测 prometheus.io 的链接。如果您想知道为什么某项操作不起作用,这非常方便。
使用 Prometheus 查询多目标导出器
到目前为止,一切顺利。恭喜自己吧。blackbox 导出器运行正常,并且您可以手动告诉它查询远程目标。您已经快成功了。现在您需要让 Prometheus 代替我们执行这些查询。
下面您会找到一个最小化的 prometheus 配置。它告诉 Prometheus 采集导出器本身,正如我们之前使用 curl 'localhost:9115/metrics' 所做的那样。
注意如果您在 Mac 或 Windows 上使用 Docker,则最后一行不能使用localhost:9115,必须使用host.docker.internal:9115。这与这些操作系统上用于实现 Docker 的虚拟机有关。您不应在生产环境中使用此设置。
Linux 的 prometheus.yml
global:
scrape_interval: 5s
scrape_configs:
- job_name: blackbox # To get metrics about the exporter itself
metrics_path: /metrics
static_configs:
- targets:
- localhost:9115
macOS 和 Windows 的 prometheus.yml
global:
scrape_interval: 5s
scrape_configs:
- job_name: blackbox # To get metrics about the exporter itself
metrics_path: /metrics
static_configs:
- targets:
- host.docker.internal:9115
现在运行 Prometheus 容器并让它挂载我们上面的配置文件。由于容器可寻址主机网络的方式,您在 Linux 上使用的命令与在 MacOS 和 Windows 上使用的命令略有不同。
在 Linux 上运行 Prometheus(生产环境请勿使用 --network="host")
docker \
run --network="host"\
--mount type=bind,source="$(pwd)"/prometheus.yml,target=/prometheus.yml,readonly \
prom/prometheus \
--config.file="/prometheus.yml"
在 MacOS 和 Windows 上运行 Prometheus
docker \
run -p 9090:9090 \
--mount type=bind,source="$(pwd)"/prometheus.yml,target=/prometheus.yml,readonly \
prom/prometheus \
--config.file="/prometheus.yml"
此命令类似于使用配置文件运行 blackbox 导出器。
如果一切正常,您应该能够前往 localhost:9090/targets ,并在 blackbox 下看到一个状态为绿色 UP 的端点。如果您看到红色的 DOWN,请确保您在上面启动的 blackbox 导出器仍在运行。如果您什么也没看到或者看到黄色的 UNKNOWN,那说明您动作太快了,在刷新浏览器选项卡之前需要再等几秒钟。
要告诉 Prometheus 查询 "localhost:9115/probe?target=prometheus.io&module=http_2xx",请添加另一个采集任务 blackbox-http,并将 metrics_path 设置为 /probe,并在 Prometheus 配置文件 prometheus.yml 中设置 params: 下的参数:
global:
scrape_interval: 5s
scrape_configs:
- job_name: blackbox # To get metrics about the exporter itself
metrics_path: /metrics
static_configs:
- targets:
- localhost:9115 # For Windows and macOS replace with - host.docker.internal:9115
- job_name: blackbox-http # To get metrics about the exporter’s targets
metrics_path: /probe
params:
module: [http_2xx]
target: [prometheus.io]
static_configs:
- targets:
- localhost:9115 # For Windows and macOS replace with - host.docker.internal:9115
保存配置文件后,切换到运行 Prometheus docker 容器的终端,按 ctrl+C 停止它,然后再次启动它以使用现有的命令重新加载配置。
终端应返回消息 "Server is ready to receive web requests.",几秒钟后,您应该开始在您的 Prometheus 中看到彩色的图表。
这可行,但有一些缺点:
- 实际目标位于参数配置中,这非常不寻常,以后很难理解。
instance标签的值是 blackbox 导出器的地址,这在技术上是正确的,但不是我们感兴趣的。- 我们无法看到我们探测的是哪个 URL。这很不实用,而且如果我们探测多个 URL,会将不同的指标混在一起。
为了解决这个问题,我们将使用 relabeling(重写标签)。在这里使用重写标签很有用,因为在 Prometheus 的幕后,许多配置都使用了内部标签。其细节比较复杂,超出了本指南的范围。因此我们将仅限于必要的部分。但如果您想了解更多,请查看这个讲座 。现在,只要您理解以下内容就足够了:
- 所有以
__开头的标签在采集后都会被丢弃。大多数内部标签都以__开头。 - 您可以设置名为
__param_的内部标签。它们会为采集请求设置键为的 URL 参数。 - 有一个内部标签
__address__,它由static_configs下的targets设置,其值是采集请求的主机名。默认情况下,它稍后被用于设置标签instance的值,该标签会附加到每个指标上,并告诉您指标来自哪里。
以下是您将使用的配置。如果一次性看到这些内容觉得有点多,不要担心,我们将一步一步地介绍。
global:
scrape_interval: 5s
scrape_configs:
- job_name: blackbox # To get metrics about the exporter itself
metrics_path: /metrics
static_configs:
- targets:
- localhost:9115 # For Windows and macOS replace with - host.docker.internal:9115
- job_name: blackbox-http # To get metrics about the exporter’s targets
metrics_path: /probe
params:
module: [http_2xx]
static_configs:
- targets:
- https://prometheus.ac.cn # Target to probe with http
- https://prometheus.ac.cn # Target to probe with https
- http://example.com:8080 # Target to probe with http on port 8080
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- target_label: __address__
replacement: localhost:9115 # The blackbox exporter’s real hostname:port. For Windows and macOS replace with - host.docker.internal:9115
那么,与上一个配置相比有什么新内容?
params 不再包含 target。相反,我们在 static_configs 的 targets 下添加了实际目标。我们还使用了多个目标,因为现在可以这样做了。
params:
module: [http_2xx]
static_configs:
- targets:
- https://prometheus.ac.cn # Target to probe with http
- https://prometheus.ac.cn # Target to probe with https
- http://example.com:8080 # Target to probe with http on port 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 # The blackbox exporter’s real hostname:port. For Windows and macOS replace with - host.docker.internal:9115
在应用重写标签规则之前,Prometheus 发出的请求 URI 看起来像这样:"https://prometheus.ac.cn/probe?module=http_2xx"。重写标签后,它将变成:"https://:9115/probe?target=https://prometheus.ac.cn&module=http_2xx"。
现在让我们探讨每条规则是如何实现这一点的。
首先,我们从标签 __address__(包含来自 targets 的值)中取值,并将其写入一个新标签 __param_target,这将在 Prometheus 采集请求中添加一个 target 参数。
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
在此之后,我们想象中的 Prometheus 请求 URI 现在有了 target 参数:"https://prometheus.ac.cn/probe?target=https://prometheus.ac.cn&module=http_2xx"。
然后,我们从标签 __param_target 中获取值,并用这些值创建一个 instance 标签。
relabel_configs:
- source_labels: [__param_target]
target_label: instance
我们的请求不会改变,但从请求返回的指标现在将带有一个标签 instance="https://prometheus.ac.cn"。
之后,我们将值 localhost:9115(我们导出器的 URI)写入标签 __address__。这将用作 Prometheus 采集请求的主机名和端口。这样它就会查询导出器,而不是直接查询目标 URI。
relabel_configs:
- target_label: __address__
replacement: localhost:9115 # The blackbox exporter’s real hostname:port. For Windows and macOS replace with - host.docker.internal:9115
我们的请求现在是 "localhost:9115/probe?target=https://prometheus.ac.cn&module=http_2xx"。通过这种方式,我们可以在那里放置实际的目标,将它们作为 instance 标签值获取,同时让 Prometheus 向 blackbox 导出器发出请求。
人们通常将这些配置与特定的服务发现结合使用。请查看配置文档以获取更多信息。使用它们没有问题,因为这些配置就像在 static_configs 下定义的 targets 一样,会将值写入 __address__ 标签。
就是这样。重启 Prometheus docker 容器并查看您的 指标 。请注意,您选择了实际收集指标的时间段。
配置示例:在同一个 Prometheus 作业中包含多个目标和多个模块
在上面的示例中,我们仅使用了一个 blackbox 导出器探测模块。module 被指定为 blackbox-http 作业的作业级参数。由于它是一个列表,它可以包含多个元素,但 blackbox 导出器只使用第一个。但是,如果我们需要使用适当的模块探测不同的目标组,我们可以在单个作业中使用多个 blackbox 导出器模块。我们不需要指定作业的 module 参数,而是可以在每个 static_config 中指定一个 module 标签。此外,relabel_configs 序列需要扩展一个新项,因为此时我们必须将模块(作为 __param_module)注入到请求中。
global:
scrape_interval: 5s
scrape_configs:
- job_name: blackbox # To get metrics about the exporter itself
metrics_path: /metrics
static_configs:
- targets:
- localhost:9115 # The blackbox exporter’s real hostname:port
- job_name: blackbox-probes # To get metrics about the exporter’s targets with different modules
metrics_path: /probe
static_configs:
- targets: # static_config: targets and http_2xx module
- https://prometheus.ac.cn
- https://prometheus.ac.cn
- http://example.com:8080
labels:
module: http_2xx
- targets: # static_config: targets and icmp module
- prometheus.io
- example.com
labels:
module: icmp
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- source_labels: [module]
target_label: __param_module
- target_label: __address__
replacement: localhost:9115 # The blackbox exporter’s real hostname:port
摘要
在本指南中,您学习了多目标导出器模式的工作原理、如何运行带有自定义模块的 blackbox 导出器,以及如何使用重写标签来配置 Prometheus 以使用探针标签采集指标。