资讯动态

Docker 部署 SmokePing:网络延迟与丢包监控实战

发布时间:2026/10/26 21:34:40 来源:尧图企业网站定制
1. SmokePing 测的到底是什么从一次 ICMP 往返到一张曲线我先说一个常被搞混的点。很多人第一次听说 SmokePing会把它当成网络监控系统装上以后发现它既不看 CPU 也不看内存只画几条歪歪扭扭的彩色线就觉得这工具功能单一。实际上它干的事情非常垂直持续、长期、可视化地测量一条链路的往返延迟和丢包率然后把数据压缩成一种体积可控、查询代价极低的时间序列让你能在半年后翻回去看那天下午三点到底是不是网络抖了。用 Docker 部署 SmokePing 的价值不在于省去几条安装命令而在于把探测进程和CGI 绘图前端这两套东西连同它们各自的权限、时区、持久化需求一次性钉在一份可复制的描述文件里。我最早接触它的场景是一个跨机房的内网链路每天上午十点左右业务方就喊卡运维过去 ping 两分钟一切正常人一走又开始卡。这种间歇性、低概率、短时间的问题靠人肉 ping 根本抓不到因为它需要的是每五分钟固定发一组包连续记录几十天。这就是 SmokePing 的舒适区。它的思路很朴素按固定周期向目标发若干个探测包统计这一组包的丢包数量和中位数延迟写进 RRD 数据库绘图前端再从数据库里把历史数据拉出来渲染成图。这个模型决定了三件事后面所有的部署配置都围绕它们展开。第一它是无状态探测 有状态存储探测进程挂掉重启没关系但 RRD 文件丢了等于历史全废所以存储必须落盘。第二它的数据写入频率是固定的叫step默认 300 秒改这个参数会连带影响已有数据库的兼容性不能随手改。第三它的探测能力由探针决定探针可以是 ICMP、DNS 查询、TCP 连接、HTTP 请求这决定了它能覆盖的场景边界。1.1 探测循环守护进程、探针与 RRD 数据库SmokePing 运行起来后有两个常驻角色。一个是smokeping守护进程它按照step的节奏醒来读配置里定义的目标列表为每个目标启动对应的探针子进程去发包收回结果后按目标名把数据写进对应的.rrd文件。另一个是 CGI 前端只有当浏览器访问时才被拉起它的工作是从.rrd里取出指定时间段的数据丢给绘图库算出一张 PNG。两者之间没有直接通信唯一的耦合点就是那个数据目录。RRD 这个存储格式老派但极其能打。它的核心设计是固定大小的环形数据库文件创建时就把所有需要保留的时间粒度全部预留好写入时只做覆盖不做追加。好处是文件大小恒定、不会随着时间膨胀、查询任意历史区间都是常数级开销。代价是建库那一刻的参数就锁死了比如你按 5 分钟粒度建了库之后想把step改成 60 秒旧文件会直接报错拒绝写入只能删库重来。这个特性在容器化场景里尤其需要注意因为很多人会把数据目录挂载到宿主机改配置试错时忘了清理旧的 RRD然后对着日志里一堆expected X, got Y发呆。一个目标对应一个 RRD 文件文件名由目标在配置里的路径加上探针名拼成比如路径是LocalMachine、探针是FPing那文件大概就叫LocalMachine~FPing.rrd。这意味着你调整配置里的目标层级结构时实际上是在改变文件的命名空间——把一个目标从China挪到Overseas下面它会从零开始积攒新数据旧数据还在磁盘上但图表里看不到了。这个坑我在第一次重构分组的时候踩得很实。1.2 两张图的读法丢包色块与中位数曲线默认每个目标会出两张图上下排列。上面那张是丢包图下面那张是延迟图。这两张图的编码方式不一样得分开理解否则很容易误判。丢包图用色块表示。没有丢包时是一条冷色调的基准带随着丢包比例上升颜色会往暖色方向走从浅到深依次过渡如果某一格完全没有收到回应连探测都失败了会用另一种颜色单独标出白色或灰色通常代表这段时间没有数据——可能是探测进程当时没跑也可能是容器重启导致的空档。所以看到图上出现灰色断层别急着怀疑网络先去看容器那段时间有没有重启过。这个判断顺序能省掉大量无谓的排查。延迟图信息更密。图里的灰色或浅色阴影区域表示这一组探测包的分布范围深色的那条线是中位数。有些配置下阴影还会分成几层表示四分位区间。读这张图的诀窍是看形状不看绝对值一条平直的中位线突然开始周期性起伏往往说明链路上有个队列在定时堆积中位线稳定但阴影区域突然变宽说明抖动变大而平均延迟没变这种情况对实时业务的影响比平均延迟上升更严重。我一般会先看阴影宽度再看中位线高度因为平均值的欺骗性太强了。提示判断是不是我这边的问题最省钱的办法是在同一台 SmokePing 上同时监控网关、出口路由和远端目标三个层级。如果三层同时抖问题在本地如果只有远端抖问题在中间链路。这个三层对照的配置方式后面会具体写。1.3 它不擅长的事以及什么时候该换方案把边界说清楚能避免大量无效投入。SmokePing 的强项是长期、低频、多目标的延迟趋势记录它不擅长做秒级实时告警也不擅长做应用层的事务追踪。它的最小粒度受step限制默认五分钟一轮就算你把step压到 60 秒一轮探测也只有pings个包默认 20 个它能告诉你这一分钟里有一半的包丢了但没法告诉你这一分钟里第 37 秒发生了什么。另外它的告警是延迟型而不是事件型。告警规则基于历史数据序列的模式匹配不是基于某个瞬时事件。想做到目标一不可达立刻响铃它的响应延迟至少是一个step加上告警检查周期。真要低延迟告警得让别的工具去做SmokePing 留在旁边负责提供证据链——出事以后翻出那张图比一百行日志都有说服力。我一般的分工是实时告警交给专门的探测系统SmokePing 负责长期取证和趋势分析两者监控同一批目标互不替代。2. 上 Docker 之前得想清楚的三个边界挂载、时区、内核权限容器化这件事本身没有难度真正的麻烦都在容器和宿主机交界的那一层。SmokePing 尤其明显因为它同时需要写数据发原始包被 Web 服务器调用这三件性质完全不同的事。我见过不少人第一次跑起来顺风顺水第二天重启容器之后历史曲线全空或者页面能打开但图上一条线都没有这些问题的根子基本都在下面三个边界上。2.1 哪些目录必须落到宿主机必须挂载的目录只有两类但每一类下面还有细节。第一类是配置目录SmokePing 的主配置文件通常叫Config里面用include引入一堆分片文件改配置只需要改宿主机上的文件然后让容器重新加载不用进容器操作。第二类是数据目录也就是 RRD 文件存放的地方这个目录丢了就等于所有历史归零。还有第三类容易被忽略图片缓存目录。SmokePing 的 CGI 为了减少重复渲染会把生成的 PNG 缓存到磁盘上下次同样的请求直接返回文件。这个目录如果放在容器可写层里容器一重建缓存就没了问题不大但如果它和 RRD 目录共用同一个挂载点权限模型就会打架——写入 RRD 的是探测进程的用户写缓存的是 Web 服务器的用户两个用户对同一个目录都需要写权限。我的处理办法是给数据区和缓存区分别建目录然后把它们的属组设成共同的一个组目录权限用2775那一位2是 setgid作用是让目录里新建的文件自动继承父目录的属组。这样探测进程和 Web 用户都能写也不会因为某次容器重建后文件属主变成 root 而突然画不出图。这个细节在文档里基本不会提但它是图表莫名变空白这个症状最常见的成因之一。mkdir -p /srv/smokeping/{config,data,cache} chown -R 1000:1000 /srv/smokeping chmod -R 2775 /srv/smokeping/data /srv/smokeping/cache上面这个1000:1000只是示例实际要填容器内探测进程和 Web 用户对应的 uid/gid。做法很简单容器跑起来之后docker exec进去id一下把两个用户的信息看清楚再回到宿主机对齐。2.2 时区不对图的时间轴会整体平移这个坑几乎每个自己打镜像的人都会踩一次。容器默认是 UTCSmokePing 按本地时间生成时间标签和图表刻度如果时区没设你在页面上看到的所有时间都会比你认知里的时间差几个小时。可怕的是它不会报错图照常画只是昨天下午三点的那次抖动在图上显示成了上午十一点你去查日志会发现对不上然后开始怀疑人生。正确的做法是双管齐下环境变量TZ设成目标时区同时在容器启动时把/etc/localtime和/etc/timezone一起写好。只设环境变量在某些基础镜像里不够因为底层的 C 库在解析时间时读的是/etc/localtime。RRD 里存的是时间戳本身不带时区信息所以时区改错不会污染已存数据改对之后历史曲线的时间轴会立刻正确这一点算是好消息。environment: - TZAsia/Shanghai配合启动脚本里的这两行基本就稳了ln -snf /usr/share/zoneinfo/$TZ /etc/localtime echo $TZ /etc/timezone2.3 ICMP 权限容器里发原始包的两条路SmokePing 最常用的探针是fping它默认走原始套接字发 ICMP 包。这里有个容易误判的地方标准 Docker 容器的默认能力集里是包含NET_RAW的所以用默认参数跑通常没有问题。但一旦你在编排文件里写了cap_drop: [ALL]或者在更严格的运行环境里跑fping就会静默失败——注意是静默探测结果全是丢包图表上一条紫色横线看起来像目标全挂了实际上是权限不够根本发不出去包。两条路可以解决。第一条是显式保留能力给容器加NET_RAW。第二条是让fping走非特权 ICMP也就是用数据报套接字而不是原始套接字这需要在容器内放开net.ipv4.ping_group_range把允许发包的 gid 范围设宽cap_add: - NET_RAW # 或者在非特权场景下 sysctls: net.ipv4.ping_group_range: 0 2147483647我给的建议是优先用第一种简单直接如果是 rootless 容器或者受限的集群环境那第二条路更干净。判断到底走没走通最快的验证是在容器里手动跑一次docker exec -it smokeping fping -c 3 1.1.1.1如果这里能出结果说明权限没问题问题在别处如果这里报socket: Operation not permitted或者直接沉默那就是权限问题别再去翻配置文件了。3. 从空目录跑通第一张图镜像、compose 与验证清单我不太建议直接用现成的第三方镜像然后黑盒使用理由不是不信任而是 SmokePing 的配置文件改动频率很高你需要清楚地知道配置在镜像里的哪个位置、CGI 脚本映射到哪个 URL、Apache 的站点配置是怎么挂进去的。自己写一份 Dockerfile几十行把所有东西摆在明面上后面调优的时候省心得多。下面这份骨架基于 Debian 系的包管理思路是把发行版已经打包好的 SmokePing、fping、Apache 装进去再用一个入口脚本把守护进程和 Web 服务一起拉起来。包名和路径以你实际使用的基础镜像为准第一次构建完务必进容器手动验证一遍不要直接上生产。FROM debian:bookworm-slim ENV DEBIAN_FRONTENDnoninteractive RUN apt-get update apt-get install -y --no-install-recommends \ smokeping \ fping \ apache2 \ tzdata \ ca-certificates \ curl \ rm -rf /var/lib/apt/lists/* RUN a2enmod cgid \ a2enconf smokeping \ a2dissite 000-default COPY entrypoint.sh /entrypoint.sh RUN chmod x /entrypoint.sh EXPOSE 80 ENTRYPOINT [/entrypoint.sh]入口脚本负责三件事设时区、修目录权限、同时启动探测守护进程和 Apache。#!/bin/bash set -e : ${TZ:Asia/Shanghai} ln -snf /usr/share/zoneinfo/$TZ /etc/localtime echo $TZ /etc/timezone mkdir -p /data /var/cache/smokeping/images /var/run/smokeping chown -R smokeping:www-data /data /var/cache/smokeping/data /var/run/smokeping 2/dev/null || true chmod -R 2775 /data /var/cache/smokeping/images 2/dev/null || true smokeping --config/etc/smokeping/config --nodaemon exec apachectl -D FOREGROUND3.1 编排文件把配置、数据、缓存三个卷分清楚services: smokeping: build: . image: smokeping:local container_name: smokeping restart: unless-stopped ports: - 8080:80 environment: - TZAsia/Shanghai volumes: - ./config:/etc/smokeping/config.d - ./data:/data - ./cache:/var/cache/smokeping/images cap_add: - NET_RAW这里有个设计选择值得说我把宿主机目录挂到config.d而不是整个/etc/smokeping。原因是主配置文件Config里通常是一串include只做编排不做内容把它留在镜像里把真正要改的分片文件General、Probes、Targets、Alerts放宿主机。这样升级镜像时不会因为挂载覆盖导致主配置丢失改动也只集中在少数几个文件上。代价是如果你要改include的结构就得重新构建镜像但这个操作频率极低可以接受。数据目录我建议不要和配置目录放在同一个父目录下再整体挂载。分开挂载的好处是备份策略可以差异化配置需要版本控制数据需要定期快照缓存可以直接丢弃。3.2 第一次启动后的五项验证容器起来之后不要急着开浏览器按下面这个顺序验一遍能提前发现八成问题。第一项看守护进程有没有真的在跑。docker logs里如果没有明显报错再docker exec进去ps aux | grep smokeping确认进程存在。第二项看数据目录里有没有开始生成.rrd文件默认step是 300 秒意味着至少要等一个探测周期结束才会有第一个数据点刚启动那几分钟目录是空的很正常别慌。第三项容器内手动跑一次 fping 验证权限。第四项访问 Web 首页确认 CGI 能执行、菜单能渲染。第五项等两个周期之后回来看图此时应该能看到至少一根线的雏形。注意第一次部署时如果只是打开首页看到菜单不要就此认为成功。菜单是静态渲染的即使数据库全空也能显示。真正的验收标准是某个目标下点进去能看到一张有数据的图。3.3 反向代理与访问控制别留到最后SmokePing 本身不带认证CGI 页面裸奔在公网上等于把内网拓扑和目标清单拱手送人——你的 Targets 配置里往往写着大量内网地址和业务节点名称这些信息本身就是资产。放在反向代理后面加一层基础认证是最低要求同时建议在代理层再做一次 IP 白名单。代理配置里有两个点容易出问题。一是cgiurl这个配置项必须和实际的对外访问路径严格一致否则前端生成的链接会 404页面能打开但点任何目标都跳不过去。二是路径前缀如果你挂在/smokeping/而不是根路径下Apache 侧的别名映射和配置里的imgurl都得同步改改漏一个就会出现图裂了但文字正常的诡异现象。4. 三份配置文件的写法General、Probes、Targets 逐项拆解配置是 SmokePing 里最需要耐心的部分好在它的语法很朴素*** 段名 ***划分大段include引入分片的数量表示层级key value写参数。真正容易出错的是哪些参数属于哪个段和层级继承怎么生效下面按实际情况拆。4.1 General 段路径变量与全局行为General 段里除了联系人和邮件设置最关键的是几个路径变量它们决定了数据写到哪里、缓存放哪里、绘图模板从哪读。*** General *** owner 运维组 contact opsexample.internal mailhost localhost cgiurl http://monitor.example.internal:8080/smokeping.cgi charset utf-8 datadir /data imgcache /var/cache/smokeping/images imgurl /smokeping/images piddir /var/run/smokepingcharset这一行看起来不起眼但如果你的菜单名或者目标标题里写了中文不设它会出乱码。datadir一定要指向你挂载的那个卷这是数据持久化的唯一入口。imgurl是浏览器访问缓存图片时用的 URL 前缀它必须和 Apache 里的别名对应不对应就是图裂。4.2 Probes 段探针定义与参数含义探针段定义用什么方式探测每个探针有个名字Targets 里通过probe 名字引用。*** Probes *** FPing binary /usr/bin/fping packetsize 56 step 300 pings 20 timeout 1.5pings和step是最需要想清楚的两个数。pings 20意味着每轮发 20 个包step 300意味着每 5 分钟一轮所以一格里其实包含了 20 次测量图上画的中位数是这 20 次的统计结果而不是单次值。丢包率也是按20 个里丢几个算出来的所以理论上最小可分辨的丢包粒度是 5%。如果你需要识别 1% 级别的偶发丢包得把pings加大或者把step缩短这两个动作都会成比例增加发包量后面容量那一节会算这笔账。packetsize 56是 ICMP 载荷大小加上 8 字节 ICMP 头和 20 字节 IP 头正好凑成常见的 84 字节报文。如果你的场景关心大包路径的 MTU 问题可以另起一个探针把packetsize调到 1400 左右做大小包对比这个手法在排查分片黑洞时非常好用。还有两个参数不常改但值得知道offset控制探测周期在时间轴上的相位多实例部署时错开可以避免所有探针同时发包mininterval限制同一探针对多个目标的发包间隔防止一瞬间打出大量包。4.3 Targets 段层级结构决定了图表的组织方式Targets 段是日常改动最多的地方。它的语法核心就一条的数量表示层级深度一级菜单一个加号二级两个以此类推。*** Targets *** probe FPing menu 总览 title 网络延迟总览 内网 menu 内网 title 内网节点 核心网关 menu 核心网关 title 核心网关延迟 host 10.0.0.1 alerts lossdetect, rttdetect 出口链路 menu 出口链路 title 出口链路延迟 host 10.0.0.254 外部 menu 外部 title 外部目标 公共DNS menu 公共DNS title 公共DNS延迟 host 1.1.1.1 probe FPing这里有两点经验。第一属性是向后继承的。顶层的probe FPing会往下传所以子节点不写probe也用 FPing同理alerts写在父节点上整个子树都会继承。这个特性很好用但也容易造成我在子节点上写了覆盖结果发现没生效的困惑原因是覆盖位置写错了层级。第二menu是菜单上显示的文字title是页面上的大标题两个都可以写中文但都要注意charset。host才是真正被探测的东西它可以是 IP 也可以是域名如果写域名每一轮都要做一次解析对 DNS 有额外压力长期监控建议直接用 IP把域名解析这件事单独用 DNS 探针去测。提示配置里不要给同一个目标起两个不同的路径名。有两个路径就等于两套 RRD 文件等于两倍的探测发包量而且两张图永远对不上。重构分组之前先想清楚改完之后旧数据不会跟着迁移。4.4 Alerts 段pattern 的匹配方向容易搞反告警段的语法是整份配置里最反直觉的。它用一套类似正则的表达式去匹配历史数据序列匹配方向是从最新一格往回退。*** Alerts *** to opsexample.internal from smokepingexample.internal lossdetect type loss pattern 0%,*12*,0%,*12*,0% comment 12 个周期内出现三次丢包 rttdetect type rtt pattern 200,*6*,200 comment 连续两个周期中位数延迟超过 200mspattern里*12*的含义是允许往回跳过最多 12 个数据点而不是第 12 个点。所以上面第一行的意思是最近一格丢包率大于 0往回最多 12 格找到第二个大于 0 的再往回最多 12 格找到第三个大于 0 的三个都满足就触发。这个语义如果不搞清楚写出来的规则要么永远不响要么一响就刷屏。type常见的有loss按丢包率匹配、rtt按延迟值匹配、matcher结合两者做更复杂的模式、baseline和同期历史基线比较。新上手建议只用loss和rtt这两种逻辑简单、行为可预期。baseline那种自适应告警虽然聪明但在数据量少的头几天会给出非常诡异的判断。5. 探针选型除了 fping 还能测什么默认大家都用 ICMP 探针因为它最通用、开销最小。但网络问题的形态很多只用 ICMP 相当于只用体温计看病。SmokePing 内置了若干探针覆盖的层次不同混着用能让故障定位快很多。5.1 从 ICMP 到应用层四类探针的适用边界探针测的是什么典型用途需要注意FPingICMP 往返延迟与丢包链路质量基线几乎所有目标都该配部分主机限速 ICMP会误报丢包DNS解析耗时与结果排查解析慢、解析结果漂移需要指定查询名和解析服务器CurlHTTP 请求整体耗时与状态码应用层可用性、TLS 握手耗时频率别太高会刷业务日志EchoPing自己实现协议交互内网私有协议探测需要自己写模块成本较高一个很实用的组合是对同一个业务入口同时配 ICMP 和 Curl 两个探针。如果 ICMP 正常但 Curl 曲线抖问题在应用层或者 TLS 握手如果两个一起抖问题在网络路径。这种二选一的判断在有图的情况下是几秒钟的事没图的时候可能要查半天。DNS 探针我要单独说一句。它测的是从 SmokePing 所在机器去问指定解析服务器拿到答案要多久不是用户解析要多久。如果你要做的是用户体验视角的解析监控得把 SmokePing 部署在接近用户的位置或者用多探针分布式部署否则测出来的是机房视角参考价值有限。5.2 采样密度与目标数量的容量账这部分是唯一需要动手算的。发包速率等于目标数乘以每轮包数除以周期秒数总发包速率 目标数量 × pings ÷ step按默认值算100 个目标、pings 20、step 300得到大约每秒 6.7 个 ICMP 包。这个量级对任何正经网络设备都是毛毛雨可以放心堆目标。但如果为了抓偶发丢包把pings抬到 100或者把step压到 60同样的目标数会变成每秒 166 个包这时候就要考虑探测机自身的网卡中断和 CPU 开销了而且在低端交换机上可能触发 ICMP 限速反而制造假丢包。存储这边反而不用太担心。每个目标一个 RRD 文件大小主要由保留的时间粒度和精度决定通常几十 KB 到一两百 KB 之间。1000 个目标大概也就是一百多 MB 的量级随便一块盘都装得下。真正的开销在绘图每打开一次页面CGI 就要读取若干个 RRD 并渲染 PNG目标多了之后首次访问会明显变慢这也是为什么缓存目录必须可写——缓存命中率直接决定了这个面板好不好用。5.3 一个目标该配几个探针我的原则是核心节点配两个边缘节点配一个。核心节点用 ICMP 打底看链路再加一个应用层探针看业务边缘节点只配 ICMP够用就行。配太多探针的副作用不只是资源消耗还有图表的可读性——一个目标下面挂四五张图排查的时候反而不知道该看哪张。另外一个细节如果某个目标本身会限制 ICMP 频率不少云厂商的网关都这么干你会看到 ICMP 图上有规律性的丢包而业务完全正常。这种时候不要急着去调网络先在配置里把这个目标的pings降下来或者干脆换成 TCP 类探针避免被自己的监控数据误导。6. 图表空白的排查链路按顺序过六个检查点页面能打开但是图上没线是 SmokePing 最高频的问题没有之一。这个症状背后可能有十几种原因但它们的排查顺序是固定的从外到内一层层收窄比随机尝试快得多。下面这个链路是我自己遇到问题时会走的顺序基本能在十分钟内定位。6.1 第一层探测到底有没有在发先确认最外层的现实容器能不能把包发出去。进容器手动跑 fping这是唯一可靠的判断依据。docker exec -it smokeping fping -c 3 10.0.0.1 docker exec -it smokeping fping -c 3 1.1.1.1如果内网通、外网不通那是网络出口或者 DNS 的问题跟 SmokePing 无关。如果两个都不通但容器能 ping 宿主那就是权限问题看前面NET_RAW那一节。这一步没通过后面所有检查都是白费。6.2 第二层数据目录里有没有文件ls -lh ./data/*.rrd | head目录为空说明探测进程根本没写数据。这时候分两种情况如果容器刚启动不到一个step正常再等等如果跑了一小时还是空的去看docker logs十有八九是配置语法错误导致守护进程启动即退出。SmokePing 的配置错误日志有时候很隐晦习惯做法是进容器手动跑一次前台模式把错误直接打在屏幕上smokeping --config/etc/smokeping/config --nodaemon --debug有文件但是图表还是空那就进第三层。6.3 第三层RRD 文件是不是在正常更新docker exec -it smokeping rrdtool lastupdate /data/内网/核心网关~FPing.rrd这条命令会输出最后一次写入的时间戳和数值。如果时间戳停在一小时前说明写入侧卡住了如果时间戳是新的但数值全是NaN或者-1说明探测发了但没有回包回到第一层重新查。这一步能明确区分写不进去和写进去了但值是空的这两个问题的处理方式完全不同。6.4 第四层CGI 能不能读到数据用命令行模拟一次 CGI 请求看返回的是 PNG 还是错误信息curl -sI http://localhost:8080/smokeping.cgi?target内网.核心网关displaymodenormal如果返回的是 500 而不是image/png去看 Apache 的错误日志。最常见的两条是权限不足读不了 RRD和找不到绘图库。前者回到 2.1 节检查属组和 setgid后者说明镜像里少装了绘图相关依赖。6.5 第五层时间范围选错了这个说起来有点蠢但确实常见。SmokePing 的图表有多种时间范围视图从几小时到一年。如果你刚部署两小时切到一年视图图上当然是空的——因为数据根本没那么长。默认视图设置不当会让人误以为没数据。检查一下 Presentation 段里配置的默认展示范围新部署时先看小时级视图。6.6 第六层缓存里躺着的是旧的坏图前面五层都通了浏览器还是显示空白或者旧图那就清缓存。因为缓存文件名通常由目标名和参数拼成配置改了但缓存键没变你会一直看到那张生成失败的图。rm -rf ./cache/*清完之后刷新页面如果图出来了说明问题已经解决只是被缓存挡住了。这也是为什么我建议在排查期间临时把缓存目录挂成可随时清空的独立卷——省得每次都要进容器操作。7. 分布式探针与长期维护slave 架构、备份与升级单实例跑到几十个目标很轻松但一旦需要从多个地理位置同时测同一个目标就得用 master/slave 架构。这个架构的原理很朴素master 负责配置和绘图slave 只负责按 master 下发的指令干活把探测结果回传给 master 写库。7.1 master 与 slave 的配置对齐要点master 侧要开一个 slaves 段声明有哪些 slave、各自的显示名和颜色并且指定一个共享密钥文件*** Slaves *** secrets /etc/smokeping/smokeping_secrets 机房A display_name 机房A color 0060a0密钥文件里一行一个格式是slave 名 密钥。slave 侧的 General 段里要填master_url和shared_secret然后用--master-url参数启动。目标节点上用slaves 机房A指定由哪个 slave 探测。这里最容易出问题的是配置同步。slave 启动时会从 master 拉取 Targets 配置但它只认自己的名字如果一个目标没指定slaves或者指定的名字拼错了这个目标就不会被任何 slave 探测而 master 自己的本地探针也可能不接这个活最终结果就是图一直是空的。排查方法是看 master 日志里有没有slave 请求配置的记录以及 slave 侧有没有成功建立连接。网络方面master 和 slave 之间是 slave 主动连 master 的 HTTP 接口所以只要 slave 能出网访问 master 就行不需要在 master 侧做端口映射。这个设计对内网穿透很友好但也意味着 slave 的密钥一旦泄露任何人都能伪装成 slave 往你的数据库里灌假数据密钥文件权限记得收紧。7.2 备份与迁移备份什么、怎么验备份清单只有三样配置目录、数据目录、镜像的构建文件。缓存不用备。数据目录的备份有个技巧——不要在探测写入的同时直接拷文件RRD 文件在写入瞬间是不一致的拷出来的副本可能损坏。稳妥做法是先停容器再拷或者用文件系统快照。如果实在不能停就用rrdtool dump导出成 XML 再压缩代价是体积会大不少。恢复的时候用rrdtool restore导回去比直接拷文件更安全。迁移到新机器时有个坑如果新机器的路径、用户名、uid 和旧机器不一致挂载上去之后文件属主会变成一串数字探测进程写不进去。迁移完第一件事是chown -R对齐属主然后跑一次写入验证别等第二天才发现数据断了。7.3 版本停滞与升级策略SmokePing 这类工具更新频率不高很多人装完就再也没动过。这在小规模场景下没什么问题但长期不升级会带来两个麻烦一是基础镜像里的依赖逐渐过时出安全问题没法快速修补二是某天想用新特性的时候发现配置格式已经变了改动成本陡增。我的策略是把它当成一个半年动一次的服务。每次动的时候按这个顺序先在另一台机器上用同样的配置起一个新实例确认能正常出图并且历史数据能挂载进去再切换流量。因为配置和数据都在宿主机卷上容器本身是无状态的所以这种新旧并行、切换卷的方式几乎零风险。唯一要小心的是不要让两个实例同时往同一个数据目录写——RRD 不是并发安全的两个进程同时更新一个文件会直接损坏它。切换前先停旧的等它把当前周期写完再起新的。注意升级或者更换基础镜像之后第一件事是进容器fping --version和rrdtool --version各看一眼。曾经出现过新镜像里 fping 参数变化导致packetsize不生效的情况图上延迟突然整体抬高查了半天才发现是探测报文变大了。最后分享一个我自己用了很久的小习惯在 Targets 里专门留一个指向本机网关的基准目标简单、稳定、几乎不会出问题。当别的目标曲线出现异常时先看这个基准目标——它平你就往远端查它抖你就往本地查。这个小小的参照物比任何复杂的排查流程图都管用。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑