
能感知到很多人对服务器监控这块的需求一直很旺盛尤其是那些手里有几台Linux服务器想实时掌握CPU、内存、磁盘、网络状况又不想被各种商业监控软件绑架的朋友。这套Prometheus Node_exporter Grafana组合基本是开源生态里最成熟、资料最多的黄金搭配了。我最早接触这套方案是给一组混合架构的业务机做资源水位分析当时对比过Zabbix和轻量面板最后还是选了这套组合原因后面讲。这篇东西我尽量写得细一点从零开始把Linux安装部署的每一步、每一个坑都讲透你照着敲命令基本就能跑起来。1. 监控方案选型与整体架构理解1.1 为什么是Prometheus Node_exporter Grafana先聊聊选型。很多人纠结选Zabbix还是Prometheus在我看来这两者路线完全不同。Zabbix诞生得早走的是监控一切的路子从网络设备、服务器到应用它都有对应的agent或者协议支持适合传统IT运维团队一个控制台管几百上千台机器。但Zabbix的痛点也很明显部署相对笨重依赖数据库MySQL/PostgreSQL自定义告警和展示逻辑学习曲线陡峭而且对云原生环境、动态扩缩容的适配性不如Prometheus。Prometheus则是生而为了云原生监控而设计的它的核心思想是“拉取模型”——监控服务主动到每个被监控目标上抓取指标数据不需要被监控端主动上报。这种设计让它天然适应动态变化的服务发现场景比如Kubernetes里一个Pod的IP随时变Prometheus可以通过服务发现机制自动找到新目标。再加上它自带的时序数据库能力一套二进制就能跑起来部署成本极低。Node_exporter是Prometheus生态里专门用来采集主机指标的采集器它暴露一个HTTP端点Prometheus定期从这个端点拉取数据采集项涵盖了CPU、内存、磁盘、网络、文件系统、系统负载等基本覆盖了日常服务器巡检的所有核心指标。Grafana则是负责把Prometheus里的时序数据变成直观图表。它最厉害的地方在于支持非常丰富的数据源类型Prometheus只是其中之一你以后想接Zabbix数据、MySQL数据、ES数据都能在同一个Grafana里看。所以这套组合的定位是从数据采集Node_exporter、到数据存储与查询Prometheus、再到数据可视化Grafana三者职责单一又各自聚焦替换成本也低。1.2 组件分工与数据流向理解这套监控体系核心就一句话Node_exporter负责暴露指标Prometheus负责拉取和存储指标Grafana负责把指标画成图表。具体数据流向是这样的你在每一台需要监控的Linux服务器上运行一个Node_exporter进程它默认监听9100端口。然后你的Prometheus服务器配置好要抓取的目标列表每隔固定间隔默认15秒向目标服务器的9100端口发出HTTP请求拿到一堆key-value形式的指标数据比如node_cpu_seconds_total、node_memory_MemTotal_bytes这些。Prometheus把这些数据按照时间戳存储在本地时序数据库中按配置的保留周期滚动清理。当你想看数据时通过Grafana去查询PrometheusPrometheus执行PromQL查询语句返回结果Grafana负责渲染成图表。这里有一个非常重要的架构理解Prometheus更像一个数据中心而不是传统意义上的Agent管理端。它不要求被监控的机器安装统一认证的agent只要目标端点能返回符合规范的metrics格式文本它就能采集。这也是为什么Prometheus能监控很多网络设备、中间件、数据库的原因——只要对方能暴露metrics接口就能纳入监控。提示Node_exporter不是唯一的采集器Prometheus生态里有针对MySQL的mysqld_exporter、针对Redis的redis_exporter、针对黑盒探测的blackbox_exporter等。理解了这套架构以后扩展其他监控目标思路完全一致。2. Linux环境准备保姆级基础配置2.1 服务器基本要求与系统检查先明确一下这套监控方案对服务器配置要求不高。以我实际部署的经验来说Prometheus单机版内存建议至少2GB磁盘根据保留周期来定一天的数据量大概是几百MB到1GB不等取决于你有多少个采集目标、采集频率多高。Node_exporter就非常轻量了1核1GB的机器跑它几乎可以忽略资源占用官方二进制只有几MB大小。Grafana的内存占用稍微大一点通常在100MB到300MB之间因为要跑前端服务和缓存。本教程以CentOS 7.9和Ubuntu 20.04为例这两套系统在实际生产环境中占比最高。CentOS虽然官方停止了维护但由于存量太大很多公司还在用所以讲一下也无妨。Ubuntu则是目前主流的替代选择尤其是国产化替代背景下不少企业转向了基于Debian的发行版。检查系统信息使用cat /etc/os-release free -h df -h nproc这几个命令分别查看系统版本、内存、磁盘、CPU核数。部署前最好确认一下这些基础资源尤其是磁盘空间不要太紧张否则Prometheus跑几天就可能因为磁盘写满而停止抓取这个坑我踩过后面在常见问题里细说。2.2 关闭防火墙干扰与SELinux很多人在安装完Node_exporter后发现Prometheus那边怎么都抓不到数据十个有八个是防火墙挡了。这里有两种处理思路一是开放指定端口二是直接关闭防火墙仅推荐在内网环境试。我建议按需开放端口更安全。CentOS 7以上的系统默认开启了firewalld操作命令如下# 对外开放端口 firewall-cmd --permanent --add-port9100/tcp firewall-cmd --permanent --add-port9090/tcp firewall-cmd --permanent --add-port3000/tcp firewall-cmd --reloadUbuntu系统默认使用的是ufw命令略有不同sudo ufw allow 9100/tcp sudo ufw allow 9090/tcp sudo ufw allow 3000/tcp sudo ufw reload如果你的环境本来就没有开启防火墙或者觉得管理麻烦可以用下面命令查看状态确认它是关闭的systemctl status firewalld # 或者 sudo ufw statusSELinux是CentOS上另一个容易卡人的东西。默认的enforcing模式会限制进程访问网络端口不少新手在这个问题上折腾一整天。如果确认是测试环境我建议直接关闭生产环境则建议放行相关端口或者按官方文档配置SELinux策略。# 临时关闭 setenforce 0 # 永久关闭编辑/etc/selinux/config把SELINUXenforcing改成SELINUXdisabled sed -i s/SELINUXenforcing/SELINUXdisabled/g /etc/selinux/config2.3 常用工具安装与时间同步部署过程中会用到wget、curl、tar这些基础工具绝大多数系统默认已经安装了没装的话先用包管理装一下。# CentOS yum install -y wget curl tar vim # Ubuntu sudo apt update sudo apt install -y wget curl tar vim时间同步是一个容易被忽略的关键点。Prometheus存储的是带时间戳的时序数据如果服务器时间不准画出来的图表会非常诡异——要么数据点对不上要么曲线断断续续。生产环境强烈建议配置NTP或chrony时间同步。# CentOS 7 yum install -y ntpdate ntpdate -u ntp.aliyun.com # Ubuntu sudo apt install -y ntpdate sudo ntpdate -u ntp.aliyun.com有条件的话可以直接用chrony它是新一代的时间同步服务精度更高配置也更灵活。不管用什么工具基本原则就是确保所有被监控机器和Prometheus服务器的时间保持一致偏差最好不要超过1秒。3. 安装部署Node_exporter、Prometheus、Grafana全流程3.1 Node_exporter安装与注册为系统服务Node_exporter是三者中最好部署的因为它就是一个单独的二进制文件解压即用。官方下载页面在GitHub的prometheus/node_exporter仓库下建议下载linux-amd64版。我是按当前版本1.8.2来写的你实际操作时可以去Release页面看最新版本号。# 创建专用的运行目录 mkdir -p /opt/node_exporter cd /opt/node_exporter # 下载二进制包注意替换版本号 wget https://github.com/prometheus/node_exporter/releases/download/v1.8.2/node_exporter-1.8.2.linux-amd64.tar.gz tar -xzf node_exporter-1.8.2.linux-amd64.tar.gz mv node_exporter-1.8.2.linux-amd64/node_exporter .直接跑后台进程也可以但为了便于开机自启和进程管理我强烈建议注册为systemd服务。vim /etc/systemd/system/node_exporter.service写入以下内容[Unit] Descriptionnode_exporter Afternetwork.target [Service] Typesimple ExecStart/opt/node_exporter/node_exporter Restartalways RestartSec3 [Install] WantedBymulti-user.target然后启动服务并验证systemctl daemon-reload systemctl enable --now node_exporter systemctl status node_exporter这里有一个经验分享Node_exporter默认绑定在所有网卡上如果你想只允许内网访问可以加--web.listen-address参数来指定IP和端口比如ExecStart/opt/node_exporter/node_exporter --web.listen-address192.168.1.10:9100。另外Node_exporter会暴露大量内核参数指标如果某些指标涉及敏感信息不想被外部获取可以在前面再加一层反向代理或者防火墙限制。验证是否采集成功在本地curl一下指标端点curl http://localhost:9100/metrics | head -50如果能看到node_cpu_seconds_total、node_memory_MemTotal_bytes这些指标输出说明Node_exporter工作正常。这些指标会被Prometheus以node_前缀收录后续在Grafana里引用时也是基于这些指标名。3.2 Prometheus主服务安装与配置抓取任务Prometheus是整套监控的核心负责定期抓取并存储所有采集器的指标数据。它的安装方式和Node_exporter类似都是解压即用。mkdir -p /opt/prometheus cd /opt/prometheus wget https://github.com/prometheus/prometheus/releases/download/v2.53.0/prometheus-2.53.0.linux-amd64.tar.gz tar -xzf prometheus-2.53.0.linux-amd64.tar.gz mv prometheus-2.53.0.linux-amd64/* .随后编辑Prometheus的核心配置文件prometheus.yml这里决定了它去哪些目标抓数据、多久抓一次、告警规则文件装在哪里。vim /opt/prometheus/prometheus.yml这是最简可用的配置global: scrape_interval: 15s # 默认抓取间隔 evaluation_interval: 15s # 规则评估间隔 scrape_configs: - job_name: prometheus static_configs: - targets: [localhost:9090] - job_name: node_exporter static_configs: - targets: - 192.168.1.10:9100 # 部署了Node_exporter的机器 - 192.168.1.11:9100 # 第二台机器以此类推注意Prometheus的抓取间隔不宜设置得太短。我见过有人为了追求实时性把scrape_interval设成1秒结果Prometheus的磁盘和内存消耗直线上升实际上大部分监控场景15秒抓一次已经够用了。如果需要更细粒度可以按job维度单独覆盖抓取间隔。把Prometheus也注册为systemd服务vim /etc/systemd/system/prometheus.service[Unit] DescriptionPrometheus Afternetwork.target [Service] Typesimple ExecStart/opt/prometheus/prometheus --config.file/opt/prometheus/prometheus.yml --storage.tsdb.path/opt/prometheus/data --storage.tsdb.retention.time30d Restartalways RestartSec3 [Install] WantedBymulti-user.target启动后访问http://服务器IP:9090/targets就能看到所有配置的抓取目标。这里会显示每个target的health状态如果为UP说明抓取正常如果为DOWN通常是网络不通、端口未开放、SELinux拦截等原因排查思路后面专门写。关于数据保留周期官方默认是15天。我通常在生产环境设置为30天甚至更长这个根据自己的磁盘空间和合规需求来定。需要注意的是数据保留时间和数据量是正相关的如果磁盘不大建议跑一周观察一下增长速度再决定要不要调整。3.3 Grafana安装与数据源接入Grafana的安装方式和前面两个不太一样它不建议用二进制包直接跑而是通过YUM或APT仓库安装这样升级维护都方便。不同发行版的操作代码如下。CentOS / RHEL系cat /etc/yum.repos.d/grafana.repo EOF [grafana] namegrafana baseurlhttps://rpm.grafana.com repo_gpgcheck1 enabled1 gpgcheck1 gpgkeyhttps://rpm.grafana.com/gpg.key sslverify1 sslcacert/etc/pki/tls/certs/ca-bundle.crt EOF yum install -y grafanaUbuntu / Debian系sudo apt-get install -y wget curl gnupg wget -q -O /tmp/grafana.gpg https://rpm.grafana.com/gpg.key sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/grafana.gpg /tmp/grafana.gpg echo deb https://packages.grafana.com/oss/deb stable main | sudo tee /etc/apt/sources.list.d/grafana.list sudo apt-get update sudo apt-get install -y grafana安装完成后启动服务systemctl daemon-reload systemctl enable --now grafana-server systemctl status grafana-server然后浏览器打开http://服务器IP:3000默认账号密码都是admin首次登录会强制改密码。改完密码进入主界面后第一步就是添加数据源——点击左侧齿轮Configuration→ Data Sources → Add data source选择Prometheus在URL栏填http://localhost:9090点击Save Test按钮。如果看到绿色提示“Successfully queried the Prometheus API”数据源就配置成功了。很多人问为什么Grafana填Prometheus地址时要用localhost:9090而不是服务器的实际IP这里其实涉及一个代理层面的理解。Grafana和Prometheus如果在同一台机器上填localhost没有问题如果不在同一台机器就要填Prometheus所在服务器的实际IP并且确保3000到9090端口的网络是通的。同时Prometheus的9090端口默认没有认证建议用防火墙限制访问来源或者前置一层反向代理加BASIC认证。4. 可视化配置与告警扩展4.1 导入现成仪表盘模板Grafana最让人喜欢的一点是它有庞大的模板市场你不需要从零画图表直接在Grafana官网上搜索现成的Dashboard模板。Node_exporter方向最经典的模板ID是8919这个模板叫“Node Exporter Full”图表非常齐全涵盖了CPU、内存、磁盘、网络、上下行、文件系统、系统负载等基本是开箱即用。导入方法很简单登录Grafana后点左侧“”号 → Import输入模板ID 8919点Load然后选择你的Prometheus数据源点Import就完事了。这时你应该就能看到一整排监控图表了。有一个小细节需要注意不同Node_exporter版本的指标名可能略有变化尤其是一些老的模板引用了已经废弃的指标导入后某些面板会显示No data。遇到这种情况不用慌点进对应面板的编辑页面看它查询语句里引用的指标名到Prometheus的图形界面9090端口打开Graph页面里用PromQL验证一下指标是否存在然后把指标名改成正确的即可。这类兼容性问题在小版本升级后偶尔会出现属于正常现象。4.2 自定义核心监控面板虽然现成模板够用但如果想要更贴合自己业务的面板还是得学会写简单的PromQL。这里分享几个我平时常用的查询你在Grafana的新建面板里可以直接用。CPU使用率百分比100 - (avg(rate(node_cpu_seconds_total{modeidle}[5m])) * 100)内存使用率(1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100磁盘使用率以根分区为例100 - (node_filesystem_avail_bytes{mountpoint/} / node_filesystem_size_bytes{mountpoint/} * 100)网络流入速率rate(node_network_receive_bytes_total[5m])这些PromQL语句看着复杂其实拆解一下就明白了。rate函数是计算一段时间的增长速率适合像CPU计数器、网络流量这种只增不减的指标。avg则是取平均特别是在有多核CPU时把每个核的使用率平均起来得到整体CPU水位。我建议新手先别急着自己造查询多看看8919模板里别人是怎么写的改改实例标签、调整一下时间范围慢慢就有感觉了。4.3 Alertmanager告警链路接入严格说Prometheus自带的告警能力很弱它只负责根据告警规则判断是否触发告警真正把告警通知到人比如邮件、钉钉、企业微信需要借助Alertmanager组件。这套链路可以简单理解成Prometheus算好“这条指标超过了阈值”推给AlertmanagerAlertmanager再做分组、抑制、静默最终把消息发到你配置的通知渠道上。Alertmanager的安装方式跟Prometheus类似下载二进制包解压即可。配置核心是alertmanager.yml文件里面需要声明你的接收端。以最简单的邮件告警为例global: smtp_smtp: smtp.qq.com:465 smtp_from: xxxqq.com smtp_auth_username: xxxqq.com smtp_auth_password: xxxxxx smtp_require_tls: false route: group_by: [alertname] group_wait: 30s group_interval: 5m repeat_interval: 4h receiver: email-notify receivers: - name: email-notify email_configs: - to: opsexample.com然后在Prometheus的prometheus.yml里加上alertmanager相关配置并编写告警规则文件比如groups: - name: node_alerts rules: - alert: 节点CPU使用率过高 expr: 100 - (avg(rate(node_cpu_seconds_total{modeidle}[5m])) * 100) 85 for: 5m labels: severity: warning annotations: summary: 服务器 CPU 使用率超过85%这套链路配置起来内容不少在监控系统搭建的第一阶段可以先放一放先把数据采集和展示跑通再慢慢加入告警。但架构上要知道Prometheus Alertmanager不是一体化的东西你后面要加告警思路和组件连接点是在这里。5. 常见问题与排查技巧实录部署过程中我积累了不少排错经验这些问题几乎每个新手都会遇到我把它们整理成了一个速查表你照着查基本能解决90%的问题。5.1 Prometheus显示Target DOWN这是最常见的现象。打开Prometheus的Targets页面发现某些节点是红色的DOWN状态。排查思路按顺序来第一步从Prometheus所在机器直接curl目标地址curl http://目标IP:9100/metrics如果curl超时或者连接拒绝问题就出在网络上。检查防火墙是否放行了9100端口检查目标机器上Node_exporter进程是否存活systemctl status node_exporter。如果curl能返回大量指标文本但Prometheus仍然显示DOWN那就看看Prometheus配置里的IP端口是否写错了常见错误是端口写成了9090或者漏了冒号。我还遇到过一种隐蔽情况Node_exporter绑定在IPv6地址上而Prometheus用的是IPv4地址去抓取导致始终连不上。这种情况在配置Node_exporter的--web.listen-address参数时要注意只监听IPv4地址就行比如0.0.0.0:9100。5.2 Grafana图表没有数据数据源测试是成功的但导入模板后图表全是No data。这个问题大概率是指标名不匹配。旧版Node_exporter和某些老模板引用的指标名可能对不上比如老版本有node_cpu这种指标新版本改成了node_cpu_seconds_total。排查方法是到Prometheus的Graph页面手敲几个指标名看有没有数据返回。比如输入node_memory_MemTotal_bytes回车如果能出数据点说明指标是存在的如果提示Empty query result就是指标名确实不对。修正方式是在Grafana面板的查询编辑器中替换成新指标名。另外时间范围也可能造成幻觉。如果Prometheus刚刚接入数据点还很少Grafana默认的now-6h时间范围可能查不到数据区间这时候可以把面板右上角的时间范围切换到last 5 minutes看看通常就有数据了。5.3 Prometheus内存和磁盘增长过快Prometheus的本地时序数据库对磁盘性能有一定要求数据量大了之后查询速度会明显下降。如果你发现服务器磁盘占用增长异常快第一看数据保留时间第二看抓取间隔第三看采集指标数量。优化思路有三个方向缩短数据保留周期--storage.tsdb.retention.time15d改成7d拉长抓取间隔从15s改成30s对日常监控影响不大如果机器数量非常多比如几百台可以考虑给Prometheus加远程存储或者采用联邦集群的方案把压力分散。内存方面Prometheus启动后会缓存大量内存中的热块如果可用内存小于2GB建议及时扩容。设置--storage.tsdb.min-block-duration和--storage.tsdb.max-block-duration也能微调块合并行为但对新手来说不必过度优化先保证资源够用再说。5.4 端口通但服务无法访问有时候检查了防火墙、确认了systemd服务正常但浏览器访问Grafana或者Prometheus页面就是打不开。这种情况在云服务器上要特别注意安全组的入方向规则很多云厂商的防火墙是独立于操作系统层面的需要在云控制台里也放行相应端口。在本地服务器上验证监听地址是否正常ss -tlnp | grep -E 9090|3000|9100如果监听地址是127.0.0.1说明进程只绑定在回环地址上外部当然访问不了。这时候需要修改配置文件或启动参数让服务监听在0.0.0.0或者具体的网卡IP上。5.5 采集到的指标数据忽高忽低、曲线不连贯这个问题几乎都是时间不同步导致的。我做第一套监控的时候就吃过亏明明各项配置都正确可画出的CPU曲线像锯齿一样乱跳。查了很久最后发现是其中一台机器的系统时间快了将近半分钟Prometheus抓到的时间戳和实际时间对不上导致数据点错位。解决办法就是在一开始就把所有机器的时间同步做好。可以参考前面说到的NTP或chrony最好统一用同一个时间源并且设置计划任务定期校准。crontab -e # 每天凌晨1点校准时间 0 1 * * * /usr/sbin/ntpdate -u ntp.aliyun.com /dev/null 215.6 需要监控多台机器的扩展方法如果你已经从一台机器扩展到几十台手工在prometheus.yml里一行行加IP显然太傻了。有两个比较常规的扩展方法一种是采用文件发现方式。在prometheus.yml的scrape_configs里用file_sd_configs指向一个json文件你只需维护这个文件里的targets列表Prometheus会定期自动加载变化无需重启服务。另一种是采用consul或者Kubernetes的服务发现机制这对动态环境更友好。比如云原生场景下Pod启停很频繁手工维护IP不现实这时服务发现的价值就体现出来了。我个人在中小规模环境几十台机器最常用的还是file_sd_configs方式简单又稳定不会引入额外的组件依赖。最后总结一点这套监控方案跑通了之后你基本上就有了一个可以无限扩展的监控基座。学会了这套组合后面再去接数据库指标、中间件指标、业务指标思路都差不多安装对应的exporter然后在Prometheus里加一个job最后到Grafana引数据画面板。我个人的体会是别急着一次性把告警、联邦架构、远程存储全都搞上先把一台机器从零跑到出图把组件之间的分工和指标流转逻辑吃透再慢慢加东西。这样哪怕以后出了问题你也能很快定位是采集端、存储端还是展示端的毛病。最后再分享一个小技巧在Prometheus的查询页面里输入node_前缀然后按Tab键会提示所有开头的指标名。这个功能在调试面板、排查指标名拼写错误时特别好用比瞎猜的快得多。