写点什么

Open-Falcon 中的交换机监控

用户头像
冯骐
关注
发布于: 2021 年 02 月 24 日
Open-Falcon 中的交换机监控

open-falcon

Open-Falcon 是当下最炙手可热的开源监控框架之一,他有以下特点:

  • 数据采集灵活:框架原生的 agent 能够采集大量的系统指标。同时也支持自定义的指标采集推送给监控系统,非常灵活。

  • 支持水平扩展:可以非常容易的水平扩展来增加整个监控系统的性能容量

  • 高效率的告警策略管理:高效的用户配置界面,支持策略模板,支持模板继承和覆盖,支持多种告警方式和回调动作。

  • 告警多样:支持最大告警次数、告警级别设置、告警恢复通知、告警暂停、不同时段不同阈值,支持维护周期设置,支持告警合并。

  • 数据查询高效:后端数据采用 RRDtool 归档策略,数据查询高效且数据存储占用空间很小

  • 灵活的数据展示:除了系统自带的 dashboard 以外,也完全可以通过监控系统的接口自己实现一个 dashboard,满足特定的需求。

  • 高可用:整个系统无核心单点,易运维,易部署。

交换机的数据采集

虽然 Open-Falcon 原生并没有交换机的数据采集模块。然而由于数据采集的灵活性,即支持自定义的指标采集推送。因此我们可以很容易的通过 snmp 采集交换机的各项指标数据,进行符合 Open-Falcon 规范的封装,并推送给 Open-Falcon。在 Open-Falcon 的社区中,已经提供了这样的交换机采集工具 —— swcollector

swcollector

swcollector 是一个基于 open-falcon 的交换机专用 agent。它支持对交换机的各项指标进行采集并上报给 Open-Falcon:

安装

swcollector 使用 go 语言编写,所以下载编译好的 release 版本 就可以直接使用,没有依赖。

当然也可以源码来编译

    依赖$GOPATH/src/github.com/gaochao1/sw    cd $GOPATH/src/github.com/gaochao1/swcollector    go get ./...    chmod +x control    ./control build    ./control pack    最后一步会pack出一个tar.gz的安装包,拿着这个包去部署服务即可。        升级时,确保先更新sw    cd $GOPATH/src/github.com/gaochao1/sw    git pull
复制代码

和 Open-Falcon 的原生 agent 一样,解压,写好配置文件之后,只需 ./control start 就可以运行

采集

ip 配置

swcollector 的采集是并发的,也就是针对每个被采集的交换机 ip,都会开启一个 goroutine 来并发采集,因此效率是比较高的。他支持多种非常灵活的配置方法:

"ipRange":[           "192.168.56.100",           "192.168.56.102-192.168.56.120",           "192.168.56.1/24",        ],
复制代码

所有需要采集的交换机 ip 都写在 ipRange 这个数组中。

首先当然可以直接把交换机的 ip 逐条写在数组里,例如"192.168.56.100" 。

但是如果需要配置的交换机很多的话,这样写显得有些臃肿,此时我们就可以通过 "192.168.56.102-192.168.56.120" 这种地址段的方式来配置,swcollector 会自动解析出其中的每一个 ip。(v4 版本新增的功能)

如果我们的交换机地址比较分散不太连续怎么办呢,比如"192.168.56.1","192.168.56.3","192.168.56.5", ... ?没关系,swcollector 也支持通过网段的方式来进行配置,例如"192.168.56.1/24",这样就简洁很多了。

此时问题来了,这个网段里不通的那部分 ip 怎么处理了,难道也去尝试 snmp 采集么?

当然不会那么蠢咯,解决的办法是根据 ping 进行存活检测

存活检测

如上文所言,swcollector 会将 ipRange 中配置的 ip 地址进行解析,生成完整 ip 列表。然后开启并发对他们做 ping 监控。为了避免无谓的 snmp 采集,只有 swcollector 首次启动时 Ping 存活的 ip 才会进入到后面 snmp 采集流程,才会产生数据上报。

问题又来了,我们的 switch.Ping 还要实现宕机监控呢,交换机如果挂了 Ping 不通了,得上报一个 -1 呀。如果 Ping 存活检测不通过就不产生数据上报了,这不就有问题了嘛。

这个问题不必担心,Ping 存活检测的原理是 swcollector 在每个采集周期,对所有的 ip 进行 存活检测后,将其放到 AliveIp 这个 ip 列表中。之后的每个周期中,如果检测到新的 ip 存活,则自动加入 AliveIp 中。但是并不会将 Ping 检查失败 ip 从 AliveIp 中移除。所以如果发生交换机宕机,会进行数据上报 switch.Ping = -1,从而触发告警。

所以只需要保障被采集的交换机,在 swcollector 首次启动时在线就好啦。

并发限制

并发开太大了也不好,服务器 hold 不住了可能会炸,交换机 hold 不住了可能不鸟你。所以我们要有并发限制。

并发限制分两块:

  1. 对交换机 ip 数量的并发。比如你一共配置了 500 个 ip。希望限制并发为 200, 则通过 limitConcur 来限制

"limitConcur": 200
复制代码
  1. 对单台交换机的 snmp 并发。交换机有很多指标需要采集,尤其是交换机接口的各种指标(流量,报文数,组播,广播等)。有些交换机响应较慢的,如果对他的 snmp 并发请求多了,可能会导致 snmp 请求超时(没错,说的就是某 H 那家的那些)。此时可以通过 "limitCon" 来限制(v4 版本新增)

"limitCon": 4
复制代码

采集模式

swcollector 提供了两种采集模式,go 原生的 gosnmp 和调用 snmpwalk 命令两种。通过配置项 gosnmp 来开启

"gosnmp":true,  ## false 则使用 snmpwalk
复制代码

如果使用 snmpwalk 模式,则需要安装 swcollector 的机器上安装有 snmpwalk 命令。

之所有会有多种模式,是由于早期 gosnmp 采集时不太稳定,比较容易出现异常超时的情况(与交换机类型有关,某 H 家)。因此提供了调用 snmpwalk 的模式来解决这一问题。

目前最新版本的 swcollector 对 gosnmp 进行了优化,异常超时的情况应该已经很少了,建议默认采用 gosnmp 模式进行采集

接口采集

终于到交换机的指标采集了。snmp 采集就需要对应的指标 oid,好在交换机的接口表都是符合 RFC 规范的,因此接口相关指标的采集对所有交换机都是一致的。swcollector 对于接口流量,接口包数等所使用的是 RFC2233 所定义的 Counter64 Oid(这年头应该不会有交换机还不支持 64 位的接口计数了)

默认 swcollector 会采集

switch.if.Inswitch.if.Outswitch.if.Speedswitch.if.InSpeedPercentswitch.if.OutSpeedPercent
复制代码

这 5 项指标。对于更多的接口指标,默认是 ignore 掉的,需要到配置项中开启,例如:

"ignorePkt": false
复制代码

GAUGE 与 COUNTER(v4 变化)

在 swcollector 的 v3 版本中,接口指标的数据都是以计数器类型——也就是 COUNTER 类型上报的。这很自然,因为采集到的就是计数器类型的数据。然而在 swcollector v4 版本中,接口指标的数据更改为了在 swcollector 本地计算,并以 GAUGE 类型上报,这是为什么呢?

原因有二:

为了能够提供 SpeedPercent ,接口流量百分比的指标。

很多时候我们想知道交换机某个接口是不是流量要跑满了。如果接口流量接近 100%,那可能就要丢包影响业务了,我们需要对这种情况进行告警。但是在计数器类型下,这个做不到。

怎么办呢?通过Aggregator来提取接口流量和速率进行计算,重新 push 吗?还是写个脚本来做?

好像都很麻烦,在 swcollector 采集时就完成可能是更好的办法。

规避异常数据

由于某些品牌的交换机的 os bug(还是某..家,算了不说了……)。他的交换机在 snmp 响应时,偶尔的会发生返回值异常的情况。异常到什么程度呢,后一次请求返回的数值比前一次请求时返回的小……

而之后下一次采集的数据如果和这个异常的小值去做计算,很可能会计算出一个天大的流量出来,吓死人了

总之很坑爹就是了,这种异常的数据丢进 graph 中,graph 并不知道他是异常的,当然就照单全收了。要能够提前过滤异常数据,就必须在 swcollector 本地进行数据的运算

异常数据的忽略(v4 新增)

如前文所言,v4 版本在本地计算流量之后,可以进行异常数据的忽略了。

我们可以通过配置

"speedlimit":0,"pktlimit": 0
复制代码

等这些 limit 配置,忽略掉超过 Limit 值的数据采集值,不进行上报。这里填 0 的时候,接口流量会根据接口的 speed 速率作为 limit 值进行忽略,而 pkt 等就不做忽略操作啦。

忽略接口

swcollector 在采集接口时,会遍历交换机的所有接口。自然也就包括了 svi ,Loopback, NULL 这些虚的逻辑接口。很多时候这些接口对我们而言并没有什么卵用,因此可以在配置中忽略掉他,不进行上报。

"ignoreIface": ["Nu","NU","Vlan","Vl"]
复制代码

cpu 和 mem

接口表的 snmp oid 是有 rfc 标准的,但是 cpu 和 mem 没有。因此需要根据不通的交换机型号来调整采集的时所使用的 oid 值。

swcollector 内置了大部分常见的交换机的 cpu 和 mem 的采集方法(亏得我们这儿交换机牌子杂),因此大部分时候 swcollector 都可以开箱即用。

如果发现您的交换机无法通过 swcollector 识别出,或者识别错误导致 cpu/mem 的指标采集异常,请在 github 发起 issues,写清楚具体的交换机型号,os 版本,以及他的 cpu/mem 的 snmp oid(如果知道的话~)。以便于在下一个版本整合进去。

自定义 oid (v4 新增)

除了 cpu 和 mem 之外,总会还有很多私有的指标,例如交换机的温度,防火墙的连接数,vpn 的 client 连接数等等。这些指标全都内置进 swcollector 并不现实,这就需要能够自定义部分指标的 oid,然后让 swcollector 去采集。在 v4 版本中,这个功能已经实现了,配置示例如下:

{    "metrics":        [            {            "ipRange":[               "192.168.0.1-192.168.0.2",                "192.168.1.1"            ],            "metric":"switch.AnyconnectSession",            "tag":"",                    "type":"GAUGE",            "oid":"1.3.6.1.4.1.9.9.392.1.3.35.0"            },
#这是 cisco asa 上 anyconnect 的在线数量 { "ipRange":[ "192.168.1.160-192.168.1.161" ], "metric":"switch.ConnectionStat", "tag":"", "type":"GAUGE", "oid":"1.3.6.1.4.1.9.9.147.1.2.2.2.1.5.40.6" }, #这是 cisco asa 上的防火墙连接数 { "ipRange":[ "192.168.33.2" ], "metric":"switch.TempStatus", "tag":"", "type":"GAUGE", "oid":"1.3.6.1.4.1.9.9.13.1.3.1.3.1004" } #这是 cisco 交换机的温度,注意通用的 oid 是 "1.3.6.1.4.1.9.9.13.1.3.1.3",这里 1004 是硬件 index。框式交换机可能会有多个温度(多块线卡),请根据实际需要填具体的 oid 值和相应的 tag ]}
复制代码

ipRange 是指需要进行自定义 oid 采集的交换机 ip 地址。支持的配置方法和全局的 ipRange 是一致的

metric 是该项自定义指标最终上报到 Open-Falcon 的 metric 名字,建议使用 switch.xxx 进行标准化的命名

tag 是该项指标所打的 tag 标签

type 是该项指标的数据类型,GAUGE 或 COUNTER

oid 这是该指标的 oid 值

注意自定义的 oid 采集时,只能使用 snmp get 的方法,也就是这里 oid 的值必须是完整的 oid 值(例如交换机的温度,填写1.3.6.1.4.1.9.9.13.1.3.1.3是不允许的,必须填写1.3.6.1.4.1.9.9.13.1.3.1.3.1004,此处 1004 是该交换机的线卡 id。建议在配置之前先使用 snmpwalk 验证一下。

上报时重命名(v4 新增)

v3 版本的时候,经常收到反馈说能不能采集交换机的 hostname 作为 endpoint 进行上报呢?毕竟 ip 地址干巴巴的也不好记忆。

直接采集 hostname 上报比较麻烦,因为在交换机宕机的时候我们还要进行宕机告警,上报 switch.Ping = -1 上去。而交换机宕机的时候显然是采集不到 hostname 的...

这样意味着需要内部维护一个数据库(用 sqlite 吧?),来存放每次采集到的 ip 和 hostname 对应关系。如果交换机宕机了,则到这个表里去查他的 hostname

如果存在交换机重名了,我又没有交换机的配置权限怎么办呢?这就还需要有个地方能够允许自己修改 ip 对应的 hostname,并打上标记,采集的时候对这些标记不做覆盖处理。

这样想想要动的地方还真的蛮多的……,下个版本再实现吧~

v4 先通过一个简单的办法实现其中部分功能,我们可以人工的维护一个 ip 与 host 的对应关系配置文件。swcollector 在上报时检查这个配置文件,将存在配置的 ip ,替换为其配置的 host 作为 endpoint 进行上报

    "switchhosts":{        "enabled":true,        "hosts":"./hosts.json"  #自定义的host与Ip地址对应表,如果配置,则上报时会用这里的host替换ip地址    },
复制代码

将这里的 enbaled 配置为 true

然后在 host.json 中维护 ip:host 的对应关系,例如:

{    "hosts":    {        "192.168.160.1":"test1",        "192.168.88.161":"test2",        "192.168.33.2":"test3",        "192.168.31.51":"test4"    }}
复制代码

从 v3 升级(重要!)

由于接口指标在 v4 版本中更新为 GAUGE 类型,因此如果原来使用 v3 版本采集的 swcollector 直接替换为 v4 版本。则由于上报的类型变化,会导致 graph 中的指标数据被新的类型覆盖,也就是所有旧的流量数据会全部丢失!

因此在升级之前,请务必衡量是否能够接受原有的流量数据清零从头开始的结果。如果需要保留原有数据的话,可以使用上报时重命名 的方法,通过 hosts.json 的配置给 endpoint 做一个重命名。

例如所采集的 ipRange 为:

            "ipRange":[               "192.168.0.1-192.168.0.2",               "192.168.1.1"            ],
复制代码

开启 switchhosts.enabled = true,然后配置 hosts.json

{    "hosts":    {        "192.168.0.1":"sw-192.168.0.1",        "192.168.0.2":"sw-192.168.0.1",        "192.168.1.1":"sw-192.168.1.1"    }}
复制代码

这样新上报的数据就的 endpoint 就是 "sw-192.168.x.x",这样就不会覆盖掉原有的数据了。新的数可以从 "sw-192.168.x.x" 去查询,而 "192.168.x.x" 则可以查询老的数据。

一些花式的玩法

拓扑展示

用过 cacti 的朋友都知道,cacti 有个插件叫 weathermap ,可以从 cacti 中提取数据进行网络拓扑的绘制,并显示流量。例如科大的这个 拓扑

Open-Falcon 能不能实现类似的效果呢?

必须是可以的啦。如最初介绍的,Open-Falcon 有非常灵活的 API 接口,可以非常方便的读取监控系统内的数据。所以说到底,这就是个前端的设计工作,想绘成啥样就绘成咯,数据从 Falcon 里取就是了。

我们使用了一个商用的 H5 拓扑绘图 js(不打广告名字就不说了,搜一下便知),非商业用途可以申请免费授权。才能有限,做出来不算漂亮,各位 js 大拿肯定能做的更好看。


流量区分

一个大型的园区网大多会有多个出口,在不做 BGP 的情况下,各个出口的流量实际上是我们人工调度的(通过 dns,通过特定的路由等等)。我们需要了解我们的网络流量最终都走向了哪些运营商,这一方面能验证我们的流量调度策略是否合理,同时也能够在和运营商谈判网络出口费用的时候掌握一些主动。

传统的实现方法肯定是用 Netflow 了。Netflow 固然是很强大了,但是商用的死贵,开源的自己搞呢又比较折腾。关键在于如果我只关心我的网络流量走向,其他的东西暂时还不那么关心,为这么点破事专门搞一套 netflow,似乎有点高射炮打蚊子的感觉。

提供一个简单的粗暴的办法,搞一台 monitor session 数量大一点的交换机(我用的是 Cisco 4500-X)做专用的镜像交换机,把主干流量镜像给他。然后在上面根据各个运营商的 ip 地址做 ACL,针对主干流量的镜像口做 monitor session filter acl。于是把 monitor 出来的接口随便一查,就可以看流量了,就像这样(因为是双栈的网络所以要把 v6 流量 deny 掉才是准确的 v4 流量)

monitor session 7 filter ip access-group edu_and_others_inmonitor session 7 filter ipv6 access-group ipv6-denymonitor session 8 source interface Te1/2monitor session 8 destination interface Te1/12monitor session 8 filter packet-type good rxmonitor session 8 filter ip access-group mobile_inmonitor session 8 filter ipv6 access-group ipv6-denymonitor session 9 source interface Te1/2monitor session 9 destination interface Te1/13monitor session 9 filter packet-type good rxmonitor session 9 filter ip access-group unicom_inmonitor session 9 filter ipv6 access-group ipv6-denymonitor session 10 source interface Te1/2monitor session 10 destination interface Te1/14monitor session 10 filter packet-type good rxmonitor session 10 filter ip access-group telecom_inmonitor session 10 filter ipv6 access-group ipv6-deny
复制代码



运营商的 ip 地址范围可以找万能的淘宝~

这个方法仅限于需要查看的运营商不多的情况下,比如只想区分下三大运营商 + CERNET,交换机的 monitor session 数还是够的。如果要再细分到二级的,或者要区分国家/城市的走向的话,这个方法会需要量极大的 monitor session 数量。此时你需要许许多多台交换机来凑够这些 monitor session,或者弄一些不限制 monitor session 数量 sdn 交换机…………还是 netflow 吧~

以上


原文于 2017 年 8 月首发于简书,搬家存档。

行文有微调。


发布于: 2021 年 02 月 24 日阅读数: 44
用户头像

冯骐

关注

教育行业码农 2020.06.19 加入

一个教育行业的码农

评论

发布
暂无评论
Open-Falcon 中的交换机监控