Docker Swarm

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

Docker Swarm 服务发现架构

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

第一个角色 nodes,代表 Swarm 集群中的主机。它可以用来自动监控 Swarm 主机上运行的 Docker 守护进程或 Node Exporter。

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

第三个角色 services,将发现部署在 swarm 中的服务。它将发现服务暴露的端口。通常情况下,你会更倾向于使用 tasks 角色而不是这个。

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
}

你可以将 0.0.0.0 替换为 Docker Swarm 节点的 IP。

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

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

对于 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

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

- 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 而不是 unix socket 来连接到 Swarm,Prometheus 提供了额外的配置选项

结论

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

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

本页内容