冷蟊初退 孤灯野澜 志起鸡鸣 墓不悲秋 技术交流 软件开发 商业合作 加Q:411239339

Day 25 Prometheus+Grafana 企业级监控

浏览:25次阅读
没有评论

共计 5150 个字符,预计需要花费 13 分钟才能阅读完成。

Docker 30 天实战系列 · Day 25

你有没有过这种经历:线上容器突然挂了,你一脸懵地看着 docker ps,发现容器已经重启了三次,但完全不知道发生了什么。CPU 飙了?内存爆了?磁盘满了?全靠猜。

这就像开车没有仪表盘——油量多少不知道,水温多高不清楚,等到车抛锚了才知道出了问题。今天我们就来给 Docker 装上一套 " 全液晶仪表盘 ":Prometheus + Grafana 监控体系。

本文你将学到

  • 理解容器监控的整体架构和数据流向
  • 使用 cAdvisor 采集容器运行指标
  • 配置 Prometheus 存储和查询时序数据
  • 搭建 Grafana 仪表盘实现可视化
  • 编写 PromQL 查询常用容器指标
  • 配置基础告警规则,让问题主动找你

阅读时间:15 分钟 | 实操时间:30 分钟 | 难度等级:中级


监控架构:三兄弟各司其职

在动手之前,先搞清楚这套监控体系的分工。我喜欢用餐厅来类比:

  • cAdvisor 是 " 传菜员 "——它贴身跟着每个容器,实时收集 CPU、内存、网络、磁盘等指标数据
  • Prometheus 是 " 账房先生 "——它定时去 cAdvisor 那里拉数据,分门别类记在自己的时序数据库里
  • Grafana 是 " 大堂经理 "——它从 Prometheus 那里取数据,画成漂亮的图表展示给你看

数据流向用一张图表示:

+------------+      +------------+      +-----------+
|            | pull |            | query|           |
|  cAdvisor  |<-----|Prometheus  |<-----|  Grafana  |
|  (采集器)   |      | (时序库)    |      | (仪表盘)  |
+------------+      +------------+      +-----------+
     |                    |                   |
     v                    v                   v
  容器指标             存储 + 告警           可视化展示
  CPU/ 内存 / 网络        PromQL 查询         图表 / 仪表盘 

注意这里的关键设计:Prometheus 是主动去 " 拉 " 数据的(Pull 模型),而不是 cAdvisor 主动 " 推 " 过来。这个设计很巧妙——Prometheus 自己控制采集频率,哪个目标挂了它也能立刻知道。


实操:一键部署监控栈

准备配置文件

首先创建项目目录和 Prometheus 配置:

mkdir -p monitoring && cd monitoring

创建 prometheus.yml 配置文件:

# prometheus.yml
global:
  scrape_interval: 15s      # 每 15 秒采集一次
  evaluation_interval: 15s   # 每 15 秒评估一次告警规则

rule_files:
  - "alert_rules.yml"

scrape_configs:
  # 监控 Prometheus 自身
  - job_name: "prometheus"
    static_configs:
      - targets: ["localhost:9090"]

  # 监控容器(通过 cAdvisor)- job_name: "cadvisor"
    static_configs:
      - targets: ["cadvisor:8080"]

  # 监控宿主机(通过 Node Exporter)- job_name: "node-exporter"
    static_configs:
      - targets: ["node-exporter:9100"]

创建 alert_rules.yml 告警规则文件:

# alert_rules.yml
groups:
  - name: container_alerts
    rules:
      # 容器 CPU 使用率超过 80%
      - alert: ContainerHighCPU
        expr: rate(container_cpu_usage_seconds_total{name!=""}[5m]) * 100 > 80
        for: 2m
        labels:
          severity: warning
        annotations:
          summary: "容器 {{$labels.name}} CPU 使用率过高"
          description: "容器 {{$labels.name}} CPU 使用率超过 80%,当前值: {{$value}}%"

      # 容器内存使用率超过 85%
      - alert: ContainerHighMemory
        expr: container_memory_usage_bytes{name!=""} / container_spec_memory_limit_bytes{name!=""} * 100 > 85
        for: 2m
        labels:
          severity: warning
        annotations:
          summary: "容器 {{$labels.name}} 内存使用率过高"
          description: "容器 {{$labels.name}} 内存使用率超过 85%,当前值: {{$value}}%"

      # 容器重启次数过多
      - alert: ContainerFrequentRestart
        expr: increase(container_last_seen{name!=""}[1h]) < 1
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "容器 {{$labels.name}} 可能频繁重启"

编写 docker-compose.yml

这是完整的监控栈编排文件:

# docker-compose.yml
services:
  # 容器指标采集器
  cadvisor:
    image: gcr.io/cadvisor/cadvisor:v0.47.2
    container_name: cadvisor
    restart: unless-stopped
    volumes:
      - /:/rootfs:ro
      - /var/run:/var/run:ro
      - /sys:/sys:ro
      - /var/lib/docker/:/var/lib/docker:ro
      - /dev/disk/:/dev/disk:ro
    ports:
      - "8080:8080"
    privileged: true
    devices:
      - /dev/kmsg:/dev/kmsg

  # 时序数据库 + 告警引擎
  prometheus:
    image: prom/prometheus:v2.51.0
    container_name: prometheus
    restart: unless-stopped
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
      - ./alert_rules.yml:/etc/prometheus/alert_rules.yml:ro
      - prometheus_data:/prometheus
    ports:
      - "9090:9090"
    command:
      - "--config.file=/etc/prometheus/prometheus.yml"
      - "--storage.tsdb.retention.time=15d"
      - "--web.enable-lifecycle"
    depends_on:
      - cadvisor

  # 可视化仪表盘
  grafana:
    image: grafana/grafana:10.4.0
    container_name: grafana
    restart: unless-stopped
    environment:
      - GF_SECURITY_ADMIN_USER=admin
      - GF_SECURITY_ADMIN_PASSWORD=admin123
      - GF_USERS_ALLOW_SIGN_UP=false
    volumes:
      - grafana_data:/var/lib/grafana
    ports:
      - "3000:3000"
    depends_on:
      - prometheus

  # 宿主机指标采集(可选但推荐)node-exporter:
    image: prom/node-exporter:v1.7.0
    container_name: node-exporter
    restart: unless-stopped
    volumes:
      - /proc:/host/proc:ro
      - /sys:/host/sys:ro
      - /:/rootfs:ro
    command:
      - "--path.procfs=/host/proc"
      - "--path.rootfs=/rootfs"
      - "--path.sysfs=/host/sys"
    ports:
      - "9100:9100"

volumes:
  prometheus_data:
  grafana_data:

启动监控栈

docker compose up -d

预期输出:

[+] Running 5/5
 ✔ Network monitoring_default    Created
 ✔ Volume "monitoring_prometheus_data"  Created
 ✔ Volume "monitoring_grafana_data"     Created
 ✔ Container cadvisor             Started
 ✔ Container node-exporter        Started
 ✔ Container prometheus           Started
 ✔ Container grafana              Started

等待约 30 秒让各组件初始化完成,然后验证:

# 检查所有容器是否正常运行
docker compose ps

# 验证 Prometheus 能采集到 cAdvisor 数据
curl -s http://localhost:9090/api/v1/targets | python3 -m json.tool | head -20

你应该能看到 cadvisorprometheusnode-exporter 三个目标的状态都是 "health": "up"


PromQL 入门:和数据对话

Prometheus 有自己的查询语言叫 PromQL,你可以把它理解为 " 时序数据的 SQL"。打开 http://localhost:9090,在查询框里试试这些:

常用查询示例

查看所有容器的 CPU 使用率(最近 5 分钟平均):

rate(container_cpu_usage_seconds_total{name!=""}[5m]) * 100

这里 rate() 计算的是每秒变化率,乘以 100 转成百分比。name!="" 过滤掉那些没名字的系统级 cgroup。

查看容器内存使用量(MB):

container_memory_usage_bytes{name!=""} / 1024 / 1024

查看容器网络接收速率(KB/s):

rate(container_network_receive_bytes_total{name!=""}[5m]) / 1024

找出内存使用 Top 5 的容器:

topk(5, container_memory_usage_bytes{name!=""})

PromQL 的套路其实很固定:选指标 → 加过滤条件 → 套函数。掌握 rate()increase()topk()histogram_quantile() 这几个函数,日常监控就够用了。


Grafana 仪表盘搭建

添加数据源

  1. 打开 http://localhost:3000,用 admin/admin123 登录
  2. 进入 Connections > Data Sources > Add data source
  3. 选择 Prometheus
  4. URL 填写 http://prometheus:9090(容器间用服务名通信)
  5. 点击 Save & test,看到绿色的 "Successfully queried the Prometheus API" 就对了

导入现成仪表盘

自己从零画仪表盘太费时间,Grafana 社区有大量现成模板。推荐这两个:

Docker 容器监控(Dashboard ID: 893):

  1. 进入 Dashboards > New > Import
  2. 输入 ID 893,点 Load
  3. 选择刚才配置的 Prometheus 数据源
  4. Import

你会立刻看到一个完整的容器监控面板,包含 CPU、内存、网络、磁盘 IO 等图表。

Node Exporter 宿主机监控(Dashboard ID: 1860):

同样的步骤,输入 ID 1860 导入,可以监控宿主机的系统资源。

自定义面板

如果想自己加一个面板,比如 " 各容器内存使用排行 ":

  1. 在仪表盘页面点 Add > Visualization
  2. 查询框输入:sort_desc(container_memory_usage_bytes{name!=""}) / 1024 / 1024
  3. 右侧面板类型选 Bar gauge
  4. 单位设置为 MB
  5. 标题填 " 容器内存排行 "

几下点击,一个实用的面板就出来了。


告警配置进阶

前面 alert_rules.yml 里已经定义了基础告警规则,但光有规则还不够——告警触发了得通知到人才行。

查看告警状态

打开 http://localhost:9090/alerts,可以看到当前所有告警规则的状态:

  • Inactive:一切正常,规则没触发
  • Pending:条件已满足,但还在等 for 指定的持续时间
  • Firing:告警已触发

接入通知渠道

生产环境建议配合 Alertmanager 使用,可以对接:

  • 企业微信 / 钉钉 Webhook
  • 邮件通知
  • PagerDuty
  • Slack

在 docker-compose.yml 中增加 Alertmanager 服务:

  alertmanager:
    image: prom/alertmanager:v0.27.0
    container_name: alertmanager
    restart: unless-stopped
    volumes:
      - ./alertmanager.yml:/etc/alertmanager/alertmanager.yml:ro
    ports:
      - "9093:9093"

然后在 prometheus.yml 中添加 Alertmanager 地址:

alerting:
  alertmanagers:
    - static_configs:
        - targets: ["alertmanager:9093"]

具体的通知渠道配置因团队而异,这里就不展开了,核心思路就是 " 规则在 Prometheus 定义,通知在 Alertmanager 分发 "。


常见问题 Q&A

Q1:cAdvisor 占用资源多吗?会不会影响业务容器?

cAdvisor 本身非常轻量,通常只占用 50-100MB 内存和极少的 CPU。它直接读取 Linux 内核的 cgroup 文件系统来获取指标,不会对业务容器产生干扰。不过在容器数量特别多(几百个以上)的场景下,建议适当调大采集间隔。

Q2:Prometheus 数据会不会把磁盘撑爆?

我们配置了 --storage.tsdb.retention.time=15d,也就是只保留最近 15 天的数据。按照采集 50 个容器、15 秒间隔来算,一天大约产生 200MB 数据,15 天也就 3GB 左右。如果你的容器特别多,可以调整保留时间或者增加磁盘。

Q3:Grafana 仪表盘打开很慢怎么办?

通常是查询时间范围太大导致的。把时间范围从 " 最近 7 天 " 缩小到 " 最近 1 小时 " 试试。另外检查一下面板里的 PromQL 查询有没有漏加 {name!=""} 过滤条件——不加过滤会查出大量系统级 cgroup 数据,严重拖慢速度。


小结

今天我们搭建了一套完整的容器监控体系:

  • cAdvisor 负责采集每个容器的实时指标
  • Prometheus 负责存储时序数据,提供 PromQL 查询能力
  • Grafana 负责将数据可视化,让你一眼看清系统状态
  • 告警规则 让问题主动找你,而不是你去找问题

这套方案是目前容器监控的事实标准,从个人项目到大厂生产环境都在用。掌握了它,你的容器就不再是 " 黑箱 " 了——每个容器用了多少 CPU、吃了多少内存、网络流量是否异常,全都一目了然。

记住一句话: 没有监控的系统就像没有仪表盘的汽车,跑得再快也不安全。

明天的 Day 26,我们将进入 Docker Swarm 集群编排,学习如何把多台机器组成一个集群来运行容器。单机玩够了,是时候搞集群了。

正文完
创作不易,扫码加点动力
post-qrcode
 0
果较瘦
版权声明:本站原创文章,由 果较瘦 于2026-03-29发表,共计5150字。
转载说明:除特殊说明外本站文章皆由果较瘦原创发布,转载请注明出处。