请参与 Prometheus 用户调研(2026 年 3 月版) ,帮助社区确定未来开发工作的优先级!

Docker Swarm

自 v2.20.0 版本起,Prometheus 可以发现 Docker Swarm  集群中的目标。本指南将演示如何使用该服务发现机制。

Docker Swarm 服务发现架构

Docker Swarm 服务发现包含 3 种不同的角色:nodes (节点)、services (服务) 和 tasks (任务)。

第一个角色 nodes 代表作为 Swarm 一部分的宿主机。它可以用于自动监控 Docker 守护进程或运行在 Swarm 节点上的 Node Exporter。

第二个角色 tasks 代表部署在 Swarm 中的任何单个容器。每个任务都会获得其关联的服务标签。一个服务可以由一个或多个任务支撑。

第三个角色 services 将发现部署在 Swarm 中的服务。它将发现服务所暴露的端口。通常建议使用 tasks 角色而不是这个角色。

Prometheus 只会发现暴露了端口的任务和服务。

注意本文档的其余部分假设您已经运行了一个 Swarm 环境。

设置 Prometheus

在本指南中,您需要 安装 Prometheus。我们假设 Prometheus 运行在 Docker Swarm 管理节点上,并且有权访问 /var/run/docker.sock 处的 Docker 套接字。

监控 Docker 守护进程

让我们深入探讨服务发现本身。

Docker 守护进程自身暴露了 指标 ,这些指标可被 Prometheus 服务器采集。

您可以通过编辑 /etc/docker/daemon.json 并设置以下属性来启用它们:

{
  "metrics-addr" : "0.0.0.0:9323",
  "experimental" : true
}

您可以将 IP 设置为 Docker Swarm 节点的 IP,而不是 0.0.0.0

需要重启守护进程才能使新配置生效。

Docker 文档  中包含了关于此功能的更多信息。

然后,您可以配置 Prometheus 来抓取 Docker 守护进程,提供以下 prometheus.yml 文件:

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

对于 nodes 角色,您也可以使用 dockerswarm_sd_configsport 参数。但是,推荐使用 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 暴露任务的期望 状态 (state of the tasks) 。在我们的示例中,我们仅 保留 (keep) 应该运行的目标。这可以防止监控那些应该被关闭的任务。

- 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 文档中包含了完整的标签列表,但以下是一些您可能会觉得有用的其他重标签配置。

仅通过特定网络抓取指标

- 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

向目标添加 docker_node 标签

- source_labels: [__meta_dockerswarm_node_hostname]
  target_label: docker_node

连接到 Docker Swarm

上述 dockerswarm_sd_configs 条目中包含 host 字段。

host: unix:///var/run/docker.sock

这使用了 Docker 套接字。Prometheus 提供了 额外的配置选项,如果您更喜欢使用 HTTP 和 HTTPS 来连接 Swarm,而不是使用 unix 套接字。

结论

有许多发现标签可以供您利用,从而更好地确定监控目标及其方式。对于任务,有超过 25 个标签可用。不要犹豫,查看您 Prometheus 服务器的“服务发现”页面(在“状态”菜单下)以查看所有已发现的标签。

服务发现不对您的 Swarm 栈做任何假设,因此只要配置得当,它应该可以插入任何现有的栈中。

本页内容