【问题标题】:Error query in Grafana/Prometheus with node-exporter in docker swarm mode在 docker swarm 模式下使用节点导出器在 Grafana/Prometheus 中查询错误
【发布时间】:2021-03-07 16:04:28
【问题描述】:

我在仪表板配置中遇到 Grafana variable 查询的查询问题。查询变量应该返回加入 swarm 的节点数,但它没有返回。就我而言,我只有一个 swarm 节点,但 Grafana 中的变量最多返回 5 个节点。我真的不明白是什么导致了错误。

情况如下:我在我的笔记本电脑中设置了 docker swarm 作为管理器,只有我的笔记本电脑具有 swarm 模式,没有其他节点加入。 我使用https://github.com/stefanprodan/swarmprom的源来监控node-exporter的主机。我将prometheus.yml 保留为原始。

当我从prometheus 执行指标时,只有一个主机返回。这是正确的,因为我只有一个节点。可以看下图

但是当我在 Grafana 中进行查询时,Grafana 返回了 5 个主机。这里真的很奇怪。我不知道为什么我有 5 个主机,因为我只有一个 swarm 节点。

我确实使用 play-with-docker 再次检查了 git repo,配置了一个管理器节点和 2 个客户端节点。一切正常。 Grafana 中的查询返回 3 个主机。

这里是查询公式:label_values(node_uname_info{job="node-exporter"}, instance) 非常感谢您提前支持。

【问题讨论】:

  • 其他实例有什么用?您是否看到他们的指标(尝试广泛的时间范围)?它们会在某个时候结束吗?
  • 在很长一段时间内我只在 prometheus 表中看到一台主机。
  • 问题是,每次 exporter 容器重新启动时,您可能会获得一个新实例。这是因为容器 IP 不是静态的,并且您的实例标签值绑定到 IP 地址。尝试将您的node 变量Refresh 选项更改为On time range change。然后将仪表板上的时间范围更改为较短的时间,例如最后五分钟。如果我是对的,您应该只会在列表中看到一个实例。
  • 是的,我遇到了你之前提到的情况。不止一个 exporter 容器正在运行,因此它们会导致多个 ip。我已经离开并再次启动 swarm 模式以确保只有一个 node_exportes 正在运行
  • 今天早上,我再次检查,现在它只显示 3 ips localhost 和我的真实服务器。这是正确的,但昨天晚上,它显示 8 ips localhost。你觉得node-exported 的容器有问题吗?

标签: docker prometheus grafana docker-swarm prometheus-node-exporter


【解决方案1】:

您所面临的是临时容器性质的结果,这是监控容器应用程序的挑战之一。在我们进入任何解决方案之前,让我们看看......

Grafana 显示的实例多于实际实例是如何发生的。

Prometheus 是一个时间序列数据库。有时它会联系其抓取目标并收集指标。这些指标与时间戳和一组标签一起保存,其中一个是相关的“实例”标签。

实例标签通常由地址(主机/域名或 IP 地址)和端口组成,prometheus 使用它来抓取指标。在此示例中,实例地址是 IP 地址,因为目标列表是通过 DNS 服务器(作业定义中的dns_sd_configs)获得的。

当您部署堆栈时,docker 为每个服务创建了至少一个容器,包括 node-exporter 和 prometheus。不久之后,prometheus 开始从 node-exporter 实例获取指标,但是过了一段时间,node-exporter 容器被重新创建。要么你更新了它,要么杀了它,要么它崩溃了——我不知道,但关键是——你有一个新容器。新的节点导出器容器获得了不同的 IP 地址,因此来自新实例的指标收到了不同的“实例”标签。

还记得 prometheus 是一个时间序列数据库吗?您没有丢失离线实例的指标,它们仍在数据库中。就在此时,您已经开始使用不同的标签集(至少在“实例”标签中的新 IP 地址)收集节点导出器指标。当 Grafana 为您查询标签时,它会请求仪表板上当前设置的时间段内的指标。由于时间段是“今天”,因此您已经看到今天出现的实例。换句话说,当您请求可能的实例值列表时,您会收到该时间段的值列表,而不会对当前活动的实例进行任何过滤。

一般解决方案。

您需要为此任务使用一些静态标签。如果您不希望在列表中看到死实例,则“实例”或“pod_name”(K8s)标签是一个糟糕的选择。选择一个代表您想要观看的事物或单位的标签并坚持下去。由于 node-exporter 是用来监控节点指标的,我认为主机名标签就可以了。

如果您认为无法避免使用动态标签,您可以在仪表板上使用较短的时间范围,这样label_values() 函数就不会返回长死标签。您希望将变量刷新选项设置为“按时间范围更改”,以便您可以使用较短的仪表板间隔来查看和选择当前活动的实例,而对于任何其他情况,您可以使用较长的时间间隔。

这个特殊问题的一个选项。

正如我之前所说,在这种情况下使用主机名标签会更好。问题是 - 有问题的指标中没有这样的标签。检查swarmprom repo,我发现这个节点导出器是通过node_meta 标签(here)暴露主机名的。因此可以使用链式变量将主机名映射到实例。

另一个问题是此解决方案可能需要更改面板查询。由于一个主机名可以解析为多个实例,必须面板查询对“实例”标签使用正则表达式匹配(即=~ 而不是=) .

以下是所有这些操作的方法:

  1. 创建一个名为“hostname”的新变量,将刷新选项设置为“On Time Range Change”,并将其用于查询字段:
label_values(node_meta, node_name)

这个将用作仪表板上的选择器。

  1. 更新“节点”变量:将刷新选项设置为“按时间范围更改”,启用“多值”和“添加所有选项”,将查询替换为:
label_values(node_meta{node_name="$hostname"}, instance)

这将返回一组与所选“主机名”匹配的“实例”标签。如果您选择全部并更新面板查询以支持多值实例标签,您将能够查看与所选主机名关联的所有容器实例的指标。

  1. 打开仪表板 JSON 模型并将其复制到您喜欢的文本编辑器中。将所有出现的 instance= 替换为 instance=~,然后将编辑后的模型复制粘贴到 Grafana 中。

【讨论】:

  • 非常感谢您的帮助,我第一次尝试时遇到了一些来自具有相同主机名的多机 ip 的问题。例如 node_meta{container_label_com_docker_swarm_node_id="bfcuw6gwdmri0i0431aharleb",instance="10.0.1.160:9100",job="node-exporter",node_id="bfcuw6gwdmri0i0431aharleb",node_name="database"} node_meta{container_label_com_docker_swarm_node_id="bfcuw6gwdmri0i0431aharleb",instance="10.0.1.160:9100",job="node-exporter",node_id="bfcuw6gwdmri0i0431aharleb",node_name="database"} 但经过几次尝试后,它工作正常
猜你喜欢
  • 1970-01-01
  • 2021-05-08
  • 1970-01-01
  • 2020-02-25
  • 2019-10-15
  • 2022-07-26
  • 2020-12-17
  • 2017-05-19
  • 2019-07-30
相关资源
最近更新 更多