郭小岗 徐益强
1.江苏天创科技有限公司 江苏 南京 210018
2.江苏省生态环境监控中心 江苏 南京 210036
随着信息化的不断发展,政府和企事业单位的内部办公和对外业务受理已基本实现了计算机应用系统化。随之而来的系统数量增加、应用规模扩大的需求,需要由服务器、存储、网络设备和安全设备等基础设置的不断扩容来提供底层支撑,同时网络环境也变得更为复杂,运维工作量不断增加。此时,传统的运维方式已经无法满足日益增长的软硬件运维需求,并逐渐暴露出其弱点。传统运维主要靠人工方式完成,很难规避人为的误操作,无法确保运维的质量;另一方面,人工一对一“串行”的运维方式,运维效率得不到提升。随着运维事务的增加,“事必躬亲”的传统运维模式下,总体运维效率已很难满足当下的计算机应用规模,只有通过计算机应用技术,对应用系统进行计算机化的运维,才能提高运维效率、提升运维质量。而选用Python作为运维的语言工具,绝非偶然。在很多操作系统中,Python是标准的系统组件,大多数Linux发行版都预装集成了Python,可以在终端下直接运行。同时,Python丰富的类库很好地满足了网络运维以及操作系统运维必要的功能需求,运维复杂度也较选用shell、perl、ruby等语言来的简单易用。
Python是一种跨平台的计算机程序设计语言,是一个高层次的、结合了解释性、编译性、互动性和面向对象的脚本语言。最初被设计用于编写自动化脚本(shell),随着版本的不断更新和语言新功能的添加,越来越多被用于独立的、大型项目的开发。
如果把一次编程比作生产一辆汽车,对使用C语言而言,就好比要自主研发生产发动机、底盘、车身和电器设备,最后进行组装。而对于Python则是拿来主义,我们并不需要开发各类配件,可以直接使用第三方的“发动机”、“底盘”等类库即可,Python开发关心的是各类配件组装的逻辑效果,而不关心程序本身运行的速度。作为“胶水语言”,Python的强大来自全世界各行各业的开发者,他们把不同领域的对象进行类库化,把优点进行了整合。目前主要应用领域有web开发、网络爬虫、计算与数据分析、人工智能、自动化运维、云计算和网络编程等方面,截至当前,TIOBE编程社区Python稳居前三,排名如图1所示。
每一种语言的诞生,都有他适用的场景,Python因其丰富类库、较强的可移植性、易于维护的源代码和可嵌入等优点,实际生产中被各领域广泛的使用[1]。
图1 TIOBE Index for July 2020
在政府和企事业单位网络运维工作中,我们通常面向大量的网络交换机和路由器的运维,此类工作具有大量的重复性,采用传统的人工维护方式,会浪费大量的时间和人力成本。因此网络运维人员可以利用Python程序语言,编写维护脚本,代替人工对网络交换机和路由器的运行状态进行检测和维护。
本文以定期备份华为或华三网络交换机的配置为例,说明Python为运维工作带来的便捷可靠性,同时结合Python多线程并发技术,将该任务以一定的并发量分批执行,即便运维人员面对大量设备的配置备份需求时,该项运维工作依然保持高效可靠。
考虑到python2官方已停止维护,以下代码部分均基于python3编写。
本例主程序主要使用了paramiko模块和multiprocessing.pool模块分别实现自动ssh登录和多线程并发,通过模拟登录交换机运行display current-configuration命令获取到每台网络交换机设备的配置。接下来具体分析每个部分的实现代码。
2.2.1 datafile为数据部分,主要是登录交换机所必需的信息,数据格式为字典。示例如下:
#!/usr/bin/python3
#coding:utf-8
dict1 = {}
dict1[“192.168.101.10”]= [22,“user”,“password”,“display cur”,“<NewF1-outside-1>”]
dict1[“192.168.101.11”] = [22,“user”,“password”,“display cur”,“<NewF2-outside-1>”]
2.2.2 导入各类所需的模块。
#!/usr/bin/python3
#coding:utf-8
import paramiko
import os, sys importtime,datetime
from datafile import *
frommultiprocessing.pool import ThreadPool
2.2.3 定义ssh登录函数,获取交换机登录欢迎信息,发送交互命令,返回交互结果。
defsshconfig(ip, port, username, password, cmd, PS1):
# 实例化SSHClient
client = paramiko.SSHClient()
# 自动添加策略,保存服务器的主机名和密钥信息
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接SSH服务端,以用户名和密码进行认证
client.connect(hostname=ip, username=username,password=password, look_for_keys=False)
#获取登陆shell,并设置超时时间
getshell =client.invoke_shell()
getshell.settimeout(9000)
# 获取登录后的消息
welcomeinfo = ‘’
while True:
line = str(getshell.recv(4096),encoding=”utf-8”)
welcomeinfo += line
if (PS1 is not None) & (len(PS1) > 0):
isFindPS1 = False;
fori in range(len(PS1)):
if PS1[i] in line:
isFindPS1 = True
if isFindPS1 == True:
break;
getshell.send(cmd + ‘ ’)
result = ‘’
# more交互处理
more1 = ‘More’
more2 = ‘--More--’
more3 = ‘<--- More --->’
more4 = ‘---- More ----’
# 循环获取数据
time.sleep(1)
while True:
line2 = str(getshell.recv(65535),encoding=”utf-8”)
result += line2
if (more1 in line2) | (more2 in line2) | (more3 in line2) | (more4 in line2):
getshell.send(“ “)
time.sleep(1)
continue
if (PS1 is not None) & (len(PS1) > 0):
isFindPS1 = False;
fori in range(len(PS1)):
if PS1[i] in line2:
isFindPS1 = True
if isFindPS1 == True:
break
return result
2.2.4 定义获取交换机配置函数,以时间、key和.config结合作为文件名保存配置文件[2]。
defgetconfig(key,port,user,passwd,command,ps):
k = sshconfig(key,port,user,passwd,command,ps)
tm = datetime.datetime.now()
recordtime = tm.strftime(“%Y-%m-%d”)
filename = recordtime + “_” + key + “.config”
file = open(filename,’w’)
file.write(k)
file.close()
file = open(filename,’r’)
f = file.read()
file.close()
if “vty” in f:
return key
else:
key1 = ‘!’ + key
return key1
2.2.5 以多线程执行交换机配置备份,线程池并发数为5。
result1 = []
if __name__ == “__main__”:
# 多线程部分定义线程池,即以5线程同时获取5台交换机设备的配置。
begin = datetime.datetime.now()
pool = ThreadPool(5)
for key, value in dict1.items():
result = pool.apply_async(getconfig,args=(key,value[0],va lue[1],value[2],value[3],value[4]))
result1.append(result)
pool.close()
pool.join()
for i in result1:
ifi.get().startswith(‘!’):
print(“fail to save %s configuration!” % i.get().strip(‘!’))
else:
print(“success to save %s configuration!” % i.get())
end=datetime.datetime.now()
print(end-begin)
2.2.6 备份结果和备份文件部分内容。
图2 备份结果
图3 备份文件内容节选
比较单任务和多任务执行的结果,虽然多任务执行备份的任务量增加了,但执行时间上来说,跟单任务执行的时间上是相当的(约44s左右),两次配置文件备份的大小也一样,说明是完整的[3]。
本次多线程并发执行是成功的。
2.3.1 单任务时,耗时44.429942秒,如下图。
2.3.2 5任务并发时,耗时44.22秒。
python自动化运维可以在提高运维效率的同时,降低运维成本和运维工作的出错率,再结合多线程技术的应用,可以使具体工作任务完成得更为高效,从而大大地提高运维交付的速度。本文是python在网络运维工作中的一个应用案例,旨在说明多线程技术为网络运维工作带来的高效性,同时python在诸如系统运维等工作中也有着广阔的应用前景,有待我们深入的学习和研究。