近年来,随着全球云计算领域的不断发展与业务的不断增长,促使网络技术也不断发展,SDN技术应运而生,从最初的基于Openflow的转发与控制分离的核心思想,人们不断的去扩展SDN的外延,目前,人们可以达成一个共识,Openflow不再是必备条件(但转发与控制分离依然是核心条件),网络可编程能力慢慢地成为衡量一套SDN架构的重要标准之一。
传统的网络设备进行可编程操作,一般是基于CLI与SNMP协议去进行的,脚本也好,网管软件也罢,都是在此基础上去进行开发,实现我们今天要谈的广义范围上的网络可编程能力,进而实现很多场景的自动化。有些设备支持一些web界面的配置,通过xml进行整体配置的替换,此类极少,本篇不做赘述。
CLI
CLI(Command-line Interface),通过命令行的方式实现人机交互,是网工必备的熟练,人们每天打开软件ssh或者Telnet到设备,然后贴入一段配置,保存生效。有一天人们厌倦了这种重复,通过程序自动生成配置脚本,批量登录到设备下发配置生效,实现自动化,这是一种网络可编程的方式。说说优点,非常符合人的思维、思路与既有的技术体系。但是说到底,这种方式更倾向于人,而非网络设备。它有着以下一些缺点:
厂商之间的命令集存在巨大差异,何止是厂商,同型号不同软件版本可能差异都非常大。
开发人员必须熟知命令集及其使用方法,从配置层面存在安全风险。比如手一瓢,想开端口变成了关闭端口...
对传输协议不强制要求(SSH与Telnet),存在生产安全风险
解析与生成配置的过程及其复杂,很多时候写的正则只能是无限接近“真相”,而不是全部“真相”。
没有事务性,一次配置可能部分生效,部分不生效
没有自动化的检查机制,完全依赖人。比如我想测试一下这段生成的脚本对不对,有办法,但是很困难,很多时候难以简单实现。
没有数据建模的思想
CLI始终是人机交互的方式,可以通过程序可以赋予网络一定的可编程能力,但它毕竟不是天生面向网络可编程的一种方式。在当今云计算与SDN的浪潮之下,不适用于网络中的大规模自动化部署,可编程能力有限,这其中的开发难度难以为外人道也。
SNMP
SNMP(SNMP,Simple Network Management Protocol),该协议能够支持网络管理系统,用以监测连接到网络上的设备是否有任何引起管理上关注的情况。它由一组网络管理的标准组成,包含一个应用层协议(application layer protocol)、数据库模式(database schema),和一组数据对象。
维基百科里的一段内容,我们划下重点,网络管理,监测,数据对象。它是用来管理网络的,能配置能采集,主要用于监测,它有数据建模,将网络设备的一些模块、特征、状态数据结构化。主要是用于网管系统(划重点,多是监控)。那我们也来说说它的缺点:
可读性差。它偏向人机中的“机”,用起来可读性差,建模数据也可读性低,用的是一个ASN.1的超集。
安全性受限,有v1 v2c v3三个版本,安全性依次提高,但是目前最通用的是v2c,安全性有限。v3版本从设计上很安全,但是普及性。。。
无备份及恢复回滚等机制。命令行我们还有show run等方式备份,但snmp。。。
极少的写操作。读很多,写很少,多用于监控。
能采集的数据项有限,无法获取整台设备的配置。很多时候我们发现能用cli采集出来,但是无法用snmp采集。
性能有瓶颈,采集数据上限64K,采集颗粒度过大,在大型复杂网络中可能是分钟级或者更久。这个也划下重点,我们对于颗粒度的要求也非常严格,很多时候希望几秒钟采集一次端口流量。大型网络中,传统的网管软件,我觉得是...多展开一句,现在的方式是Telemetry(比如gRPC)可以实现微秒级,有的需要软硬件结合才行,目前还未普及,但未来一定是趋势,至于这个未来什么时候来..
SNMP自诞生之日,极大地被应用在了网络监控领域,用于获取数据进行监控,配置能力的缺失与复杂导致人们对其在网络配置方面使用甚少。只有读的网络可编程...
Netconf协议与YANG Model
面向下一代网络,我们需要什么样的网络管理协议去更好地实现网络可编程能力,提高自动化的水平?
IETF于2002年在RFC3535提出了以下几点设想(实际有33条之多,结合网上资料与笔者认知,写了以下几条):
1、有对网络配置的可编程接口
2、同样的配置可以跨厂商型号
3、需要统一可读性良好的建模语言
4、完整的错误检查及恢复功能
5、事务性
有了想法,那就去实现,在2006年IETF提出了Netconf协议,基于RFC3535提出的问题进行了解决。最初的Netconf只规定了协议的基本框架和操作,定义考虑RFC3535的一些问题的解决方法,没有规定统一的建模语言,所以早期部分厂商的设备只是支持Netconf的一些基本操作,底层没有使用统一的数据建模语言。
在2010年发布了RFC6020, 提出了YANG Model建模语言,以及和NETCONF 的结合方法。一个定义的是数据建模的语言统一各厂商之间的底层资源逻辑,一个定义的是对配置数据、状态数据的操作统一各厂商的命令集,YANG模型创建的数据实例包裹在Netconf协议之中传输,二者相互结合,构建了一套新的基于YANG模型的使用Netconf协议驱动的新时代的通用网络可编程接口。
在2016年之后,Netconf协议与YANG Model紧密结合并流行开来。至此我们再去看一些SDN架构软件层面的时候,多多少少听到了这两个名词。
YANG 与Netconf,一个是静,一个动,就好比阴阳,二者衍生出了下一个时代的网络可编程世界。(当我们去看github上,YANG的仓库时也会发现,它的图标是太极,包括它名字中与“阳”的关联也多少透露出当初设计者的设计思想)
我们接下来就简单讲讲YANG Model与Netconf协议,我们先来讲数据建模语言YANG,看看它是如何描述这个网络世界的数字孪生。
YANG Model
在RFC6020的文档中,开篇明义,YANG,A Data Modeling Language for the Network Configuration Protocol。是Yet Another Next Generation (Yang) Data Modeling Language的缩写。
支持定义列表、字典、甚至更复杂的数据结构,支持约束、枚举、引用导入,版本管理、命名空间。由于篇幅,我们做简单讲解,详细信息大家可以参考:
官方文档:https://tools.ietf.org/html/rfc6020
互联网博文:https://www.jianshu.com/p/ca7f5fe11fae
它可以非常简单的用结构化语言描述出这个网络设备。比如对于一个端口的定义:
作为一个专业的运维人员,有点网络基础和一点点编程基础就可比较清晰的了解端口的定义,它是一个list结构的,可以有多个,它的一个属性是interface-name(同时是key,唯一,不可重复),还有speed属性和duplex属性,他们都是字符串。
一个网络设备的很多属性都以YANG Model去描述,包括配置状态和运行状态。
就这样,YANG Model用结构化语言描述了这个网络世界。有兴趣额的可以看看上面的那个互联网博文,有非常深入的描述。
它可以很好的转换成XML数据,包裹在Netconf协议之中进行传输(我们后续会讲解):
同时为了拉平厂商之间的差异,谷歌牵头的Openconfig对数据模型就行了标准化,从官网中我们看到这样一行标语“Vendor-neutral, model-driven network management designed by users”,由用户设计的、跨厂商通用的、模型驱动的网络编程(我么先这么翻译吧)。简单点说它是为了让各厂商之间的建模是相同的,大家再去配置某些数据的时候就不用一个个去翻看各厂商的私有的yang model了。但是网络总有私有协议,不同厂商总会为了“更好的用户体验”和“更好的商业战略”去创造新的、更牛的私有协议(这真的是网络厂商的原罪啊)。图中是一些比较常用openconfig的yang model实现。
从图中来看,我觉得还是挺多的,常用的配置比较齐全。但是实际中要看厂商是否也支持这些yang model。某科的一些高版本的设备基本都是支持的。国产的我暂时没去细看。
网络是不可能完全相同的,能做到大同,对于一个做网络运维开发的工程师来说,已经是谢天谢地了!
openconfig可以在
https://github.com/openconfig/public/tree/master/release/models
查找。私有的yang model 大家可以去各个官网查找。
Netconf协议
说完了yang model,我们来聊聊Netconf协议,yang model定义了网络世界的数字描述,Netconf定义了对数据的获取(get)与调整(config)。
Netconf对yang model描述的世界的数据yang data封装操作,实现对网络世界的管理。
yang data封装在xml中,然后通过Netconf协议进行管理。它是一个分层思想很棒的协议,有层次的描述了这个协议的一些细节。我们看看上图。
传输:Netconf是通过SSH协议传输,面向连接,且有安全保障。
消息:通过RPC进行对网络设备的远端调用,网管发出rpc请求,网络设备恢复rpc-reply。
操作:这是Netconf的灵魂所在,它支持get(配置及运行数据)、get-config(获取配置数据,且一个设备可以有多个配置数据,一个running,一个startup,多个candidate候选)、edit-config(配置网络设备的参数,支持增删改)这些常用的,还有delete-config、copy-config(复制配置到目的地,目的地可以是ftp、文件或者是正在running的配置等等)、lock\unlock(对配置进行锁定,防止多进程操作导致的配置冲突或者失败等情况)等等。
数据:data就是xml包裹的yang data,如上图我们所描述的那个端口一样,结构化数据易于编程。用来描述要配置或者删除或者获取的数据。
这就是Netconf的四个layer,控制端与网络设备端通过Netconf沟通,通过传统的ssh协议,用Netconf子系统,默认端口是830。如下图:
这个图用原始的ssh演示了交互,但是实际上我们是通过编程去实现这个过程的。编程的实现方式我后续会演示给大家。
Netconf配置网络设备,交互过程大致如下:
这个图,如此low,大家也可以看出来,是我自己画的... 我对Netconf的理解如上,网上很多图,是从网络视角去解读的。我是从开发者的程序去解读这个过程。这个是我登录设备所直观感受的,当然也和官方文档是一一对应的。
我们可以看看一些Netconf的例子:
hello,建链。
我们看到了几个关键字,Netconf的版本,支持的YANG Model,session id。同时hello中表明我们是在什么样的命名空间下操作,此例中是Netconf对应版本。
获取配置
get-cofig有一个参数是source,即获取哪里的配置数据(running、startup 或者其他)。还有一个参数是filter,即在哪个yang model描述的数据模型获取哪个数据。这个对应的是网络设备当初发送的capability中的。如果成功会回复对应的配置数据。
获取配置或者运行数据
类似get-config,但是获取的是running配置(个人理解)或者运行数据。可以指定filter。
复制配置
复制操作两个参数,源与目的。成功回复的是ok标签。
编辑配置
编辑配置的时候指定编辑的数据项,capability的命名空间及对应标签,比如这个是配置dhcp的,它是有http://tail-f.com/ns/example/dhcp这个yang model所描述。
优雅的关闭session
在ssh里来回传输的就是这种报文,我们只是把报文部分摘出来,方便大家理解。
然后简单补充一些内容,供参考。
Netconf是基于session的,每次成功都会有一个session id。
每次请求都有message id,只要是逐渐变大即可。
对数据配置可以锁定,独占,通过lock操作。
Netconf是事务性的,操作要么全部实现,要么全部不实现。同时根据官网文档,这个事务性是针对N台网络设备的配置,即一次配置多态都可以支持事务性。不过我没操作过...
Netconf支持订阅,看设备性能而言,数量级大概是5个session左右,我可以订阅某数据项,当发生变化的时候,设备会告知我。
capability,我是这样理解的,网络设备发送的是Netconf的版本和YANG Model,控制端发送的是Netconf的版本,二者对的上Netconf版本才能继续。这条是我的直观感受。欢迎指教。
get edit等操作会指定要改的数据,用filter可以过滤。
copy-config支持把一个配置全集从某处复制到某处,某处可以是FTP File,设备上的running、startup、candidate配置。
Netconf还支持对配置的验证,使用validate操作。
本文还是希望做到科普,具体细节不做赘述,大家可以去看看RFC的相关协议,其实不是很长。
在实际中基于一些开源的软件,比如python的ncclient,我们可以非常方便的对网络设备进行自动化配置,实现网络可编程。这就是Netconf与YANG Model的使命所在。
网络人员阅读格式良好的YANG Model定义,基于Netconf定义的操作,使用相关的编程语言对网络设备进行可编程操作。通过这种方式铸就网络可编程的道路。
我们再去扩展的想象一下,YANG Model已经定义了网络设备的数据结构,我们可以通过Netconf去操作,那是不是也可以通过其他协议去操作呢?
答案是肯定的,实际上后续也从Netconf衍生出了很多其他的协议,比如RESTConf。如下图,
YANG Model(public与native)定义了数据结构,之上是新的网管协议,Netconf、RESTCon、gRPC等等。这样我们可以通过基于HTTP RESTful API的RESTConf对网络设备操作,也可以通过基于SSH的Netconf对网络设备操作,也可以通过基于HTTP2.0的gRPC对网络设备操作,他们都是基于数据结构良好的YANG Model,编写对应的data,封装到xml或者json当中对网络设备编程,这就是未来的网络可编程之路,准确点说,是Model Driven Program,基于模型的网络可编程。网工逐步的关注于设备的参数,而不是命令集,通过阅读对应的数据模型,对网络进行参数配置。
写在最后,我为什么要开这个公众号。本人上学期间学的是计算机科学与技术,步入职场后,进行的是网络运维工作,想想分团队原因可能是我研究生是网络技术研究院导致的(手动滑稽),从最开始的网络运维到后期通过工具基于CLI去简化工作,提高效率,后逐步将工具开发成BS架构的web应用,不断接触新技术,后续不断丰富新功能,有幸赶上了开源技术与SDN的发展,逐步转型做了NetDevOps方面的工作,用自己的编程能力为团队提高运维能力,自己也乐于这一行行代码的编写中。随着编写的不断深入,逐步发现,NetDevOps应该是一个未来每个网工应该具备的技能(众人拾柴火焰高),这样才能即高屋建瓴又可快速实现。反观网络上的一些资料,说实话国内非常少,国内的氛围也不是很强,国内的很多软件都是基于老的CLI后者snmp,大家工作还是在用文本工具和SSH工具。于是希望自己能够授人以渔,将自己的经验(坑)和技能分享给更多的网络运维工程师,尽自己的一点绵薄之力。小处说,你能学点东西减少自己的工作量,着眼远处,国内的网络运维能真正向自动化方向演进。
后续会录一些视频和编写一些文章,写一个文档,感觉真费劲,欢迎订阅收藏点击喜欢在看之类的。
附录:
Netconf常见的operation
网友评论