Categraf 本身是一个单二进制采集器,看起来部署很简单:把二进制和 conf 放到机器上,启动即可。但线上问题往往不是“命令跑不起来”,而是“手工前台正常,systemd 没数据”“宿主机能 curl,容器里连不上”“改了配置,进程还在用旧路径”“日志写到容器里,重建后找不到”。
这些问题本质上都和运行环境有关。Categraf 采集的对象可能在本机、远端、容器、Kubernetes、数据库或网络设备里;运行方式一变,配置路径、网络命名空间、文件权限、环境变量和日志位置都会变。
本文把 systemd 和容器部署中最常见的坑集中梳理出来,目标不是替代安装文档,而是给生产排障和标准化部署提供一份检查清单。
核心要点
- 推荐把二进制和配置放在
/opt/categraf,再用sudo ./categraf --install生成 systemd 服务;安装前必须先把文件放到最终目录。 --install会生成 unit、启用服务并执行daemon-reload,但不会自动启动;还需要sudo ./categraf --start。- systemd 不会自动继承登录 shell 的
PATH、代理、Token、数据库密码等环境变量。需要使用受控的 EnvironmentFile 或密钥管理方式注入。 - Categraf 默认读取二进制旁边的
conf;二进制移动后,旧 unit 不会自动更新ExecStart。 - 容器内的
127.0.0.1指向容器自身,不是宿主机,也不是其他容器。remote write、数据库地址和探测目标都要按实际网络命名空间配置。 - 容器部署必须显式挂载配置、证书、运行状态目录和必要的宿主机路径;否则重建容器后配置、日志或 WAL 状态可能丢失。
- 不管 systemd 还是容器,部署后都要用“服务状态、日志、
--test、后端裸指标、Dashboard 变量”做闭环验收。
1. 先选清楚部署模型
常见部署方式可以分成三类:
| 模型 | 适用场景 | 注意事项 |
|---|---|---|
| systemd 裸机部署 | 采 Linux 主机、数据库、本机进程、系统资源 | 权限、配置路径、EnvironmentFile |
| Docker/Compose 部署 | 快速试用、独立采远端目标、伴随夜莺环境 | 网络命名空间、volume、日志 |
| Kubernetes DaemonSet/Sidecar | 采节点、Pod、Service、集群组件 | ServiceAccount、hostPath、容器权限 |
如果需要采集宿主机 CPU、磁盘、进程、systemd、Docker socket 等本机资源,systemd 或特权受控的 DaemonSet 更直观。普通容器如果没有挂载宿主机路径,看到的是容器自己的文件系统和命名空间。
如果只采远端数据库、HTTP 探测、TCP 探测,容器部署也可以很好用,但要明确所有地址都是“从容器里访问”的视角。
2. systemd 推荐目录结构
推荐布局:
/opt/categraf/
├── categraf
├── conf/
│ ├── config.toml
│ ├── logs.toml
│ ├── input.cpu/
│ ├── input.mem/
│ ├── input.redis/
│ └── input.postgresql/
├── run/
├── data-agent/
└── meta/
安装:
cd /opt/categraf
sudo ./categraf --install
sudo ./categraf --start
sudo ./categraf --status
默认生成的 systemd 配置会以当前二进制路径为准,关键项类似:
[Service]
ExecStart=/opt/categraf/categraf -configs /opt/categraf/conf
WorkingDirectory=/opt/categraf
Restart=on-failure
RestartSec=120
EnvironmentFile=-/etc/sysconfig/categraf
ExecReload=/bin/kill -HUP "$MAINPID"
因此有两个常见坑:
- 在临时目录执行
--install,再把文件移动到/opt/categraf,unit 仍然指向临时目录; - 覆盖二进制后没有确认
ExecStart,导致启动的仍是旧路径。
检查:
systemctl cat categraf
systemctl show categraf \
-p FragmentPath \
-p ExecStart \
-p WorkingDirectory \
-p User \
-p EnvironmentFiles
如果路径不对,先确认没有自定义 unit 依赖,再按标准方式重建:
cd /opt/categraf
sudo ./categraf --stop
sudo ./categraf --remove
sudo ./categraf --install
sudo ./categraf --start
sudo ./categraf --status
3. systemd 不继承登录 shell 环境
手工终端里能成功:
export PG_PASSWORD='example'
export HTTPS_PROXY='http://proxy.example.com:8080'
./categraf --debug --inputs postgresql
不代表 systemd 服务也能成功。systemd 默认不会读取用户的 .bashrc、.zshrc 或 .profile。如果配置中用了环境变量:
address = "host=10.23.25.10 user=categraf password=${PG_PASSWORD} sslmode=disable"
应把变量放进受控环境文件。默认 unit 会读取:
/etc/sysconfig/categraf
示例:
sudo install -d -m 755 /etc/sysconfig
sudo tee /etc/sysconfig/categraf >/dev/null <<'EOF'
PG_PASSWORD=replace_with_real_secret
NO_PROXY=127.0.0.1,localhost,10.0.0.0/8
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
EOF
sudo chmod 600 /etc/sysconfig/categraf
sudo ./categraf --stop
sudo ./categraf --start
sudo ./categraf --status
分享配置或日志时,不要暴露真实密码、Token、代理账号和 Header。
验证 systemd 实际环境:
systemctl show categraf -p Environment -p EnvironmentFiles
pid=$(systemctl show categraf -p MainPID --value)
sudo tr '\0' '\n' < /proc/$pid/environ | sort
最后一条可能包含敏感信息,只在受控终端排查,不要直接贴到公开工单。
4. 前台测试和正式服务要使用同一份配置
排障时常见误判:
./categraf --test --inputs redis
这个命令可能读取当前二进制旁边的 conf,而正式服务读取的是 unit 中 --configs 指定的目录。先确认:
systemctl show categraf -p ExecStart -p WorkingDirectory
再用同一份配置测试:
/opt/categraf/categraf \
--configs /opt/categraf/conf \
--test \
--inputs redis
如果正式服务限制了 --inputs,前台命令也要加同样过滤,否则会出现“手工能采,服务没采”的错觉。
修改配置后,建议先做目标插件测试,再重启服务:
cd /opt/categraf
./categraf --test --inputs redis
sudo ./categraf --stop
sudo ./categraf --start
sudo ./categraf --status
journalctl -u categraf -n 100 --no-pager
HUP 可以触发 Agent reload,但只要改了主配置、writer、heartbeat、Prometheus Agent、Logs Agent、运行用户或二进制,生产上更推荐受控重启。
5. 日志写到哪里
默认 conf/config.toml 中:
[log]
file_name = "stdout"
systemd unit 把标准输出和错误输出写入 journal,因此查看日志:
journalctl -u categraf -b -n 200 --no-pager
journalctl -u categraf -f
如果改成文件:
[log]
file_name = "/var/log/categraf/categraf.log"
max_size = 100
max_age = 7
max_backups = 3
compress = true
要提前创建目录并设置权限:
sudo install -d -m 750 -o root -g root /var/log/categraf
如果 systemd 使用非 root 用户,目录属主也要对应调整。否则 Categraf 可能在日志初始化或运行中因为权限问题失败。
6. 容器内 127.0.0.1 是第一大坑
在 Docker 容器中:
127.0.0.1 = 当前 Categraf 容器
它不是宿主机,不是 Nightingale 容器,也不是 VictoriaMetrics 容器。
错误示例:
[[writers]]
url = "http://127.0.0.1:17000/prometheus/v1/write"
如果 Categraf 在容器里,而夜莺在另一个 Compose service,应该使用 service 名:
[[writers]]
url = "http://nightingale:17000/prometheus/v1/write"
如果后端在宿主机,Linux Docker 默认不一定支持 host.docker.internal。可以在启动时显式增加:
docker run --add-host=host.docker.internal:host-gateway ...
然后配置:
[[writers]]
url = "http://host.docker.internal:17000/prometheus/v1/write"
或者使用 host 网络模式:
docker run --network host ...
host 网络模式下容器共享宿主机网络命名空间,127.0.0.1 才会指向宿主机。但这也扩大了网络权限,应按实际安全要求选择。
7. 容器部署必须挂载配置和运行目录
最小 Docker 运行示例:
docker run -d \
--name categraf \
--restart unless-stopped \
-v /opt/categraf/conf:/etc/categraf/conf:ro \
-v /opt/categraf/run:/opt/categraf/run \
-v /opt/categraf/data-agent:/opt/categraf/data-agent \
-v /opt/categraf/meta:/opt/categraf/meta \
flashcatcloud/categraf:latest \
/usr/bin/categraf -configs=/etc/categraf/conf
如果只使用普通 Metrics Agent,run、data-agent、meta 不一定都需要;但一旦启用 Logs Agent、Prometheus Agent 或 Ibex Agent,就应该显式挂载对应状态目录:
| 目录 | 常见用途 |
|---|---|
conf |
主配置和 input 配置 |
run |
Logs Agent 读取状态 |
data-agent |
Prometheus Agent WAL |
meta |
Ibex Agent 任务目录 |
| 证书目录 | writer、数据库或 HTTP TLS 文件 |
不要把配置只 baked 到镜像里后在线修改容器内部文件。容器重建后这些改动会丢失,也不利于审计。
8. 采宿主机资源时不能只跑普通容器
如果容器里的 Categraf 要采宿主机文件系统、进程、Docker 或 systemd,需要额外挂载和权限。否则它看到的是容器内部视角。
常见挂载示例:
docker run -d \
--name categraf \
--restart unless-stopped \
--pid host \
-v /:/hostfs:ro \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
-v /opt/categraf/conf:/etc/categraf/conf:ro \
flashcatcloud/categraf:latest \
/usr/bin/categraf -configs=/etc/categraf/conf
是否需要这些挂载取决于启用的插件。比如:
- 只采远端 Redis,不需要 Docker socket;
- 采 Docker 插件,需要访问 Docker socket;
- 采宿主机进程、磁盘或网络时,需要确认插件读取的是宿主机路径还是容器路径;
- 采 systemd 相关指标时,需要考虑 DBus 权限和宿主机环境。
这些权限会扩大容器对宿主机的访问范围。生产环境应按最小权限原则配置,而不是为了省事直接 --privileged。
9. Compose 中的网络和依赖
Compose 示例:
services:
categraf:
image: flashcatcloud/categraf:latest
container_name: categraf
restart: unless-stopped
volumes:
- /opt/categraf/conf:/etc/categraf/conf:ro
- /opt/categraf/run:/opt/categraf/run
- /opt/categraf/data-agent:/opt/categraf/data-agent
- /opt/categraf/meta:/opt/categraf/meta
command:
- /usr/bin/categraf
- -configs=/etc/categraf/conf
depends_on:
- nightingale
nightingale:
image: flashcatcloud/nightingale:latest
这里 depends_on 只保证启动顺序,不保证夜莺或后端已经可写。Categraf 的 writer 会在运行中发送,后端稍晚起来通常可以恢复,但首次验收要看日志和后端裸指标,不要只看容器状态 Up。
Compose service 之间应使用服务名访问:
[[writers]]
url = "http://nightingale:17000/prometheus/v1/write"
如果要访问宿主机上的数据库,也必须使用容器可达的宿主机地址,而不是 127.0.0.1。
10. 重启策略和退出频率限制
systemd 默认:
Restart=on-failure
RestartSec=120
StartLimitInterval=3600
StartLimitBurst=10
这能避免配置错误时无限快速重启。修好配置后,如果 systemd 已经进入失败限制,可以执行:
sudo systemctl reset-failed categraf
sudo ./categraf --start
Docker 常用:
--restart unless-stopped
注意:自动重启不能替代配置验证。TOML 错误、证书权限、writer URL 错误会导致容器或服务反复重启,但根因仍然在日志最早的错误里。
11. 权限和文件属主
systemd 使用默认 root 运行时,读取配置和证书通常没问题,但安全边界较宽。自定义运行用户时,要提前检查:
systemctl show categraf -p User -p Group
namei -l /opt/categraf/conf/config.toml
ls -ld /opt/categraf /opt/categraf/conf /opt/categraf/run /opt/categraf/data-agent /opt/categraf/meta
常见权限问题:
- 配置目录只有 root 可读,服务用户不可读;
- TLS 证书文件权限过严;
run_path、wal_storage_path、meta_dir不可写;exec插件调用的脚本没有执行权限;- Docker socket 对服务用户不可读;
- 容器内 UID/GID 与宿主机挂载目录不匹配。
不要为了快速修复直接 chmod -R 777 /opt/categraf。应该明确 Categraf 运行用户,并只授予需要的读写权限。
12. 部署后的最小验收
systemd:
cd /opt/categraf
sudo ./categraf --status
systemctl show categraf -p ExecStart -p WorkingDirectory -p User -p EnvironmentFiles
journalctl -u categraf -n 100 --no-pager
容器:
docker ps --filter name=categraf
docker logs --tail=100 categraf
docker inspect categraf --format '{{json .Mounts}}'
docker exec categraf /usr/bin/categraf --version
采集验证:
/opt/categraf/categraf --configs /opt/categraf/conf --test --inputs redis
docker exec categraf /usr/bin/categraf -configs=/etc/categraf/conf --test --inputs redis
后端验证:
redis_up
如果已经导入 Dashboard,再验证变量:
count by (instance, agent_hostname) (redis_up)
最小闭环:
服务或容器处于运行状态
+ 日志没有持续 fatal/error
+ 前台 test 能采到目标插件
+ 正式模式写入后端
+ 后端裸指标有最新样本
+ Dashboard 变量能列出实例
13. 常见问题
为什么 --install 后 --status 还是 stopped?
--install 只负责安装并启用服务,不会自动启动。继续执行 sudo ./categraf --start。
为什么手工 --test 正常,systemd 没有指标?
优先比较 ExecStart、WorkingDirectory、--configs、--inputs、运行用户和 EnvironmentFile。两者很可能不是同一份配置或同一套环境。
容器里 writer 写 127.0.0.1 为什么失败?
容器内 127.0.0.1 是 Categraf 容器自身。使用 Compose service 名、宿主机网关地址,或选择 host 网络模式。
容器重建后配置丢了怎么办?
配置不应只修改容器内部文件。把 conf、证书和状态目录挂载到宿主机,并纳入配置管理。
生产环境应该用 HUP 还是重启?
只改本地 input 配置且已确认版本行为时可以考虑 HUP。改主配置、writer、日志、Prometheus/Logs/Ibex、环境变量、证书、运行用户或二进制时,使用受控重启更清晰。
14. 生产建议
- systemd 部署前先把文件放到最终目录,再执行
--install; - 所有服务都记录
ExecStart、WorkingDirectory、配置目录和二进制版本; - 密码、Token、代理和 PATH 通过受控 EnvironmentFile 或密钥系统注入;
- 配置和证书权限按运行用户最小授权;
- 容器部署显式挂载
conf和所需运行状态目录; - 容器内地址按容器网络视角编写,不把宿主机
127.0.0.1直接照搬; - 不依赖容器内部可变文件保存配置;
- 日志进入 journal、容器日志系统或持久化文件,不能只留在临时容器层;
- 配置变更先 test,再重启,再查后端裸指标;
- 自动重启只作为兜底,不能替代日志和指标验收。
15. 小结
systemd 和容器部署的差异,本质上是运行上下文差异:
配置路径
+ 运行用户
+ 环境变量
+ 网络命名空间
+ 文件系统挂载
+ 日志位置
只要这六件事说清楚,Categraf 部署问题通常可以很快定位。反过来,如果只看“进程是 running”或“容器是 Up”,很容易漏掉真正的数据链路问题。
下一篇继续讲维护层问题:Categraf 升级与回滚实践:配置备份、灰度验证和版本兼容。
内容更新时间:2026-07-21
证据边界:systemd unit 模板、--install 行为、HUP reload 和默认配置路径来自当前 Categraf 仓库源码与默认配置;容器镜像入口、Kubernetes 部署方式和不同发行版的 systemd 细节可能随环境变化,应以实际部署产物为准。