运维知识
悠悠
2026年11月13日

别再半夜爬起来查服务器了,这套 Prometheus 监控照着抄就能跑

如果你现在还靠人肉盯服务器,靠用户打电话告诉你"系统挂了",那这篇你认真看,能帮你把半夜接电话这事给戒了。

我今天讲的这套东西,就是我上个月搭的,开源的 Prometheus 那一套,一台服务器就够,没花一分钱。命令和配置文件我全给齐,你照着抄,一个下午就能在自己机器上跑起来。

先把这个认知掰过来:监控不是大厂才配拥有的东西。恰恰相反,小团队、一两个人管机器的,才更得靠监控。因为大厂出了事有值班的人扛,我们就这么几个人,机器半夜撂挑子,连个帮你背锅的都没有,电话一响就是你上。

还有人担心监控告警会把人搞得麻木,最后告警群变成没人看的死群。这个担心有道理,但根子不在监控,在你告警规则配得稀烂,什么都报、动不动就报。规则配好了,告警只会报真正要命的事。这个后面细说。

所以监控这事,我的态度就一句:不是做不做的问题,是早晚得做,早做早解脱。


说下这套监控的组成,其实就四样东西,别被名字唬住。

Prometheus 负责采集和存数据,是核心。Node Exporter 负责把服务器的 CPU、内存、磁盘、网络这些指标扒出来。cAdvisor 专门看容器级别的资源。最后 Grafana 负责把数据画成漂亮的图。告警这块再加个 Alertmanager,负责把 Prometheus 算出来的告警推送到微信、邮件这些地方。

看着组件不少,其实一条 docker-compose 就全起来了。我在 EulerOS 上跑的,你用 CentOS、Ubuntu 都一样,这套东西跟系统发行版关系不大,有 Docker 就成。

第一步装 Docker,命令直接抄:

sudo yum update -y
sudo yum install -y docker-ce docker-ce-cli containerd.io
sudo systemctl enable --now docker

Ubuntu 就把 yum 换成 apt。装完再装 docker-compose:

sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

接着建工作目录:

mkdir -p /data/monitoring/{prometheus,alertmanager,grafana/data}
cd /data/monitoring

这里插一句,目录名你最好就按这个来,别乱改。因为 compose 文件里的挂载路径都是相对这个目录算的,你改了名字,容器一启动就报挂载失败,那个报错还特别隐晦,够你查半天的。


接下来是配置文件,这是整个监控的灵魂,也是多数人卡壳的地方。

第一个是 Prometheus 主配置,决定它去抓哪些指标:

global:
  scrape_interval: 15s
  evaluation_interval: 15s

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

rule_files:
  - "/etc/prometheus/rules/*.yml"

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

  - job_name: 'node'
    static_configs:
      - targets: ['node-exporter:9100']

  - job_name: 'cadvisor'
    static_configs:
      - targets: ['cadvisor:8080']

盯一下 targets 里写的那些地址,是 node-exporter:9100 这种服务名,不是 IP。因为它们都在同一个 docker 网络里,容器之间直接用服务名就能互通。你要是照网上某些教程填 localhost 或者 IP,到这一步就抓不到数据了,还查不出为什么,我头一回就栽在这。

第二个是告警规则文件。这就是"告警麻不麻木"的关键所在。我一开始图省事配了一堆规则,上线当天告警跟放鞭炮似的,一条 CPU 高、一条内存紧,我在群聊里刷了十分钟,当场关掉大半。

后来学乖了,规则少而精,只留真正要命的,而且都加持续时间阈值,避免那种抖一下就误报的。贴两条核心的:

groups:
  - name: host_and_container_alerts
    rules:
      - alert: HostCpuUsageHigh
        expr: (1 - avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) by (instance)) * 100 > 85
        for: 2m
        labels:
          severity: warning
        annotations:
          summary: "主机 CPU 使用率过高"
          description: "CPU 连续2分钟超过 85%"

      - alert: ContainerMemoryUsageHigh
        expr: (container_memory_usage_bytes{container!=""} / container_spec_memory_limit_bytes{container!=""} > 0.85)
        for: 3m
        labels:
          severity: critical
        annotations:
          summary: "容器内存告警"
          description: "容器内存使用率已超 85%,存在 OOM 风险"

注意那个 for: 2m,这就是防抖的关键。CPU 飙一下又掉下来,不算事,得连续两分钟超了才真报。这个时间你设短了,就等着被误报刷屏。


第三个是重头戏,docker-compose.yml,整个监控栈的骨架,直接建文件粘进去:

version: '3.8'

services:
  prometheus:
    image: prom/prometheus:v2.48.0
    container_name: monitoring-prometheus
    restart: unless-stopped
    volumes:
      - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
      - ./prometheus/rules:/etc/prometheus/rules:ro
      - prometheus_data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
      - '--web.enable-lifecycle'
    ports:
      - "9090:9090"
    networks:
      - monitor-net

  node-exporter:
    image: prom/node-exporter:v1.7.0
    container_name: monitoring-node-exporter
    restart: unless-stopped
    volumes:
      - /proc:/host/proc:ro
      - /sys:/host/sys:ro
      - /:/rootfs:ro
    command:
      - '--path.procfs=/host/proc'
      - '--path.sysfs=/host/sys'
      - '--path.rootfs=/rootfs'
    ports:
      - "9100:9100"
    networks:
      - monitor-net

  cadvisor:
    image: gcr.io/cadvisor/cadvisor:v0.47.2
    container_name: monitoring-cadvisor
    restart: unless-stopped
    privileged: true
    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"
    networks:
      - monitor-net

  grafana:
    image: grafana/grafana:10.2.0
    container_name: monitoring-grafana
    restart: unless-stopped
    ports:
      - "3000:3000"
    volumes:
      - ./grafana/data:/var/lib/grafana
    environment:
      - GF_SECURITY_ADMIN_USER=admin
      - GF_SECURITY_ADMIN_PASSWORD=HuaweiCloud@2026
    networks:
      - monitor-net

networks:
  monitor-net:
    driver: bridge

volumes:
  prometheus_data:

Alertmanager 那段我先省了,因为告警推送要配微信机器人、邮箱这些,因人而异,而且一次给你太多容易乱。等前面跑通了,再单独补 Alertmanager,思路是一样的。

还有个坑提前说:cAdvisor 配了 privileged: true,这是它要读宿主机 /sys 这些目录,必须开特权。有些安全扫描器会因为这个标红,但监控容器不开特权就抓不到容器数据,这个你得跟安全的人解释清楚,不是啥都能一刀切关掉的。


文件备齐了,一条命令启动:

docker-compose up -d
docker-compose ps

起来之后别急着看 Grafana,先开 http://你的IP:9090/targets 确认采集正常。会看到 prometheus、node、cadvisor 三个 target,状态都得是绿色 UP。哪个是红色 DOWN,多半是网络或挂载的问题。

我头一回就卡在这,cadvisor 一直 DOWN,查了老半天,结果根子是那个 gcr.io 的镜像拉不下来。国内环境嘛。后来换了个镜像源才解决,这个提前给你打个预防针。

采集正常了再开 http://你的IP:3000,用 compose 里设的账号密码登录。然后三步:

  1. 加数据源,类型选 Prometheus,URL 填 http://prometheus:9090。
  2. Dashboards 里导入官方模板,主机的用 1860,容器的用 14282。
  3. 保存,一整套大屏就出来了。

这俩 Dashboard ID 是 Grafana 社区现成的经典款,几万人在用,导入后 CPU、内存、磁盘、网络、容器图全自动画好,省你一天时间。


监控跑起来只是第一步。要上生产,还有几件事我吃过亏的,啰嗦几句。

第一,数据持久化。compose 里 Prometheus 数据存在命名卷 prometheus_data,默认只留 15 天。想多存点,加个 --storage.tsdb.retention.time=30d。别不当回事,我有次想回看半个月前的指标,发现早没了,那个懊恼。

第二,端口别乱暴露。Prometheus 的 9090 是没鉴权的,谁扫到都能看你监控数据。生产环境千万、千万、千万别把 9090 裸奔到公网。要么走内网,要么前面套 Nginx 做反向代理加 Basic Auth。我见过有人 9090 裸奔被扫,监控数据全让人看光了,比被入侵还尴尬。

第三,告警得真能送到你手上。Prometheus 配规则只是第一步,得让 Alertmanager 把告警推出去。我自己接的微信机器人,半夜告警直接推微信。别用邮件,半夜你也不会看邮件,微信你至少会瞄一眼。


总结一下。这套东西一个下午搭起来,你换回来的是:服务器出问题之前你先知道,而不是等用户来告诉你;半夜不用爬起来;老板问系统稳不稳,你能甩一张漂亮大屏,而不是干巴巴一句"还行"。

我一直觉得运维拼的不是救火多快,是让火根本烧不起来。监控就是你灭火器前面那道烟雾报警器,早装一天早安心一天。

照着搭的过程里卡壳了,评论区留言,我看到就回。踩到的坑也欢迎发出来,大家一起避一避。

觉得有用,点个赞、点个在看,转发给你那个总在半夜接电话的同事,说不定帮他少熬一个通宵。关注 @运维躬行录,后面接着写怎么配 Alertmanager 把告警推到微信、怎么拿这套监控做容量规划,都是能直接抄的干货。

公众号:耕云躬行录
个人博客:躬行笔记

文章目录

博主介绍

热爱技术的云计算运维工程师,Python全栈工程师,分享开发经验与生活感悟。
欢迎关注我的微信公众号@运维躬行录,领取海量学习资料

微信二维码