4. 网络设备交互协议与库

在网络自动化工程师的面试中,协议与库的对比几乎是必考项。面试官真正想确认的不是你能否背出缩写,而是你能否在具体场景中做出合理选择,并说清背后的原因。本节围绕两条主线展开:一是设备交互协议(SSH、NETCONF、RESTCONF、gNMI、SNMP、Telnet)的定位与取舍;二是 Python 自动化库(Netmiko、Nornir、NAPALM、Scrapli)的适用边界与组合方式。

一、协议层:先分清"配置通道"与"监控通道"

六种协议可以按两个维度快速定位:是否面向配置、是否结构化。Telnet 与 SSH 属于交互式命令行通道,返回的是非结构化文本;SNMP 主要面向监控与状态采集,配置能力弱且厂商实现差异大;NETCONF、RESTCONF、gNMI 属于模型驱动(Model-Driven)的结构化通道,返回 XML、JSON 或 Protobuf,可直接被程序解析。

面试中常被追问的细节是:NETCONF 基于 SSH 传输(默认 830 端口),用 XML 编码,通过 <get-config>、<edit-config> 等操作配合 YANG 模型工作;RESTCONF 把同样的数据模型映射到 HTTP 方法上,用 GET/PUT/PATCH/DELETE 操作资源路径;gNMI 则基于 gRPC + HTTP/2,支持流式订阅(Subscribe),在遥测场景中优势明显。SNMP 的 GET/GETNEXT/GETBULK 适合周期性轮询,Trap 用于事件上报,但 MIB 覆盖度因厂商而异。

一个典型的选型判断可以这样表达:如果设备支持且需要高频、细粒度的状态采集,优先 gNMI 的 Subscribe 而非 SNMP 轮询;如果需要标准化配置下发且设备支持 YANG,优先 NETCONF/RESTCONF;如果面对老旧设备只开放 CLI,则退回 SSH + 文本解析,Telnet 仅在无 SSH 的极端遗留场景使用,且必须说明其明文传输的安全风险。

二、库层:从单机脚本到批量编排

Netmiko 建立在 Paramiko 之上,核心价值是把"连接设备、进入配置模式、发送命令、读取回显"这套 CLI 交互封装成稳定接口。它适合单设备或少量设备的脚本化操作,例如批量备份配置、下发 ACL。它的短板是并发能力有限、返回仍是文本,需要自己写正则或 TextFSM 解析。

Scrapli 同样面向 CLI,但更强调性能和异步支持,提供同步与 asyncio 两套 API,连接建立和命令执行速度通常优于 Netmiko,适合对执行效率敏感的场景。面试中可以这样对比:Netmiko 生态成熟、文档丰富、上手快;Scrapli 更轻量、更快、原生支持异步,但社区规模相对小。

NAPALM 的定位是"多厂商统一抽象"。它把 get_config、load_merge_candidate、commit_config 等操作抽象成统一方法,屏蔽了不同厂商 CLI 的差异,适合需要跨厂商统一配置管理的场景。但它的抽象层也带来限制:并非所有厂商特性都被覆盖,遇到抽象层未支持的命令时需要回退到原生方式。

Nornir 不是连接库,而是编排框架。它本身不负责与设备通信,而是通过 inventory 管理设备清单、通过 task 组织任务、通过 runner 控制并发,底层可挂接 Netmiko、Scrapli、NAPALM 等插件。它解决的是"几百台设备如何高效、可维护地批量执行"的问题。

三、组合实践:一个可复现的批量采集示例

下面用 Nornir + Netmiko 组合,演示批量采集设备版本信息并判断结果。示例中的 IP、账号均为假设值,仅用于说明结构。

# inventory/hosts.yaml(示例数据)
r1:
  hostname: 192.0.2.11
  platform: ios
  username: auto
  password: "Example@123"
r2:
  hostname: 192.0.2.12
  platform: ios
  username: auto
  password: "Example@123"

# tasks.py
from nornir import InitNornir
from nornir_netmiko.tasks import netmiko_send_command
from nornir_utils.plugins.functions import print_result

def get_version(task):
    return task.run(
        task=netmiko_send_command,
        command_string="show version",
        use_textfsm=True,   # 尝试结构化解析
    )

nr = InitNornir(config_file="config.yaml")
result = nr.run(task=get_version)
print_result(result)

# 判断依据:逐台检查 result 是否 failed
for host, r in result.items():
    if r.failed:
        print(f"{host} 采集失败: {r.exception}")
    else:
        print(f"{host} 采集成功,返回条目数: {len(r.result)}")

执行后需要观察三点:一是每台设备的 failed 标志,用于区分连接失败与命令失败;二是 use_textfsm=True 时返回是否为字典列表,若为原始字符串说明该平台缺少对应 TextFSM 模板,需要自行补充;三是整体耗时,若设备数量大而耗时线性增长,说明并发度不足,应调整 Nornir 的 num_workers 参数。

四、面试答题要点与常见追问

回答协议对比时,建议按"结构化程度—传输方式—典型用途—局限"四步展开,而不是罗列名词。回答库对比时,先说明它解决的是连接问题还是编排问题,再给出组合建议。常见追问包括:NETCONF 与 RESTCONF 如何选?可以答:设备同时支持时,若团队更熟悉 HTTP 生态、需要与 Web 系统集成,选 RESTCONF;若需要更完整的 NETCONF 操作集和事务能力,选 NETCONF。gNMI 与 SNMP 如何选?答:需要秒级遥测和流式订阅选 gNMI,只需分钟级轮询且设备 MIB 完善可用 SNMP。

下表可作为面试前的快速对照,字段只保留选型真正需要的维度。

协议/库 结构化 主要用途 关键局限
Telnet否遗留设备 CLI明文传输,不安全
SSH否通用 CLI 交互返回文本需解析
SNMP半结构化监控轮询、TrapMIB 差异大,配置弱
NETCONF是(XML)标准化配置下发依赖 YANG 模型覆盖
RESTCONF是(JSON/XML)HTTP 风格配置操作集少于 NETCONF
gNMI是(Protobuf)遥测、流式订阅设备支持度参差
Netmiko否单机/少量 CLI 脚本并发弱,需自行解析
Scrapli否高性能 CLI、异步生态相对小
NAPALM是多厂商统一配置抽象特性覆盖有限
Nornir—批量编排框架需搭配连接插件

最后提醒一个高频失分点:不要声称某个协议或库"最好"。面试官更看重你能否说出"在什么约束下选它"。把设备能力、团队技能、数据消费方式这三个约束讲清楚,选型结论自然成立。