
1. 项目概述1.1 核心需求解析做网络运维的朋友应该都遇到过这种情况设备台账里躺着几十上百台华为交换机领导要求每周出一份巡检报告还要把所有设备的配置备份到本地。手动登录每台设备敲几条命令看状态再一条条复制配置内容……运气好两个小时搞定一台核心设备运气不好赶上设备性能波动命令回显半天不出来整个人坐在机房或者工位上心里全是什么时候能干完。这个项目的核心就是解决这个痛点用 Python 写一套脚本自动登录华为交换机批量执行巡检命令收集设备状态再把每台设备的配置文件和关键运行状态自动备份到本地。我最初的目标很简单每天早上到工位双击一下脚本喝杯水回来巡检报告和备份文件都已经躺在文件夹里了。适合谁来参考第一类是像我一样负责中小规模网络、手里管着几十台设备的运维工程师第二类是刚入行、想用 Python 提升网工效率的朋友第三类是要做自动化运维转型、想了解网络设备南向接口怎么玩的同学。项目本身不难但把登录、执行、解析、备份这一套流程跑通你能省下的时间非常可观。1.2 项目最终效果脚本跑完以后你会在本地目录里看到类似这样的结构backup/ ├── config_20250115/ │ ├── S5700-01_config.txt │ ├── S5700-02_config.txt │ └── ... └── report_20250115/ ├── S5700-01_report.txt └── ...每台设备一个配置文件、一份巡检报告。配置文件里是设备的完整 running-config 和 startup-config巡检报告里记录了设备名、型号、系统运行时间、CPU 内存利用率、接口状态、告警日志里的关键异常、VRRP 状态、DHCP 地址池状态这些核心信息。整个流程跑下来平均每台设备耗时在 30 秒到 1 分钟之间和手动登录操作一比效率提升非常明显。2. 整体方案设计与技术选型2.1 为什么选 Python 而不是现成的网管软件有人可能会问华为有 eSight第三方有 SolarWinds、Zabbix为什么还要自己写脚本说实话正经大厂部署一套完整网管平台效果确实比脚本强但问题是很多中小企业只有两三台核心交换机为一个几百台设备的网管平台花几万块买授权、搞服务器完全不现实。而且商业网管软件在做配置备份这件事上往往做得比较重——要装 Agent、要配 SNMP 告警、要维护 CMDB都是系统工程。Python 的好处恰恰是轻量。我只需要一台能联网的电脑装个 Python 3 环境加两个第三方库写一套逻辑简洁的脚本就能把巡检和备份这两件高频重复的日常任务自动掉。对运维来说日常工作中最贵的是时间用最小成本解决最痛的问题这才是关键。2.2 技术栈拆解项目里我用到了这几样东西Python 3.8当前主流版本对第三方库的支持最稳。Netmiko这是一个基于 Paramiko 的库专门用来做网络设备的 SSH 连接和命令交互。它最大的价值在于把登录设备、进入 enable 模式、关闭分页、执行命令、读取输出这些重复劳动封装成了简单的 API。ParamikoNetmiko 底层依赖的 SSH 协议实现库负责真正建立加密连接。textfsm / re处理命令回显文本时用来做正则表达式匹配和模板解析。pandas / openpyxl把解析出来的结构化信息写入 Excel 格式的巡检报告。这里我特别说一下为什么选 Netmiko。直接用 Paramiko 我也试过确实能做但需要手工处理很多细节比如命令回显的读取时机、设备的分页提示符---- More ----要怎么翻页、enable 模式的切换。Netmiko 把这些都封装掉了你只需要告诉它设备的 IP、用户名、密码、设备类型它就能自动完成交互过程。不过要注意Netmiko 本质上只是给 Paramiko 包了一层友好的接口你在深入调试时还是能遇到 SSH 层面的问题后面我会在常见问题里详细展开。2.3 设备访问方式的选择华为交换机支持的远程管理方式有 SSH、Telnet、SNMP 和通过网络管理接口的 Web 页面。我的选择是 SSH理由很简单Telnet 是明文传输密码在网络里裸奔这在生产环境里要尽量避免。SNMP 适合读取状态信息但配置备份和完整巡检命令的执行能力很弱。Web 页面交互复杂无法脚本化。SSH 是网络设备自动化的标准通道安全性好、交互可控性高Netmiko 对华为设备的 SSH 支持也很成熟。如果你的网络环境里面有些老旧设备只支持 Telnet我也会给一个备选方案但建议优先级不要放在 SSH 前面。2.4 整体流程规划整个项目的执行流程分为四步设备清单维护用一个 Excel 或 yaml 文件记录所有待巡检设备的 IP、名称、登录账号密码、设备类型。连接与命令执行脚本读取清单后逐台通过 SSH 连接设备依次执行巡检命令。配置备份抓取 display current-configuration 的输出写入以设备名和日期命名的文本文件。报告生成把巡检命令的输出做关键字分析和状态提取生成一份可读的巡检报告。这个流程写起来并不复杂但实际执行时有很多坑。比如华为设备的display current-configuration输出非常长默认会分页如果没关掉分页脚本会卡死在---- More ----提示符上。又比如不同型号的华为交换机命令回显的格式存在细微差异做文本解析时不能把正则写死。3. 环境准备与依赖安装3.1 安装 Python 环境我默认你的电脑是 WindowsLinux 和 macOS 的操作逻辑类似只是安装包下载方式不同。去 Python 官网下载对应你操作系统的安装包版本选 3.8 或更高就行注意安装时勾选Add Python to PATH这个选项。如果不勾选后续在命令行里输入python会提示找不到命令这个坑很常见。安装完成后在命令行输入python --version能正常输出版本号就说明装好了。我当前用的版本是 3.10跑这个项目没有任何问题。如果提示python不是内部或外部命令去 Windows 的设置 - 系统 - 关于 - 高级系统设置 - 环境变量把 Python 的安装目录和Scripts子目录加到Path变量里保存后重新打开命令行。3.2 安装第三方依赖库在命令行依次执行下面两条命令pip install netmiko pip install pandas openpyxl如果你在公司内网环境可能没有外网权限pip 会一直卡在连接超时。这种情况建议用公司内部搭建的 PyPI 镜像源或者临时用国内镜像源。命令可以这样写pip install netmiko -i https://pypi.tuna.tsinghua.edu.cn/simple安装完以后可以用pip show netmiko确认版本。我这里用的 Netmiko 版本是 4.x如果你用的是老版本比如 3.x部分 API 的返回结构会有细微差异遇到问题先升级库再说。3.3 设备侧的准备工作华为交换机默认可能只开放了 Telnet 或 Console 管理口要支持 SSH 远程登录需要在设备上手动开启 SSH 服务。这是个常见的前置条件很多人在跑脚本时发现连不上最后排查半天发现是设备 SSH 功能压根没开。设备上的配置大概如下system-view stelnet server enable ssh user admin authentication-type password ssh user admin service-type stelnet local-user admin password irreversible-cipher yourpassword local-user admin service-type ssh配置完成后用任意 SSH 客户端比如 PuTTY先手动连一次确认能正常登录。这一步很关键如果 PuTTY 都连不进去脚本更不可能连上。4. 核心脚本实现4.1 设备清单文件设计我建议用 Excel 文件来维护设备清单运维同事看起来直观修改也方便。表格结构长这样设备名管理IP用户名密码端口设备类型S5700-01192.168.1.10adminpassword12322huaweiS5710-02192.168.1.11adminpassword12322huawei设备类型这里写huaweiNetmiko 会识别并选择对应的交互逻辑。如果你的环境里混入了思科设备把设备类型换成cisco_ios就行但命令集 middleware 得调整后面会讲到。4.2 核心登录与命令执行模块先写一个最基础的版本验证网络连通性和登录逻辑。下面是核心代码from netmiko import ConnectHandler import time device { device_type: huawei, ip: 192.168.1.10, username: admin, password: password123, port: 22, timeout: 30, } connection ConnectHandler(**device) output connection.send_command(display version) print(output) connection.disconnect()send_command是同步阻塞的命令执行完、回显读取完毕才返回。这里你可能会遇到两个小问题如果设备上开启了交互式确认比如display current-configuration在某些设备上会询问是否需要分页Netmiko 的默认逻辑可能处理不了需要你在设备侧关闭相应交互。如果命令执行时间特别长超过了 Netmiko 的默认超时时间会抛出超时异常。我建议在设备连接参数里显式设置timeout和session_timeout两边都拉长一点。下面是带超时配置的优化版本from netmiko import ConnectHandler device { device_type: huawei, ip: 192.168.1.10, username: admin, password: password123, port: 22, timeout: 60, session_timeout: 60, } connection ConnectHandler(**device) connection.enable()这里有个细节华为设备的enable模式和思科的密码机制不同。华为默认没有单独的 enable 密码如果你在设备上设置了super密码需要给ConnectHandler传递secret参数然后enable()才会切换成功。如果你不确定设备有没有配置 super 密码先手动登录敲一下system-view看能不能进。4.3 巡检命令清单巡检的核心是收集哪些信息我把日常运维中必须关注的点整理成了下面的命令清单命令巡检目标display version设备型号、软件版本、运行时间display device硬件状态查看是否有异常部件display cpu-usageCPU 利用率display memory-usage内存利用率display temperature设备温度display interface brief接口状态概览是否有 Down 口display current-configuration设备当前配置display logbuffer系统日志缓冲区中的告警和错误信息display vrrp brief如果跑 VRRP确认主备状态display dhcp server ip-pool如果开了 DHCP 服务确认地址池状态执行这些命令时合理的顺序很重要。状态类命令version、device、cpu、memory、temperature应该优先执行因为它们执行快、能快速判断设备是否健康配置类命令display current-configuration放在最后执行因为它输出量大、耗时长。万一中途脚本断掉你已经拿到了最关键的状态信息。4.4 完整巡检与备份脚本下面是一个完整的单设备巡检与备份脚本我尽量把注释写清楚from netmiko import ConnectHandler from datetime import datetime import os import re # 设备连接参数 device { device_type: huawei, ip: 192.168.1.10, username: admin, password: password123, port: 22, timeout: 60, session_timeout: 60, } def save_to_file(directory, filename, content): 将内容写入文件自动带时间戳 if not os.path.exists(directory): os.makedirs(directory) filepath os.path.join(directory, filename) with open(filepath, w, encodingutf-8) as f: f.write(content) return filepath def collect_device_info(connection): 收集设备状态信息 info {} commands { 设备信息: display version, CPU使用率: display cpu-usage, 内存使用率: display memory-usage, 设备温度: display temperature, 接口状态: display interface brief, VRRP状态: display vrrp brief, DHCP地址池: display dhcp server ip-pool, } for description, command in commands.items(): try: output connection.send_command(command) info[description] output except Exception as e: info[description] f[错误] {str(e)} return info def backup_config(connection): 备份设备配置 output connection.send_command(display current-configuration) return output def parse_cpu_usage(text): 解析CPU利用率 match re.search(rCPU Usage\s*:\s*(\d)%, text) if match: return match.group(1) return N/A def parse_memory_usage(text): 解析内存利用率 match re.search(rMemory Usage\s*:\s*(\d)%, text) if match: return match.group(1) return N/A def generate_report(device_name, info, config_content): 生成巡检报告 now datetime.now().strftime(%Y-%m-%d %H:%M:%S) report_path save_to_file( reports, f{device_name}_report_{now.split( )[0]}.txt, f设备巡检报告 - {date.today()}\n设备名称: {device_name}\n巡检时间: {now}\n\n ) # 解析关键状态 cpu parse_cpu_usage(info.get(CPU使用率, )) mem parse_memory_usage(info.get(内存使用率, )) # 写入报告内容 with open(report_path, a, encodingutf-8) as f: f.write(fCPU利用率: {cpu}%\n内存利用率: {mem}%\n\n) f.write( 详细状态信息 \n) for desc, output in info.items(): f.write(f\n--- {desc} ---\n{output}\n) return report_path def main(): now datetime.now() date_str now.strftime(%Y%m%d) try: connection ConnectHandler(**device) device_name connection.send_command(display current-configuration | include sysname).split()[-1] # 备份配置 config backup_config(connection) config_path save_to_file( backups, f{device_name}_config_{date_str}.txt, f# 备份时间: {now.strftime(%Y-%m-%d %H:%M:%S)}\n{config} ) print(f[成功] 配置已备份到 {config_path}) # 巡检 info collect_device_info(connection) report_path generate_report(device_name, info, config) print(f[成功] 巡检报告已生成: {report_path}) except Exception as e: print(f[失败] {device[ip]} 连接或执行异常: {str(e)}) finally: try: connection.disconnect() except: pass if __name__ __main__: main()这个脚本能跑通基本流程但还有一些细节可以优化比如接口状态统计中 Down 口的数量、日志告警的关键字提取。下面我专门讲这些细节。5. 关键细节增强5.1 接口状态分析与 Down 口告警display interface brief的输出里接口状态分up和down两种。日常巡检最烦的就是某个接口悄悄 down 了可能是对端设备关机、光模块故障也可能是人为误操作。脚本里可以加一段统计逻辑def analyze_interfaces(output): down_interfaces [] for line in output.splitlines(): parts line.split() if len(parts) 4 and parts[0].startswith(GE) or parts[0].startswith(XGE): if parts[2] down or parts[3] down: down_interfaces.append(parts[0]) return down_interfaces拿到 down 口列表后报告的开头就直接列出这样打开报告第一眼就知道有没有异常。如果不想看一堆正常接口可以只把 down 口写进报告正常接口的统计数字写在旁边就行。5.2 日志告警关键字提取display logbuffer的输出非常长动不动几万行。全部写进报告没意义反而是关键告警容易淹没在里面。我一般在收集日志后用正则筛选级别为ERROR、WARNING、ALERT的记录再把匹配到的行写进报告的告警摘要部分。def filter_alarm_logs(log_text): lines log_text.splitlines() alarm_lines [] for line in lines: # 华为日志常见级别关键词 if re.search(r\b(ERROR|WARNING|ALERT)\b, line, re.IGNORECASE): alarm_lines.append(line) return alarm_lines然后报告里给出一个计数和最近 20 条告警内容足够快速判断设备是否存在潜在风险。5.3 CPU 使用率的历史比对单次 CPU 使用率只能反映当前时刻的状态如果设备在高峰期 CPU 跑到 90%可能只是瞬时抖动过一会儿就恢复了。为了更准确地判断可以额外执行display cpu-usage history把设备历史上的 CPU 使用率曲线数据抓下来。虽然这个主要是用来看趋势的但只要能拿到峰值和当前值就可以大致判断设备负载是突发型还是持续型。脚本里可以做个简单判断cpu_value int(cpu_usage) if cpu_value 80: alert 警告: CPU使用率过高 elif cpu_value 60: alert 注意: CPU使用率偏高 else: alert 正常这种判断虽然简单但配合历史数据能发现很多早期隐患。6. 批量设备管理6.1 多设备循环处理单设备脚本只是第一步生产环境里你要管理的是几十台设备。改进方式是把设备清单放到一个列表里遍历登录和执行。这里我直接把登录逻辑封装成一个类方便代码复用import pandas as pd from netmiko import ConnectHandler import time class HuaweiDeviceManager: def __init__(self, excel_path): self.df pd.read_excel(excel_path) self.results [] def process_all_devices(self): for index, row in self.df.iterrows(): device { device_type: huawei, ip: row[管理IP], username: row[用户名], password: row[密码], port: int(row[端口]) if 端口 in row else 22, timeout: 60, session_timeout: 60, } try: connection ConnectHandler(**device) # 收集信息和备份配置 # ... connection.disconnect() self.results.append({ 设备IP: row[管理IP], 设备名: row[设备名], 状态: 成功 }) except Exception as e: self.results.append({ 设备IP: row[管理IP], 设备名: row[设备名], 状态: f失败: {str(e)} })注意 Excel 文件里的密码是明文存储这个在个人脚本里可以接受但如果你的设备密码有强合规要求建议改为在程序运行时从环境变量或密码库读取。还有一个细节如果设备登录失败一次不要立即重试避免在有账户锁定策略的设备上把账号锁掉。6.2 串行与并行执行的选择批量执行有两种模式串行和并行。串行是一台接一台地处理逻辑简单不容易出错并行是同时开多个 SSH 连接处理速度快但对设备的性能和管理通道的压力有要求。我的建议是设备数量少于 30 台串行完全够用平均一台 30 秒30 台也就 15 分钟。如果你管的是上百台设备可以用concurrent.futures.ThreadPoolExecutor做并行线程数控制在 5 到 10别贪多。下面是并行执行的关键代码from concurrent.futures import ThreadPoolExecutor, as_completed def process_one(device_row): # 单台设备处理逻辑 pass with ThreadPoolExecutor(max_workers5) as executor: futures [executor.submit(process_one, row) for _, row in self.df.iterrows()] for future in as_completed(futures): result future.result() print(result)并行执行时需要注意华为设备默认只允许有限数量的并发 SSH 会话通常是 5 到 10 个如果你开太多线程后面的连接会被设备拒绝。所以线程数要根据设备能力来定保守一点就 5 个以内。6.3 失败重试机制设备偶尔会抽风SSH 握手超时、网络闪断、用户名密码输错这在批量巡检时几乎必然发生。脚本里最好加上重试逻辑import time def connect_with_retry(device, retries3, delay5): for attempt in range(retries): try: connection ConnectHandler(**device) return connection except Exception as e: if attempt retries - 1: print(f连接失败(第{attempt1}次){delay}秒后重试...) time.sleep(delay) else: raise e重试次数建议 2 到 3 次间隔时间 5 秒以上。太重试会把设备的管理会话数占满反而引发其他问题。7. 常见问题与排查技巧实录7.1 SSH 登录失败Authentication failed这个问题排在第一位遇到概率太高了。常见原因有三个账号密码错误明文核对一下注意 Excel 里可能有多余空格strip()一下再传入。设备上没开启 SSH 服务用 PuTTY 手动连一次如果能连但脚本连不上大概率是 Netmiko 的device_type参数不对。华为设备一般用huawei如果是新版本 VRP 平台可以试试huawei_vrpv8。密码里有特殊字符比如、#、$等在 Excel 或 yaml 里会被转义或者被 Python 字符串处理出问题。建议先打印出来核对。7.2 命令执行卡在 ---- More ----这是华为设备最常见的老坑。display current-configuration输出过长设备会自动分页显示---- More ----等待用户按键。如果不处理Netmiko 会一直等下去直到超时。解决办法是登录连接后先发送命令关闭分页。Netmiko 针对华为设备有自己的自动处理逻辑但也会遇到漏网之鱼稳妥的做法是手动发送关闭分页的命令connection.send_command(screen-length 0 temporary)这条命令只对当前登录会话生效不会修改设备永久配置非常安全。执行完以后后续所有命令的回显都不会分页。提示不同华为设备型号对screen-length 0 temporary的支持情况略有差异。S5700 系列基本没问题有些老款 S3700 上这条命令可能不存在需要用undo terminal monitor之类的命令辅助具体以设备提示为准。7.3 命令回显内容乱码部分华为设备 SSH 登录后的默认语言是中文或英文取决于系统配置。如果你的终端编码和设备的编码不一致输出到文件里会出现乱码。解决办法有两个方向在代码里用encodingutf-8写入文件同时保证设备的 SSH 会话编码是 UTF-8。如果设备侧不支持改编码可以在脚本开头统一把回显内容用errorsignore的参数写入至少能保证脚本不中断。另外注意华为的设备名如果包含中文字符生成文件名时要做清洗把非 ASCII 字符替换掉否则某些系统上创建文件会失败。7.4 Netmiko 超时设置不合理Netmiko 有两个超时维度timeout是全局阻塞超时session_timeout是会话级超时。默认值对小型设备够用但执行display memory-usage等命令时如果设备繁忙回显可能会超过默认的阻塞时间。我建议统一设置device { ... timeout: 60, session_timeout: 60, conn_timeout: 30, }conn_timeout只控制建立 TCP 连接阶段如果网络不通它会很快报错不用和timeout混在一起。7.5 备份文件内容不完整如果你发现备份出来的配置文件比设备上实际配置短多半是命令执行时机太早设备还没有把完整配置回显完。排查方法是手动执行一次display current-configuration看最后一行是否以return结尾。如果备份文件末尾缺少return说明回显被截断了可以在脚本中增加一个配置结束判断循环读取直到遇到return。或者把send_command换成send_command_timing手动控制读取节奏。后一种方式看似灵活实际容易踩坑因为需要自己判断每次读取的数据长度不稳定。我更推荐前一种做法——检查输出末尾的特征字符串。7.6 脚本在 Windows 计划任务里跑不起来Windows 计划任务执行 Python 脚本时经常会遇到路径不对或找不到 python的问题。解决办法是在计划任务里把起始于目录设为脚本所在目录并在命令里写全 Python 的绝对路径例如C:\Python310\python.exe C:\scripts\network_inspect.py另外如果脚本里有相对路径比如backups目录一定要用绝对路径因为计划任务启动时的工作目录不是你脚本所在的目录很容易出现目录不存在的问题。8. 自动化调度与报告格式优化8.1 配置 Linux Crontab 定时任务如果你的巡检机是 Linux 服务器比如一台内网跳板机可以用 crontab 实现每日自动巡检。# 每天早上 08:30 执行巡检 30 8 * * * cd /home/admin/network_inspect /usr/bin/python3 network_inspect.py /var/log/network_inspect.log 21注意使用 Python 的绝对路径避免 PATH 环境变量不同导致找不到 python。日志重定向一定要加这样有问题时能回溯。8.2 巡检报告转 Excel 格式很多人更喜欢 Excel 报告方便筛选、排序和做图表。pandas 可以轻松实现。下面是把多台设备的摘要信息汇总到一张表里的示例import pandas as pd summary_data [] for result in results: summary_data.append({ 设备IP: result[ip], 设备名: result[name], CPU利用率: result[cpu], 内存利用率: result[mem], Down口数量: result[down_count], 告警数量: result[alarm_count], 巡检状态: result[status], }) df pd.DataFrame(summary_data) df.to_excel(巡检报告_20250115.xlsx, indexFalse)这样每次巡检结束Excel 表格里就是每台设备的健康状态摘要领导要数据也能直接发过去。8.3 异常状态钉钉/邮件通知巡检完了没人看等于白巡检。建议加一个告警通知如果有设备 CPU 超过阈值、有 Down 口或者有 ERROR 级别日志就通过邮件或钉钉机器人推消息。邮件可以用 Python 内置的smtplib发送。钉钉机器人更简单用requests库往 webhook 地址 POST 一条 JSON 消息就行。我在实际使用中会同时开邮件和钉钉邮件留给领导查历史记录钉钉即时推给运维群有问题能第一时间发现。9. 安全性与权限管理9.1 账号权限最小化巡检脚本在设备上使用什么账号很重要。我建议创建一个专用的巡检账号权限只读不要直接给 admin 或超级管理员权限。在华为设备上创建一个只有查看权限的本地用户可以这样配置system-view local-user inspect password irreversible-cipher yourpassword local-user inspect service-type ssh local-user inspect privilege level 1privilege level 1 的账号能执行大部分display命令但不能修改配置。这样即使脚本或者账号泄露也不会被别人远程改了设备配置。要说缺点就是极少数 display 命令在 level 1 下会没有权限比如display diagnostic-information这种诊断命令可能被拒那种场景单独加白名单即可。9.2 密码存储方案脚本里明文存储密码虽然方便但确实存在安全隐患。如果你在公司内网环境、大家的信任边界明确可以接受但如果是共享的跳板机我建议把密码放到环境变量或独立配置文件中配置文件权限设成 600。读取环境变量的方式import os password os.getenv(SWITCH_PASS, )在你的 shell 环境里设置好SWITCH_PASS脚本运行时会自动读取。对我个人来说如果设备数量少、运维团队就我一个人直接用yaml文件存密码也够用但记得把那个文件加入.gitignore。9.3 敏感设备操作保护自动巡检脚本不涉及配置变更所以风险相对可控。但如果你想扩展成自动备份并上传配置、或者自动执行某些变更操作一定要加确认机制在执行变更命令前让脚本使用send_command而不是send_command_timing并且在代码里做二次确认防止误操作。10. 期望管理与后续扩展10.1 这个脚本能做什么、不能做什么不少朋友看我分享这类脚本第一反应就是能不能顺带做个配置下发我的回答是能但请慎重。巡检脚本的核心价值是收集和记录不是变更。配置变更涉及的风险远高于巡检写错一条命令可能导致整个业务中断。所以项目里我只做巡检和备份不做自动下发等你有足够信心再考虑把那部分能力加上。10.2 从脚本到平台当设备数量超过 100 台以后单纯的脚本模式管理起来会有些吃力。那时候可以考虑把脚本演进成一个轻量的内部工具加一个 Web 界面把设备清单改成数据库存储把巡检结果存成带索引的记录。但这个升级要一步步来不要一开始就想做一个大平台先把巡检脚本用熟、用好积累出稳定可靠的执行逻辑再谈上层。其实很多团队的自动化运维就是从这样一个几十行的小脚本起步的。10.3 聊聊替代方案除了 Python Netmiko还有几个现成的方案值得大家了解Ansible基于 Python 开发华为设备有对应的 collection用 playbook 写巡检和备份更规范但学习成本也更高。Nornir更适合做并行批量任务的 Python 框架。Paramiko 原生如果你不想引入 Netmiko直接基于 Paramiko 自己写灵活度和可控性最高但要自己处理很多交互细节。对我个人来说日常跑增量巡检和临时备份Netmiko 最顺手。Ansible 适合正式一点、需要版本化管理 playbook 的场景如果你已经在用 Ansible 管服务器顺手把网络设备也管起来是不错的选择。11. 踩坑心得与实战建议11.1 先小范围试点再全量推开第一次跑全量巡检前我强烈建议先选三台不同类型的设备做试点一台核心交换机、一台接入交换机、一台汇聚设备。把试点设备跑通、输出内容人工核一遍确认脚本的解析逻辑兼容后再扩展到全部设备。原因很简单各型号华为设备的命令回显格式存在差异你很难一次性把所有情况都覆盖到。11.2 保留历史版本形成对比备份配置这件事不要只存最新版本。我会在每次巡检备份后额外把上一次的配置做一个 diff把差异行输出到报告里。这样哪天设备配置被意外改动能快速定位到是哪台设备、哪一行变了。实现 diff 可以用 Linux 自带的diff命令或者 Python 里的difflib库。import difflib with open(config_old.txt, r) as f1, open(config_new.txt, r) as f2: old_lines f1.readlines() new_lines f2.readlines() diff difflib.unified_diff(old_lines, new_lines, lineterm, n0) for line in diff: print(line)实战中我发现配置 diff 的价值甚至比巡检本身还大。很多棘手的网络故障最后定位下来就是某台设备配置被谁改了一行有了 diff 历史这种问题就很好查了。11.3 定期验证备份文件的可恢复性备份文件躺在文件夹里不等于关键时刻能恢复。我一般每季度抽一台设备做一次恢复演练把备份里的配置恢复到设备上确认业务正常。这样做一方面验证了备份文件的完整性另一方面也验证了整个备份流程没有静默失败。如果哪次发现备份文件不完整多半是回显截断问题那就回到上面的第 7.5 节去排查。11.4 脚本的可维护性代码写清楚注释和模块化不只是给别人看的更是给三个月后的自己看的。我有一次临时急着改脚本跳过了封装函数全写在一个大 for 循环里结果一个月后自己都看晕了。后来老老实实把设备列表、连接、采集、解析、报告生成拆成不同模块维护成本直线下降。11.5 结合业务视角做巡检最后提醒一点巡检不只是看设备健康指标更要结合业务视角。比如某台交换机是专门承载办公网络的那在巡检报告里除了看 CPU、内存、接口状态最好还要关注网络是否出现过广播风暴、有没有 CPU 占用率突增的时段。你的巡检脚本是手段最终目的是让网络稳定运行、问题提前暴露。12. 写在项目之后整个项目跑下来我最深刻的体会是用 Python 做华为交换机的巡检和配置备份本质上就是用自动化替代手工重复劳动把运维人员从登录设备、敲命令、复制粘贴这种低价值工作里解放出来。脚本写起来不算复杂但一次投入、长期受益每天省下的半小时一小时累积下来是相当可观的时间成本。如果你也是运维或者网络管理人员我建议你先从一两条命令做起不要一上来就写一个完整的批量巡检系统。先把display version用脚本跑通再逐步加命令、加设备最后做成一个每天自动跑的完整流程。踩过的坑我都写在前面了希望你能绕开它们把你的第一套网络巡检自动化项目顺利落地。