当前位置: 首页 > news >正文

告别手动show run!用Python+Netmiko批量备份Cisco设备配置(附完整脚本)

用Python+Netmiko实现Cisco设备配置的智能备份与管理

网络工程师每天都要面对数十台甚至上百台网络设备的配置管理工作,传统的手工登录每台设备执行show run并保存配置的方式不仅效率低下,而且容易出错。我曾经管理过一个拥有200多台Cisco设备的网络环境,每周手动备份配置就要花费大半天时间,直到发现了Python+Netmiko这个黄金组合。

1. 为什么需要自动化配置备份

网络设备的配置备份是运维工作的基础,但传统方式存在诸多痛点:

  • 时间成本高:每台设备手动登录需要3-5分钟,100台设备就需要5-8小时
  • 人为错误风险:容易输错命令、漏掉设备或保存到错误位置
  • 版本管理混乱:手工备份难以建立规范的版本控制系统
  • 应急恢复慢:故障时难以快速找到正确的配置版本

真实案例:去年我们遇到一次核心交换机故障,由于手工备份不及时,最后只能基于3天前的配置进行恢复,导致部分新业务规则丢失,花了整整两天时间才完全修复。

2. Netmiko环境准备与基础配置

2.1 安装Netmiko库

Netmiko是基于Paramiko开发的网络设备连接库,支持SSH和Telnet协议。安装非常简单:

pip install netmiko

注意:建议使用Python 3.6+版本,避免兼容性问题

2.2 基础连接测试

先创建一个简单的测试脚本,验证与设备的连接:

from netmiko import ConnectHandler device = { "device_type": "cisco_ios", "ip": "192.168.1.1", # 替换为你的设备IP "username": "admin", "password": "admin123", "secret": "enablepass" # enable密码 } try: with ConnectHandler(**device) as conn: print(f"成功连接到 {device['ip']}") output = conn.send_command("show version") print(output[:200]) # 只打印前200字符 except Exception as e: print(f"连接失败: {str(e)}")

常见连接问题排查:

问题现象可能原因解决方案
连接超时网络不通/设备未开启SSH检查网络连通性,确认SSH服务已启用
认证失败用户名/密码错误确认凭据正确,检查大小写
提示符不匹配device_type设置错误确认设备型号选择正确

3. 实现智能配置备份系统

3.1 单设备配置备份

基础版的配置备份脚本:

from netmiko import ConnectHandler from datetime import datetime def backup_single_device(device_params): try: with ConnectHandler(**device_params) as conn: conn.enable() # 进入特权模式 # 取消分页显示 conn.send_command("terminal length 0") # 获取运行配置 running_config = conn.send_command("show running-config") # 生成带时间戳的文件名 timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") filename = f"{device_params['ip']}_config_{timestamp}.txt" # 写入文件 with open(filename, "w") as f: f.write(running_config) print(f"{device_params['ip']} 配置备份成功,保存为 {filename}") return True except Exception as e: print(f"{device_params['ip']} 备份失败: {str(e)}") return False

3.2 多设备批量备份

实际工作中,我们需要处理的是设备列表。创建一个CSV文件devices.csv

ip,username,password,enable_secret,device_type 192.168.1.1,admin,admin123,enablepass,cisco_ios 192.168.1.2,admin,admin123,enablepass,cisco_ios 192.168.1.3,admin,admin123,enablepass,cisco_ios

批量备份脚本:

import csv from concurrent.futures import ThreadPoolExecutor def backup_all_devices(csv_file, max_workers=5): success = 0 failure = 0 with open(csv_file) as f: devices = list(csv.DictReader(f)) # 使用线程池并行执行 with ThreadPoolExecutor(max_workers=max_workers) as executor: results = executor.map(lambda d: backup_single_device(d), devices) for result in results: if result: success += 1 else: failure += 1 print(f"备份完成: 成功 {success} 台, 失败 {failure} 台")

提示:线程数(max_workers)不宜设置过高,一般5-10为宜,避免对设备造成过大负载

4. 高级功能与最佳实践

4.1 配置差异比较

备份后,我们经常需要比较不同版本的配置变化。使用Python的difflib库可以实现:

import difflib def compare_configs(old_file, new_file): with open(old_file) as f1, open(new_file) as f2: old_lines = f1.readlines() new_lines = f2.readlines() differ = difflib.HtmlDiff() html_diff = differ.make_file(old_lines, new_lines, fromdesc=old_file, todesc=new_file) diff_file = f"diff_{old_file}_{new_file}.html" with open(diff_file, "w") as f: f.write(html_diff) print(f"差异报告已生成: {diff_file}")

4.2 自动备份调度

结合操作系统的定时任务功能,可以实现全自动备份:

  • Windows:使用任务计划程序
  • Linux/macOS:使用crontab

示例crontab配置(每天凌晨2点执行备份):

0 2 * * * /usr/bin/python3 /path/to/backup_script.py

4.3 备份文件管理策略

合理的备份管理应包括:

  1. 命名规范设备IP_日期_时间.txt,如192.168.1.1_20230815_143022.txt
  2. 目录结构
    /backups ├── /daily # 每日备份 ├── /weekly # 每周完整备份 └── /monthly # 每月归档
  3. 保留策略
    • 每日备份保留7天
    • 每周备份保留4周
    • 每月备份保留12个月

4.4 异常处理与日志记录

健壮的备份系统需要完善的错误处理和日志记录:

import logging from netmiko.ssh_exception import NetmikoTimeoutException, NetmikoAuthenticationException logging.basicConfig( filename='backup.log', level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s' ) def backup_with_logging(device): try: # ...备份逻辑... logging.info(f"{device['ip']} 备份成功") except NetmikoTimeoutException: logging.error(f"{device['ip']} 连接超时") except NetmikoAuthenticationException: logging.error(f"{device['ip']} 认证失败") except Exception as e: logging.error(f"{device['ip']} 未知错误: {str(e)}")

5. 安全增强方案

5.1 凭据安全管理

不要在脚本中硬编码密码,推荐使用以下方法:

  • 环境变量

    import os username = os.getenv('NET_USERNAME') password = os.getenv('NET_PASSWORD')
  • 加密配置文件:使用python-keyring等库

5.2 备份文件加密

敏感配置应该加密存储:

from cryptography.fernet import Fernet # 生成密钥(只需一次) key = Fernet.generate_key() cipher_suite = Fernet(key) # 加密配置 encrypted_config = cipher_suite.encrypt(running_config.encode()) # 解密配置 decrypted_config = cipher_suite.decrypt(encrypted_config).decode()

5.3 备份完整性验证

添加校验和确保备份文件未被篡改:

import hashlib def calculate_checksum(config): return hashlib.sha256(config.encode()).hexdigest() # 保存校验和 checksum = calculate_checksum(running_config) with open(f"{filename}.sha256", "w") as f: f.write(checksum)

6. 扩展应用场景

6.1 配置变更自动化

除了备份,Netmiko还可以用于批量配置变更:

def update_ntp_servers(device, servers): commands = [ "configure terminal", "no ntp server", # 移除现有NTP配置 *[f"ntp server {server}" for server in servers], "end", "write memory" ] with ConnectHandler(**device) as conn: conn.enable() output = conn.send_config_set(commands) print(f"{device['ip']} NTP配置更新完成")

6.2 设备健康检查自动化

定期收集设备状态信息:

def health_check(device): commands = { "cpu": "show processes cpu", "memory": "show processes memory", "interfaces": "show interfaces summary" } results = {} with ConnectHandler(**device) as conn: conn.enable() for name, cmd in commands.items(): results[name] = conn.send_command(cmd) return results

6.3 与CMDB系统集成

将备份的配置信息存入CMDB:

import requests def upload_to_cmdb(device_ip, config): cmdb_url = "https://cmdb.example.com/api/devices" payload = { "ip": device_ip, "config": config, "backup_time": datetime.now().isoformat() } response = requests.post(cmdb_url, json=payload, auth=("api_user", "api_pass")) if response.status_code == 201: print(f"{device_ip} 配置已上传至CMDB") else: print(f"{device_ip} 上传失败: {response.text}")

7. 性能优化技巧

7.1 连接池管理

频繁建立SSH连接开销很大,可以使用连接池优化:

from netmiko import ConnectHandler from functools import lru_cache @lru_cache(maxsize=10) def get_connection(device_ip): device = { "device_type": "cisco_ios", "ip": device_ip, "username": "admin", "password": "admin123" } return ConnectHandler(**device) def backup_with_pool(device_ip): conn = get_connection(device_ip) config = conn.send_command("show running-config") # ...保存配置...

7.2 异步IO实现

使用asyncio提高并发性能:

import asyncio from scrapli.driver.core import AsyncIOSXEDriver async def async_backup(device): try: async with AsyncIOSXEDriver( host=device["ip"], auth_username=device["username"], auth_password=device["password"], auth_strict_key=False, ) as conn: await conn.send_command("terminal length 0") config = await conn.send_command("show running-config") with open(f"{device['ip']}_config.txt", "w") as f: f.write(config.result) print(f"{device['ip']} 备份成功") except Exception as e: print(f"{device['ip']} 备份失败: {str(e)}") async def main(devices): await asyncio.gather(*[async_backup(d) for d in devices]) # 使用示例 devices = [...] # 设备列表 asyncio.run(main(devices))

7.3 内存优化

处理大型配置时优化内存使用:

def backup_large_config(device): with ConnectHandler(**device) as conn: conn.enable() conn.send_command("terminal length 0") # 流式处理,避免大内存占用 with open(f"{device['ip']}_config.txt", "w") as f: # 分块读取 output_gen = conn.send_command("show running-config", read_timeout=30, delay_factor=2) for chunk in output_gen: f.write(chunk)

8. 企业级部署建议

8.1 架构设计

对于大型网络环境,建议采用分布式架构:

[调度服务器] → [工作队列] → [多个备份工作节点] → [集中式存储]

关键组件:

  • 消息队列:RabbitMQ或Redis
  • 分布式任务:Celery或Dask
  • 集中存储:S3/MinIO或NAS

8.2 监控与告警

实现备份系统的自我监控:

def monitor_backup_system(): # 检查最近备份时间 last_backup = get_last_backup_time() if (datetime.now() - last_backup) > timedelta(hours=24): send_alert("备份系统异常: 超过24小时未备份") # 检查存储空间 if get_disk_usage() > 90: send_alert("备份存储空间不足")

8.3 灾备方案

确保备份系统自身的高可用:

  1. 多地备份:在不同物理位置保存备份副本
  2. 定期恢复测试:每季度抽样恢复验证
  3. 系统冗余:备份服务器集群化部署

9. 常见问题解决方案

9.1 设备兼容性问题

不同厂商、型号的设备可能需要特殊处理:

DEVICE_PROFILES = { "cisco_ios": { "cmd": "show running-config", "pre_cmds": ["terminal length 0"] }, "huawei": { "cmd": "display current-configuration", "pre_cmds": ["screen-length 0 temporary"] }, "juniper": { "cmd": "show configuration | display set", "pre_cmds": ["set cli screen-length 0"] } } def get_config(device): profile = DEVICE_PROFILES.get(device["device_type"]) if not profile: raise ValueError(f"不支持的设备类型: {device['device_type']}") with ConnectHandler(**device) as conn: for cmd in profile["pre_cmds"]: conn.send_command(cmd) return conn.send_command(profile["cmd"])

9.2 网络延迟问题

针对高延迟链路优化参数:

device = { # ...其他参数... "timeout": 60, # 连接超时(秒) "session_timeout": 120, # 会话超时 "delay_factor": 2, # 命令间隔延迟因子 "global_delay_factor": 2 # 全局延迟因子 }

9.3 大规模部署优化

当设备数量超过500台时:

  1. 分区域部署:按地理位置部署多个备份节点
  2. 分级备份:核心设备每日备份,接入设备每周备份
  3. 增量备份:只备份变更的配置部分

10. 从备份到配置管理

成熟的配置管理应该包括:

  1. 版本控制:使用Git管理配置变更历史
  2. 合规检查:自动检查配置是否符合安全规范
  3. 变更管理:任何变更都应有工单和审批记录
  4. 文档生成:自动生成网络拓扑和配置文档
def git_commit_config(device_ip, config): repo_path = f"/backups/repo/{device_ip}" if not os.path.exists(repo_path): os.makedirs(repo_path) subprocess.run(["git", "init"], cwd=repo_path) config_file = os.path.join(repo_path, "running-config.txt") with open(config_file, "w") as f: f.write(config) subprocess.run(["git", "add", "."], cwd=repo_path) subprocess.run(["git", "commit", "-m", f"Backup {datetime.now()}"], cwd=repo_path)
http://www.cnnetsun.cn/news/2083190.html

相关文章:

  • Qwen3-0.6B效果展示:看小模型如何完成复杂问答任务
  • 深度解析:Realtek USB网卡驱动在Synology NAS上的企业级部署与性能优化
  • QQ音乐解析终极指南:2025年免费高效音乐资源解决方案
  • 放弃内卷运维,转行网安一年,我终于读懂了赛道选择的底层逻辑
  • 为什么传统远程方案效率低下?如何构建新一代跨平台远程桌面系统
  • S32K3开发实战:手把手教你用SIUL2配置GPIO和外部中断(附完整代码)
  • CUDA 13与Hopper架构协同优化全路径,手撕GEMM、Softmax、LayerNorm三大高频算子,含Nsight Compute热力图诊断模板
  • 终极指南:如何用APK安装器在Windows电脑上直接运行安卓应用
  • 从零开始:用蜂鸟E203 SoC和芯来科技视频课,手把手带你入门RISC-V处理器设计
  • 2026 SMT智能工厂数字孪生平台对比选型
  • HarmonyOS 启动模式实战:singleton、multiton 与 specified 怎么选?
  • LFM2.5-1.2B-Instruct效果展示:system/user/assistant三段式结构稳定性
  • IgH EtherCAT 从入门到精通:第 20 章 数据报文与通信机制
  • 用Vue 2.7 + SpringBoot 3.1 + MySQL 8 从零搭建一个超市商品管理系统(附完整源码和数据库脚本)
  • GitHub Copilot SDK实战:从API调用到智能代码审查助手开发
  • GitHub 一夜爆火!这个项目解决了 AI 编程最大的坑:没有记忆
  • 抖音下载神器:如何一键批量保存无水印视频和直播回放?
  • Vivado 2023.2版本实战:从“Labtools 27-3303”到“Place 30-602”,一次解决时钟与烧录难题
  • Redis怎样利用Lua脚本批量抓取多类型数据
  • copyKAT实战:从单细胞转录组数据自动识别肿瘤细胞CNV与亚克隆结构
  • 告别AC5!在Keil MDK AC6环境下为STM32配置串口打印(Retarget详解)
  • 别再踩坑了!Docker容器里用systemctl报错Failed to get D-Bus connection的完整解决手册
  • League Akari终极指南:英雄联盟本地自动化工具完整使用教程
  • 别再只盯着USB和HDMI了!聊聊LVDS这个‘老将’为什么在工业屏和医疗设备里依然能打
  • 3个魔法步骤:让Windows 11完美运行20年前的经典游戏
  • 从零开始:如何快速掌握Switch大气层系统1.7.1完整安装指南
  • 基于scikit-learn的轻量级手语识别系统实践
  • 如何在Windows 11上完美运行DirectX 1-7经典游戏:DDrawCompat终极兼容方案
  • Zotero PDF Translate:你的学术翻译助手到底有多强大?
  • 给Linux小白的模块管理指南:从插U盘到装显卡驱动,都离不开modprobe