1. OpenRig 是什么:一个为多机 GPU 运维而生的开源监控平台
先说个我自己的经历。去年我给工作室配了 6 台双卡机器,陆陆续续跑了差不多一个季度,最头疼的事情不是装系统也不是调驱动,而是“不知道哪台机器现在什么状态”。每台机器在干什么、显存吃满了没有、温度是不是已经逼近临界点、有没有哪台死机了——这些信息全靠人肉巡检,每天开机第一件事就是挨个 ssh 上去敲nvidia-smi,6 台机器敲完半小时就没了。后来机器越来越多,我发现这种做法完全不可持续,这才开始认真找开源方案。找了一圈之后,我把目光落在了 OpenRig 上。
OpenRig 是一个面向多机 GPU 设备集群的开源远程监控与管理平台。它的核心定位非常聚焦:帮你把分散在不同位置的算力设备统一接入到一个控制台里,实时掌握每台机器的运行状态。通俗地说,它就是给你所有 GPU 机器装了一套“体检仪”加“遥控器”——哪台机器温度高了、哪台功耗异常、哪台已经掉线失联,打开面板一眼就能看到;配合告警机制,还能在机器出问题的第一时间推消息给你,不用你一直盯着屏幕等。
我之所以特别看好这个项目,是因为它解决的是“单机工具无法覆盖”的规模化痛点。单机场景下,nvidia-smi -l加个 watch 命令就够用了,但当你手里有十台、几十台甚至跨地点的机器时,状态管理就成了一个系统工程:设备发现、指标聚合、历史趋势、告警通知、远程复位,每一环都需要专门设计。OpenRig 走的就是这条“轻量级集群管理”路线,它不像 Prometheus + Grafana 那样需要你理解一整条监控生态,而是把 GPU 场景需要的功能全部封装好,开箱即用。
这篇文章我基于自己的实际部署和使用经验,把 OpenRig 的整体设计、架构逻辑、部署步骤和避坑要点完整梳理一遍。适合谁看?如果你手里有多台 GPU 机器(不管是跑 AI 训练、视频渲染、3D 设计还是分布式计算任务),并且对“每天手动挨个查状态”这件事已经感到厌烦,那这套东西能直接帮你把运维效率拉高一个档次。后面所有的配置和命令我都尽量写细,你照着操作基本就能跑起来。
2. 架构设计与核心拆解
2.1 整体架构:采集端 + 服务端 + 面板端
OpenRig 的架构属于典型的“端-云”模式,但不依赖任何外部云服务,完全可以在内网环境自闭环。整个系统由三个部分组成:Agent 采集端、Server 服务端和 Web 控制面板。
Agent 是部署在每台 GPU 机器上的轻量级程序,负责采集本机硬件信息,包括 GPU 型号、驱动版本、显存总量与占用、核心温度、功耗、风扇转速、算力利用率,以及主机层面的 CPU 负载、内存占用、磁盘空间和网络吞吐量。采集完成后,Agent 会按照设定的时间间隔(默认 10 秒一次)把数据推送到 Server。
Server 是系统的中心节点,负责接收所有 Agent 上报的数据,完成解析、入库、聚合和告警判断。数据默认存储在本地数据库中,同时 Server 对外提供 REST API 和 WebSocket 接口,前端面板通过这些接口实时渲染数据。告警模块也跑在 Server 侧,它根据预设的阈值规则逐条判断每个设备的状态,一旦触发就执行通知动作。
Web 面板是用户直接交互的界面,主要功能包括设备总览、单机详情、历史曲线、告警记录和系统设置。面板基于 Web 实现,意味着你在任何一台联网的设备上用浏览器就能查看整个集群的状态,不需要额外安装客户端。
这个三层结构与常见监控系统(比如 Zabbix)相比,最明显的区别是 OpenRig 把 GPU 相关的采集项做了深度定制。通用监控系统往往只能看到主机级别的 CPU、内存、磁盘指标,想要 GPU 数据还得自己折腾 exporter 或自定义脚本;OpenRig 在 Agent 端直接把nvidia-smi的数据全部结构化整理好,省掉了中间所有“自己写采集逻辑”的功夫。
2.2 数据上报:为什么选择推送而不是拉取
这里有一个值得展开的设计决策:Agent 主动向 Server 推送数据,而不是让 Server 定期去每台机器上拉取数据。两者在实现效果上天差地别,原因主要有三个。
第一,NAT 穿透的友好性。实际部署中,很多算力机器其实是在内网里的——工作室的局域网、机房的私网、家里的宽带环境,没有公网 IP,也没有配置端口映射。如果采用拉取模式,Server 端必须能直接访问到每台设备,这就意味着你必须为每台机器都打通网络通路,配置繁琐且容易出错。推送模式下,Agent 只需要能“主动连上”Server 即可,对 Agent 所在网络没有任何入站要求,极大地降低了接入门槛。
第二,多路径的容灾能力。Agent 推送时,数据包会先经过 Server 的网关端口进入系统,再落到存储层。哪怕某台机器与 Server 之间的网络出现抖动,Agent 自身具备本地缓存与重连机制,恢复后会自动补传,不会因为一次网络中断就丢一整段监控数据。拉取模式下,Server 拉不到就是拉不到,中间没有任何缓冲,数据断档是常态。
第三,动态扩缩容的便利性。新加一台机器时,给它装好 Agent、填上 Server 地址,几十秒后它就会出现在面板上,Server 端完全不需要做任何配置变更。这种“让设备自己来找平台”的模式,在设备数量频繁变动时特别舒服,不用每加一台机器就去改服务端配置。
当然,推送模式也有代价——Server 端必须暴露一个可访问的地址(IP 或域名),所有 Agent 都依赖这个入口才能上报。所以不管你部署在内网还是公网,都需要保证 Server 的端口对 Agent 可达,这是唯一的“硬性网络要求”。
2.3 告警链路:从“发现问题”到“通知到人”
OpenRig 的告警模块我单独拿出来说,因为在实际运维中,这才是真正帮你省心的地方。
告警规则的设计思路是“阈值触发 + 状态恢复”。你可以对每项指标分别设置告警阈值,比如 GPU 温度超过 85 度触发警告、超过 92 度触发严重告警;显存占用率超过 95% 提醒扩容;设备心跳超过 2 分钟未收到则判定离线;磁盘剩余空间低于 50GB 提醒清理。每条规则都可以独立开关,并且支持按设备单独配置,避免“全局一刀切”导致误报。
当某条指标触发阈值后,系统会自动生成一条告警记录并执行通知动作。通知渠道常见的有 Webhook 和邮件,Webhook 模式特别适合国内用户,因为可以接到企业微信/钉钉/飞书这类办公协同工具的机器人上。我自己的做法是配了一个企业微信机器人——GPU 温度告警的消息直接推到手机,不需要登录任何后台就能第一时间知道哪台机器出了问题。
告警的“恢复通知”也做得不错。当指标回落到安全区间后,系统会自动消除告警状态并发送一条恢复消息。这么做的好处是避免“狼来了”效应——如果只有告警没有恢复,时间长了人就会麻木;有了恢复通知,你能明确知道故障持续了多久、什么时间点解除的,对后续复盘很有用。
提示:告警频率一定要设置冷却时间。比如同一条 GPU 温度告警,触发后 30 分钟内不再重复发送,否则机器温度在阈值附近反复横跳时,你的手机能在一个小时内收到几十条消息,那体验非常酸爽。
3. 从零部署:服务端与采集端完整实操
3.1 环境准备:硬件需求与依赖清单
先看硬件底子。OpenRig 的服务端并不吃资源,因为它本质上就是“接收数据 + 写库 + 展示”,不是计算密集型的任务。一台 2 核 4G 内存的小主机、NUC、甚至吃灰的旧笔记本都能扛住几十台设备的接入规模。存储方面,默认数据库按天归档,按每台设备 20 个指标、10 秒一次上报来算,单台设备一天大约产生 17 万条数据点,占总空间差不多 30 到 50MB。如果管理 20 台设备,预留 50GB 磁盘跑半年没什么压力。
依赖方面需要准备的东西也很少,核心就两样:Docker(服务端一键部署用)和 Linux 环境。OpenRig 的服务端提供了现成的 Docker Compose 编排文件,不用自己一个个装 PostgreSQL、Redis 再手动配置连通性,这点对运维同学非常友好。
Agent 端的兼容范围比较宽,主流 Linux 发行版(Ubuntu、Debian、CentOS、Rocky Linux)都有对应二进制包。Agent 的实现依赖系统自带的nvidia-smi工具,所以安装 Agent 之前,记得确认目标机器的 NVIDIA 驱动已经装好,执行nvidia-smi能看到正常的信息输出。
3.2 服务端部署:Docker Compose 一键拉起
部署服务端我用的是 Docker Compose 方式,这也是官方推荐的首选路径。整个过程可以拆成三步来理解。
第一步,准备编排文件。拉取 OpenRig 项目仓库后,在server/docker目录下会看到一个docker-compose.yml文件。打开检查两个端口配置:8080(Web 面板及 API 入口)和9000(Agent 上报入口)。如果这两个端口在你的机器上有占用冲突,改成其他空闲端口即可,注意后续配置 Agent 时要用一致的值。
第二步,启动服务。在 docker-compose 文件所在目录执行docker compose up -d,Docker 会自动拉取后端服务、数据库等镜像并启动。首次执行时因为要拉镜像,耗时取决于网络速度,一般几分钟内能完成。看到所有容器状态显示 Up 就说明服务端已经跑起来了。
第三步,验证服务。浏览器访问http://你的服务器IP:8080,如果能看到登录页面,服务端基本就成功了。默认账号密码在部署文件里有标注,首次登录后务必改掉。另外用curl http://你的服务器IP:9000/api/v1/ping之类的路径能直接验证 Agent 上报端口是否正常响应。
3.3 Agent 采集端部署:两台机器的三种接入方式
Agent 的部署方式比较灵活,我按场景分别说明,你可以对号入座。
第一种是联网环境的二进制部署。在有公网或内网能访问到 Server 的机器上,下载对应架构(一般是 amd64 或 arm64)的安装包,解压后编辑config.yaml文件,填入 Server 地址、端口和设备分组信息,然后运行./openrig-agent start即可。启动后观察日志,如果出现 “connected to server” 类似字样,说明上报通道已经建立。
第二种是离线环境的拷贝部署。有些算力机器部署在生产内网,与外网隔离,没法直接下载安装包。这时候在能上网的机器上下载好二进制包,用 U 盘或内部文件服务器传到目标机器上,手工放置并赋可执行权限,再配置服务文件实现开机自启。整个过程不需要任何编译,因为 OpenRig 的 Agent 是静态编译的二进制文件,不依赖额外的解释器或运行库。
第三种是 Docker 容器方式。如果目标机器已经用容器管理 GPU 应用,Agent 也完全可以容器化运行。启动容器时加两个参数:--device /dev/nvidia0等 GPU 设备映射,以及-v /usr/bin/nvidia-smi:/usr/bin/nvidia-smi:ro将宿主机的 nvidia-smi 挂载进容器。这种方式的好处是 Agent 随容器管理,升级时直接替换镜像即可。
无论采用哪种方式,有几项配置是通用的。interval参数控制上报频率,默认 10 秒,我觉得这个值在“实时性”和“存储成本”之间取得了一个比较合理的平衡;如果机器数量多、存储压力大,可以调大到 30 秒。group参数用于设备分组,建议一开始就规划好——比如按机房、按用途、按业务项目来划,后面在面板上做筛选会方便得多。
3.4 设备接入与面板实操:从空页面到全集群可视化
所有 Agent 配置完毕、开始上报之后,打开面板首页,你会看到设备列表开始陆续出现。每台设备的信息卡上会展示 GPU 数量、总显存、在线状态、最近心跳时间等摘要信息。点击设备进入详情页,能看到每个 GPU 的独立监控面板,包括温度、功耗、风扇转速、核心频率和显存占用率的实时曲线。
历史查询是我用的比较多的功能。默认面板展示最近一小时的曲线,但可以自由调整时间范围。当你怀疑某台机器“昨晚某个时段”出现异常时,把时间轴拖过去,温度曲线、功耗曲线和在线状态在同一个时间轴上对照着看,定位问题非常直观。比如我踩过的一个坑:机器半夜跑任务经常自动重启,从面板上看温度和功耗都正常,但曲线在某个时间点戛然而止,紧接着又是重新启动的轨迹,基本可以断定是供电问题而不是过热。
面板上还有一个比较实用的功能是设备备注。每台机器可以自定义名称和标签,建议用“位置 + 用途 + 编号”的方式命名,比如“机房A-训练-01”,比默认的 IP 地址可读性强太多了。机器多了之后你会发现,命名规范直接决定管理效率。
注意:首次纳管大量设备时,不建议一次性接入超过 20 台。先接 3 到 5 台跑一两天,确认系统稳定、数据完整、没有异常告警后,再批量推进。这个习惯能帮你把部署风险控制在最小范围内。
4. 避坑手册:常见问题与排查技巧实录
4.1 Agent 持续掉线:先检查心跳,再看网络路径
Agent 掉线是使用过程中最常遇到的问题。现象是面板上设备状态变成灰色,显示“离线”或“失联”。排查思路从简单到复杂分三步走。
第一步,确认 Agent 进程本身还活着。在目标机器上执行systemctl status openrig-agent或ps aux | grep openrig-agent,如果进程已经不存在,检查系统日志看是否崩溃或被杀掉。我遇到过一起比较隐蔽的情况:机器内存耗尽后 OOM Killer 把 Agent 干掉了,加上日志被系统清理,看起来就像“无缘无故消失”。解决方法是限制 Agent 的内存占用上限,或者把它配置在更高级别的 OOM 保护组里。
第二步,检查 Agent 到 Server 的网络连通性。在目标机器上telnet ServerIP 9000,能通说明网络正常;不通就要排查防火墙、安全组策略,以及跨网段路由的问题。这里特别提醒一下,很多内网机器之间有防火墙策略,允许“随意的出站连接”不等于“允许你访问指定端口”,确认 Server 的 9000 端口在目标机器所在网段是被放行的。
第三步,查看 Agent 日志中有没有“retry”或“reconnect”字样。有的话说明 Agent 一直在试图重建连接但握手失败,问题大概率出在协议或地址配置上。对照 Server 端日志看是否有对应连接记录,如果 Server 完全没收到任何请求,那就是网络层问题;如果收到了但握手失败,重点查配置文件里的密钥或认证信息是否匹配。
4.2 温度数据读数为零或不变
这个问题第一次遇到时我愣了一下:明明机器在满载跑任务,面板上温度曲线却是平的,或者干脆显示为 0。后来排查发现,原因是 Agent 依赖的nvidia-smi输出格式在不同驱动版本下略有差异,当驱动版本过旧(尤其是 470 及更早版本)时,部分字段(例如功耗)的格式与新版不同,Agent 解析失败就会填默认值。
解决办法有两种。第一条路径是把驱动升级到较新的稳定版本——目前市面上 535 或 550 系列驱动对nvidia-smi输出兼容性最好,升级后重跑一遍数据基本就正常了。第二条路径是在 Agent 配置里开启compat_mode兼容模式,这个模式会启用一套更宽松的解析规则,牺牲一点精度来换取兼容性。如果你是混合驱动版本的大集群,我建议统一升级驱动,因为兼容模式在指标精度上确实有折损。
另外还有一种特殊情况:一些 vGPU 虚拟化环境(比如通过 GPU 虚拟化成多个实例)里,虚机中看到的温度本来就是 0,这是宿主机屏蔽了传感器数据的结果,属于硬件虚拟化的正常表现,不是 OpenRig 的问题。碰到这种情况直接把温度告警规则关闭即可,避免误报刷屏。
4.3 告警不触发:阈值、状态和通知三个环节逐一排查
告警模块“失灵”是我在实际使用中踩过的一个硬坑。有一天机器温度飙到 94 度,面板上曲线已经很刺眼了,但手机一条通知都没收到。我顺着链路查了一圈,把原因总结成三个排查点。
第一,阈值是否真的配置生效。OpenRig 的告警规则是“按设备单独配置”的,很多时候你配置了 A 设备的告警模板,但新增的 B 设备没有关联那个模板,默认规则可能没覆盖到。配置完告警规则后,一定要在设备详情页确认“已启用”状态是打开的,并且规则关联到了正确设备。
第二,告警状态机是否被卡住。OpenRig 的告警逻辑是“触发 -> 通知 -> 冷却 -> 恢复 -> 可再次触发”。如果某条告警触发了之后一直没有收到恢复数据(比如设备正好在这期间掉线了),状态机会一直停在“告警中”,此时即使指标继续恶化也不会再次发通知,因为系统认为“已经在告警了,不用重复通知”。解决方法是把掉线检测的阈值调短,让设备离线时能尽快进入离线告警,从而重置整个状态机。
第三,通知链路是否通畅。Webhook 通知走的是 Agent 侧配置的 webhook 地址,从 OpenRig Server 发出到企业微信机器人,中间经过任何一层转发(比如自建的反向代理),都需要确认目标地址直接可达。我调试时习惯先用curl手动调用一次 Webhook 地址,确认机器人接口本身没问题,再回到 OpenRig 里测试一条临时告警。
4.4 数据断档:补传策略与存储清理
数据断档偶尔会出现,尤其是在 Agent 与 Server 之间网络不太稳定的环境。表现为曲线图上有几段“空白期”,对应时间内没有数据点。
OpenRig 在 Agent 端内置了一个本地环形缓存,默认缓存最近 15 分钟的数据。当网络恢复后,Agent 会按照时间戳顺序自动补传缓存中的数据,Server 端收到后按时间戳入库,不会打乱原有曲线顺序。这里有一个需要注意的点:如果你人为重启了 Agent 进程,缓存会丢失,所以尽量不要在机器运行任务的关键期间重启 Agent。
存储清理方面,OpenRig 默认保留最近 30 天的原始数据明细,更早的数据会自动进入归档表并按天聚合。如果磁盘空间紧张,可以在配置里调整数据保留天数,比如缩短到 14 天。另外数据库支持自动清理任务,不用手动处理过期数据。
提示:建议给 Server 单独挂一块固态硬盘,并把 OpenRig 的数据目录放到 SSD 上。我一开始图省事放在机械盘上,设备数量到十几台时,查询历史曲线明显变卡,换成固态后立竿见影。
5. 写在最后:一些个人心得
前面把部署和使用讲得差不多了,最后分享两个我自己用下来的体会。
第一个体会是,OpenRig 这类“场景垂直”的开源工具,价值往往不在功能全面,而在“上手成本低”。我早先用通用监控方案折腾过一套 GPU 集群监控,光是把数据采集流程打通就花了三天,还要自己维护 exporter 和告警规则。换到 OpenRig 之后,从装服务端到所有 Agent 上线,全程不到半天。对一个追求“能用就行”的团队来说,这种效率优势就是最大的吸引力。
第二个体会是监控这件事,稳定比功能重要。用了大半年,我最满意的不是它功能有多少,而是它一直很稳定——Agent 很少崩、数据很少丢、告警基本准时。稳定的监控工具才值得依赖,如果监控工具本身经常出问题,那还不如不用。
最后再分享一个小技巧:给每台机器设置一个固定备注名的时候,顺带在备注里写上机器的大致硬件配置,比如“机房A-训练-01(8卡A800)”。这样在面板上扫一眼就知道哪台机器大概能跑什么任务,不用每次点击详情看 GPU 型号。这个习惯帮我省过不少事,值得各位试一下。