You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker Swarm多副本Node.js API的Prometheus监控配置问题

问题描述

我用Prometheus监控Docker Swarm上的6副本Express Node.js API,遇到两个核心问题:

  1. 最初基于dockerswarm_sd_configs的配置无法抓取到目标服务
  2. 改用dns_sd_configs后能成功抓取指标,但每个副本的计数器独立存在,无法在Grafana中聚合展示2XX/5XX等请求统计数据

最初的无效Prometheus配置

- job_name: 'dockerswarm'
  dockerswarm_sd_configs:
    - host: unix:///var/run/docker.sock
      role: tasks
  relabel_configs:
    # 仅保留运行状态的容器
    - source_labels: [__meta_dockerswarm_task_desired_state]
      regex: running
      action: keep
    # 仅保留指定服务名的容器
    - source_labels: [__meta_dockerswarm_service_name]
      regex: backend-server
      action: keep
    - source_labels: [__meta_dockerswarm_node_address]
      target_label: __address__
      replacement: $1:9464/api/metrics

服务状态确认命令输出

root@srv:~# docker service ls | grep backend
z5bnz2t5riw8   backend-server            replicated   6/6        xx/xx/backend-server:x           *:3000->3000/tcp

root@srv:~# docker service ls | grep promethe
8zlh5kwfx8ks   prometheus                replicated   1/1        prom/prometheus:v2.52.0          *:9090->9090/tcp

改用的有效配置(但指标分散)

scrape_configs:
  - job_name: cadvisor
    scrape_interval: 1m
    static_configs:
      - targets:
          - cadvisor:8080
  - job_name: node
    scrape_interval: 1m
    static_configs:
      - targets: ['host.docker.internal:9100', 'victoria.consorcio.local:9100']
  - job_name: backend
    scrape_interval: 15s
    metrics_path: /victoria/api/metrics
    dns_sd_configs:
      - names:
          - 'tasks.backend-server'
        type: 'A'
        port: 9464

分散的指标示例

error_counter_total{instance="10.0.1.15:9464", job="backend", method="POST", status="401"}
error_counter_total{instance="10.0.1.16:9464", job="backend", method="POST", status="401"}
解决方案

一、修复Docker Swarm服务发现配置

最初配置无效的原因是__address__的替换逻辑错误:__meta_dockerswarm_node_address是节点IP,但任务容器的访问应该用容器内部IP+端口,且__address__仅需包含IP:端口,指标路径要单独放在metrics_path中。

修改后的有效配置:

- job_name: 'dockerswarm-backend'
  dockerswarm_sd_configs:
    - host: unix:///var/run/docker.sock
      role: tasks
  metrics_path: /api/metrics  # 把指标路径移到这里
  relabel_configs:
    # 仅保留运行中的任务
    - source_labels: [__meta_dockerswarm_task_desired_state]
      regex: running
      action: keep
    # 仅保留指定服务
    - source_labels: [__meta_dockerswarm_service_name]
      regex: backend-server
      action: keep
    # 使用任务容器的内部IP和端口拼接地址
    - source_labels: [__meta_dockerswarm_task_address, __meta_dockerswarm_task_port]
      target_label: __address__
      replacement: "${1}:${2}"
    # 可选:添加服务标签,方便后续聚合
    - source_labels: [__meta_dockerswarm_service_name]
      target_label: service

说明:

  • 如果你的服务没有在Swarm中声明9464端口,可以直接硬编码端口:replacement: "${1}:9464"
  • 确保Prometheus服务在Swarm集群中拥有访问Docker Socket的权限

二、多副本指标聚合方法

1. Grafana查询时聚合(推荐)

直接在PromQL中使用sum()或rate()函数,按业务需要的标签分组,忽略instance标签:

  • 统计所有副本的总401请求数:
sum(error_counter_total{job="backend", status="401"}) by (method, status)
  • 统计2XX请求的实时QPS:
sum(rate(error_counter_total{job="backend", status=~"2.."}[1m])) by (status)

这种方式保留了单个实例的监控数据,方便后续排查单副本问题。

2. Prometheus配置中统一实例标签(可选)

如果希望指标在存储时就合并,可以通过relabel规则将所有副本的instance标签替换为服务名:
在backend任务的relabel_configs中添加:

- source_labels: [__meta_dockerswarm_service_name]
  target_label: instance
  replacement: "backend-server"

注意:这种方式会丢失单个实例的监控维度,仅适合不需要排查单副本问题的场景。


内容的提问来源于stack exchange,提问作者Carlos David

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 23:37:07