从 v2.20.0 开始,Prometheus 可以在 Docker Swarm 集群中发现目标。本指南演示如何使用该服务发现机制。
Docker Swarm 服务发现包含 3 种不同的角色:节点、服务和任务。
第一个角色,节点,表示构成 Swarm 的主机。它可用于自动监控 Docker 守护进程或在 Swarm 主机上运行的 Node Exporters。
第二个角色,任务,表示部署在 swarm 中的任何单独的容器。每个任务都有其关联的服务标签。一个服务可以由一个或多个任务支持。
第三个角色,服务,将发现部署在 swarm 中的服务。它将发现服务暴露的端口。通常,您会希望使用任务角色而不是此角色。
Prometheus 将仅发现暴露端口的任务和服务。
对于本指南,您需要设置 Prometheus。我们将假设 Prometheus 在 Docker Swarm 管理器节点上运行,并且可以访问位于 /var/run/docker.sock
的 Docker 套接字。
让我们深入了解服务发现本身。
Docker 本身,作为守护进程,会公开可由 Prometheus 服务器摄取的指标。
您可以通过编辑 /etc/docker/daemon.json
并设置以下属性来启用它们
{
"metrics-addr" : "0.0.0.0:9323",
"experimental" : true
}
您可以设置 Docker Swarm 节点的 IP 而不是 0.0.0.0
。
需要重新启动守护进程才能使新配置生效。
Docker 文档包含有关此内容的更多信息。
然后,您可以配置 Prometheus 以通过提供以下 prometheus.yml
文件来抓取 Docker 守护进程
scrape_configs:
# Make Prometheus scrape itself for metrics.
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
# Create a job for Docker daemons.
- job_name: 'docker'
dockerswarm_sd_configs:
- host: unix:///var/run/docker.sock
role: nodes
relabel_configs:
# Fetch metrics on port 9323.
- source_labels: [__meta_dockerswarm_node_address]
target_label: __address__
replacement: $1:9323
# Set hostname as instance label
- source_labels: [__meta_dockerswarm_node_hostname]
target_label: instance
对于节点角色,您还可以使用 dockerswarm_sd_configs
的 port
参数。但是,建议使用 relabel_configs
,因为它使 Prometheus 可以在相同的 Docker Swarm 配置中重用相同的 API 调用。
现在,让我们在 Swarm 中部署一个服务。我们将部署 cadvisor,它会公开容器资源指标
docker service create --name cadvisor -l prometheus-job=cadvisor \
--mode=global --publish target=8080,mode=host \
--mount type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock,ro \
--mount type=bind,src=/,dst=/rootfs,ro \
--mount type=bind,src=/var/run,dst=/var/run \
--mount type=bind,src=/sys,dst=/sys,ro \
--mount type=bind,src=/var/lib/docker,dst=/var/lib/docker,ro \
google/cadvisor -docker_only
这是用于监控它的最小 prometheus.yml
文件
scrape_configs:
# Make Prometheus scrape itself for metrics.
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
# Create a job for Docker Swarm containers.
- job_name: 'dockerswarm'
dockerswarm_sd_configs:
- host: unix:///var/run/docker.sock
role: tasks
relabel_configs:
# Only keep containers that should be running.
- source_labels: [__meta_dockerswarm_task_desired_state]
regex: running
action: keep
# Only keep containers that have a `prometheus-job` label.
- source_labels: [__meta_dockerswarm_service_label_prometheus_job]
regex: .+
action: keep
# Use the prometheus-job Swarm label as Prometheus job label.
- source_labels: [__meta_dockerswarm_service_label_prometheus_job]
target_label: job
让我们分析一下 relabel 配置的每个部分。
- source_labels: [__meta_dockerswarm_task_desired_state]
regex: running
action: keep
Docker Swarm 通过 API 公开任务所需的状态。在我们的示例中,我们仅 保留 应该正在运行的目标。它会阻止监控应该关闭的任务。
- source_labels: [__meta_dockerswarm_service_label_prometheus_job]
regex: .+
action: keep
当我们部署 cadvisor 时,我们添加了一个标签 prometheus-job=cadvisor
。当 Prometheus 获取任务标签时,我们可以指示它 仅 保留具有 prometheus-job
标签的目标。
- source_labels: [__meta_dockerswarm_service_label_prometheus_job]
target_label: job
最后一部分会获取任务的 prometheus-job
标签,并将其转换为目标标签,从而覆盖来自抓取配置的默认 dockerswarm
作业标签。
Prometheus 文档包含标签的完整列表,但是这里还有一些您可能会觉得有用的其他 relabel 配置。
- source_labels: [__meta_dockerswarm_network_name]
regex: ingress
action: keep
全局任务在每个守护进程上运行。
- source_labels: [__meta_dockerswarm_service_mode]
regex: global
action: keep
- source_labels: [__meta_dockerswarm_task_port_publish_mode]
regex: host
action: keep
- source_labels: [__meta_dockerswarm_node_hostname]
target_label: docker_node
上面的 dockerswarm_sd_configs
条目具有一个字段主机
host: unix:///var/run/docker.sock
它正在使用 Docker 套接字。如果您喜欢通过 HTTP 和 HTTPS 而不是 Unix 套接字连接到 Swarm,则 Prometheus 提供了其他配置选项。
您可以尝试使用许多发现标签,以更好地确定要监控的目标以及如何监控,对于任务,可以使用 25 个以上的标签。请随时查看 Prometheus 服务器的“服务发现”页面(位于“状态”菜单下)以查看所有发现的标签。
服务发现不假设您的 Swarm 堆栈,因此,在给定适当的配置的情况下,它应该可插入到任何现有堆栈。
此文档是开源的。请通过提交问题或拉取请求来帮助改进它。