本系列应该是记录我在网络自动化中的学习、使用。具体更新多少期、什么频率都不太清楚。
同时本文的记录方式不会是那么的符合学习的思路,需要更加详细的内容建议阅读官方文档等。
本人学习的路径是基于九净老师
的NetDevOps加油站
,但本文有所简化,取舍了难度较高的深入逻辑,仅保留最常用、最直观的内容。
目录
- 什么是netmiko
- Netmiko和Paramiko
- 安装netmiko
- 环境
- 最简单的Netmiko Demo脚本
- 针对上述代码所用到的类的介绍
- 1. 设备信息取值
- 推荐使用的场景
- 写在最后
什么是netmiko
网络设备的配置,我们一般都是采用CLI的方式,通过Console、Telnet、SSH登录到设备,然后执行需要的命令。
一般来说网络自动化的底层逻辑分为两种:
- 让机器以机器的方式完成操作(一般用API)
- 让机器模拟人的方式完成操作
以目前的设备来说,支持API、同时有比较完善生态的网络设备不多,同时价格比较昂贵(我个人认为可以类比支持SDN的设备)。
所以选用让机器模拟人的方式完成操作
这个方案是在网络自动化中比较常见的。实际上,这就是让我们的脚本通过远程登陆(SSH、Telnet)等方式登陆到设备,然后发送命令即可。
Python基于CLI模式与网络设备进行交互的工具包有很多,而netmiko
与paramiko
无疑是这类库中最有名的。
Netmiko和Paramiko
netmiko是工程师Kirk Byers 于2015年发布的一个用于简化众多厂商网络设备CLI连接(ssh、telnet、serial)的工具类。实际2015年的版本只支持ssh,所以它最早是为了简化ssh通用工具类paramiko的连接和操作(后续netmiko已经支持了telnet和serial),所以它的名字从中取了"miko",又因其垂直于网络自动化领域,所以又添加了“net”,组成了netmiko的名称。
相较paramiko,netmiko有着更加简化的操作和更加针对网络设备的高阶封装。通过抽象一些底层的状态控制,消除查看配置和改变配置的在一众平台中的差异,目前支持的厂商平台覆盖了日常网络运维所需,所以更建议新手使用netmiko
,让我们更聚焦在网络业务逻辑层面
,这些我们也会在后续的使用中都将体会到。
安装netmiko
前置的Python安装流程不再赘述,需要的请通过别的笔记自行学习安装
我的环境是Python 3.9
、Pycharm 2024.2
、Windows11
# 安装netmiko
pip install netmiko
以上执行成功后,即安装完成了netmiko。
我们打开一个交互式的窗口,或者编写一个脚本,导入netmiko的对应函数没有报错,代表安装成功。
from netmiko import Netmiko
环境
我使用EVE-NG部署的Cisco与Huawei设备混合的简单网络,拓扑图如下:
所有设备直接通过Net云朵桥接到VMnet8网卡,均设置VMnet8网段中的可用地址。
所有设备均以提前配置好了ssh,用户名python,密码123。
所有设备均已ssh测试确定可以通过ssh登录。
最简单的Netmiko Demo脚本
先通过一个查看接口ip信息
的脚本,为大家带入网络自动化。
# 导入库
from netmiko import ConnectHandler# 设备信息
sw1 = {'device_type':'cisco_ios','ip':'192.168.100.11','username':'python','password':'123'
}# 使用netmiko
with ConnectHandler(**sw1) as conn:# 如果设备需要进入enable模式,需要输入# 如果默认就是enable模式,或者设备没有enable模式,不会报错conn.enable()# 发送show ip int bri 命令,并将回显保存到output中output = conn.send_command(command_string='show ip int bri')# 输出output保存的内容,即show ip int bri的回显print(output)
以上就是最简单的一个netmiko实现网络自动化的方式。或许会说设备太少、命令太简单,但实际上,网络自动化的逻辑就是这样的:
- 记录所需设备信息
- 调用netmiko的ConnectHandler方法,使用设备信息中的ip、username、password创建ssh隧道
- 调用send_command方法发送需要发送的命令(一般是show命令) 或者调用send_config_set方法发送需要发送的命令(一般是配置命令)
- 关闭ssh隧道(上述代码通过with方法,不必使用disconnect方法手动关闭)
- 根据需求打印、记录、处理、收集回显信息
- 结束脚本
在上述代码中,值得注意的一点是:netmiko为我们处理好了不同厂商的命令集区别,即通过设备信息的device_type
指定驱动类
,后续的进入配置模式究竟是conf t
还是system-v
,最终保存配置的wri mem
还是save
就是脚本自行处理,而无需人工思考处理。
设备信息需要以字典dict
保存(什么是字典这个问题,请先掌握好python基础),其中ip或host
、device_type
、username
、password
字段是必须有,且不能打错。因为netmiko是根据这些字段创建与设备通信的ssh隧道。ip
和host
只需要有一个就可以,如果都有的话,默认采用ip
针对上述代码所用到的类的介绍
这里涉及到更多的python基础,个人认为如果只是用到如上代码的内容的话,其实不需要了解太多。
1. 设备信息取值
上文有提到,netmiko的ConnectHandler方法通过设备信息中的部分字段创建ssh隧道。所以设备信息变量中可以用的值是根据这个方法的参数量确定的。
而这个ConnectHandler方法,又是继承于BaseConnection
类
这个类就是netmiko的所有连接类的基类(可以理解为这个netmiko连接家族的老祖宗),它的构造方法中有着众多的参数,用于去创建一个连接对象,即登录到一台设备。
# 内容太多,仅截取构造函数部分
class BaseConnection:"""Defines vendor independent methods.Otherwise method left as a stub method."""def __init__(self,ip: str = "",host: str = "",username: str = "",password: Optional[str] = None,secret: str = "",port: Optional[int] = None,device_type: str = "",verbose: bool = False,global_delay_factor: float = 1.0,global_cmd_verify: Optional[bool] = None,use_keys: bool = False,key_file: Optional[str] = None,pkey: Optional[paramiko.PKey] = None,passphrase: Optional[str] = None,disabled_algorithms: Optional[Dict[str, Any]] = None,disable_sha2_fix: bool = False,allow_agent: bool = False,ssh_strict: bool = False,system_host_keys: bool = False,alt_host_keys: bool = False,alt_key_file: str = "",ssh_config_file: Optional[str] = None,## Connect timeouts# ssh-connect --> TCP conn (conn_timeout) --> SSH-banner (banner_timeout)# --> Auth response (auth_timeout)conn_timeout: int = 10,# Timeout to wait for authentication responseauth_timeout: Optional[int] = None,banner_timeout: int = 15, # Timeout to wait for the banner to be presented# Other timeoutsblocking_timeout: int = 20, # Read blocking timeouttimeout: int = 100, # TCP connect timeout | overloaded to read-loop timeoutsession_timeout: int = 60, # Used for locking/sharing the connectionread_timeout_override: Optional[float] = None,keepalive: int = 0,default_enter: Optional[str] = None,response_return: Optional[str] = None,serial_settings: Optional[Dict[str, Any]] = None,fast_cli: bool = True,_legacy_mode: bool = False,session_log: Optional[SessionLog] = None,session_log_record_writes: bool = False,session_log_file_mode: str = "write",allow_auto_change: bool = False,encoding: str = "utf-8",sock: Optional[socket.socket] = None,sock_telnet: Optional[Dict[str, Any]] = None,auto_connect: bool = True,delay_factor_compat: bool = False,disable_lf_normalization: bool = False,) -> None:...
......
........
以下是比较重要的部分参数的解释:
说明 | 参数名 |
---|---|
ip | 设备IP地址 |
host | 设备host名称,需要可以解析出IP地址 |
username | 用户名 |
password | 密码 |
secret | enable密码,提权时需要输入的密码 |
port | 端口,会根据device_type自动判断(如有“ssh”字符串是22,如有“telnet”是23),也可以用户指定 |
device_type | 设备的驱动名称 |
conn_timeout | 连接超时时间,默认为5秒,如果网络条件不好,建议适当增加,尤其是广域网或者国际网络(在show配置,经常使用) |
timeout | 执行命令的超时时间,根据情况适当延长,默认为100秒 |
session_log | 记录log的路径,如填写则会将与设备的所有操作记录(但可能和脚本内部分内容冲突,建议只有在检查脚本问题时或运行脚本留样时少量使用) |
session_log_file_mode | 记录log的模式,覆盖"write" ,追加 “append”,默认覆盖 |
global_delay_factor | 默认的全局的延迟因子,值为1,结合后续篇章了解,在这里引出,在某些场景需要它参与计算,但是一般不修改。 |
fast_cli | 快速模式,默认False,不开启,netmiko内部提供一种优化性能的方式,设置为True后,在与设备交互过程中读取隧道中信息的频率会加快(全局延迟因子与单个方法中的延迟因子取较小值)。 |
推荐使用的场景
首先,我个人认为,在使用这种方式的自动化运维时,它就已经继承了人的不确定性,所以极力不推荐使用netmiko用在下发配置的场景上。
反而,使用netmiko批量获取信息,这个场景,我认为是netmiko最有用,也是对我们来说风险最低的使用方式。
写在最后
这篇文章主要就记录了最简单netmiko demo,以及netmiko一些简介。
主要是怕自己学了就忘了,所以还是根据自己想到哪写到哪的思路记下了这篇内容。
对于netmiko,实际上如上就是最常用的操作。我个人认为,对于在收集信息
场景中,继续使用python对信息进行处理
这个操作才是网路自动化真正的难点。
同样的,由于网络自动化这个场景过于小众,初级网络工程师觉得没必要,开发人员又觉得代码通用性较低,基本都是根据需求进行简单的脚本开发。只有设备量级达到一个程度,网络自动化才真实有效。
目前也只是我刚出学最浅显的理解,如有未来的改变或大家的争论,本人都非常欢迎。