一文读懂网管协议 - SNMP,NETCONF,RESTCONF


本文篇幅较长,主要涉及以下内容:

  • 介绍传统 CLI 配置网络设备存在的挑战,网管协议出现的背景

  • SNMP 原理,交互过程,以及 trade-off

  • NETCONF 架构,交互过程

  • RESTCONF 架构,和 NETCONF 的对比

随着 5G 的大火,SDN, NFV 等概念被频繁提及。想要更好的理解这些概念,网络协议自然是对必不缺少的一环。

拿 SDN 来说,全称为 Software Defined Networking - 软件定义网络。从传统网络来说,整体采用分布式的架构,控制平面和转发平面都位于同一台设备上。在运维,以及灵活性上都有着不小的挑战。

而 SDN 的出现,将控制平面和转发平面解耦,并将所有的设备统一管理起来,使得网络具有了可编程的能力,从面相服务的角度,根据业务需要,实时动态的调整设备的配置或状态,大大降低了管理难度。

那么 NETCONF,RESTCONF 这样的协议又是起到怎样的作用呢?

这就要从 SDN 架构说起,SDN 主要有三个角色,SDN 应用,SDN 控制,网络设备。

SDN 应用一般会通过 HTTP 的方式,调用 SDN 控制器暴露的接口,而 SDN 控制器,会通过 NETCONF,RESTCONF 类似的协议,与设备进行交互,进行业务的下发。

可见,NETCONF 类似的协议起到和设备直接交互的作用。

还有最近 DEVOPS 概念的流行,也强调从传统人工 CLI 配置,过度到自动化的网络配置。而 NETCONF 类似协议,就让这些自动化操作成为可能,比如现在的 ANSIBLE,Python 的各种类库。

下面是网管协议的实际用例,可以看到涵盖的范围已经非常之广:

下面就从传统 CLI 面临的挑战开始,来详细了解下这些发挥着重要作用的协议。

传统命令操作带来的主要挑战

采用传统 CLI 配置方式主要存在着如下的挑战:

在兼容性方面,若是网络工程师的话肯定深有体会。

拿配置静态路由举例, Cisco 设备命令如下:

Router(config)#ip route 0.0.0.0 0.0.0.0 10.10.10.1 

而对于华为和华三设备来说:

Router(config)#p route-static 0.0.0.0 0.0.0.0 10.10.10.1 

有时不光是不同厂商之间的命令不同,甚至同一厂商不同型号之间的命令也不相同。

比如思科针对不同的场景就区分了不同的网络软件系统:

  • 针对于企业的 IOS
  • 针对于运营商的 IOS-XR
  • 针对于数据中心的 NX-OS
  • 以及面向下一代的 IOS-XE,将数据层面和控制解耦,底层支持 Linux.

而出错率这方面,更不必说,人工配置远没有机器配置的准确以及迅速。

而且目前的网络在规模和需求上也和之前大不一样,比如在实时性上,作为运营商需要根据业务需求动态调整策略如 EVPN,L3VPN,L2TP。传统 CLI 手工配置根本无法满足,而无法做到维护管理。而现在的常用解决方案都是利用一些现成的 SDN Controller 进行实时调整如 Cisco 的 NSO.

在数据采集方面,传统人工定时登上设备材料系统日志,分析情况,这更加无法适用。在故障响应上,数据采集,分析都存在先天的不足。比如收集效率低,数据的利用率延迟或不高。

最后从商业成本的考虑,人工的维护方案也是较高的一笔输出。

而且对于工程师而言,需要不断学习不同厂商的配置命令,学习成本很高,但意义不大。

通常来说,网络工程师在开始一个项目前,会进行如下四个部分:

  1. 了解用户的需求
  2. 针对用户的需求,确定相应的具体方案。
  3. 根据用户的方案,查找并学习对应设备的配置命令
  4. 最后申请割接窗口,准备回滚方案并实施。

在这里的第三步,其实就是一个比较耗时,但没多少意义的过程。因为在集中学习不同厂商的设备命令,但从业务考虑明明解决的都是同一个问题。

在发现 CLI 管理设备的方式出现瓶颈后,并不是马上过度到现在流行的网络自动化配置方式,而是先推出了一个叫 Simple Network Management Protocol - SNMP 的应用层协议,甚至在当前的一些现网中,依然被使用。

SNMP

SNMP 的出现,主要想解决两个问题:

  1. 设备信息的采集
  2. 使用 GUI 替代 CLI 的方式进行设备配置下发

但由于其读多写少的特点,现被广泛用于设备信息的监控和采集。

SNMP 目前共有三个版本:

  • SNMP V1,第一个版本。在管理设备上,采用明文的方式,有 read-only, read-write, trap 三种和设备通信的方式。
  • SNMP V2,主要改进了性能,安全性以及设备交流的方式。
  • SNMP V3,主要优化了安全性,增加了一些更强的认证流程。

SNMP 原理

SNMP 整体架构上有些类似于 Client / Server,其主要的工作组件主要有三个:

  • SNMP Manager:,主要用于管理网络中的多个设备,对其进行读和写的操作。类似于 Server.

  • SNMP Agent:运行在网络设备上,通常都需要手动开启。作为 SNMP 代理,在收到 SNMP Manager 发出请求后,对请求的内容进行解析,然后对设备进行配置,将配置的结果作为 Response 回复给 Manager.

  • SNMP MIB: MIB - Management Information Base 全称为信息管理库。可以将其理解成用于交互的一种数据模型,也就是交互的规则。MIB 同样存在于网络设备中。定义和描述了如何管理设备上的资源。Manager 和 Agent 之间的交流的信息就是 MIB 的内容。

可以看到一个 Manager 可以管理网络中的多个设备。而每台设备上运行着 SNMP Agent 用于和 Manger信息交互,交流的内容需要符合 MIB 的规范。

看到这,可能对 MIB 这个概念还是有些模糊。这样,我们先不从最后的结果来分析这个组件的作用,而是从设计的角度,来说一下推导下为什么要有 MIB 这个东西?

这里想要实现的是通过 Manager 去管理网络上的 Agent(其实就是管理设备)。那么如何管理呢,比如 Manager 想要获取 Agent1 的 GigabitEthernet0/0/0/1 的 IP 地址。

这时就需要在 Agent1 上先约定好一个内容,比如当 Agent 接收到 1.1 这个字符串时,就会将接口的信息返回给 Manager.

之后如果 Manager 发送 1.1 就能获取到接口的信息了,但发送别的内容,Agent 是无法识别并工作的。MIB 本质就是这样,确定了如 1.1 这样的一组规则,去规范信息交互的访问方式。

其实,这里的 1.1 就是 MIB 中的一个对象,在 MIB 中还以层级的方式存在着许多这样的对象,将网络的设备的资源抽象成形如 1.1 对象。通过这些对象,Manger 和 Agent 就可以实现很好的交流了。

真正的 MIB 类似与下图,而这里形如 1.3.6.1.1.1.2 这样连接起来的字符串称为 ASN,其实就是对应了设备上的各种资源,Manager 和 Agent 也通过它们进行交流。

SNMP 操作

SNMP Manger 和 SNMP Agent 间的交互主要有三种类型:

  • SNMP Get
  • SNMP SET
  • SNMP Notifications

SNMP Get:主要是检索设备的信息,Get 一种有三种类型:

  • GET - 从 SNMP agent 获取固定的对象。
  • GETNEXT - 检索当前对象的后一个对象,由于 MIB 本身层级的树形结构,存在后继。
  • GETBULK - 获取一组固定的对象。

SNMP SET:主要是修改 MIB 中的对象,进而修改设备的配置。

SBMP Notifications:是 SNMP 的主要特性,之前的 GET 和 SET 是属于拉的操作,而 SNMP 正好相反,类似于推的操作,可以由 agent 发起,将一些信息 push 到 SNMP Manager 上。类似于 Web Socket. 主要用于通知如认证失败,重启,断开连接等事件。

Notifications 主要有两种形式:Traps 和 Informs. 两者间的不同主要在于可靠性,agent 在产生 Informs 给 Manager 后,如果发送失败,会重新发送。Manager 收到后,需要回复确认给 agent。

而 Traps 不同,无论消息发送是否成功,Manager 都不需要回复。

SNMP 缺点

虽然 SNMP 的出现,在一定程度上解决了网络设备的管理问题。但面对现代大规模的网络来说,依然有着很多挑战:

  1. 性能不足,在下发和读取配置时,采用依次读取,效率低。
  2. 下发不足,支持写 MIB 的对象相对于读较少。
  3. 不支持事务机制,在配置下发失败是,无法回滚。
  4. 拓展性差,提供给外部的接口较少。
  5. 模型兼容性差,MIB 库混乱,无法适配所有厂商,导致定义各种私有 MIB 库。

面对这些问题,06 年由 IETF 领导并开发出了一个新的协议 - NETCONF,网络管理协议。和 SNMP 不同,NETCONF 基于 RPC 的方式,天生就能很好的支持事务回滚等操作,从而更好地处理复杂网络的各种需求。

NETCONF

NETCONF 协议提供了一种更简单的方式来管理("查询,配置,修改,删除")设备,就像数据库操作中的 DML. 同时开放了 API 接口,当想要对设备进行操作时,直接通过调用 API 进行。

对于支持 NETCONF 的设备来说,至少能开启一个或多个 session。并且在每个 session 中应用的配置更改,都可以被全局的 session 监听到。这就让一个或多个 Manager(Client) 操作同一个设备(agent)成为了可能。

相比 SNMP 而言,有着如下的优势:

  1. 基于 RPC,增加了事务支持
  2. 优化查询功能,增加过滤查询方式
  3. 拓展性强,在其协议内部分为 4 层,各层之间相互独立
  4. 更好的将配置和状态数据解耦,并区分状态数据(candidate, running, startup)
  5. 易使用,结合提供的 API,实现可编程性的网络操作
  6. 安全性更好,在传输层可选用 SSH,TLS 协议等。

NETCONF 采用 C/S 的架构,通过 RPC 在 client 和 server 间交流。client 可以是 Python 脚本或应用。server 一般指的是网络设备,在具体实现上有三个组件:

  1. NETCONF agent:运行在网络设备上,用于接收和处理 RPC 请求。还可主动将一些告警事件通知客户端。

  2. NETCONF 客户端:利用 NETCONF 协议对网络设备进行管理以及接收 agent 发出的告警通知。

  3. datastore:在 NETCONF 中,区分了多个不同类型的 datastore, 这些 datastore 保存着不同状态下的设备信息。

关于 datastore 可以将其理解成一个可以获取和存储信息的概念。在具体实现上,可以是文件,数据库,内存等等。

在 NETCONF 中常用到三类 datastore:

  • startup configuration datastore: 保存了设备启动时,加载的配置信息。

  • candidate configuration datastore: 保存了想要运行的配置信息,修改该数据库时,并不会影响设备的真实配置。

  • running configuration datastore: 保存了当前设备上正在生效的配置,修改时会影响真实的设备。

此外提到 datastore 就必须要提到一种数据模型语言 —— YANG,datestore 中就是以 YANG 的形式来约束配置的数据。

YANG 的出现结合上 NETCONF 和 RESTCONF 这样的协议,为自动化,可编程化的网络提供了强大的支持。YANG 的本质和之前 SNMP 中 MIB ASN 一样,作用都是以一种方式来约束数据,关于 YANG 之后会写一篇文章单独介绍。

NETCONF 协议架构

NETCONF 分为 4 层,各层之间项目独立。

  1. 内容层:

这一层包含了以 XML 或 JSON 格式的配置数据,也就是想对设备进行管理的具体内容。(由 XSD 或者 YANG 约束生成)

  1. 操作层:

定义了 Client 和 Server 交互时的一系列操作方法,用于获取或修改配置数据。

  1. 消息层:

为编码数据时,提供了一种 RPC 和通知的机制:

* RPC invocations( messages)  
* RPC results( messages)
* event notifications( messages)
  1. 传输层:

NETCONF 使用 SSH 或 TLS 协议,保证数据在 Client 和 Server 传输的安全性。

NETCONF 交互

对于 Manager 和 Agent 来说,Session 建立会经历如下的过程:

  1. Manager 请求 NETCONF 中 SSH 子系统建立连接。
  2. Agent 回复 Hello 消息,包含本身支持的特性和能力。
  3. Manager 告知 Agent 自己所支持的特性和能力。
  4. Manager 开始发送 RPC 操作请求。
  5. Agent 回复 RPC 请求操作结果。

具体看下 NETCONF 中消息的报文结构,以修改接口配置举例:

Manager 请求变更接口配置:

 
       
         
           
         
         
           
             
               Ethernet0/0
               1500
             
           
         
       

Agent 回复结果:

 
       
 

首先可以看到,NETCONF 使用 XML 作为数据传输的格式。

第一行的 标签,表明该请求是 RPC 请求,message-id 属性由 client/manager 确定。Agent 在回复结果时,会带上 message-id,用于表示该操作的结果。

urn:ietf: 属性表示 XML 中的命令空间。 base:1.0 表示当前 NETCONF 的版本。

第二行 指定执行 RPC 操作的内容为修改配置。

之后 中包裹的内容就是,想要下发的配置内容,修改 mtu 为 1500.

但这里还有一个疑问,在说到 NETCONF 时,总提到一种叫 YANG 的语言,那么它们之间的关系是什么?

在组装修改设备配置 Payload 时,这里也没有用到 YANG ?

其实,YANG 早已用到了。为什么 中可以包含 属性。而不是把 mtu 放在和 同级。

原因就在于上面的格式,都是按照 YANG 的约束而来。

在设备中,存在着许多的 YANG Module,这些 Module 都是由 YANG 语言编写的文件。当 agent 接收到 RPC 请求时,会通过 YANG Module 来校验发来的数据,格式是否合法。

简单来说,可以把 YANG 理解成一份约束文件,里面规定着传来参数的格式,是数组,对象还是其他格式。

至于说为什么 YANG 文件能约束 XML 的文件格式,原因在于 YANG 和 XML 之间是可以相互转换的,甚至 YANG 还可以转换成 JSON. 在之后的 RESTCONF 中会提到这一点。

到目前为止,对 NETCONF 已经有了一个大体认识:

NETCONF 的出现是为了弥补像 SNMP 这些协议的不足。更好的满足现在网络的需要,在易用性,拓展性等等方面都做出了进一步优化,从而更方便,高效的管理网络。

究其本质,NETCONF 是由多个协议组装而成。数据的产生及校验通过 YANG,数据的格式是 XML. 接口的调用通过 RPC,数据的传输通过 SSH.

NETCONF 操作

Server 端:打开设备 NETCONF

#  打开 netconf 
netconf-yang

# 查看 netconf 进程
show platform software yang-management

Client 端:测试设备 NETCONF

ssh admin@IP -p 830 -s netconf

关于 NETCONF 具体实现编程化操作,可以参见 SNMP 介绍


NETCONF - wiki

RFC6241 - NETCONF

NETCONF datestore

通过 NETCONF 实现网络自动化


REST 介绍

RESTCONF - RFC8040

基于Model驱动的自动化网络

RESTCONF 介绍

CISCO 可编程化网络


SDN 和 NFV 的关系