2026年8月12日 1 分钟阅读

别把 Docker 监控做成一套重系统:用 Beszel 把 Hub、Agent 与容器历史指标拆开部署

tinyash 0 条评论

想给几台 VPS、家里的小主机和若干 Docker 服务补上监控时,很多人会先想到一整套指标、日志、查询和告警系统。但实际需求往往更具体:我想知道某台机器的磁盘何时接近满载,某个容器为什么突然吃掉内存,以及异常发生前半小时的网络流量有没有变化。

Beszel 是一个自托管的轻量监控项目。它不要求把全部采集与展示逻辑塞进同一进程,而是将系统拆成 HubAgent:Hub 是基于 PocketBase 的 Web 应用,负责展示、管理和告警;Agent 部署在被监控主机上,负责上报数据。这个分离很适合从一台 Docker 主机起步,再逐步扩展到多台机器的场景。

项目使用 Go 编写、采用 MIT 许可证;GitHub 仓库的介绍明确列出了历史数据、Docker 统计与告警三个核心方向。它不是要替代所有可观测性平台,而是把“先看清机器和容器现在发生了什么”这件事做得足够直接。

先确认:你需要的是监控边界,而不只是仪表盘

Beszel 可以记录系统的 CPU、内存、磁盘、带宽、温度、负载与在线状态;对 Docker 容器,还能查看 CPU、内存和网络用量的历史数据。这里“历史”很重要:一次 docker stats 只能回答当前瞬间,而排查内存泄漏、定时任务挤占资源或流量突刺时,时间轴才能解释现象。

Hub 与 Agent 的分工也把权限问题摆在台面上:

  • Hub 不必直接登录每一台服务器;
  • Agent 只在本机采集并向 Hub 建立连接;
  • 需要容器指标时,Agent 才读取 Docker socket;
  • 告警规则集中在 Hub 侧配置,而不是把脚本散落到每台主机。

因此,部署前应先决定采集范围。仅做主机资源监控时,不要为了“以后可能用到”而挂载 Docker socket;只在确实需要逐容器指标时,才授予这项能力。

用官方同机 Compose 样例启动最小环境

Beszel 仓库提供了 Hub 与 Agent 同机运行的 Docker Compose 示例。下面保留了其中最关键的关系:Hub 对外提供管理界面,Agent 通过本地 Unix socket 找到 Hub;Docker socket 以只读方式挂载给 Agent。

services:
  beszel:
    image: henrygd/beszel:latest
    ports:
      - "8090:8090"
    volumes:
      - ./beszel_data:/beszel_data
      - ./beszel_socket:/beszel_socket

  beszel-agent:
    image: henrygd/beszel-agent:latest
    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: "替换为 Hub 创建系统后生成的 Token"
      KEY: "替换为 Hub 创建系统后生成的 Key"

保存为 docker-compose.yml 后启动:

docker compose up -d

首次运行后访问 http://localhost:8090,完成 Hub 初始化。在 Hub 中创建被监控系统时会得到 Agent 所需的 TOKENKEY;将真实值写入 Compose 环境变量后,再重新创建或重启 Agent。不要把这两个值提交到 Git 仓库,也不要把包含它们的 Compose 文件发到工单或聊天记录中。

这个示例还体现了一个容易被忽略的取舍。/var/run/docker.sock 虽然是只读挂载,但它仍是敏感的宿主机控制接口。Beszel 的用途是读取容器指标,不代表每个环境都必须给它这个入口。对于只需要系统级 CPU、磁盘与网络监控的节点,移除这行挂载即可缩小暴露面。

从单机验证走向多机接入

最小部署完成后,不要立刻把所有服务器接进来。先用一台主机验证三个问题:数据是否持续出现、容器统计是否与 docker stats 的趋势一致、告警是否能到达负责处理的人。

建议按以下顺序推进:

  1. 先验证存储路径。 Hub 数据目录与 Agent 数据目录应使用持久化卷或宿主机目录。否则容器重建后,初始化状态和历史采样可能丢失。
  2. 再验证容器采集。 人为启动一个短时高负载容器,观察对应容器的 CPU、内存和网络历史曲线是否产生变化。测试结束后及时清理测试容器。
  3. 最后配置阈值。 Beszel 提供 CPU、内存、磁盘、带宽、温度、负载和状态的可配置告警。阈值应该从真实基线开始:例如磁盘应预留给日志增长和镜像更新的空间,而不是机械地把所有机器设为同一个百分比。

多机环境中,每台被监控机器运行一个 Agent,Hub 统一管理系统条目。这样做的收益不是“少开几个标签页”,而是让主机、容器与告警在相同的时间维度下可比较:发布后某个容器内存持续上升、某台节点带宽异常,都会更容易与变更时间关联。

身份、备份与访问边界:上线前别跳过这三项

监控面板本身掌握了服务器名称、资源曲线和可能的告警信息,因此它也应按管理系统而非普通网站来保护。Beszel 文档导航提供 OAuth/OIDC、通知、数据管理和反向代理等主题;具体采用哪些能力取决于部署环境。无论使用哪种方式,至少应考虑以下边界:

  • 将 Hub 放在 VPN、内网或受控反向代理之后,不直接把管理端口裸露到公网;
  • 需要多人协作时,优先使用清晰的账号与权限边界,而不是共享管理员密码;
  • 在变更前验证持久化目录和备份策略,定期演练恢复,而不是只确认备份任务“曾经成功”;
  • 为 Hub 本身安排资源余量,避免监控系统先于业务主机耗尽磁盘。

这些不是额外的“企业化配置”,而是部署决策的一部分:哪些数据离开网络、哪些端口可访问、谁能看见主机清单,都应该由部署者显式决定。

遇到“没有数据”时,按链路而不是猜配置排查

监控部署最容易浪费时间的地方,是直接在面板里反复刷新。Hub + Agent 架构有明确的数据路径,排查应沿着路径前进。首先确认两个容器都在运行,再检查 Agent 的 HUB_URL 是否能从它所在的网络命名空间访问;同机示例使用 network_mode: host,因此它访问的是宿主机的 localhost:8090。如果将 Agent 改为普通 Docker 网络,就不能沿用这个地址,应按实际网络拓扑调整 Hub 地址。

接着检查 TOKENKEY 是否来自当前 Hub 中对应的系统条目。复制旧系统的凭据、在不同环境之间混用凭据,都会让“容器在运行”与“Hub 没有数据”同时出现。最后再判断 Docker 指标:只有挂载了 /var/run/docker.sock 且目标主机确实运行 Docker 时,才应期待容器列表和逐容器曲线。不要把主机指标正常、容器指标为空一概当成故障;在未授予 Docker socket 的最小权限部署中,这正是预期行为。

对于告警,也应刻意做一次演练。选择一个可控且不会影响业务的测试阈值,确认触发、送达和恢复三件事都发生,再设置生产阈值。只验证仪表盘可打开,不等于值班时真的能收到并理解告警。

Beszel 适合什么,不适合什么

Beszel 适合希望快速获得主机与 Docker 容器历史指标、并且愿意自己维护一个小型 Hub 的团队或个人。Hub + Agent 模式让它能够从单机 Compose 开始,也能自然延伸到多机管理;Docker 指标、告警和持久化备份则覆盖了日常排障的高频需求。

但如果目标是保存海量高基数指标、做复杂查询语言分析,或把日志、链路追踪和指标统一进企业级平台,仍应评估更完整的可观测性栈。轻量并不等于功能不足,它意味着先把边界收紧:先采集真正需要的数据,再按故障模式扩展系统。

对于 Docker 主机而言,一个务实的起点是:用 Beszel 的同机 Compose 样例跑通 Hub 与 Agent,确认数据和告警链路,再决定是否给其他节点安装 Agent。这样既能尽快获得历史视图,也不会在第一天就背上一套超出需求的监控基础设施。

相关链接

发表评论

你的邮箱地址不会被公开,带 * 的为必填项。