龙空技术网

网络拓扑自动发现与监控实践

运维杂谈 1952

前言:

眼前大家对“节点与节点之间的通信网络关系”大致比较着重,你们都想要学习一些“节点与节点之间的通信网络关系”的相关内容。那么小编也在网上汇集了一些有关“节点与节点之间的通信网络关系””的相关资讯,希望兄弟们能喜欢,朋友们快快来学习一下吧!

所谓网络拓扑就是构建网络节点(计算机、路由器、交换机、打印机等)、网络节点之间的关系。在此基础上绘制出网络拓扑图,基于图像展示各种实时监控指标(流量、丢包、错误数、广播包等),这样就可以帮助运维管理人快速发现和解决网络问题。

01现状

很多时候我们都是手动构建我们的网络拓扑图,甚至都没有网络拓扑图,依赖产商提供的工具进行维护。各种类型、不同产商设备的存在,运维的难度变大,因此能够自动发现网络拓扑结构可以为运维带来极大的便利。

02 通用方法基于链路层协议

通过监测网络中的链路层帧或数据包来发现网络拓扑,例如ARP/NDP/LLDP等

基于路由协议

发现网络中的节点和建立路由表。节点可以交换路由信息,了解网络中其他节点的存在和连接关系。常见的协议如RIP、OSPF、IGRP、EIGRP、EGP、BGP和IS-IS。

基于网络流量分析

通过分析网络流量,推断出网络中的节点和它们之间的连接关系。例如,通过监测网络中的数据包流向和端口信息,可以推断出节点之间的通信关系和拓扑结构。

基于网络管理协议

用于发现网络中的设备和节点、查询设备的管理信息,可以获取设备的拓扑信息和连接关系, 如SNMP。

其他网络拓扑工具03 实践

一种较好的解决方法是使用基于LLDP/SNMP的网络拓扑自动发现和SNMP进行监控。本文讨论了基于SNMP的网络拓扑自动发现和监控方法,并通过代码实现展示了主要步骤和基于拓扑结构的界面效果。实现原理尽量避免了网络设备的MIB库差异,而是从通用的OID出发来发现网络拓扑并监控网络指标。

实现原理和具体步骤如下:

1. 采集节点获取默认网关,并通过SNMP信息采集获取本机地址、各种路由信息。分析获取本机IP列表信息和子网,并根据路由类型和端口索引建立直接路由和间接路由的端口索引映射。

func DiscoverIps(target string, snmpClient *gsnmp.GoSNMP) (result *Arp){  result = &Arp{}  if v, ok := DiscoverIpsCache.Get(target); ok {    return v.(*Arp)  }    r0, er := FetchItems("walk", target, []string{OLibrary.IpAdEntAddr}, snmpClient)  if er != nil {    logrus.Warnf("fetch %s %s failed %v", target, OLibrary.IpAdEntAddr, er)    return  }  ......  Routes.Store(result.Target, result)  return}

2. 将直接路由列表划分到本机网络,并对间接路由列表进行递归执行第1和第2步骤。

func L3Topology(target string, graph *TopologyGraph, recursive bool) {   ......   arp := DiscoverIps(target, snmpClient)   horizontal, vertical, er := Layer3IpLinks(target, snmpClient)   ......   for ip, ifIndex := range horizontal {      Topology3SyncWait.Add(1)      go func(ip string, ifIndex int64) {         ......         if _, ok := L3Nodes.LoadOrStore(tmpArp.Target, false); !ok {            if recursive {               L3Topology(tmpArp.Target, graph, recursive)            } else {               Topology3SyncWait.Done()            }         } else {            Topology3SyncWait.Done()         }      }(ip, ifIndex)   }}

3. 基于前两步构建的路由信息,扫描各个子网内的交换机、路由器和整个ARP表。对于子网中的路由器和交换机设备,获取其端口索引的映射,并建立邻接信息表。

func ScanTotalSubnetsAndNeighbor(graph *TopologyGraph) (map[string]map[string]int64, map[string]map[string]string) {   // step1 扫描出各个子网内的交换机、路由器,以及整个arp表   {      wg := sync.WaitGroup{}      ch := make(chan struct{}, 1000)      Routes.Range(func(key, value any) bool {         for _, objs := range [][]string{value.(*Arp).Subnets, value.(*Arp).PeerIps} {            for _, v := range objs {               ips, er := CidrHosts(v)               for _, v1 := range ips {               ......               }            }         }         return true      })   }   // step2 针对子网的route,switch 获取接口映射   ......   {      SubnetsVar.Range(func(k, v any) bool {         for ip := range v.(*Subnet).Routers {            f1(ip)         }         for ip := range v.(*Subnet).Switches {            f1(ip)         }         return true      })   }   ......}

4. 整理前几步获取到的设备和连接信息,构建完整的拓扑信息。

func tidyGraph(graph *TopologyGraph, portMapIfIndex map[string]map[string]int64,   portMapDes map[string]map[string]string) {   r := map[string]StpInfo{}   NodeLinks.Range(func(key, value any) bool {      v := value.(StpInfo)      r[key.(string)] = v      return true   })   var links []*Link   for _, v := range r {      ......      links = append(links, gh)   }   graph.Links = links   var ips []string   for index, v := range graph.Nodes {      if v1, ok := NodeInfo.Load(v.Name); ok {         ......         graph.Nodes[index].DesIps = d      }   }}

5. 在建立好完整信息后,定时对各个设备进行各项指标的采集和输出。

04 成果

通过以上方法,可以实现网络设备的自动发现、网络设备之间的拓扑关系以及对网络各种指标的完整监控。

拓扑数据输出样例

{"nodes":[{ "name": "10.172.135.254", "alias": "", "type": "router", "x": 0, "y": 0, "ips": [ "10.172.135.254" ], "locals": [ "10.172.135.0/255.255.255.0", "10.172.135.255/255.255.255.255" ], "des_ips": { "GigabitEthernet0/0/0": [ "10.172.135.1" ], "GigabitEthernet0/0/6": [ "58.33.167.73" ] } },],"links": [ { "node_from": "GigabitEthernet0/0/1", "node_to": "",  "node_from_name": "192.168.1.2", "node_to_name": "192.168.13", "value": 0, "unit": "", "level": 0, "if_index": "", "traffic_load": 0, "port": "", "options": null }],"location": false,"graph_id": "id1"}

基于数据采集到的数据,我们使用前端工具进行的数据展示,最终效果图如下,前端也可以自己调整页面布局。

手动调整网络拓扑结构,同时根据实际场景配置颜色用于告警。

05 后续

目前只是基于SNMP v2去做自动发现,后续将结合LLDP协议,进一步提高网络拓扑结构的准确性,加入v3支持以及进一步完善设备类型的判断。

06 开源

目前开源项目的内容主要后端网络拓扑数据的自动发现,以及监控数据的采集。前端展示尚未加入到开源项目中、后续很快将整理好之后补充进来。

开源地址为:GitHub - veops/ops-tools: 运维的一些常用实践和代码

同时也开源了灵活简单易用的运维CMDB,网络设备以及拓扑关系可以存放到CMDB里,大家有兴趣可以尝试一下,有线上的demo可以尝鲜的,觉得有用的话欢迎点赞加⭐️

标签: #节点与节点之间的通信网络关系