Beszel 实战:用 Hub + Agent 给小型服务器做轻量自托管监控
一台 VPS、一台家用 NAS,再加几组 Docker 容器,很容易进入一个尴尬阶段:机器不算多,Prometheus、长期存储和大套仪表盘显得过重;但只靠 SSH 登录后运行 top,又只能看到问题发生后的瞬间。尤其是容器重启、磁盘 I/O 变高或温度异常这类问题,缺少历史记录时很难复盘。
Beszel 提供了一个更小的切入点。它是 MIT 许可证的开源服务器监控平台,项目 README 明确列出了 Docker 统计、历史数据和告警功能。它不是把所有可观测性需求塞进一个平台,而是把目标收敛为:用一个 Web Hub 汇总多台机器的状态,每台被监控机器运行一个 Agent 上报指标。
截至本文核查时,项目最新发布版本为 v0.18.7;版本会继续演进,部署前仍应以官方发布页和文档为准。
先理解 Hub 与 Agent 的边界
Beszel 的 Hub 是基于 PocketBase 的 Web 应用:它保存和展示系统数据,也负责在界面中管理被监控的系统。Agent 则运行在目标主机上,负责采集指标并与 Hub 通信。这个拆分有一个实际好处:不必在每台机器上部署完整的 UI 和数据库。
官方 README 所列的采集范围包含主机 CPU、内存、磁盘使用率、磁盘 I/O、网络、负载、温度,以及 Docker/Podman 容器的状态和资源历史;还提到了 GPU 功耗/使用率、电池和 S.M.A.R.T. 磁盘健康等指标。这里要注意两个边界:这些能力会受主机硬件、驱动、挂载方式和 Agent 权限影响;而“看到异常”也不等于已经完成根因分析。Beszel 适合先回答“哪台主机、哪个容器、从什么时候开始异常”。
用 Compose 启动本机 Hub 与 Agent
最容易验证的起步方式,是按官方 Getting Started中的示例,在同一台 Linux 主机同时运行 Hub 和 Agent。新建目录后保存如下 docker-compose.yml:
services:
beszel:
image: henrygd/beszel:latest
container_name: beszel
restart: unless-stopped
environment:
APP_URL: http://localhost:8090
ports:
- 8090:8090
volumes:
- ./beszel_data:/beszel_data
- ./beszel_socket:/beszel_socket
beszel-agent:
image: henrygd/beszel-agent:latest
container_name: beszel-agent
restart: unless-stopped
network_mode: host
volumes:
- ./beszel_agent_data:/var/lib/beszel-agent
- ./beszel_socket:/beszel_socket
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
LISTEN: /beszel_socket/beszel.sock
HUB_URL: http://localhost:8090
TOKEN:
KEY: ""
然后启动:
mkdir beszel cd beszel docker compose up -d
首次启动后访问 http://localhost:8090 创建管理员账户。在 Hub 界面的 Add System 流程中创建系统,并取得该系统对应的 TOKEN 与 KEY;将它们替换进 Compose 文件,再执行一次 docker compose up -d。对于同机示例,系统地址使用共享的 Unix socket:/beszel_socket/beszel.sock。这一步是让 Hub 与 Agent 对上的关键,不能把示例里的 、 原样保留。
为什么 Docker socket 要当成敏感接口
为了读取 Docker 容器统计,官方示例将 /var/run/docker.sock 以只读方式挂进 Agent:
- /var/run/docker.sock:/var/run/docker.sock:ro
只读挂载比可写挂载更克制,但 Docker socket 仍是高权限接口,不能因为它只用于“监控”就把风险忽略掉。实践中应把 Agent 镜像来源固定为可信版本、限制能接触该主机的管理员账号,并避免把 Hub 管理界面直接暴露给公网。
如果只想先监控主机而不关心容器,可以参考官方的Agent 安装说明,选择不提供 Docker socket 的部署路径。不要为了展示容器图表而把 socket 无差别复制到每一台机器。
接入远端机器时,先收紧网络面
Hub 与远端 Agent 的部署应该先明确网络拓扑。较稳妥的做法是让 Agent 和 Hub 经私有网络、VPN 或受控反向代理互通,而不是把 Agent 监听端口直接公开到互联网。Hub 的 APP_URL 也必须改为实际访问地址;官方文档特别提示,该值应是访问 Hub 所使用的域名或公网 IP(需要时包括端口)。
接入顺序建议保持简单:先只加一台非关键机器,观察它是否稳定变绿;确认指标、时区和容器列表合理后,再逐步扩大范围。告警也应从少量明确的阈值开始,例如磁盘接近耗尽或系统离线。把所有 CPU 短暂峰值都当作告警,最终只会制造通知疲劳。
接入后的第一周可以刻意做一次小验证:记录某个容器的正常内存范围,安排一次可控的重启,确认状态变化能在界面中看见;再检查一天后历史曲线是否仍在增长。这个过程的目的不是制造压力测试数据,而是确认采集、存储和展示三个环节没有断开。若 Hub 在反向代理之后运行,还要分别从内网和预期访问入口登录一次,避免 APP_URL 与真实地址不一致造成后续的回调或访问问题。
数据、备份与告警不是同一件事
Beszel README 提到自动备份,并支持保存到磁盘或 S3 兼容存储。即便如此,部署者仍需要明确自己要保留什么:Hub 的 ./beszel_data 是持久化目录,若它跟容器一起被随手删除,历史记录就失去了。至少应把该目录纳入主机备份策略,并定期测试恢复,而不是只确认备份任务“曾经成功”。
告警设计也应区分三个层面。第一层是可用性:Agent 或主机离线时需要知道;第二层是容量:磁盘、内存或网络使用量持续逼近边界时需要提早处理;第三层才是性能波动,例如负载或 CPU 突然升高。前两类通常能定义出稳定阈值,第三类则应先收集一段时间的基线。把一次构建、备份或镜像拉取造成的短峰值直接当故障,会让告警频道很快失去可信度。
可以为每台机器写一张简短的运行卡:它承载哪些服务、正常磁盘余量是多少、哪个容器重启应当告警、发生离线时谁负责处理。这样 Beszel 的图表和告警就不只是“数据展示”,而能连接到具体的处置动作。对于临时实验机,则可以只保留离线和磁盘告警,避免把不重要的波动带进生产值班流程。
同样,监控平台本身也需要最小健康检查:检查容器是否在运行、Hub 页面是否可访问、Agent 状态是否连续。一个离线的监控系统不会替你报告自己的离线。
升级前先固定可回退的版本
官方快速开始示例使用 latest 镜像,适合首次体验;长期运行时,更稳妥的做法是把镜像标签固定到经过验证的版本,并在升级前备份 Hub 数据目录。本文不把某个版本号写进 Compose,是因为可用镜像标签和发布节奏会变化;应先查看官方 Releases,再根据团队的变更流程决定升级时间。
升级后先检查 Hub 是否能正常登录、已接入系统是否仍显示在线、容器统计是否持续更新,再处理告警规则或其他配置变更。若出现异常,保留旧镜像标签和已验证的数据备份,比在生产机器上反复拉取 latest 更容易回退。这个习惯不只适用于 Beszel,也适用于绝大多数带持久化状态的自托管服务。
适用场景与取舍
Beszel 很适合小型多机环境:个人服务器、实验室设备、家庭机房,或需要同时看主机和 Docker 状态的小团队。它提供的是快速建立历史视图和基础告警的路径,而不是宣称替代日志平台、链路追踪或完整的指标生态。
当你的需求扩展到海量时间序列、复杂查询、跨团队服务目标或深度业务指标时,仍可能需要更完整的观测体系。但在那之前,先用清晰的 Hub + Agent 边界、受控的网络暴露和可恢复的数据目录,把“机器现在怎么样”变成可持续回答的问题,通常比先搭一套重型平台更实际。