Ubuntu服务器上线后最容易忽略的不是初始部署,而是监控与告警体系的搭建。很多运维人员习惯等到服务不可用时才登录机器排查,这种方式在单机时代勉强可行,但在多节点、容器化、定时任务密集的环境下,问题发现往往滞后于业务影响。监控告警配置的核心不是装一个工具,而是建立一套“指标采集—阈值判断—通知触达—持续优化”的闭环。下面直接围绕Ubuntu服务器环境,给出可落地的配置方案和关键细节。
监控对象与指标选择
Ubuntu服务器的监控不能只看CPU和内存。一套有效的监控体系至少覆盖四类对象:系统基础资源、磁盘与I/O、网络连接状态、关键进程与服务。CPU方面要关注user、system、iowait、steal四个维度,单纯看总使用率会掩盖问题。例如iowait持续高于10%通常说明磁盘存在瓶颈,steal值在云服务器上异常升高代表宿主机资源争抢。内存监控要同时看free、available、swap usage,Ubuntu的swap使用策略受vm.swappiness参数影响,如果swap使用率突然上升,往往意味着物理内存不足或内存泄漏。磁盘监控必须包含空间使用率、inode使用率和磁盘I/O延迟,很多故障不是因为空间写满,而是inode耗尽或I/O等待队列过长。网络层面除了流量,还要监控TCP连接状态分布,特别是TIME_WAIT和CLOSE_WAIT的数量,CLOSE_WAIT堆积通常说明应用代码未正确关闭连接。进程监控建议按服务名配置,比如nginx、mysql、redis、php-fpm,检测进程是否存在、重启次数、内存占用趋势。
Prometheus与node_exporter部署
Ubuntu服务器监控的主流方案是Prometheus加node_exporter。node_exporter负责暴露主机指标,Prometheus负责抓取和存储,Alertmanager负责告警路由。安装node_exporter不需要编译,直接从官方发布页下载对应架构的二进制文件即可。以Ubuntu 22.04为例,可以执行以下步骤:
wget https://github.com/prometheus/node_exporter/releases/download/v1.7.0/node_exporter-1.7.0.linux-amd64.tar.gz tar -xzf node_exporter-1.7.0.linux-amd64.tar.gz sudo mv node_exporter-1.7.0.linux-amd64/node_exporter /usr/local/bin/ sudo useradd -rs /bin/false node_exporter
然后创建systemd服务文件/etc/systemd/system/node_exporter.service:
[Unit] Description=Node Exporter After=network.target [Service] User=node_exporter Group=node_exporter Type=simple ExecStart=/usr/local/bin/node_exporter --collector.systemd --collector.processes [Install] WantedBy=multi-user.target
启用并启动服务后,node_exporter默认监听9100端口。建议在防火墙中仅允许Prometheus服务器的IP访问该端口,不要对公网开放。node_exporter默认开启的collector已经覆盖大部分系统指标,但有些细节需要手动调整。例如需要监控systemd服务状态时,必须加上--collector.systemd参数;需要监控进程级指标时,加上--collector.processes。另外--collector.filesystem.mount-points-exclude可以用来排除临时文件系统,避免无意义的告警。
Prometheus配置与抓取规则
Prometheus服务器可以独立部署在一台Ubuntu机器上,也可以与被监控节点共用。生产环境建议独立部署,避免目标机器宕机后监控数据同时丢失。Prometheus的配置文件prometheus.yml中,scrape_configs部分定义抓取目标。一个典型的配置如下:
global:
scrape_interval: 15s
evaluation_interval: 15s
alerting:
alertmanagers:
- static_configs:
- targets: ['localhost:9093']
rule_files:
- "/etc/prometheus/alert_rules.yml"
scrape_configs:
- job_name: 'ubuntu-servers'
static_configs:
- targets: ['192.168.1.10:9100', '192.168.1.11:9100']
labels:
env: 'production'
region: 'cn-north'
scrape_interval设为15秒是比较平衡的选择,过短会增加Prometheus和目标节点的负载,过长则影响告警时效。对于关键业务机器,可以单独设置更短的抓取间隔。labels部分非常重要,后续告警分组和路由都依赖这些标签。建议从一开始就规范标签命名,至少包含环境、区域、角色三个维度。
告警规则设计原则
告警规则的质量直接决定运维人员是否会对告警产生疲劳。一条好的告警规则应该具备三个特征:指标明确、阈值合理、持续时间恰当。不要对瞬时抖动做告警,例如CPU使用率瞬间冲到90%又立即回落,这种告警没有意义。Prometheus的告警规则通过PromQL表达,配置在独立的rule_files中。下面给出几个Ubuntu服务器常用的告警规则示例:
groups:
- name: ubuntu-server-alerts
rules:
- alert: HighCPUUsage
expr: 100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 85
for: 5m
labels:
severity: warning
annotations:
summary: "实例 {{ $labels.instance }} CPU使用率过高"
description: "CPU使用率已超过85%持续5分钟,当前值为{{ $value }}%"
- alert: HighMemoryUsage
expr: (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100 > 90
for: 5m
labels:
severity: warning
annotations:
summary: "实例 {{ $labels.instance }} 内存使用率过高"
description: "内存可用率低于10%,当前使用率为{{ $value }}%"
- alert: DiskSpaceLow
expr: (node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"}) * 100 < 15
for: 2m
labels:
severity: critical
annotations:
summary: "实例 {{ $labels.instance }} 根分区空间不足"
description: "根分区可用空间低于15%,当前可用率为{{ $value }}%"
- alert: HighDiskIOWait
expr: rate(node_cpu_seconds_total{mode="iowait"}[5m]) * 100 > 10
for: 10m
labels:
severity: warning
annotations:
summary: "实例 {{ $labels.instance }} 磁盘I/O等待过高"
description: "iowait已超过10%持续10分钟,可能存在磁盘性能瓶颈"
- alert: ServiceDown
expr: node_systemd_unit_state{state="failed"} == 1
for: 1m
labels:
severity: critical
annotations:
summary: "实例 {{ $labels.instance }} 服务 {{ $labels.name }} 运行失败"
description: "systemd服务 {{ $labels.name }} 状态为failed,请立即检查"
这些规则中,for参数是防止误报的关键。CPU和内存类告警建议至少持续5分钟再触发,磁盘空间类可以缩短到2分钟,服务状态类1分钟即可。severity标签用于告警分级,critical级别的告警应该立即触达值班人员,warning级别可以聚合后定时发送。阈值设置要结合业务实际,例如数据库服务器的内存使用率长期在80%以上是正常的,如果按70%告警就会产生大量噪音。
Alertmanager告警路由与通知
Alertmanager负责接收Prometheus推送的告警,进行分组、去重、静默和路由。很多团队忽略Alertmanager的配置优化,导致告警通知混乱。Alertmanager的核心配置文件是alertmanager.yml,重点在于route和receivers两部分。一个生产可用的配置如下:
global:
resolve_timeout: 5m
smtp_smarthost: 'smtp.example.com:587'
smtp_from: 'alert@example.com'
smtp_auth_username: 'alert@example.com'
smtp_auth_password: 'your-password'
route:
group_by: ['alertname', 'instance']
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
receiver: 'default-email'
routes:
- match:
severity: critical
receiver: 'critical-email'
group_wait: 10s
repeat_interval: 1h
- match:
severity: warning
receiver: 'warning-email'
group_wait: 30s
repeat_interval: 6h
receivers:
- name: 'default-email'
email_configs:
- to: 'ops-team@example.com'
headers:
subject: '[监控告警] {{ .GroupLabels.alertname }}'
- name: 'critical-email'
email_configs:
- to: 'oncall@example.com'
headers:
subject: '[严重告警] {{ .GroupLabels.alertname }}'
- name: 'warning-email'
email_configs:
- to: 'ops-team@example.com'
headers:
subject: '[警告] {{ .GroupLabels.alertname }}'
group_by决定了哪些告警会合并到一条通知中。按alertname和instance分组可以避免同一台机器多个指标同时告警时发送多条邮件。group_wait是首次告警触发后的等待时间,用于收集同一组内的其他告警。group_interval控制同一组告警新增时的发送间隔。repeat_interval是重复发送间隔,critical级别建议1小时重复一次,warning级别6小时即可。如果通知渠道是企业微信或钉钉,可以使用webhook receiver,将告警内容以JSON格式推送到群机器人。
磁盘与inode专项监控
磁盘空间监控有一个常见误区:只监控根分区。Ubuntu服务器如果有独立的数据分区、日志分区或备份分区,每个分区都需要单独配置告警。node_exporter的node_filesystem_avail_bytes指标包含所有挂载点,但默认也会采集tmpfs、devtmpfs等临时文件系统。建议在告警规则中用mountpoint正则过滤,只监控真实磁盘分区。例如:
expr: (node_filesystem_avail_bytes{mountpoint=~"/|/data|/var/log"} / node_filesystem_size_bytes{mountpoint=~"/|/data|/var/log"}) * 100 < 20
inode耗尽比空间写满更隐蔽,因为df -h显示空间充足,但创建新文件会失败。inode告警规则如下:
expr: (node_filesystem_files_free{mountpoint="/"} / node_filesystem_files{mountpoint="/"}) * 100 < 10
for: 5m
inode使用率超过90%就需要关注,特别是邮件服务器、日志服务器这类会产生大量小文件的场景。另外建议对磁盘I/O延迟做监控,使用node_disk_io_time_seconds_total指标计算磁盘繁忙度,或者用node_disk_read_time_seconds_total和node_disk_write_time_seconds_total观察读写延迟趋势。I/O延迟持续升高通常是磁盘硬件老化的前兆。
进程与systemd服务监控
Ubuntu使用systemd管理服务,node_exporter的systemd collector可以采集所有unit的状态。node_systemd_unit_state指标有active、inactive、failed、activating等多个状态值。对于关键服务,建议配置两条规则:一条检测failed状态,一条检测服务意外停止。服务意外停止后systemd可能会自动重启,如果只监控failed状态,可能会错过服务反复重启的异常。可以通过监控node_systemd_unit_state{state="active"}的值变化来发现服务重启,或者使用changes指标。更直接的方式是监控进程数量,例如:
expr: sum by(instance) (node_processes{name="nginx"}) < 1
for: 1m
这条规则在nginx进程不存在时触发。但需要注意,node_exporter的processes collector默认只采集node_exporter自身进程,要采集其他进程需要开启--collector.processes参数,并且进程名必须与/proc/pid/comm中的名称完全一致。对于容器化部署的服务,进程监控方式需要调整,建议直接使用cAdvisor或容器平台的监控能力。
日志监控与关联告警
指标监控只能发现症状,日志监控才能定位根因。Ubuntu服务器的系统日志集中在/var/log目录,应用日志位置因服务而异。建议部署Loki或使用轻量级的日志采集工具,将关键错误日志纳入告警体系。例如监控/var/log/syslog中的OOM Killer事件,当内核触发OOM时,说明内存压力已经达到临界点。可以配置一条日志告警规则,匹配“Out of memory”关键字,触发后立即通知。同样,监控/var/log/auth.log中的SSH暴力破解尝试,如果短时间内出现大量失败登录,应该触发安全告警。日志监控与指标监控的关联分析是提升告警准确率的重要手段,例如CPU使用率告警同时伴随应用错误日志增加,说明不是单纯的资源竞争,而是应用逻辑异常。
告警测试与持续优化
配置完成后必须进行告警测试,不能等到真实故障时才发现通知链路不通。测试方法包括手动触发告警规则、模拟资源耗尽、停止关键服务等。Prometheus的表达式浏览器可以用来验证PromQL是否正确,Alertmanager的silence功能可以临时屏蔽已知维护窗口的告警。告警体系上线后,建议每周回顾告警记录,统计误报率、漏报率和平均响应时间。对于频繁触发但无需处理的告警,要么调整阈值,要么降级为报表而非告警。对于从未触发过的规则,要检查规则本身是否有效。监控告警配置不是一次性工作,而是需要随业务变化持续迭代的过程。Ubuntu服务器内核版本升级、应用架构调整、流量增长都会影响原有阈值的合理性,定期审视和调优才能保持告警体系的有效性。
