ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Prometheus + node_exporter 监控实践:从部署到告警的完整指南

Prometheus + node_exporter 监控实践:从部署到告警的完整指南 1. 监控这件事为什么我最终选了 Prometheus node_exporter先说点实在的。做运维和 DevOps 这行时间久了都会面对一个灵魂拷问服务器上到底跑着多少个进程内存是什么时候开始飙高的磁盘是不是又悄悄满了我见过太多人靠 SSH 登上去敲free -h、df -h一台一台看看完再拿 Excel 记一下。这种方式在只有三五台机器的时候没问题一旦规模到几十上百台人就废了。你需要的不是更多命令而是一个能替你盯着所有机器的“眼睛”。Prometheus 就是这套眼睛的核心。它是一个开源的监控系统和时序数据库专门用来采集、存储和查询各种指标数据。而 node_exporter 是 Prometheus 官方维护的一个采集器组件作用非常纯粹暴露 Linux 服务器本身的操作系统指标包括 CPU、内存、磁盘、网络、文件系统、负载等等。两个搭配起来就是你今天要搭的东西一台 Prometheus 服务器集中收集所有机器的指标每台被监控的机器上跑一个 node_exporter把系统状态变成可以查询的时序数据。这套方案解决的核心问题很明确不用再反复登服务器手动看资源历史数据能回溯出问题时光看曲线就能定位指标数据统一格式接入 Grafana 可视化非常方便后续加机器、加告警都很顺畅不用推倒重来这篇文章适合谁如果你刚接触监控或者已经在用 Zabbix 之类传统方案但觉得太重、想换换口味又或者手上正好有几台裸机/虚拟机想纳入监控下面的内容可以直接照着操作。我假设你已经有一台装了 LinuxCentOS 7/8 或 Ubuntu 18.04 都行的机器并且在上面安装了 Prometheus 主体程序。如果没有 Prometheus 主程序先按官方文档装好解压即用配置文件在prometheus.yml。我们下面所有配置都围绕这个文件展开。顺便说一句Prometheus 是开源项目但它在 GPL 许可下部分组件有自己的开源协议商业使用没问题这点不用纠结。接下来我从头到尾过一遍配置和踩坑记录尽量讲透“为什么这么做”而不是只丢给你一堆命令。2. 整体设计与方案选型为什么是这个组合而不是那套2.1 为什么不用 Agent 主动上报而是 Prometheus 主动拉取在设计监控方案的时候首先要面对一个方向性的问题数据是客户端主动上报到服务端还是服务端主动去客户端拉取主流的监控系统两种模式都有。Zabbix 的 Agent 是被动模式Server 去 Agent 上取数据Telegraf InfluxDB 则是 Agent 定时往 InfluxDB 写数据属于主动推送。Prometheus 走的是 pull 模型——每个抓取周期默认 15 秒Prometheus 服务器主动请求 node_exporter 暴露的 HTTP 接口拿数据。这个差异听起来不大但实际用起来区别很明显。pull 模型的优势是服务端完全掌控节奏数据要不要采、多久采一次由 Prometheus 说了算不会因为客户端疯狂上报把服务打爆。更实用的一点是——你只要访问curl http://被监控机IP:9100/metrics就能直接看到数据是否正常排查问题非常直观。当然 pull 模型也有个前提Prometheus 和被监控的机器必须在网络上是可达的。防火墙要放行 9100 端口安全组规则也要注意。这是新手最容易忽略的地方。2.2 node_exporter 和 Prometheus 的职责边界有人会问既然 Prometheus 能拉数据为什么不直接在 Prometheus 里加个模块收集系统信息还要多装一个 node_exporter原因在于职责分离。Prometheus 本身不关心“你暴露的是什么数据”它只负责按时间戳把这些数据抓过来、存进自己的时序数据库然后对外提供 PromQL 查询和告警计算能力。具体暴露什么数据、以什么格式暴露由各类 exporter 负责。这个设计的好处是生态极其丰富。想监控 MySQL 就装 mysqld_exporter监控 Redis 就装 redis_exporter监控网络设备就用 snmp_exporter。一套 Prometheus 核心搭配一堆 exporter能覆盖几乎所有监控需求。node_exporter 只是其中最基础、最常用的一款负责操作系统的通用指标但它的实现思路和所有 exporter 一致搞懂它其他 exporter 也就触类旁通了。2.3 监控架构里的三个关键角色整套组合装完你会看到三个不同的角色协同工作我习惯把它们形象地分成三层角色部署位置端口职责被监控服务器node_exporter每台需要监控的机器9100暴露操作系统原始指标Prometheus Server独立一台机器运行9090定时拉取指标、存储、查询、告警计算Grafana通常和 Prometheus 同机3000数据可视化把指标变成图表有条件的可以把第二层和第三层部署在独立机器上也可以用 Docker 把它们装在一起。在一开始实验阶段一台机器上同时跑 Prometheus 和 Grafana 完全没问题。3. node_exporter 部署实操从解压到开机自启3.1 下载与安装版本别乱选先从 GitHub 官方 Releases 下载。这里有一个版本选择的经验不要盲目追最新版也不用太纠结旧版。node_exporter 的更新频率不高选一个如 1.7.0 / 1.8.2 之类的 stable 版本即可新特性对你日常监控没有太大影响但稳定性优先。下载链接类似这样wget https://github.com/prometheus/node_exporter/releases/download/v1.8.2/node_exporter-1.8.2.linux-amd64.tar.gz下载完解压tar xvf node_exporter-1.8.2.linux-amd64.tar.gz cd node_exporter-1.8.2.linux-amd64里面就一个二进制文件node_exporter把它放到/usr/local/bin/下cp node_exporter /usr/local/bin/这个二进制是编译好的不依赖任何额外的运行环境也不需要装 Python 或者别的什么依赖。放到环境变量目录里即可全局执行。如果你是在华为云、腾讯云之类国内机器上GitHub 下载可能会很慢。此时有两个办法用代理下载或者去国内镜像源比如一些云的软件镜像仓库查找对应的 rpm 包。每个环境网络情况不一样这里不再展开。3.2 用 systemd 管好它别直接 nohup 后台跑很多新手习惯nohup ./node_exporter 这么裸跑但这样有几个隐患进程意外退出没人管、机器重启不会自动拉起、日志管理也不规范。我建议直接用 systemd service 管理三步就搞定。创建/etc/systemd/system/node_exporter.service文件内容如下[Unit] DescriptionPrometheus Node Exporter Afternetwork.target [Service] Typesimple Usernode_exporter Groupnode_exporter ExecStart/usr/local/bin/node_exporter \ --web.listen-address:9100 \ --web.config.file/etc/node_exporter/web.yml Restarton-failure RestartSec5s [Install] WantedBymulti-user.target这里有几个配置项值得说清楚Usernode_exporter建议创建一个专用系统用户不要用 root 跑 exporter。虽然 node_exporter 需要读取系统/proc等文件但以普通用户组身份读取大多数指标没问题安全性更好。创建用户的命令useradd -M -s /usr/sbin/nologin node_exporterRestarton-failure和RestartSec5s保证进程挂掉后能自动拉起这是 systemd 管理进程的核心价值。--web.listen-address:9100监听所有网卡上的 9100 端口。如果只希望本机访问可以换成--web.listen-address127.0.0.1:9100但要注意 Prometheus 如果装在其他机器上就无法拉取了。--web.config.file这一行是可选的用来配置 HTTP basic auth。如果不打算开启认证可以删掉这行。写好 service 文件后依次执行systemctl daemon-reload systemctl enable node_exporter systemctl start node_exporter systemctl status node_exporterenable确保开机自启start立即启动status用来确认状态。看到active (running)就说明起来了。3.3 验证是否真的在采集数据node_exporter 起来后用 curl 直接访问它的 metrics 接口curl http://127.0.0.1:9100/metrics | head -50你会看到一堆形如# HELP、# TYPE和node_xxx指标。# HELP是说明文字# TYPE是指标类型counter、gauge、histogram 等剩下的就是真正的指标了。比如# HELP node_cpu_seconds_total Seconds the cpus spent in each mode. # TYPE node_cpu_seconds_total counter node_cpu_seconds_total{cpu0,modeidle} 2.0285912e06 node_cpu_seconds_total{cpu0,modesystem} 5342.66从这里就能确认 exporter 工作正常。如果 curl 不到先检查服务状态、再检查防火墙端口是否放行firewall-cmd --list-ports # 或 iptables -L -n放行 9100 端口firewall-cmd --zonepublic --add-port9100/tcp --permanent firewall-cmd --reload这一步是最常见的坑90% 的“我明明配好了但 Prometheus 拉不到数据”都是防火墙导致的。4. 配置 Prometheus 拉取 node_exporter 指标4.1 prometheus.yml 核心配置拆解Prometheus 的配置都在默认的prometheus.yml里。打开它默认有一个scrape_configs段落里面定义了一组 job。你要做的是把 node_exporter 的地址加进去。一个典型的配置如下global: scrape_interval: 15s evaluation_interval: 15s scrape_configs: - job_name: node_exporter static_configs: - targets: [192.168.1.10:9100, 192.168.1.11:9100] labels: env: production这里解释几个关键点scrape_interval: 15s全局抓取间隔意思是 Prometheus 每 15 秒到目标地址拉一次数据。evaluation_interval: 15s告警规则计算周期。这两项可以不同但通常保持一致。job_name这个抓取任务的名字会在 Prometheus 内部和 Grafana 图表里作为标签出现取有意义的名字方便后续查询过滤。static_configs.targets被监控机器的 IP 加端口列表。可以写多个Prometheus 会逐个抓取。labels可选字段给这批目标统一加上自定义标签。我习惯加env: production后续在查询或告警匹配时就能区分不同环境的机器。修改后需要重启 Prometheus 才能生效systemctl restart prometheus或者如果你直接用二进制跑就 kill 再重新启动进程管理方式自己掌握。4.2 在 Targets 页面确认抓取状态启动后打开 Prometheus 自带的 UIhttp://你的PrometheusIP:9090/targets。这里会列出所有配置的抓取目标并给出状态。正常状态是绿色的UP。如果你看到的是红色的DOWN点开详情会有报错信息基本上是下面几种情况Get http://x.x.x.x:9100/metrics: dial tcp ... connection refused说明目标機器的 node_exporter 没启动或者端口不是 9100context deadline exceeded网络不通多半是防火墙或在防火墙安全组层面被拦截。502 Bad Gateway少见一般和目标机器反向代理有关。很多朋友看到这里的 endpoint 是http://IP:9100/metrics就以为 Prometheus 在访问一个完整的 URL。实际上它确实就是在做这个事——拉取就是 HTTP GET 请求。这也是为什么你本地 curl 通了Prometheus 就一定通。4.3 用 PromQL 直接验证一下采集结果Targets 页面显示 UP 说明抓取链路是通的但为了确认数据真的入库了切到 Prometheus 的Graph页面在输入框输入一个最简单的查询up{jobnode_exporter}这个up指标是一个特殊的内部指标值为 1 表示目标正常0 表示目标挂了。如果查询结果出现一条值为 1 的线恭喜你数据已经在正常流转了。再试几个常用查询node_memory_MemTotal_bytes node_cpu_seconds_total{modeidle} node_filesystem_avail_bytes{fstype!~tmpfs|overlay}输入后点 Execute图表区域会出现数据。到这里你可以确定node_exporter - Prometheus 这条链路完全打通。5. 指标到底有哪些核心字段逐一解读很多新手配通了链路就开始用 Grafana 画图但画了半天不知道每个指标是什么意思。为了以后排查问题不吃亏我把 node_exporter 最重要的几组指标整理了一下。5.1 CPU、内存在 PromQL 里的正确打开方式node_exporter 暴露的 CPU 指标是node_cpu_seconds_total是一个 counter 类型累计值按 cpu 核心数和 modeuser、system、idle、iowait 等分开统计的。直接看这个值意义不大因为它只会无限增长。要看 CPU 使用率你得用rate()函数计算变化速率100 - (avg by (instance) (rate(node_cpu_seconds_total{modeidle}[5m])) * 100)这条查询的意思是取过去 5 分钟内idle空闲模式 CPU 时间的变化速率这个值代表 CPU 空闲的百分比用 100 减去它得到的就是 CPU 使用率。关键是rate()函数——它接收一个 counter 指标和一段时间窗口计算出每秒的平均变化量。内存指标相对直接node_memory_MemTotal_bytes是总内存node_memory_MemAvailable_bytes是可用内存。注意 1.8 版本建议优先用MemAvailable_bytes而不是计算MemFree_bytes因为后者不考虑缓存回收会导致把明明可以释放的缓存当成了已用内存。常见的内存使用率查询(1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 1005.2 磁盘和网络指标要注意单位换算磁盘相关的核心指标有node_filesystem_size_bytes总容量、node_filesystem_avail_bytes可用容量、node_filesystem_used_bytes已用容量。它们都带有一堆 labels 比如mountpoint、fstype、device。注意不要统计 tmpfs、overlay 这些虚拟文件系统所以我在上面的查询里加了过滤条件。磁盘使用率查询(node_filesystem_size_bytes - node_filesystem_avail_bytes) / node_filesystem_size_bytes * 100网络指标主要是node_network_receive_bytes_total和node_network_transmit_bytes_total是两个 counter。查看某个网卡比如 eth0的实时速率rate(node_network_receive_bytes_total{deviceeth0}[1m])这个数据经常被用于画出流量曲线排查链路拥塞问题时很管用。5.3 其他值得关注的指标node_load1 / node_load5 / node_load15系统负载表示 1 分钟、5 分钟、15 分钟内的平均活跃进程数。负载高不一定说明 CPU 满也可能是 IO 等待要结合 CPU 指标一起看。node_processes当前进程数能快速发现进程数量异常暴涨。node_time_seconds系统时钟如果服务器时间漂移大监控数据的时序也会出问题值得盯一眼。node_reboot_required内核更新后是否需要重启这个指标在运维大版本升级时会用到。6. 接入 Grafana让数据真正“看起来”6.1 数据源配置与仪表板导入Prometheus 自带的表格和简单图形只能说是“能用”真正把监控数据变得直观还是得靠 Grafana。Grafana 是一个开源的可视化平台支持非常多的数据源Prometheus 是它的原生支持对象之一。假设你已经装好了 Grafana这东西也是解压即用或者用 Docker 跑打开浏览器访问 3000 端口默认账号密码是admin/admin首次登录会提示改密码。配置数据源的步骤打开左侧齿轮图标里的 “Data Sources”点 “Add data source”选择 “Prometheus”在 URL 栏填http://localhost:9090如果 Grafana 和 Prometheus 不在同一台机器填 Prometheus 的实际 IP拉到下方点 “Save Test”页面会提示连接成功关键一步Grafana 本身不存监控数据它只是把 Prometheus 当数据库来查询。所以数据源配置里的 URL 必须保证 Grafana 能访问到 Prometheus 的 9090 端口。6.2 快速拿到一套能用的仪表板Grafana 有一个官方共享平台叫 Grafana Dashboards上面有大量别人做好的仪表板 JSON可以一键导入省去从头画图的时间。对 node_exporter 来说最经典的是 ID 为1860的仪表板名字是 “Node Exporter Full”包含 CPU、内存、磁盘、网络、负载几乎所有常见图表。导入方法鼠标悬停左侧 “” 号选 “Import”在输入框里填1860点 “Load”在弹出来的页面里Prometheus 数据源选你刚才配置的那个点 Import 完成需要注意有些仪表板预设的指标名称和你当前 node_exporter 版本不兼容。特别是老版本的仪表板还在用node_cpu这种旧指标名而新版本 node_exporter 已经是node_cpu_seconds_total了。导入后如果看到图表全是 “No data”第一反应就是去检查仪表板里的 PromQL 查询是否匹配当前指标名。我个人比较推荐直接用 1860 或者 8919 这两个 ID它们都是社区里持续维护的版本兼容性比较好。6.3 按照自己的需求微调面板导入的仪表板终究是别人按通用场景做的实际使用中我会调整几个地方把仪表板变量里的$instance设置成默认值这样打开就展示所有机器的聚合情况。在单机视图里我习惯加一个“当前机器概览”的行把 CPU、内存、磁盘三个使用率做成 singlestat 面板数字大、醒目适合投到大屏上。磁盘使用率这块我会把虚拟文件系统过滤掉加一个fstype~ext4|xfs的条件避免一堆 tmpfs 干扰视觉。调整完记得右上角保存仪表板。以后每次开门看监控这些图就能直观看出一台机器的健康状况。7. 告警配置从“看监控”到“被监控喊醒”7.1 用 rules 文件定义规则别写在主配置里监控到位了如果出事没人知道那监控的意义就少了一半。Prometheus 的告警体系分为两部分规则负责判断什么时候该报警Alertmanager 负责发送发到哪、怎么发。本篇文章先把规则这块讲清楚。我习惯把规则单独放一个文件比如/etc/prometheus/rules/node.yml。然后在主配置prometheus.yml里引入rule_files: - rules/node.yml这样做的目的是让规则文件独立修改规则的时候不用动主配置也便于用 git 管理。规则文件内容示例groups: - name: node_alerts rules: - alert: InstanceDown expr: up{jobnode_exporter} 0 for: 1m labels: severity: critical annotations: summary: Instance {{ $labels.instance }} down description: {{ $labels.instance }} 已停止上报指标持续超过1分钟 - alert: HighCpuUsage expr: 100 - (avg by (instance) (rate(node_cpu_seconds_total{modeidle}[5m])) * 100) 90 for: 5m labels: severity: warning annotations: summary: High CPU usage on {{ $labels.instance }}规则里最重要的几个字段expr触发条件写的是 PromQL 表达式返回有结果就触发。for持续多久才触发。避免瞬时抖动导致误报这个值很实用。labels给告警打标签后面 Alertmanager 可以根据 severity 不同走不同的通知策略。annotations告警消息的内容模板用{{ $labels.instance }}可以动态带入实例地址。配置完重启 Prometheus然后在 UI 的 “Alerts” 页面就能看到规则列表。如果规则语法有问题Prometheus 启动日志里会直接报错启动时注意看一眼。7.2 关于 Alertmanager 的一句话说明真正把告警发到钉钉、邮件、飞书需要单独部署 Alertmanager 并配置 receiver。部署方式类似 Prometheus下载解压即可。然后在prometheus.yml里添加alerting: alertmanagers: - static_configs: - targets: [localhost:9093]本文不展开 Alertmanager 的告警通道配置那是另一个比较大的主题。但至少先把规则配上后面接 Alertmanager 就是水到渠成的事。8. 常见问题与避坑技巧实录8.1 高频问题速查表这段时间我帮不少同事排过 node_exporter 配置的问题把最常遇到的整理成一个表现象可能原因解决办法Prometheus Targets 显示 DOWNnode_exporter 未启动systemctl status node_exporter检查状态Targets 显示 DOWNcurl 也连不上防火墙拦了 9100 端口firewall-cmd --add-port9100/tcp --permanent并 reloadcurl 本机通但 Prometheus 不通监听地址限制在 127.0.0.1启动参数改为--web.listen-address:9100数据能采但 Grafana 面板全是 No data旧版仪表板用了老指标名修改面板 PromQL匹配node_*_seconds_total新格式node_exporter 启动报权限错误用了非 root 用户但没有相应读取权限确认/proc和/sys可读或把 user 设为有权限的用户9100 端口被占用已有其他实例跑着换端口或 kill 旧进程Prometheus 存储目录磁盘满了指标数据量过大调整retention.time限制保留周期8.2 几个值得单独说几句的坑第一个坑别把 node_exporter 装在 Docker 里就跑以为万事大吉。容器里的/proc和/sys默认不是宿主机的数据会非常不准。如果一定要容器化需要挂载-v /proc:/host/proc:ro并配置--path.procfs/host/proc之类的参数麻烦且容易踩坑。我的建议是物理机/虚拟机直接装二进制最省心。第二个坑生产环境务必加上 systemd 的Restarton-failure。我遇到过 node_exporter 因为内核升级或其他原因进程突然退出如果没有自动重启Prometheus 会一直显示 DOWN直到有人发现。加上自动重启后基本能保证这个采集器“隐身”——平时感受不到它的存在才是最好的监控状态。第三个坑Prometheus 的存储容量不要忽略。默认情况下数据保留 15 天但我曾经遇到一台机器因为指标量太大磁盘直接被打满的情况。经验做法是在启动参数里加上--storage.tsdb.retention.time30d --storage.tsdb.retention.size20GB这样既限制了时间也限制了最大容量磁盘占用就不会失控。node_exporter 本身指标不算多但如果你以后加了 mysqld_exporter、blackbox_exporter 一大堆数据量就会明显上涨。第四个坑tls 或者认证别急着加。node_exporter 支持通过--web.config.file开启 basic auth 和 HTTPS但新手阶段建议先裸跑等链路都通了再考虑安全加固。否则排查问题时会多一层干扰。当然如果跑在公网上务必要加认证或者用防火墙把端口限制在内网。8.3 我实测下来的部署顺序为了让后面的朋友少走弯路我把整个部署顺序重新梳理一遍按这个顺序来基本一套通过在目标机器上安装 node_exporter 并启动curl 验证 metrics 接口在 Prometheus 机器上确认网络连通用 telnet 9100 或者 curl 目标端口修改 prometheus.yml 加 job重启并到 /targets 页面确认 UP在 Prometheus 页面跑一条 PromQL 确认数据入库部署 Grafana加数据源导入仪表板写告警规则文件在 Alerts 页面验证规则生效每一步都验证完再进下一步这样出了问题你能清楚地知道坏在哪一层。9. 小技巧分享让监控更省心的一点心得最后再分享几个我平时用了很久的小技巧不一定写在官方文档里但实打实提升效率。第一给 node_exporter 的 systemd unit 添加一个 drop-in 文件来传额外的启动参数而不要直接改主 unit 文件。比如以后想改 metrics 路径建一个/etc/systemd/system/node_exporter.service.d/override.conf写到里面去主程序升级更新时不受影响。第二采集到的指标里有一个node_uname_info记录了主机名、内核版本、操作系统信息。这个指标不用专门做查询但偶尔排障时很有用——通过它你可以直接从 Prometheus 里查到所有被监控机器的系统信息省得登录机器看uname -a。第三不要只盯 Usage使用率多看看 Saturation饱和程度和 Error错误数。CPU 使用率 80% 不一定说明有问题但如果 load average 长时间是 CPU 核数的 2 倍以上那就说明队列已经排出去了性能开始劣化。这种从 Google SRE 书里学来的思路比单纯设一堆阈值告警有价值得多。监控这件事搭起来只需要一天但真正让它发挥作用的是后续的持续调优加机器、调告警阈值、看趋势做容量规划。node_exporter 只是第一步但它是最扎实的一步。希望你照着这篇文章配完能看到所有目标都是绿色的 UP那就说明你已经迈入“用数据运维”这条赛道了。
返回列表