ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

基于NETCONF协议的华为CE系列交换机配置自动化与管理实践

基于NETCONF协议的华为CE系列交换机配置自动化与管理实践 简介基于NETCONF协议与YANG模型构建的网络设备配置管理系统面向网络运维工程师、自动化平台开发者及华为CE系列交换机使用者系统实现了针对CE12800与CE6800的配置脚本自动下发、收集与拓扑监控可显著降低手工配置负担其图形化客户端也屏蔽了复杂命令行操作使设备管理更加直观高效。压缩包共376个文件以Python后端、Vue前端与JavaScript脚本为主线辅以样式文件、图标及配置文件完整覆盖图形化界面前后端实现整体体积仅2.48MB便于本地部署与二次开发。已有167人浏览学习。压缩包内含完善的构建与部署配置如环境变量、项目页面入口及开发辅助文件并附赠说明文档可帮助读者快速理解NETCONF会话管理、YANG数据建模和华为设备对接逻辑配合网络拓扑监控模块还能实时查看设备运行状态与连接关系。结合配置管理流程既能作为企业网络自动化改造的参考原型也可作为学习协议体系的落地案例。1. 给CE12800和CE6800做配置自动化为什么我选定基于NETCONF协议的网络设备配置管理系统某次夜间割接同事在CE6800上用脚本刷几百行接口配置回显顺序和预期差了半行后面的配置全部没生效现场又没有第二台设备可对照回滚。事后复盘问题其实不在命令本身而在于配置手段没有结构、没有对象、也没有状态。基于NETCONF协议的网络设备配置管理系统核心就是把华为CE12800和CE6800的配置工作拆成三条标准链路用YANG模型描述设备配置对象用配置脚本自动下发与收集替代人工粘贴和抓屏再用图形化客户端界面和网络拓扑监控把执行过程变成可视、可查、可回滚的流程。这套路径适合正在做数据中心网络自动化的团队也适合手里握着几十台CE系列交换机、已经受够CLI脚本维护成本的人。下面按我实际搭建这套系统的顺序展开先讲模型准备再讲下发与收集通道最后讲图形界面和拓扑监控并把生产环境最容易踩的坑单独列出来。2. 前置准备华为CE12800/CE6800的YANG模型与NETCONF能力摸底很多团队拿到这套需求后立刻写代码结果连设备侧的NETCONF服务都没开或者开了服务却不知道设备到底支持哪些YANG模型导致后面每次下发都在猜字段。这一章先把地基打好为什么选NETCONF、设备上开什么命令、怎么把YANG模型版本固定下来。2.1 为什么不是CLI抓屏也不是SNMP写配置做网络设备配置管理系统最诱惑的方案是继续用paramiko或expect去模拟命令行登录。这个路数在小规模场景里能跑但到了CE12800这种框式交换机上就会出问题命令回显内容随VRP版本变化分页符、缩进、错误提示的格式都不一样脚本里每一个正则都可能因为一次设备升级而失效。再加上CLI本身没有事务概念一批命令执行到一半失败根本没有回滚入口。SNMP在读取流量和接口状态时很高效但用SNMP做配置写入一直很受限。很多MIB表在华为CE系列上只读写接口IP这类高频操作还要依赖私有MIB跨型号兼容性很差配置回滚更是基本不存在。NETCONF和YANG的组合解决了这两个痛点。NETCONF提供标准会话通道配置内容以XML承载通过edit-config、get-config这些标准操作完成增删改查YANG模型则把接口、VLAN、路由协议这些配置对象变成有约束的数据结构客户端代码不用再解析自然语言式的命令行回显。下表是我在选型时做的对比对比维度CLI脚本paramiko/expectSNMPNETCONF/YANG配置表达文本命令依赖回显顺序MIB节点OID很多表只读XML节点遵循YANG约束结构化明确事务与回滚无执行一半无法整体回退无支持candidate配置库加commit确认回滚靠配置快照批量下发每次都要登录、解析回显容易碎可以并发但写操作支持有限一个会话管理多个配置对象批量任务可追踪每条执行结果采集结果可靠性需要处理分页、缩进、版本差异依赖MIB实现型号差异大XML带命名空间解析稳定能做基线差异主流工具链自己维护交互逻辑pysnmp等库但写操作鸡肋ncclient、yanglint、pyang等生态完整所以面向CE12800和CE6800这类华为数据中心交换机采用基于NETCONF协议的网络设备配置管理系统是当前最稳妥的路径。它不是银弹但至少把配置从“字符串艺术”变成了“数据结构”。2.2 设备侧开启NETCONFCE12800/CE6800上的最小命令集拿到设备后我一般先在CE6800上做试点把NETCONF服务开起来命令大致如下具体以当前设备运行的VRP版本为准system-view netconf ssh server enable port 830 acl 2000 source 10.10.20.0 0.0.0.255 quit acl 2000 rule 5 permit source 10.10.20.0 0.0.0.255 quit aaa local-user netconf_ops password cipher Huawei123 local-user netconf_ops service-type ssh local-user netconf_ops privilege level 15 quit这段命令在CE12800和CE6800上的含义是一致的开启NETCONF服务并让它监听在830端口。SSH是NETCONF最常用的传输层ssh server enable不能漏否则客户端连上来会被拒绝。ACL和source限定只允许管理网段10.10.20.0/24访问NETCONF服务这是安全的第一道门。最后在AAA里创建专用账号service-type必须是sshprivilege level给到15是为了避免后续下发复杂配置时权限不足实际生产环境建议按最小权限拆分成配置只读账号和配置下发账号。配置完以后在设备上执行display netconf可以看到服务状态和会话数执行display netconf session能查当前活动的NETCONF会话。这个地方有一个常见操作误区有人直接在PC上用ssh -p 830 netconf_ops10.10.20.10去测连通性发现能登录就以为NETCONF通了。其实NETCONF的SSH子系统会在登录后进入NETCONF的HELLO报文交换普通SSH登进去看到的不是命令行也不是NETCONF报文。真正的连通性测试应该用编程语言里的NETCONF客户端库来做。2.3 用能力集与模型库把YANG模型版本固定下来华为CE12800和CE6800的YANG模型不是只有一个文件而是按功能域拆分成华为私有的YANG模块接口管理、VLAN、路由、LLDP、ACL各有各的模型命名空间。设备开启NETCONF后客户端发起的第一次会话里设备会通过能力交换把支持的模型和版本全部告诉客户端。我习惯用一个最简短的Python脚本把能力集拉下来作为模型库的初始输入from ncclient import manager with manager.connect( host10.10.20.10, port830, usernamenetconf_ops, passwordHuawei123, hostkey_verifyFalse, device_params{name: huawei}, timeout30, allow_agentFalse, look_for_keysFalse, ) as device: for cap in sorted(device.server_capabilities): print(cap)这段代码的核心是device_params{name: huawei}。不同厂商对SSH子系统的协商细节不同ncclient需要指定设备类型才能正确完成NETCONF会话握手。华为设备的这个参数不能省否则经常在HELLO阶段就报错。拉出来的能力集会包含大量形如http://www.huawei.com/netconf/vrp/huawei-ifm之类的URLURL里的路径通常带版本号或日期信息。拿到这些能力后我不会直接开始写配置下发脚本而是先建一个模型版本表记录设备型号、VRP版本、能力集哈希、拉取日期。之后每次设备升级先重新拉一次能力集和上一次对比如果发现YANG模型版本变化系统就把对应设备标记为“配置下发需审核”防止老模板带病运行。这一步看起来多余却是后面避坑章节里最重要的一道保险。3. 配置脚本自动下发与收集NETCONF会话、XML模板和差异管理系统真正的核心链路在这一章。先建稳定的NETCONF会话再把配置脚本渲染成YANG模型对应的XML通过标准协议下发最后定时把运行配置拉回来做差异比对。这三步环环相扣每一环的容错设计都决定了系统能不能从实验环境走进生产。3.1 先用Python ncclient建立一条稳定连接第一步先封装一个连接管理类目的是让系统中的采集引擎复用连接而不是每次任务都新建会话from ncclient import manager class NetconfClient: def __init__(self, host, port, username, password): self.host host self.port port self.username username self.password password self.conn None def connect(self): self.conn manager.connect( hostself.host, portself.port, usernameself.username, passwordself.password, hostkey_verifyFalse, device_params{name: huawei}, timeout30, allow_agentFalse, look_for_keysFalse, ) return self.conn def get_capabilities(self): return sorted(self.conn.server_capabilities) def close(self): if self.conn: self.conn.close_session()连接参数里有两个容易忽略的地方。allow_agentFalse和look_for_keysFalse必须带上否则ncclient会尝试调用本机的SSH agent和默认密钥在自动化服务器上容易触发奇怪的认证失败。timeout30建议根据设备规模调整批量下发时如果设备CPU繁忙这个值太小会误判超时。这一层封装好后系统中的所有模块都通过这个类访问设备后续如果要替换成华为自己的iMaster NCE或其它协议栈只需要改这一处接口。连接池策略上我一般按设备IP建立字典缓存超过5分钟空闲就关闭避免设备侧NETCONF会话数被占满。3.2 配置脚本自动下发从模板渲染到candidate提交配置下发不是简单地拼字符串。正确做法是把配置模板写成XML文件将变量位置用占位符标记渲染后再提交给设备。这样配置脚本和代码逻辑分离新增一种配置任务不需要改代码。下面是一个下发接口管理配置的示例实际命名空间URL从设备能力集里复制不要手敲from xml.sax.saxutils import escape import time def render_interface_config(interface_name, interface_type, description): desc_escaped escape(description) payload f config xmlnshttp://www.huawei.com/netconf/vrp/huawei-ifm ifm interfaces interface ifName{interface_name}/ifName ifType{interface_type}/ifType ifPhyType{interface_type}/ifPhyType l2Enabletrue/l2Enable ifDescription{desc_escaped}/ifDescription /interface /interfaces /ifm /config return payload client NetconfClient(10.10.20.10, 830, netconf_ops, Huawei123) client.connect() has_candidate :candidate in client.get_capabilities() target candidate if has_candidate else running payload render_interface_config(10GE1/0/1, 10GE, uplink-to-core-01) resp client.conn.edit_config(targettarget, configpayload) if has_candidate: if :validate in client.get_capabilities(): client.conn.validate(sourcetarget) client.conn.commit() client.close()这段代码有几个关键点。target变量的选择是通过能力集探测得到的华为CE系列有些版本只支持直接写在running配置库有些支持candidate加commit。直接探测能力集比写死配置更可靠否则换一个版本就会翻车。如果设备支持candidate修改会先暂存在候选配置库提交前还可以用validate做合法性校验校验通过再commit这一步给了配置脚本一次后悔药的机会。escape(description)是很多新手容易漏掉的。YANG模型里的字符串节点如果包含、、这些XML特殊字符直接拼接会导致XML解析失败。华为设备经常在描述字段里写“MSTPVRRP”其中的必须转义。所有从表单或配置文件里读进来的内容都必须做XML转义。另外节点内的空值也要小心ifDescription/ifDescription可能会被部分版本解释成删除描述而不是清空描述。3.3 配置自动收集定时拉取运行配置并生成差异下发只是系统的一半配置收集和差异管理才是日常运营的核心。每次变更前后各拉取一次running配置一对比就能知道配置脚本到底生效了没有所以我们需要一个稳定的采集函数和前后的差异视图from lxml import etree import difflib import datetime def collect_running_config(client, hostname): filter_xml filter typesubtree config xmlnshttp://www.huawei.com/netconf/vrp/config /config /filter resp client.conn.get_config(sourcerunning, filterfilter_xml) root etree.fromstring(resp.xml) formatted etree.tostring(root, pretty_printTrue).decode(utf-8) timestamp datetime.datetime.now().strftime(%Y%m%d_%H%M%S) filename f{hostname}_running_{timestamp}.xml with open(filename, w, encodingutf-8) as fp: fp.write(formatted) return filename def diff_configs(before_file, after_file): with open(before_file, r, encodingutf-8) as bf, \ open(after_file, r, encodingutf-8) as af: before_lines bf.readlines() after_lines af.readlines() diff difflib.unified_diff( before_lines, after_lines, fromfilebefore_file, tofileafter_file ) return .join(diff)采集到的XML文件不直接扔给人工看而是入库保存为配置基线。系统会为每台设备维护最近一次变更前的基线下次下发前自动先采集一次再和上一次基线比较确认没有非计划内的漂移。这个“配置漂移检测”是很多配置管理系统的隐藏需求实际生产里经常出现某台CE6800被同事手工登录改了一个接口描述结果自动化批量下发时把这个手工改动覆盖掉的事。通过基线比对就能提前发现这种漂移并告警。filter参数用的是subtree过滤能减少传输数据量。但注意如果设备没有正确返回期望的配置层级往往是因为filter里的根节点命名空间不对这时把整个filter去掉先做一次全量采集再看XML结构是最常见的排错方式。4. 图形化客户端界面和网络拓扑监控系统架构与实现要点协议层跑通以后系统还缺一张脸。标题里的图形化客户端界面和网络拓扑监控不是花架子而是让配置管理系统从“个人脚本”变成“团队工具”的关键环节。网工团队的配置操作不能依赖每个成员都懂Python必须有个界面能发起任务、查看结果同时拓扑视图要把设备之间的物理链路状态实时展示出来。4.1 把采集、任务、拓扑和数据放在同一个系统里的架构划分我通常把系统拆成五个模块边界清晰方便不同人维护模块职责关键数据采集引擎维护NETCONF会话、XML编解码、设备连接池设备列表、能力集缓存任务中心配置下发、收集、回滚任务调度维护任务状态机任务表、变更单记录配置库运行配置快照、基线配置、差异结果存档配置文件、基线版本拓扑服务从接口状态、LLDP邻居构建并刷新网络拓扑邻居关系、节点状态图形化客户端可视化操作、任务结果展示、告警提醒用户、角色、权限采集引擎只跟设备打交道对外提供“采集一台设备配置”这样的原子能力。任务中心负责编排比如一个批量任务要对20台CE6800下发同一份配置脚本任务中心会先检查每台设备的状态再决定并发度。配置库单独拆出来是因为配置数据量增长很快而且要做基线对比、审计查询不能混在任务数据里。图形化客户端界面我这边采用Web方式实现后端提供API前端用Vue或React都行。选Web不是因为它比桌面客户端时髦而是支持多账号登录、权限分隔和操作审计网工团队不需要在每台电脑上装客户端。标题里的图形化客户端界面本质是要把任务流程变成菜单式操作点击、填参、确认、看结果。4.2 图形化客户端界面一次变更任务的完整交互图形化客户端界面至少要覆盖四个操作页面设备管理、任务创建、任务详情、配置对比。设备管理页展示所有CE12800和CE6800的清单每台设备一行包含型号、软件版本、NETCONF连通状态、最近一次配置采集时间。连通状态由采集引擎定时探测发现异常直接标红。任务创建页让用户选择目标设备或设备分组选择配置模板填写模板变量比如接口名、描述、VLAN号提交前系统会把渲染后的XML展示出来供人确认。任务详情页是这个界面的灵魂。它按设备展示执行状态状态依次是等待、连接中、下发中、校验中、已提交、失败。失败时把设备返回的错误XML原样贴出来这一点比任何自定义错误码都有用因为华为设备的NETCONF错误信息本身就够精确人为翻译成“下发失败”反而丢了信息。界面上的配置对比功能直接复用3.3节的diff逻辑变更前后两次配置的差异用左右两栏展示新增行绿色、删除行红色。这样配置脚本自动下发与收集就形成完整闭环人在界面上能回答“改了没有、改了什么、谁能看到”。4.3 网络拓扑监控用LLDP和接口状态自动画图网络拓扑监控模块我建议用LLDP作为数据源因为它不需要额外配置太多东西华为CE12800和CE6800默认开启LLDP的场景很常见。采集引擎定期从每台设备查询LLDP邻居信息再把邻居关系汇总成一张拓扑图。下面是提取LLDP邻居的XML过滤模板和解析代码filter_lldp filter typesubtree lldp xmlnshttp://www.huawei.com/netconf/vrp/huawei-lldp device ifName/ifName neighbors neighbor systemName/systemName neighborIfName/neighborIfName /neighbor /neighbors /device /lldp /filter def parse_lldp_edges(resp_xml): import xml.etree.ElementTree as ET root ET.fromstring(resp_xml) edges [] for device_node in root.iter(device): local_device None local_if None # 根据实际返回的XML层级提取 local_name_el device_node.find(.//ifName) if local_name_el is not None: local_if local_name_el.text for neighbor in device_node.iter(neighbor): remote_name_el neighbor.find(systemName) remote_if_el neighbor.find(neighborIfName) if remote_name_el is not None: remote_device remote_name_el.text remote_if remote_if_el.text if remote_if_el is not None else edges.append((remote_device, remote_if)) return edges这里我特意没把XML命名空间写死在上面的解析逻辑里因为不同版本返回的层级结构可能有差异建议先用全量LLDP响应打印一次XML再按实际结构调整解析代码。拿到边关系后把设备清单里的已知设备映射为节点不在清单里的识别为外部网络节点这样拓扑图不会因为发现了一台非纳管设备就崩掉。拓扑绘制方面前端用开源的图形库就够用节点上叠加设备告警状态线和接口up/down状态绑定。每次采集刷新时对比上一轮拓扑把新增设备、断开的链路都标出来网络拓扑监控的价值就出来了配置下发前可以看清楚哪些链路会被影响这个视角是纯命令行给不了的。5. 生产环境避坑五个最容易让NETCONF配置下发失败的问题前面几章把主链路走通后真正折磨人的是生产环境里的各种暗坑。下面五条都是我在CE12800和CE6800上实际遇到过、并且花时间排查过的问题按现象、原因、解决的顺序整理。5.1 批量任务并发一高后面的设备全部连接超时现象同时给20台CE6800下发配置前几台很快就成功跑到大约第10台之后新增连接全部报超时。原因华为CE系列设备的NETCONF服务有最大会话数限制默认不高而且前面的会话没有正常关闭一直占着名额。同时设备开启的NETCONF会话如果长时间空闲也会被回收批量任务的执行速度跟不上会话创建速度时就会出现这种“前面成功、后面超时”的假故障。解决一是降低并发数把采集引擎的连接池并发控制在4到6个二是同一个设备尽量复用连接执行完立刻关闭会话释放名额三是在任务中心增加重试机制报超时的设备自动进入等待队列等待5秒后重试一次。另外检查设备上是否有历史遗留的死会话用display netconf session查看手工踢掉异常会话再跑批量任务。5.2 昨天还能下发的模板今天突然报invalid value或unknown element现象配置模板没有改动但设备返回的错误信息指向某个节点不识别或者字段值不在合法范围内。同一台设备昨天手动测试还能通过。原因设备升级过软件版本YANG模型版本也跟着变了。华为CE12800在升级VRP后可能修改了某个YANG节点的取值范围也可能废弃了一个字段把旧模板发过去就会报invalid value如果整个命名空间都换了就会报unknown element。解决把章节2.3里的能力集拉取做成定时任务发现模型版本变化后自动把受影响设备上的配置下发权限挂起。模型库更新后所有配置模板都要重新做一次schema级校验再启用。这个坑最容易出现在设备批次升级的窗口期宜提前通知自动化团队而不是等模板跑挂了再查。5.3 一个大XML里塞了几百个配置节点设备直接无响应现象批量创建几百个VLAN或者批量修改一堆接口描述单个编辑配置发送后设备长时间不返回最后客户端超时也不知道配置到底套用成功没有。原因配置数据一次性太大设备内部XML解析和配置回写的压力过高。NETCONF协议本身没有限制报文长度但设备实现有隐藏的深度和长度阈值超过就会卡住或直接丢弃请求。解决把一个大配置拆成多个小批次每批控制在50个节点以内发一批、确认一批再做下一批。中途失败时用当前设备的运行配置去对账看看这批里哪些已生效、哪些没生效而不是盲目重发。这里顺便说一句别信什么“一把梭”的技巧批量变更场景下分片下发才是稳定的前提。5.4 配置里的中文描述在设备上显示正常但在系统里采集回来变成乱码现象通过系统下发的中文接口描述在交换机上用命令看没有问题但通过NETCONF采集回来在系统页面显示为乱码或问号。原因字符编码两头不一致。设备的CLI显示环境可能是GBK或GB18030而NETCONF通道传输的配置上下文字节流要求按UTF-8解释。如果客户端代码在拼接配置时用了默认编码或者读取模板文件时没指定编码中文字符就会在传输前已经被破坏了字节序列。解决里里外外统一UTF-8。代码里打开配置文件时显式写encodingutf-8下发前对XML字符串做UTF-8编码检查页面端也统一按UTF-8渲染。另外不要在Windows记事本里编辑配置模板记事本保存的带BOM头文件会让XML解析器在第一行报错这也是一个经常出现的隐性问题轻量文本编辑器也要确认默认保存为无BOM的UTF-8格式。5.5 两个任务同时改同一台设备后一个任务把前一个的改动覆盖了现象变更单A下午三点给CE12800下发VLAN 100的配置变更单B下午三点半下发接口MTU配置B执行成功后检查发现VLAN 100不见了两台设备上的配置互相覆盖。原因两个巡检脚本或两个工单操作了同一台设备NETCONF配置库被后写入的一方整体覆盖。尤其是没走candidate、直接在running上edit-config时如果操作语义是replace就把不属于本次变更的其它节点也冲掉了。解决每台设备在同一时间只允许一个写任务。代码层面下发前用NETCONF的lock操作锁定配置库拿到锁才允许修改结束后释放锁。下面是加锁的固定姿势client.connect() target running try: client.conn.lock(targettarget) client.conn.edit_config(targettarget, configpayload) # 根据需要决定要不要执行 commit, 华为running直接生效 finally: client.conn.unlock(targettarget)如果拿锁失败不要反复重试直接把任务标记为“冲突”等另一个任务结束后再重新排队。在任务中心层面还要把设备维度加一把分布式锁防止两个工单同时发起代码锁只能防住同一套系统内部防不住多系统并发。6. 上线前先做灰度放量、回滚三板斧和账号加固三个必须养成的习惯系统在测试环境跑通不等于能直接上生产。我每次接入一批新设备都会按固定顺序走三步这三步已经成了团队的习惯缺一步都不敢让配置脚本自动下发。6.1 灰度路径先CE6800浅上量再CE12800全量CE12800和CE6800虽然都跑华为VRP但框式交换机的CPU主控架构和盒式差别很大同样一个配置模板在两款设备上的生效时间、资源占用完全不同。我先选一台业务影响最小的CE6800做验证把下发、采集、对比完整走一遍观察设备CPU和内存没有异常再扩大到同一机房的CE6800批次最后才轮到CE12800。灰度期间每台设备执行完任务后都必须人工或自动核对一次关键业务状态比如接口能否正常收发确认无误再把下一批放进来。6.2 回滚三板斧快照、基线、commit确认第一板斧每次变更前对目标设备做一次全网配置采集存档为变更前快照。第二板斧把这台设备上一份已知正常的基线配置单独存好不能用最新快照替代基线因为最新快照可能已经被手工改动污染了。第三板斧对于支持candidate加commit的设备下发后不要立刻commit先validate再等待一段时间观察设备状态确认无误再提交。一旦commit后发现问题就把第一板斧的全量快照通过配置脚本整体回灌到设备上。6.3 安全加固让NETCONF管理面只对特定管理网段开放配置管理系统拥有对全网设备的写权限管理面被攻破等于网络被接管。我现在的做法是在设备侧用ACL限定NETCONF服务只允许管理网段的源IP接入账号上分三类巡检只读账号、变更下发账号、管理员账号密码全部走统一的密钥管理服务不在代码里明文保存。系统侧再留一条审计日志记录谁在什么时间用哪个模板改了哪台设备日志保留至少六个月。这样出问题能追溯也防止配置变更变成个别人的黑匣子。有一次新同事图省事把系统里所有设备的管理密码配成了同一个第二天一台设备因弱口令被扫描到我们用了整整一个下午才把所有相关账号轮换完期间所有自动化任务都停摆。那次之后我就把账号和ACL加固列在上线的最后一道卡口上。这套系统能不能长期跑稳靠的不是某一次脚本写得漂亮而是每次变更都有快照、有基线、有权限边界。希望帮到你。本文还有配套的精品资源点击获取
返回列表