Docker Swarm

从 v2.20.0 开始,Prometheus 可以在 Docker Swarm 集群中发现目标。本指南演示了如何使用该服务发现机制。

Docker Swarm 服务发现架构

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

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

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

第三个角色,服务,将发现部署在 swarm 中的服务。它将发现服务暴露的端口。通常,您会希望使用任务角色而不是此角色。

Prometheus 将仅发现暴露端口的任务和服务。

注意: 本文的其余部分假设您已有一个 Swarm 正在运行。

设置 Prometheus

对于本指南,您需要设置 Prometheus。我们假设 Prometheus 在 Docker Swarm 管理节点上运行,并且可以访问 /var/run/docker.sock 上的 Docker socket。

监控 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.yml 文件来配置 Prometheus 以抓取 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_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

让我们分析 重新标记配置 的每个部分。

- 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 文档 包含完整的标签列表,但这里还有其他您可能会觉得有用的重新标记配置。

仅通过特定网络抓取指标

- 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 socket。如果您喜欢通过 HTTP 和 HTTPS 连接到 Swarm 而不是 unix socket,Prometheus 提供了其他配置选项

结论

您可以使用许多发现标签来更好地确定要监控哪些目标以及如何监控,对于任务,有超过 25 个可用的标签。请随时查看 Prometheus 服务器的“服务发现”页面(在“状态”菜单下)以查看所有已发现的标签。

服务发现不对您的 Swarm 堆栈做任何假设,通过适当的配置,它应该是可插入到任何现有堆栈的。

本文档是开源的。请通过提交 issue 或 pull request 来帮助改进它。