smokeping主从机tcping备忘录

九月 26, 2026 / 3ku / 0阅读 / 0评论

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. 必须记住的几条

  1. 判断从节点死活看"有没有有效数据",不看文件时间、不看 rrdtool last(主节点会一直写 U 值)。
  2. 升级顺序永远是先从节点后主节点。
  3. 改时间范围(Presentation)后必须 pkill -f smokeping_cgi,光发 SIGHUP 不够。
  4. 改 RRA 行数只影响新建 RRD,已有文件要 rrdtool resize;扩容救不回已丢历史。
  5. 从节点时间戳比主节点快 ~30 秒是正常的(打的是测量窗口末尾),别当成时钟问题。
  6. 从节点容器务必带 --restart unless-stopped,否则退出后就是静默停摆(9/23 那次停了 3 天)。
  7. 别在从节点容器里手改文件(除了探针应急那次),容器重建即丢。
  8. 密钥若还是示例里的 123456 就务必换掉(主从同时改,步骤见第 5 节),并把 8080 只放行从节点 IP。
  9. 从节点的"恢复材料"(/root/smokeping-rescue/)别删,里面是探针 + 主节点地址 + 密钥。

文章作者:3ku

文章链接:https://nanodesu.net/archives/82

版权声明:本博客所有文章除特别声明外,均采用CC BY-NC-SA 4.0 许可协议,转载请注明出处!


评论