
如果你要在 Rocky Linux 上部署一套带 Web 管理界面的 Agent 服务Hermes Agent 和 Hermes-Web-UI 这套组合值得认真对待。Agent 负责在节点上跑任务、采集数据、上报心跳Web-UI 则把这些节点、任务、告警统一收口到一个浏览器页面里不用每台机器都 SSH 上去敲命令。这篇文章把我个人在 Rocky Linux 8.10 和 9.6 上从零装完这整套服务的实操过程完整记录下来包括系统初始化、静态 IP、yum 源、Agent 安装、Web-UI 部署、反向代理以及我踩过的几个印象深刻的坑。不管你是刚接触 Rocky Linux 的新手还是准备把 Agent 类组件迁到 Rocky 上的运维老手这套流程都能直接照着走。1. 装这套东西之前先把系统底层收拾干净很多人在 Rocky Linux 上装完 Agent 起不来回头查原因发现根本不是 Agent 的问题而是系统基础环境没弄好。我建议所有步骤开始之前先把系统层面这几件事处理完后面能省掉一大半排错时间。1.1 选择 Rocky Linux 8 还是 9先看依赖要求Rocky Linux 8 对应的是 EL8 生态软件包和库版本偏稳适合跑一些基于旧版 glibc 编译的二进制。Rocky Linux 9 对应的是 EL9 生态glibc、OpenSSL、Python、Node.js 这些基础组件的版本都要新不少。我的建议是如果是全新部署优先选 9.x支持周期更长Python 3.9、Node.js 18 都在官方源里省去自己编译的麻烦。如果是存量环境或者 Agent 包明确标注只支持 EL8那就在 8.10 上装。判断系统版本只需要一条命令cat /etc/redhat-release1.2 配置 yum 源8.10 和 9.6 的换源思路Rocky Linux 装完系统后默认的官方源在国内拉取速度通常不太理想建议直接换到国内镜像站。这里有个关键点8.10 和 9.6 的 yum 源路径不一样直接套用网上旧脚本经常会遇到 404。以阿里云镜像为例8.10 的 BaseOS 仓库地址大致是https://mirrors.aliyun.com/rockylinux/8.10/BaseOS/x86_64/os/而 9.6 则是https://mirrors.aliyun.com/rockylinux/9.6/BaseOS/x86_64/os/换成 8.10 的仓库时注意不要手滑把变量写错。我习惯先把原仓库文件做备份再动手mkdir -p /root/repo-backup cp /etc/yum.repos.d/*.repo /root/repo-backup/然后编辑/etc/yum.repos.d/Rocky-*.repo把mirrorlist开头的行注释掉把baseurl改成镜像站对应路径。改完记得刷新缓存dnf clean all dnf makecache这里有个容易踩的坑9.6 刚发布不久时部分镜像站的同步还不到位可能出现 404。遇到这种情况可以先去镜像站目录确认对应版本的文件夹是否存在或者直接改用dnf update把系统补丁升到当前最新版本大概率能避开路径不一致的问题。1.3 给服务器设静态 IPnmcli 两条命令搞定Agent 节点和 Web-UI 服务之间要长期保持通信服务器必须用静态 IP不然 DHCP 到期换地址之后所有节点会同时失联。Rocky Linux 默认用 NetworkManager 接管网络直接通过nmcli改最靠谱。先查一下当前连接的名称nmcli con show假设网卡连接名是ens192要设置的 IP 是192.168.1.100/24网关192.168.1.1DNS 用223.5.5.5执行nmcli con mod ens192 ipv4.addresses 192.168.1.100/24 ipv4.gateway 192.168.1.1 ipv4.dns 223.5.5.5 ipv4.method manual nmcli con up ens192第一行修改配置第二行让配置立即生效。这个操作远程执行时有一定风险我建议先在本地测试机练一遍或者确保自己有带外管理通道否则一旦 IP 写错远程连接直接断掉只能去机房或者靠 IPMI 恢复了。1.4 基础依赖与常用工具装齐后面不管是解压 Agent 包、编辑配置、查看日志还是排查网络这些工具都得提前备好。一次性装完dnf install -y epel-release wget git vim tar net-tools lsof如果 Agent 或 Web-UI 依赖 Python再装一下dnf install -y python3 python3-pipWeb-UI 如果是个 Node.js 项目Rocky 8 官方源的 Node.js 版本偏低直接用 nvm 装一个 Node.js 20 LTS 更省事。Rocky 9 的话官方源的 nodejs 版本相对新一些但装 nvm 统一管理也不亏curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash source ~/.bashrc nvm install 20提醒装完 nvm 后务必重新source ~/.bashrc不然 shell 里找不到nvm命令很多人第一次都卡在这里。2. Hermes Agent 和 Hermes-Web-UI 是什么关系装之前必须想清楚动手装之前至少要明白这两个东西各自干什么、怎么通信。否则装完发现连不上排查方向会很乱。这套架构其实和很多采集节点 管理中心的产品类似把这个模型理解了其它同类工具都能快速上手。2.1 Agent 与 Web-UI 的职责拆分Hermes Agent 是部署在每台被纳管机器上的组件职责是采集本机状态、执行下发的任务、把结果上报给中心端。Hermes-Web-UI 则是中心端的控制台负责展示所有 Agent 节点的在线状态、配置任务、查看历史执行记录。简单说Agent 是手脚Web-UI 是大脑操作台。一台机器上只需要装 Agent不需要装 Web-UIWeb-UI 可以单独跑在一台性能更好的服务器上管理成千上万台 Agent 节点。这种拆分方式是刻意设计的因为被纳管的节点通常资源有限不适合再塞一个重型 UI 服务。2.2 两者通信依赖什么端口、Token、心跳Agent 与 Web-UI 之间不是随随便便就能连上的注册机制通常包含三个要素服务地址、身份令牌、心跳周期。假设我在实验环境里做了这样的规划组件监听端口说明Hermes Agent9100本机指标与健康检查端口Hermes-Web-UI API8080中心端 API 服务Nginx80/443对外提供 Web 访问反代到 8080Agent 启动后会拿着配置文件里的register_token主动访问 Web-UI 的 API 地址完成注册注册成功后拿到新的身份标识之后每隔一段时间发送一次心跳。Web-UI 通过心跳判断节点是否在线。网络策略上只需要保证 Agent 节点能访问 Web-UI 的 API 端口就行不需要把 Agent 的 9100 端口对 Web-UI 开放除非你打算让中心端主动采集数据。这个方向一定要搞清不然防火墙规则会配反。2.3 为什么我坚持用 systemd 托管而不是 nohup不少教程让你用nohup ./hermes-agent 这种方式启动方便是方便但有几个致命问题重启机器后进程不会自动拉起SSH 断开后进程虽然可能存活但没人保证日志管理全靠重定向追加进程崩溃不会自动恢复。用 systemd 接管之后这些都不是问题开机自启enable一下就完事崩溃自动重启Restartalways兜底日志统一到 journaldjournalctl -u直接看出问题方便回查权限隔离可以指定专用系统用户运行不用 root模块化的服务本来就该交给 systemd 管尤其是生产环境别偷懒。3. 安装 Hermes Agent从下载到 systemd 托管这一章我按拿到安装包 - 规划目录 - 写配置 - 写 unit - 启动验证的顺序来。如果你用的是 RPM 包或者 Docker 镜像思路一致只是命令不同我会在关键节点提醒差异。3.1 获取安装包官方发布页与校验和Hermes Agent 一般通过官方 Release 页面发布选择对应 Linux amd64 架构的二进制压缩包。如果官方提供了 RPM 包直接用 dnf 安装最省事如果只有 tar.gz 压缩包按下面的流程操作。下载完成后先做校验避免拿到损坏或不完整的包wget https://your-download-host/hermes-agent-linux-amd64.tar.gz sha256sum hermes-agent-linux-amd64.tar.gz把输出结果和官方页面公布的 SHA256 值对比一致再继续。这个习惯看起来繁琐但生产环境部署必须养成尤其是涉及到需要注册令牌的组件校验一下更安心。解压到指定目录mkdir -p /opt/hermes-agent tar -zxvf hermes-agent-linux-amd64.tar.gz -C /opt/hermes-agent解压后先看一下目录结构确认主程序名称和目录层级后面写 systemd unit 时要精确指定 ExecStart 路径。3.2 规划目录结构别学我一开始乱放我第一次装的时候图省事直接把 Agent 解压到/root/下配置、日志、可执行文件全混在一起结果后来升级时极其痛苦备份都不知道该拷哪个目录。推荐按下面的结构来/opt/hermes-agent/ # 可执行文件与静态资源 /opt/hermes-agent/bin/ # 主程序 /etc/hermes-agent/ # 配置文件 /var/lib/hermes-agent/ # 运行时数据与缓存 /var/log/hermes-agent/ # 日志文件这样分的主要原因升级时只替换/opt/hermes-agent下的程序文件备份时打包/etc/hermes-agent和/var/lib/hermes-agent就足够日志目录独立方便按需清理。创建目录并赋予运行用户权限mkdir -p /opt/hermes-agent/bin /etc/hermes-agent /var/lib/hermes-agent /var/log/hermes-agent3.3 编辑配置文件一份最小可用的 hermes.confHermes Agent 的配置格式因版本而异可能是 INI、TOML 或 YAML但核心配置项大同小异。我以一个常见的 TOML 风格为例# /etc/hermes-agent/hermes.conf # 本节点唯一标识 server_id node-rocky-01 # 本地监听地址 listen_addr 0.0.0.0 listen_port 9100 # Web-UI 的 API 地址Agent 会主动访问这个地址完成注册 webui_endpoint http://192.168.1.10:8080 # 注册令牌需要在 Web-UI 后台创建 register_token 改成你在UI创建的Token # 心跳周期单位秒 heartbeat_interval 30 # 日志级别debug / info / warn / error log_level info # 运行时数据存储路径 storage_path /var/lib/hermes-agent写完之后配置文件里包含 Token 和节点信息权限要收紧chmod 600 /etc/hermes-agent/hermes.conf注意配置文件里的字段名务必以你实际下载版本的官方文档为准不同版本可能叫agent_id、server_url或api_endpoint。先./hermes-agent --help或看文档确认不要直接照抄。3.4 编写 systemd unit 并启动Agent 建议用专用系统用户运行不要直接用 rootuseradd -r -s /sbin/nologin hermes chown -R hermes:hermes /opt/hermes-agent /etc/hermes-agent /var/lib/hermes-agent /var/log/hermes-agent创建 unit 文件# /etc/systemd/system/hermes-agent.service [Unit] DescriptionHermes Agent Afternetwork-online.target Wantsnetwork-online.target [Service] Typesimple Userhermes Grouphermes WorkingDirectory/opt/hermes-agent ExecStart/opt/hermes-agent/bin/hermes-agent --config /etc/hermes-agent/hermes.conf Restartalways RestartSec5 LimitNOFILE65535 EnvironmentLANGen_US.UTF-8 EnvironmentLC_ALLen_US.UTF-8 [Install] WantedBymulti-user.targetAfternetwork-online.target和Wantsnetwork-online.target的意思是等服务网络就绪后再启动避免开机时网络没起来导致 Agent 注册失败。Restartalways保证进程崩溃后 5 秒自动拉起。加载并启动systemctl daemon-reload systemctl enable --now hermes-agent验证是否正常运行systemctl status hermes-agent journalctl -u hermes-agent -f ss -lntp | grep 9100systemctl status看进程状态journalctl看启动日志ss确认端口监听。这三步走完Agent 这边基本就绪。4. 部署 Hermes-Web-UI前端页面与后端 APIHermes-Web-UI 是管理和展示的入口所有 Agent 节点最终都会在这个界面上呈现。部署方式有现成 Docker 镜像和手动 Node.js 部署两种我以手动部署为例因为这种方式对网络和资源要求更可控也方便排查问题。4.1 Web-UI 的运行时依赖与部署方式Web-UI 一般是一个 Node.js 服务可能还依赖数据库做持久化。如果只是本地测试SQLite 够用生产环境建议上 PostgreSQL数据安全性和并发能力都更可靠。另外如果 Web-UI 用到 Redis 做任务队列或会话缓存也要先把 Redis 跑起来。安装 PostgreSQL 和 Redisdnf install -y postgresql-server postgresql-contrib redis postgresql-setup --initdb systemctl enable --now postgresql redis创建数据库和用户sudo -u postgres psql CREATE DATABASE hermes; CREATE USER hermes WITH PASSWORD 你的密码; GRANT ALL PRIVILEGES ON DATABASE hermes TO hermes;Web-UI 安装包同样从官方渠道获取解压到独立目录mkdir -p /opt/hermes-web-ui tar -zxvf hermes-web-ui-linux-amd64.tar.gz -C /opt/hermes-web-ui cd /opt/hermes-web-ui4.2 初始化数据库与管理员账号多数 Web-UI 项目会提供一个.env.example示例文件复制成.env后修改cp .env.example .env典型配置项PORT8080 NODE_ENVproduction DATABASE_URLpostgres://hermes:你的密码127.0.0.1:5432/hermes REDIS_URLredis://127.0.0.1:6379/0 SECRET_KEY随机生成一串64位字符串其中 SECRET_KEY 必须改成随机值推荐用下面命令生成openssl rand -hex 32然后执行数据库迁移和初始化npm install --production npm run migrate npm run seed具体命令以官方文档为准。初始化完成后通常会有一个创建管理员账号的命令比如./hermes-web-ui create-admin -u admin -p 你的强密码创建完成就可以启动服务了。为了让 Web-UI 也能开机自启我给它也写了一个 systemd unit# /etc/systemd/system/hermes-web-ui.service [Unit] DescriptionHermes Web UI Afternetwork-online.target postgresql.service redis.service Wantsnetwork-online.target [Service] Typesimple Userhermes WorkingDirectory/opt/hermes-web-ui ExecStart/usr/bin/node server.js Restartalways RestartSec5 EnvironmentNODE_ENVproduction [Install] WantedBymulti-user.target执行systemctl daemon-reload systemctl enable --now hermes-web-ui这时在服务器本地curl http://127.0.0.1:8080应该能返回页面内容或接口响应。4.3 用 Nginx 反向代理并开启 HTTPSWeb-UI 默认监听 8080如果直接用这个端口对外开放不仅暴露服务端口传输也不安全。Nginx 在这里做一个反向代理统一走 80/443。安装 Nginxdnf install -y nginx systemctl enable --now nginx配置示例# /etc/nginx/conf.d/hermes-web-ui.conf server { listen 80; server_name your-server-domain-or-ip; client_max_body_size 50m; location / { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } location /api/ { proxy_pass http://127.0.0.1:8080/api/; proxy_read_timeout 1800s; } }这里我把/api/单独拎出来配了一个更长的超时时间是因为 Agent 注册、任务下发这类接口可能需要长轮询或者上传大文件时请求时间较长。如果不调超时时间Nginx 默认 60 秒就会断开很多 Agent 注册到一半被掐断还查不出原因。配置生效nginx -t systemctl reload nginx如果要上 HTTPS建议直接用 certbot 签发证书这里不展开但记住一点启用 HTTPS 后Agent 配置文件里的webui_endpoint也要改成https://前缀否则 Agent 会访问一个不可达的 80 端口地址。4.4 在 Web-UI 中完成 Agent 注册与状态确认打开浏览器访问 Web-UI 地址用刚才创建的管理员账号登录。进入节点管理页面创建一个注册令牌然后把它填到 Agent 的hermes.conf里重启 Agentsystemctl restart hermes-agent回到 Web-UI 的节点列表正常情况下几秒内就能看到 Agent 节点出现状态变为 Online心跳时间会不断刷新。如果节点一直显示 Offline先用命令确认 Agent 能访问 Web-UI 的 APIcurl -v http://web-ui-ip:8080/api/health再确认 Web-UI 能被外部访问curl -v http://agent-ip:9100/health双向验证之后问题基本能定位到网络策略或 Token 不匹配上。5. 我踩过的坑从 SELinux 到端口不通装这套东西的过程中我踩过的坑比预想的多下面这几个是最高频的几乎每换一台新机器重装都会遇到其中一个。我把排查链路写出来你能顺着思路快速定位。5.1 SELinux 拦截服务起不来的第一元凶现象systemctl status hermes-agent显示 active (running)但端口就是没在监听日志也没有明显报错或者在启动后几秒内进程被悄悄杀掉。Rocky Linux 默认开启 SELinux它的强制访问控制策略会拦截没有被打上正确标签的可执行文件或目录访问。第一次装的时候我没考虑这一点卡了将近一个小时。排查命令dmesg | grep -i avc ausearch -m avc -ts recent如果确实看到 AVC denied 记录可以临时测试setenforce 0 systemctl restart hermes-agent服务恢复正常说明就是 SELinux 的问题。但生产环境不建议长期关闭 SELinux正确做法是为相关目录设置正确的文件上下文semanage fcontext -a -t bin_t /opt/hermes-agent/bin(/.*)? restorecon -Rv /opt/hermes-agent如果你安装的 Agent 有官方提供的 SELinux 支持模块直接安装之后restorecon即可。5.2 防火墙与云安全组双重放行现象服务监听正常本机 curl 也能通但其他机器就是连不上。问题基本上都出在两层策略上第一层是本机 firewalld第二层是云平台安全组。本机放行端口firewall-cmd --permanent --add-port9100/tcp --add-port8080/tcp firewall-cmd --reload提示如果 Agent 服务部署在腾讯云、阿里云等平台上云控制台里的安全组或防火墙规则同样需要放行对应端口。很多时候本机firewall-cmd全关了还是连不上一查安全组才发现没放行这个顺序颠倒排查起来特别浪费时间。5.3 yum 源失效导致依赖装不上现象dnf install时大量 404或 makecache 报错。主要原因是 Rocky Linux 旧版本源被下架到 vault或者镜像站同步不及。比如你装的是 8.10官方源可能已经把 8.10 的仓库标记为 archive镜像站路径里只剩vault/目录。解决办法有两种一是直接升级到当前最新的 8.x 或 9.x 补丁版本仓库路径自动修正二是手动把仓库文件的 baseurl 指向 vault 路径这种方式适合只想保持旧版本基线的情况。另外国内镜像站在大版本刚发布后偶尔会同步不全等半天还是 404那就换个镜像站试试不要死磕一个源。5.4 Agent 日志乱码与 timezone 设置现象Web-UI 上 Agent 节点上报的时间比实际时间差了 8 小时或者journalctl查看日志时中文乱码。系统时区如果保持默认 UTC时间会差整整 8 个小时直接影响心跳、任务调度和告警判断。我每装一台机器都会强制设置时区为 Asia/Shanghaitimedatectl set-timezone Asia/Shanghai日志乱码则多半是环境变量没设对。在 unit 文件里加EnvironmentLANGen_US.UTF-8和EnvironmentLC_ALLen_US.UTF-8基本能解决。另外时间同步服务也别省systemctl enable --now chronyd timedatectl确认 NTP synchronized 为 yes 再继续不然时钟偏移会导致 Agent 注册令牌校验失败。5.5 Web-UI 页面打不开时按这个顺序排查Web-UI 页面打不开这个问题我碰到过好几次每次原因都不同总结下来按这个顺序排查最有效率本机curl http://127.0.0.1:8080—— 先确认服务本身活着curl http://服务器公网IP—— 确认 Nginx 层没问题telnet 服务器IP 80—— 确认端口能从外部访问看 Nginx 错误日志/var/log/nginx/error.log看 Web-UI 日志journalctl -u hermes-web-ui -f按链路从内到外一层层验证很快就能定位到问题在哪个环节。我见过不少人直接拿浏览器访问打不开就开始怀疑代理配置到处改配置最后发现其实就是服务根本没启动。5.6 版本不匹配UI 与 Agent 的兼容性检查现象Agent 能正常启动日志里显示注册成功但 Web-UI 上节点状态异常或者 Agent 上报的数据 UI 解析不出来。这是升级之后最容易踩的坑。Hermes Agent 和 Hermes-Web-UI 的版本并不是无脑最新的互相兼容它们在注册协议、数据格式上可能有差异。升级之前一定要看官方 CHANGELOG 里的兼容矩阵最好保持 Agent 和 Web-UI 的大版本一致。我在测试环境就吃过一次亏把 Web-UI 从 1.x 升到 2.x但 Agent 集群还是 1.x结果所有节点注册后都显示协议错误最后只能逐个节点升级 Agent 才恢复正常。生产环境升级前务必先备份、再在测试环境验证一轮。6. 安装完成之后的日常维护Agent 装完、Web-UI 跑通这只是开始。日常维护里最容易忽略的两件事是日志轮转和升级备份这里给出我常用的配置。6.1 日志轮转配置如果 Agent 把日志写到/var/log/hermes-agent/而不是完全交给 journald时间一长日志文件会越来越大。用 logrotate 做自动轮转最省心# /etc/logrotate.d/hermes-agent /var/log/hermes-agent/*.log { daily rotate 14 compress delaycompress missingok notifempty copytruncate }copytruncate的优点是进程不用重启日志文件就被截断代价是有极小概率丢几行日志。如果 Agent 支持收到 USR1 信号后重新打开日志文件用create加sharedscripts配合 kill 信号更稳妥但实际场景下copytruncate基本够用。6.2 备份与升级备份建议只关注配置、数据和数据库不需要备份整个程序目录tar -czvf hermes-backup-$(date %F).tar.gz \ /etc/hermes-agent \ /var/lib/hermes-agent \ /opt/hermes-web-ui/.env如果用了 PostgreSQL还要导出数据库sudo -u postgres pg_dump hermes hermes-db-backup-$(date %F).sql升级流程我通常这样走下载新版本安装包备份当前配置与数据停服务systemctl stop hermes-agent hermes-web-ui替换程序文件启动服务systemctl start hermes-agent hermes-web-ui验证 Agent 注册和 UI 登录观察 10 分钟心跳是否正常升级前多看几眼官方的 CHANGELOG确认是否有破坏性变更尤其是 Agent 和 Web-UI 的版本匹配关系。这个习惯能避免绝大多数升级事故。我在多台 Rocky Linux 8.10 和 9.6 上重复过这套流程最大的体会是Agent 类服务安装本身并不复杂但系统底子如果不干净后面排查起来会非常痛苦。SELinux、防火墙、时区、yum 源这几个基础项建议新装完系统后先全部处理好再动手。还有一个很小的技巧每次改完 systemd unit 或配置文件第一时间执行systemctl daemon-reload然后打开journalctl -u hermes-agent -f看启动日志里前 20 行。很多配置路径写错、启动参数不对的问题在这个日志里一眼就能看出来根本不用等到节点下线了再去到处找原因。这套流程整体走下来正常情况下两个小时以内就能把 Agent 和 Web-UI 全部拉起来剩下的就是根据自己的业务需求去调整任务模板和告警规则。