Prometheus 部署后 Cadvisor 与 Nodes 状态 Down 的排查与解决

在基于 Prometheus 的监控体系中,Cadvisor(容器资源监控)和 Node Exporter(节点资源监控)是核心的监控目标(Target)。当这两个 Target 状态显示为 down 时,会导致容器和节点的监控数据丢失,影响整体可观测性。本文将从问题现象、原因分析、排查步骤、解决方案到最佳实践,系统性地讲解如何定位并解决该问题。

目录#

问题现象#

部署 Prometheus 后,在 Prometheus UI 的 Status → Targets 页面中,发现:

  • cadvisor 对应的 Target 状态为 down,Last Scrape 显示“Connection refused”或“Timeout”。
  • nodes(Node Exporter)对应的 Target 状态为 down,错误信息类似“context deadline exceeded”。

此时,Prometheus 无法从这两个 Target 拉取监控指标,容器和节点的资源使用、性能数据将缺失。

可能原因分析#

1. 目标服务未运行#

  • Cadvisor 容器未启动(如 Docker/Pod 异常退出)。
  • Node Exporter 进程未启动(如系统服务未开机自启、K8s DaemonSet 调度失败)。

2. 网络连通性故障#

  • Prometheus 所在机器(或 Pod)与目标服务的网络不通(如端口被防火墙拦截、K8s NetworkPolicy 限制)。
  • 目标服务的监听地址/端口配置错误(如 Cadvisor 监听 127.0.0.1:8080 而非 0.0.0.0:8080,导致外部无法访问)。

3. Prometheus 配置错误#

  • prometheus.ymlscrape_configstargets 地址/端口错误(如 Node Exporter 实际端口为 9101,但配置为 9100)。
  • 服务发现(如 K8s SD)配置错误,导致 Target 未被正确发现。
  • Relabel 规则错误,修改了 Target 的地址或标签,导致访问失败。

4. 权限或兼容性问题#

  • Node Exporter 缺少系统权限(如无法读取 /proc/sys 目录,导致指标采集失败)。
  • Prometheus、Cadvisor、Node Exporter 版本不兼容(如 API 变更导致指标拉取失败)。

详细排查步骤#

步骤 1:检查目标服务是否运行#

Cadvisor 检查(容器化场景)#

# Docker 环境
docker ps | grep cadvisor  # 查看容器是否运行
docker logs <cadvisor-container-id>  # 查看容器日志,排查启动错误
 
# K8s 环境
kubectl get pods -n <namespace> -l app=cadvisor  # 查看 Pod 状态
kubectl logs <cadvisor-pod> -n <namespace>       # 查看 Pod 日志

Node Exporter 检查(节点级监控)#

# 物理机/虚拟机
ps -ef | grep node_exporter  # 查看进程是否存在
systemctl status node_exporter  # 系统服务状态(如使用 systemd)
 
# K8s DaemonSet 环境
kubectl get daemonset -n <namespace> -l app=node-exporter  # 查看 DaemonSet 状态
kubectl get pods -n <namespace> -l app=node-exporter       # 查看所有节点的 Node Exporter Pod
kubectl describe pod <node-exporter-pod> -n <namespace>    # 分析 Pod 启动失败原因(如权限、资源不足)

步骤 2:网络连通性测试#

从 Prometheus 侧发起请求#

# 物理机/虚拟机场景
curl http://<target-ip>:<port>/metrics  # 如 Cadvisor 默认 8080,Node Exporter 默认 9100
 
# K8s Pod 场景(进入 Prometheus Pod)
kubectl exec -it <prometheus-pod> -- curl http://<node-ip>:9100/metrics

若返回 Connection refused,说明:

  • 目标服务未监听该端口(如端口配置错误)。
  • 目标服务仅监听 127.0.0.1(需修改为 0.0.0.0)。

若返回 Timeout,需检查:

  • 防火墙规则(如 iptables -L 查看是否拦截端口)。
  • K8s NetworkPolicy(如是否禁止 Prometheus Pod 访问节点端口)。

步骤 3:验证 Prometheus 配置#

检查 prometheus.ymlscrape_configs#

scrape_configs:
  # Cadvisor 配置示例(静态 Target)
  - job_name: 'cadvisor'
    static_configs:
      - targets: ['node1:8080', 'node2:8080']  # 需确保节点 IP/端口正确
 
  # Node Exporter 配置示例(K8s 服务发现)
  - job_name: 'node-exporter'
    kubernetes_sd_configs:
      - role: node  # 自动发现所有节点
    relabel_configs:
      - source_labels: [__address__]
        target_label: __address__
        replacement: $1:9100  # 节点的 9100 端口(Node Exporter 默认端口)

常见配置错误#

  • 静态 Target 错误targets 写死 localhost(但 Prometheus 与目标不在同一节点/容器)。
  • 服务发现错误kubernetes_sd_configsrolerelabel 规则错误,导致 Target 地址无效。
  • 端口错误:Node Exporter 实际端口为 9101,但配置为 9100

步骤 4:分析 Prometheus 日志与指标#

查看 Prometheus 日志#

# 物理机/容器日志
journalctl -u prometheus  # 系统服务场景
kubectl logs <prometheus-pod> -n <namespace>  # K8s 场景

日志关键词示例:

  • level=error msg="error scraping target":Scrape 失败的详细原因(如 connection refusedcontext deadline exceeded)。

分析 Prometheus 自身指标#

# 查看 Scrape 成功率
curl http://<prometheus-ip>:9090/api/v1/query --data-urlencode 'query=up{job=~"cadvisor|node-exporter"}'

若返回 up: 0,说明 Target 仍未恢复。

步骤 5:权限与兼容性检查#

Node Exporter 权限(K8s 场景)#

Node Exporter 需要读取节点的系统信息(如 /proc/sys),需通过 hostPath 挂载和 privileged 权限(或最小权限):

# Node Exporter DaemonSet 示例(关键配置)
spec:
  template:
    spec:
      hostNetwork: true  # 共享节点网络(访问节点端口)
      hostPID: true      # 共享节点 PID 命名空间(可选,部分指标需要)
      volumes:
        - name: proc
          hostPath:
            path: /proc
        - name: sys
          hostPath:
            path: /sys
        - name: rootfs
          hostPath:
            path: /
      containers:
        - name: node-exporter
          image: prom/node-exporter:v1.6.1
          volumeMounts:
            - name: proc
              mountPath: /host/proc
              readOnly: true
            - name: sys
              mountPath: /host/sys
              readOnly: true
            - name: rootfs
              mountPath: /rootfs
              readOnly: true
          args:
            - --path.procfs=/host/proc
            - --path.sysfs=/host/sys
            - --path.rootfs=/rootfs
          securityContext:
            privileged: true  # 生产环境可缩小权限(如使用 capabilities)

版本兼容性#

  • Prometheus v2.40+ 需确保 Cadvisor/Node Exporter 为兼容版本(如 Cadvisor ≥ v0.47.0)。
  • 查看 官方兼容性文档 或 GitHub Release Notes。

解决方案与场景化修复#

场景 1:服务未启动或异常退出#

Cadvisor 修复(Docker 场景)#

# 启动 Cadvisor 容器(挂载宿主机目录,确保权限)
docker run -d \
  --name=cadvisor \
  --mount type=bind,source=/,target=/rootfs,readonly \
  --mount type=bind,source=/var/run,target=/var/run,readonly \
  --mount type=bind,source=/sys,target=/sys,readonly \
  --mount type=bind,source=/var/lib/docker,target=/var/lib/docker,readonly \
  --publish=8080:8080 \
  google/cadvisor:v0.47.0

Node Exporter 修复(K8s DaemonSet 场景)#

# 重新部署 DaemonSet(修正配置后)
kubectl apply -f node-exporter-daemonset.yaml
 
# 查看 Pod 状态(确保所有节点都有 Running 的 Pod)
kubectl get pods -n monitoring -l app=node-exporter

场景 2:网络连通性故障#

防火墙/安全组修复#

# 开放 Node Exporter 端口(CentOS/RHEL)
firewall-cmd --permanent --add-port=9100/tcp
firewall-cmd --reload
 
# K8s NetworkPolicy 允许 Prometheus 访问节点端口
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-prometheus-node-exporter
  namespace: monitoring
spec:
  podSelector:
    matchLabels:
      app: prometheus
  policyTypes:
    - Egress
  egress:
    - to:
        - ipBlock:
            cidr: 192.168.0.0/16  # 节点网段
      ports:
        - protocol: TCP
          port: 9100  # Node Exporter 端口

目标服务监听地址修复(Cadvisor 示例)#

修改 Cadvisor 启动参数,确保监听所有接口:

# Docker 启动时指定 --http_address=0.0.0.0
docker run -d \
  --name=cadvisor \
  --http_address=0.0.0.0 \  # 监听所有接口
  ...
  google/cadvisor:v0.47.0

场景 3:Prometheus 配置错误#

静态 Target 修正#

# 修改 prometheus.yml 的 cadvisor job
- job_name: 'cadvisor'
  static_configs:
    - targets: ['192.168.1.10:8080', '192.168.1.11:8080']  # 替换为实际节点 IP

热加载配置(无需重启 Prometheus)#

curl -X POST http://<prometheus-ip>:9090/-/reload  # 需确保启用了 --web.enable-lifecycle

场景 4:权限或兼容性问题#

Node Exporter 最小权限配置(K8s)#

securityContext:
  runAsUser: 0  # 需 root 权限读取 /proc、/sys(或使用 capabilities)
  capabilities:
    add: ["SYS_PTRACE", "SYS_ADMIN"]  # 按需添加

版本升级#

# 升级 Node Exporter 到最新稳定版
docker pull prom/node-exporter:v1.6.1
kubectl set image daemonset/node-exporter node-exporter=prom/node-exporter:v1.6.1 -n monitoring

最佳实践#

1. 监控目标的预验证#

部署前,手动验证指标接口:

curl http://<target-ip>:<port>/metrics  # 如 http://node1:9100/metrics

确保返回包含 CPU、内存等指标的文本。

2. 配置管理与验证#

  • 使用 promtool 验证配置语法:
    promtool check config prometheus.yml
  • 版本化配置(如 Git 管理 prometheus.yml),避免手动修改出错。

3. 服务发现与自动化#

优先使用服务发现(如 K8s SD、Consul SD),减少静态配置:

- job_name: 'node-exporter'
  kubernetes_sd_configs:
    - role: node
  relabel_configs:
    - source_labels: [__address__]
      target_label: __address__
      replacement: $1:9100

4. 权限与安全#

  • Node Exporter 权限遵循最小原则:避免 privileged: true,使用 capabilitieshostPath 只读挂载。
  • 限制 Prometheus 暴露的端口(如仅内网可访问 9090)。

5. 告警与自愈#

  • 告警规则:配置 Target Down 告警,及时发现故障:
    groups:
    - name: target_down
      rules:
      - alert: TargetDown
        expr: up{job=~"cadvisor|node-exporter"} == 0
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "Target {{ $labels.instance }} 离线"
          description: "{{ $labels.instance }} 已离线超过 5 分钟,请检查服务状态。"
  • 自愈机制:结合 K8s 健康检查(如 Pod 的 livenessProbe),自动重启故障容器。

总结#

当 Prometheus 的 Cadvisor 和 Node Exporter Target 状态为 down 时,需从服务运行状态、网络连通性、配置、权限、兼容性五个维度排查。通过预验证监控目标、使用服务发现、最小化权限配置、及时告警等最佳实践,可有效避免此类问题。

参考资料#