部署 Beszel,监控主机、容器并配置邮件告警

部署 Beszel 时,先启动 Hub 并复制接入公钥,再在 Linux 上启动 Agent;Agent 挂载 Docker socket 后采集主机与容器指标,最后配置 SMTP 并发送测试邮件。 这条链路适合运行在 Linux 主机上的 Docker 环境:同机部署时,Hub 与 Agent 放在同一台服务器;跨主机部署时,Hub 集中放在管理服务器,每台被监控主机运行 Agent,并只放通 Hub 到 Agent 的连接端口。

最终验收不能只看容器是不是启动,而应确认 Hub 页面可以登录、Agent 状态在线、Linux 指标持续更新、Docker 容器列表与资源统计可见、SMTP 测试邮件能够收到,并且告警规则可以实际触发。这样可以在业务用户反馈之前发现异常,避免等服务器已经不可用了再回看曲线。

先把 Hub 和 Agent 跑起来

Beszel 分为 Hub 和 Agent 两部分。Hub 提供 Web 管理端,Agent 部署在待监控主机上,向 Hub 传递指标;Agent 还提供用于传输指标的最小 SSH 服务。 两种部署拓扑的区别主要在网络和防火墙:

拓扑 部署位置 需要处理的网络问题
同机部署 Hub 与 Agent 都在同一台 Linux 服务器 Hub 容器访问 Agent 时不能误用自己的 127.0.0.1
跨主机部署 Hub 集中运行,每台目标主机运行 Agent 放通 Hub 到 Agent 的端口,并限制来源地址

Linux Docker Compose 骨架如下,镜像、挂载点和环境变量与 Beszel Docker 模板中的基本结构一致。 具体参数仍应与当前稳定版官方文档和仓库模板核对。

services:
  beszel:
    image: henrygd/beszel:latest
    restart: unless-stopped
    ports:
      - "127.0.0.1:8090:8090"
    volumes:
      - ./data:/beszel_data
    environment:
      TZ: ${TZ:-Asia/Shanghai}

  beszel-agent:
    image: henrygd/beszel-agent:latest
    restart: unless-stopped
    network_mode: host
    pid: host
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - /proc:/host/proc:ro
      - /sys:/host/sys:ro
      - /var/lib/docker/containers:/var/lib/docker/containers:ro
    environment:
      KEY: ${BESZEL_AGENT_KEY:-}
      LISTEN: ${BESZEL_AGENT_PORT:-45876}
      TZ: ${TZ:-Asia/Shanghai}

这里的 latest 只适合初次验证。生产环境确认可用后,应固定到经过验证的版本标签或镜像摘要,避免一次普通拉取就改变运行版本。

先建立目录并保存上面的文件为 compose.yaml:

mkdir -p /opt/beszel/data
cd /opt/beszel

再建立 .env。接入公钥需要在 Hub 初始化之后才能取得,因此先保留空值:

TZ=Asia/Shanghai
BESZEL_AGENT_KEY=
BESZEL_AGENT_PORT=45876

不要把 .env 提交到 Git,也不要把真实 SMTP 密码写进公开的 Compose 文件:

chmod 600 .env

当前 Docker Compose V2 使用下面的命令;如果服务器只有旧版 docker-compose,后续检查、拉起和查看日志都统一换成旧命令,不要混用:

docker compose version
docker compose config
docker compose up -d beszel
docker compose ps
docker compose logs --tail=100 beszel

Hub 默认使用 8090 端口。 上述配置只绑定在服务器的 127.0.0.1,从远程管理时可以通过 SSH 隧道访问:

ssh -L 8090:127.0.0.1:8090 user@hub-server

随后在本机浏览器打开 http://127.0.0.1:8090。如果确实需要局域网直接访问,可以调整端口绑定地址,但必须同时设置防火墙或反向代理访问控制,不建议把没有认证和 TLS 的 Hub 直接暴露到公网。

首次初始化时,先创建管理员,再新增被监控系统并复制页面给出的接入公钥。把公钥作为一行完整值写入 .env:

BESZEL_AGENT_KEY='ssh-ed25519 这里替换为页面给出的完整公钥'

这里放的是公钥,不要误放私钥。公钥包含空格或注释时,保留页面生成的完整内容,并确保 .env 中没有被换行截断。填好后启动 Agent:

docker compose up -d beszel-agent
docker compose ps
docker compose logs --tail=100 beszel-agent

Agent 的监听端口、Hub 中新增系统时填写的端口以及防火墙规则必须保持一致。上面的 45876 是示例监听值;如果当前官方模板或新增系统页面给出了其他值,应同步修改 BESZEL_AGENT_PORT、Hub 中的端口和防火墙规则。

同机部署时,Hub 如果运行在普通 bridge 网络中,容器里的 127.0.0.1 指向 Hub 容器自己,不是宿主机上的 Agent。此时应使用宿主机对 Hub 容器可达的地址。支持 host-gateway 的 Docker Engine 可以增加下面的可选配置:

    extra_hosts:
      - "host.docker.internal:host-gateway"

然后在新增系统时使用 host.docker.internal;不支持该功能时,使用宿主机实际 IP。不要在未验证路由的情况下照抄 localhost。

跨主机部署时,管理服务器只启动 Hub:

docker compose up -d beszel

每台目标主机只运行 Agent 服务,并把该系统对应的接入公钥写入各自的 .env。Hub 新增系统时填写目标主机的内网 IP 或可解析名称,以及 Agent 监听端口。目标机的防火墙只允许 Hub 服务器地址访问该端口:

ss -lntp | grep ':45876'

从 Hub 所在主机检查网络路径:

nc -vz AGENT_IP 45876

这里的 AGENT_IP 需要替换为目标主机地址。宿主机测试通过只能说明宿主机侧的路径可用;如果 Hub 本身在容器中,还要结合 Hub 日志确认容器侧的连接没有被额外网络策略拦截。

Agent 一直离线时,检查顺序应当是接入公钥是否与当前系统记录一致、.env 是否真正被 Compose 读取、Agent 是否监听预期端口、Hub 到 Agent 的路由是否可达,以及防火墙是否只放行了错误来源。KEY 正确但监听端口不同,同样无法接入。

Hub 页面打不开时,先看容器是否运行,再看日志、端口和防火墙:

docker compose ps
docker compose logs --tail=100 beszel
ss -lntp | grep ':8090'

如果前面还有 Nginx、Caddy 或其他反向代理,还要确认代理上游指向的是实际运行 Hub 的地址。反向代理本身也在容器中时,127.0.0.1 指向代理容器,不是 Hub 容器。

重建容器后配置和历史数据消失,通常是数据目录没有持久化。上面的 ./data:/beszel_data 是关键,不要只依赖容器可写层或匿名卷。可以检查实际挂载:

docker inspect "$(docker compose ps -q beszel)" --format '{{json .Mounts}}'

如果旧部署使用了匿名卷,迁移前先停止相关容器并按当前官方升级说明备份、复制数据,不要在运行过程中直接覆盖 PocketBase 数据文件。

如果目标机器不能使用 Docker,Beszel Hub 和 Agent 也提供二进制安装方式。 改用二进制后,Hub 数据目录、Agent 接入公钥、监听端口和防火墙规则仍需重新配置;Agent 运行账号还必须具有访问 Docker socket 的权限。此时不能再照搬容器里的 /beszel_data、network_mode: host 等路径或参数,具体安装方式应从当前官方发布页核对。

排查主机和容器指标缺失

Beszel 可以展示 CPU、内存、磁盘、带宽、温度、系统状态以及 Docker 容器信息,容器侧还可以查看运行状态和日志。 如果页面能够登录但部分指标为空,问题通常在采集条件,而不是 Web 页面本身。

Linux 网络接口指标缺失时,首先检查 Agent 是否使用主机网络模式。Agent 必须使用 network_mode: host 才能按官方模板访问网络接口指标。 页面能打开、CPU 和内存也有数据,但网卡流量为空时,这一项比 SMTP 配置更值得先查。

CPU、内存、磁盘等系统指标还依赖 Agent 对宿主机 /proc、/sys 的只读访问。示例中保留了这些挂载和 pid: host,不要为了缩小挂载范围而随意删除。温度数据是否可用则取决于宿主机是否向虚拟化环境或容器暴露相应传感器;某些 VPS 和虚拟机没有可读温度源,因此温度为空不一定代表 Agent 故障。

Docker 容器列表为空或资源统计不显示时,先确认 socket 挂载的是当前 Docker daemon 使用的端点:

docker context inspect "$(docker context show)" --format '{{ .Endpoints.docker.Host }}'
docker info --format '{{.DockerRootDir}}'

默认 Docker 通常使用 /var/run/docker.sock,rootless Docker 则可能使用用户运行时目录中的 socket。此时不能直接照抄默认挂载,应把 Compose 中的 socket 源路径改成 docker context inspect 返回的实际端点,并去掉 unix:// 前缀。

挂载路径正确也不代表 Agent 进程一定有权限访问。可以在宿主机检查 socket:

stat -c '%A %U:%G %n' /var/run/docker.sock

rootless 环境应检查实际 socket,而不是继续检查默认路径。修复权限时,应让 Agent 容器用户加入 socket 所属组或采用当前官方推荐的 UID/GID 映射,不要为了省事把 socket 随意改成全局可写。

Docker 容器数据要同时从宿主机和 Beszel 两条线核对:

docker ps -a
docker stats --no-stream
docker inspect --format '{{.State.Status}} {{.State.Running}} {{.State.ExitCode}}' CONTAINER_NAME
docker logs --tail=100 CONTAINER_NAME

其中 CONTAINER_NAME 要替换为实际容器名。docker stats --no-stream 主要显示正在运行的容器,因此某个容器已经停止时,统计为空是正常现象;但如果 docker ps -a 能看到运行中的容器,宿主机 docker stats 也有数据,而 Beszel 没有列表或统计,就应继续检查 Agent 的 socket 权限、容器数据根目录和 Agent 日志。

容器状态和采集失败也要分开判断。Docker 本身处于 exited 状态时,Beszel 显示停止是正确结果;如果宿主机显示容器正常运行,而 Beszel 长期没有 CPU、内存和网络数据,则属于采集链路异常。涉及容器日志时,还要确认 Docker 的日志驱动确实保留了可读取的日志。

内存占用持续上涨不一定是进程泄漏。Linux 会利用空闲内存缓存文件数据,free 中的 buffers 和 cached 不能简单等同于无法回收的进程占用;判断是否还有可用内存时,MemAvailable 比单看 used 更有参考价值。

free -m
grep '^MemAvailable:' /proc/meminfo
ps -eo pid,comm,%mem,%cpu --sort=-%mem | head
docker stats --no-stream

这几条数据要放在一起看:MemAvailable 持续下降、宿主机进程占用同步增加,才更像真实内存压力;cached 上升但 MemAvailable 稳定,同时没有对应进程或容器持续增长,通常不能直接判定为泄漏。

Docker socket 是高权限入口。即使 Compose 中使用了 :ro,也不应把它理解成完整的安全隔离;挂载 Docker socket 的 Agent 应当只运行可信镜像,并限制相关账号和目录权限。Hub 同样应放在 VPN、SSH 隧道或带认证与 TLS 的反向代理之后,不要直接暴露到公网。

配置 SMTP 并验证告警邮件

Beszel 支持邮件和 Webhook 通知。 这里只展开 SMTP 邮件通道。SMTP 的具体配置入口可能随稳定版调整,应在 Hub 的管理员设置页中找到当前版本文档所指的 SMTP 或邮件通知配置;部分版本会把它归入通知设置,升级后不要依赖旧截图中的菜单位置。

需要准备的信息包括 SMTP 服务器地址、端口、加密方式、认证账号、认证密码、发件人地址和测试收件人。邮件服务商如果要求应用专用密码,应使用服务商单独生成的凭据,不要把真实密码写进文章、截图或版本库。

配置内容 应填写或确认的内容
SMTP 服务器 邮件服务商提供的域名或地址
端口与加密 必须与服务商要求一致,不能只照搬其他邮件服务的配置
认证信息 用户名、密码或应用专用密码
发件人 服务商允许使用的发件地址
测试收件人 用于验证通道的真实邮箱

发送测试邮件前,可以先检查 DNS 和 TLS。下面的主机名与端口是占位值,需要替换:

getent hosts smtp.example.com
openssl s_client -connect smtp.example.com:SMTP_PORT -servername smtp.example.com </dev/null

如果服务商明确使用 STARTTLS,则使用:

openssl s_client -starttls smtp -connect smtp.example.com:SMTP_PORT -servername smtp.example.com </dev/null

这一步只验证 DNS、路由和 TLS 握手。通过宿主机测试不代表 Hub 容器一定具备相同的外网出口,最终仍以 Hub 发出的测试邮件和 Hub 日志为准。

配置完成后先发送测试邮件。若当前版本提供测试发送入口,直接使用;如果没有,可以用一条临时告警规则产生测试邮件。测试成功后,再创建正式规则。告警规则至少要明确监控对象、指标、比较条件、阈值、通知通道和启用状态。

临时验证阈值时,先查看当前指标值,选择一个在本次测试中必然越过的条件,等待至少一个采集周期,确认邮件到达后再恢复正常阈值。不要在生产环境长期保留明显偏低或偏高的测试条件。

邮件完全收不到时,应按“通道”和“规则”分开排查。如果测试邮件也失败,优先检查 SMTP 连通性、认证凭据、加密方式、发件人和收件人配置,并查看 Hub 日志中的原始错误:

docker compose logs --since=10m beszel

如果测试邮件能够收到,但告警规则不触发,就不要继续反复修改 SMTP。此时应检查规则是否绑定到正确的系统、指标是否持续更新、比较方向是否正确、阈值是否能够被当前值越过,以及规则是否启用。指标采集失败时,告警判断自然也可能没有有效输入。

如果邮件已经出现在发件记录或服务商后台,但收件箱里看不到,应检查垃圾箱、邮件服务商拦截和发件人域名信誉。测试邮件成功只证明 SMTP 通道和收件路径基本可用,不代表每一条告警规则都已经配置正确。

告警过于频繁时,不要直接套用一个固定百分比。先观察正常业务高峰、历史曲线和指标波动,再按实际负载设置条件;高峰期如果阈值过低会持续误报,阈值过高又会漏报。 当前版本如果提供持续时间、恢复条件或通知间隔,也应结合业务周期设置,而不是只改一个数字。

排障时应保留完整错误原文。可以同时记录 Docker、Compose 和镜像版本,以及 Hub、Agent 的近期日志:

docker version
docker compose version
docker compose ps
docker compose logs --since=30m
docker image inspect henrygd/beszel:latest --format '{{.Id}} {{json .RepoTags}}'
docker image inspect henrygd/beszel-agent:latest --format '{{.Id}} {{json .RepoTags}}'

升级前备份 Hub 的持久化目录并固定镜像版本。升级后先执行 docker compose pull,再重新创建对应容器;不要通过反复删除所有容器来“碰运气”,这样既会丢失排障上下文,也可能掩盖真正的配置错误。

上线前可以按以下清单完成最后验收:

  • Hub 页面能够正常打开并完成登录。
  • Agent 状态为在线,Linux 指标持续更新。
  • Docker 容器列表、运行状态和资源统计可见。
  • 网络接口指标正常,缺失时已检查主机网络模式。
  • SMTP 测试邮件能够收到。
  • 告警规则可以按预期触发,并已恢复正常阈值。
  • 重建容器后,Hub 配置和历史数据仍然存在。
  • Docker socket、Agent 端口和 Hub 访问范围都已按最小权限处理。

如果仍然失败,保留 docker compose ps、Hub 与 Agent 日志、Agent 监听状态、Hub 到 Agent 的网络检查结果、完整 SMTP 错误、Docker 与 Compose 版本以及实际镜像摘要,再按对应版本逐项对照官方文档。有效证据比反复重建容器更有助于定位问题。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容