smokeping主从机tcping备忘录
SmokePing 维护命令手册(自用)
所有命令都在主节点宿主机上执行,除非标注了【从节点机器】或【容器内】。 文中
monitor.example.com指主节点地址、probe.example.com指从节点机器地址, 换成自己的域名或 IP 就能照抄。
环境速查
| 项 | 值 |
|---|---|
| 监控页面 | http://monitor.example.com:8080/smokeping/smokeping.fcgi.dist |
| 主节点容器 | smokeping-master(镜像 asdjkm1234/smokeping-master:latest) |
| 主节点目录 | 配置 /root/smokeping-docker/smokeping_config/,数据 /root/smokeping-docker/smokeping_data/ |
| 从节点 | 异地机器(下文用 probe.example.com 指代),容器 smokeping-slave(SMOKEPING_SLAVE_NAME=host1) |
| 从节点探针路径(容器内) | /usr/local/smokeping/lib/Smokeping/probes/TCPConnect.pm |
| 从节点日志(容器内) | /var/log/smokeping_slave.log |
| 探针 | TCPConnect(tcping 风格,探测 TCP 443,20 次/周期,间隔 1 秒,超时 1 秒) |
| 体检脚本 | /root/check-smokeping-slaves.sh(退出码 0 正常,1 异常) |
| 仓库打包 | /root/smokeping-docker-bundle-20260926.tar.gz(91KB,含 git 历史,用于重建从节点镜像) |
| RRD 备份 | /root/smokeping-rrd-backup-20260926/(6 个文件,18MB) |
| 回退用配置 | /root/smokeping-config-fping.bak(切回 ICMP ping 用) |
| 从节点救援材料 | 在从节点机器上:/root/smokeping-rescue/(TCPConnect.pm + env.txt) |
1. 日常体检(30 秒)
# ① 主节点容器在不在
docker ps --filter name=smokeping-master --format '{{.Names}} {{.Status}}'
# ② 数据是否新鲜 —— 最重要的一条,看有没有真实数据
/root/check-smokeping-slaves.sh
# CMCC-SH~host1.rrd OK (近10分钟 11 格有数据)
# 退出码 0 = 正常,1 = 有从节点掉了
# ③ 从节点是否在上报(每分钟一条 POST)
docker logs smokeping-master 2>&1 | grep smokeping-slave | tail -3
# ④ 页面是否正常
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8080/smokeping/smokeping.fcgi.dist
【从节点机器】上:
docker ps -a --filter name=smokeping-slave # 必须是 Up,不能是 Exited
docker logs --tail 5 smokeping-slave # 应有 TCPConnect: probing 3 targets
⚠️ 不要用 RRD 文件时间或
rrdtool last判断从节点死活。 从节点掉线后主节点仍会每分钟写空值(U), 文件时间照常在变。必须看近 N 分钟有没有有效 median 值(体检脚本就是干这个的)。
2. 看日志和内部状态
# 主节点日志(实际是 Apache 访问日志)
docker logs -f smokeping-master
docker logs smokeping-master 2>&1 | grep smokeping-slave | tail -5 # 从节点上报记录
docker logs smokeping-master 2>&1 | grep -E '" 5[0-9][0-9] ' | tail -10 # 有没有 5xx(注意带上引号,否则会误匹配响应字节数)
# 从节点日志【从节点机器】
docker logs --tail 30 smokeping-slave
docker logs smokeping-slave > /tmp/slave-$(date +%F).log # 容器重建前先存证据
# 守护进程加载的是哪个探针(进程名会带 [TCPConnect])
docker exec smokeping-master ps aux | grep '[s]mokeping \['
# 跑一轮并打印内部细节(不影响正在跑的守护进程,看 RRD 写入命令和报错)
docker exec smokeping-master /usr/local/smokeping/bin/smokeping \
--config=/usr/local/smokeping/etc/config --debug
# 配置语法检查
docker exec smokeping-master /usr/local/smokeping/bin/smokeping \
--config=/usr/local/smokeping/etc/config --check
# 缓存目录里的图(每个目标每个时间范围一张)
docker exec smokeping-master ls -l /usr/local/smokeping/cache/ | grep CT-SH
3. 改完配置怎么生效
两步,按改动内容选用:
# ① 守护进程(管写 RRD)—— 改了 Probes / Targets / Database / Slaves 后
docker exec smokeping-master sh -c 'kill -HUP $(cat /usr/local/smokeping/var/smokeping.pid)'
# ② CGI(管出图)—— 改了 *** Presentation *** 的时间范围后必须执行,否则新图不出现
docker exec smokeping-master pkill -f smokeping_cgi # 无停机,fcgid 会自动拉起
不想记这两步就直接重启容器(页面中断约 10 秒):
docker restart smokeping-master
注意:改 *** Database *** 里的 RRA 行数只对以后新建的 RRD 生效,已经在跑的文件要按第 6 节扩容。
4. 从节点维护
4.1 从节点容器没了 / 重装后恢复(高频,记住这一个就行)
【从节点机器】上:
cd /root/smokeping-rescue # 材料目录,先确认里面有 TCPConnect.pm 和 env.txt
docker run -itd --name smokeping-slave --restart unless-stopped \
-e SMOKEPING_MASTER_URL="(env.txt 里的值)" \
-e SMOKEPING_SHARED_SECRET="(env.txt 里的值)" \
-e SMOKEPING_SLAVE_NAME="host1" \
asdjkm1234/smokeping-slave:latest
docker cp TCPConnect.pm smokeping-slave:/usr/local/smokeping/lib/Smokeping/probes/
docker restart smokeping-slave
docker logs --tail 10 smokeping-slave # 出现 TCPConnect: probing 3 targets 即恢复
如果救援材料被删了,用主节点上的探针重新下载(主节点上要先把文件放进 web 目录):
# 主节点上
docker cp /root/smokeping-docker/probes/TCPConnect.pm \
smokeping-master:/usr/local/smokeping/cache/TCPConnect.pm
# 从节点机器上
curl -fsSL http://monitor.example.com:8080/smokeping/cache/TCPConnect.pm -o /tmp/TCPConnect.pm
4.2 升级顺序(不能反)
先升从节点,再升主节点。 主节点配置一旦指向新探针,缺探针的从节点 require 失败会直接退出
(启动命令是 smokeping && tail,smokeping 一退容器就退),彻底不上报。
4.3 从节点重建镜像(彻底方案)
# 把 /root/smokeping-docker-bundle-20260926.tar.gz 传到从节点机器,然后
tar xzf smokeping-docker-bundle-*.tar.gz && cd smokeping-docker
docker build -f smokeping-slave/Dockerfile -t asdjkm1234/smokeping-slave:latest .
docker rm -f smokeping-slave
docker run -itd --name smokeping-slave --restart unless-stopped \
-e SMOKEPING_MASTER_URL="..." -e SMOKEPING_SHARED_SECRET="..." -e SMOKEPING_SLAVE_NAME="host1" \
asdjkm1234/smokeping-slave:latest
必须用仓库根目录做构建上下文(要拷贝 probes/TCPConnect.pm)。重建后镜像自带探针,不用再 cp。
4.4 从节点到主节点通不通
【从节点机器】上:
curl -I --max-time 10 http://monitor.example.com:8080/smokeping/smokeping.fcgi.dist
curl -s -o /dev/null -w '%{http_code}\n' --max-time 10 \
http://monitor.example.com:8080/smokeping/smokeping.fcgi.dist
5. 新增/修改从节点、目标、密钥
新增从节点(如 host2):① 主节点 smokeping_secrets.dist 加 host2:强密钥;
② config 的 *** Slaves *** 加 +host2 + display_name + color;
③ 目标上加 slaves = host1 host2;④ 执行第 3 节的重载两步;⑤ 在新机器上按第 4 节部署。
新增监控目标:*** Targets *** 下加一段,然后重载:
+ CT-BJ
menu = 北京电信
title = 北京电信
host = xxx.example.com
port = 443 # 可按目标覆盖探针参数
connecttimeout = 2
slaves = host1
nomasterpoll = yes # 主节点不自己探测
新目标第一次探测时主节点会自动创建对应 RRD。
换密钥:主节点 smokeping_secrets.dist 改 + 重载,从节点容器的 SMOKEPING_SHARED_SECRET 同步改
(重建容器或用 docker run 时改)。
临时看从节点当前用的主节点地址和密钥:
# 【从节点机器】
docker inspect smokeping-slave --format '{{range .Config.Env}}{{println .}}{{end}}' | grep SMOKEPING
6. RRA 扩容(时间范围画不全时)
覆盖时长公式:行数(rows) × 聚合步数(pdp_per_row) × step
| 配置 | 分辨率 | 覆盖 | 服务于 |
|---|---|---|---|
AVERAGE 0.5 1 1008 |
1 分钟 | 16.8 小时 | 3 小时图 |
AVERAGE 0.5 12 4320 |
12 分钟 | 36 天 | 10 天图 |
AVERAGE 0.5 144 2160 |
2.4 小时 | 216 天 | 90 / 180 天图 |
镜像里没有 rrdtool 命令行,用临时容器:
# ① 备份
mkdir -p /root/rrd-backup-$(date +%F)
cp -a /root/smokeping-docker/smokeping_data/*.rrd /root/rrd-backup-$(date +%F)/
# ② 起临时容器并装 rrdtool
docker run -d --name rrdtools -v /root/smokeping-docker/smokeping_data:/data \
asdjkm1234/smokeping-master:latest sleep 3600
docker exec rrdtools sh -c 'apt-get update -qq && apt-get install -y --no-install-recommends rrdtool'
# ③ 先看 RRA 序号(顺序和 config 里的定义顺序一致)
docker exec rrdtools sh -c 'cd /data && rrdtool info "CT-SH~host1.rrd" | grep -E "^rra\[[0-9]+\]\.(cf|pdp_per_row|rows)"'
# ④ 扩容:第 4/5/6 档各增加 1440 行(720 → 2160 行 = 216 天)
docker exec rrdtools sh -c 'cd /data && for f in *.rrd; do
rrdtool resize "$f" 4 GROW 1440 >/dev/null && mv resize.rrd "$f"
rrdtool resize "$f" 5 GROW 1440 >/dev/null && mv resize.rrd "$f"
rrdtool resize "$f" 6 GROW 1440 >/dev/null && mv resize.rrd "$f"
chown www-data:www-data "$f"; chmod 644 "$f"
done && echo 扩容完成'
# ⑤ 清理
docker rm -f rrdtools
要点:GROW n 的 n 是增加的行数;resize 会把结果写成当前目录的 resize.rrd,必须 mv 回去;
扩容保留现有数据但救不回已被覆盖的旧历史;尽量在刚写完一次数据的空档做;
*** Database *** 里的行数也要同步改,否则以后新建的 RRD 还是旧的。
不用 rrdtool CLI 也能看结构和数据(用镜像里的 Perl RRDs):
# 看 RRA 结构 / 覆盖
docker exec smokeping-master perl -MRRDs -e '
my $f = shift; my $i = RRDs::info($f) or die RRDs::error;
my @r = sort { $a <=> $b } map { /^rra\[(\d+)\]\.cf$/ ? $1 : () } keys %$i;
printf "%s step=%ss\n", $f, $i->{step};
for my $k (@r) {
printf " RRA%d %-8s pdp=%-4s rows=%-5s 覆盖=%.1f 天\n", $k,
$i->{"rra[$k].cf"}, $i->{"rra[$k].pdp_per_row"}, $i->{"rra[$k].rows"},
$i->{"rra[$k].rows"} * $i->{"rra[$k].pdp_per_row"} * $i->{step} / 86400;
}' /usr/local/smokeping/data/CT-SH~host1.rrd
# 看某目标最近 20 分钟有没有数据(单位 ms,U = 无数据)
docker exec smokeping-master perl -MRRDs -MPOSIX=strftime -e '
my $f = shift;
my ($s,$st,$n,$d) = RRDs::fetch($f,"AVERAGE","-s","-20min");
my %i; @i{@$n} = (0..$#$n);
for my $k (0..$#$d) {
printf "%s:%s ", strftime("%H:%M", localtime($s+$k*$st)),
(defined $d->[$k][$i{median}] ? sprintf("%.1f", $d->[$k][$i{median}]*1000) : "U");
} print "\n";' /usr/local/smokeping/data/CT-SH~host1.rrd
缓存图命名对照(<目标>_last_<秒数>.png):3 小时=10800,24 小时=86400,10 天=864000,
90 天=7776000,180 天=15552000。
7. 备份与回滚
# 备份(配置 + 数据)
cd /root/smokeping-docker && tar czf /root/smokeping-backup-$(date +%F).tar.gz smokeping_config smokeping_data
# 回滚到 ICMP ping(新镜像里 fping 还在,能直接用)
cp /root/smokeping-config-fping.bak /root/smokeping-docker/smokeping_config/config
docker restart smokeping-master
# 回滚 RRD 到扩容前(会丢掉扩容之后写入的数据)
cp -a /root/smokeping-rrd-backup-20260926/*.rrd /root/smokeping-docker/smokeping_data/
docker restart smokeping-master
8. 报错对号入座
| 现象 / 日志 | 原因 | 处理 |
|---|---|---|
| 【从节点】容器 Exited | 探针缺失导致 smokeping 退出 | 第 4.1 节恢复 |
【从节点】Can't locate Smokeping/probes/TCPConnect.pm |
容器里没探针(容器被重建过) | 第 4.1 节 |
【从节点】Master said 500 read timeout |
主节点 CGI 响应慢,这一轮数据丢 | 看主节点负载,一般自愈 |
【从节点】smokeping took 79 seconds to complete 1 round |
一轮超过 step(目标不通/丢包重) | 确认目标可达;减 pings 或加大 connecttimeout |
| 【从节点】容器在跑但主节点没有 POST | 网络/端口不通或主节点挂了 | 第 4.4 节 |
| 【主节点】新加的时间范围图不出现 | CGI 进程缓存旧配置 | 第 3 节第 ② 步 |
| 【主节点】图左侧空白 | 该范围超过最长 RRA 覆盖,或那段时间从节点停了 | 第 6 节;查体检脚本 |
【主节点】slave 'host2' is not defined |
*** Slaves *** 里没这个名字 |
第 5 节 |
| 【主节点】看不到守护进程日志 | 配置没设 logfile,日志进了 syslog 黑洞 |
加 logfile = /var/log/smokeping.log 后重启 |
| 页面 502/空白 | CGI 挂了或容器重启中 | docker restart smokeping-master;docker logs 看 Apache |
9. 必须记住的几条
- 判断从节点死活看"有没有有效数据",不看文件时间、不看
rrdtool last(主节点会一直写 U 值)。 - 升级顺序永远是先从节点后主节点。
- 改时间范围(Presentation)后必须
pkill -f smokeping_cgi,光发 SIGHUP 不够。 - 改 RRA 行数只影响新建 RRD,已有文件要
rrdtool resize;扩容救不回已丢历史。 - 从节点时间戳比主节点快 ~30 秒是正常的(打的是测量窗口末尾),别当成时钟问题。
- 从节点容器务必带
--restart unless-stopped,否则退出后就是静默停摆(9/23 那次停了 3 天)。 - 别在从节点容器里手改文件(除了探针应急那次),容器重建即丢。
- 密钥若还是示例里的
123456就务必换掉(主从同时改,步骤见第 5 节),并把 8080 只放行从节点 IP。 - 从节点的"恢复材料"(
/root/smokeping-rescue/)别删,里面是探针 + 主节点地址 + 密钥。
评论