郭小崗 徐益強(qiáng)
1.江蘇天創(chuàng)科技有限公司 江蘇 南京 210018
2.江蘇省生態(tài)環(huán)境監(jiān)控中心 江蘇 南京 210036
隨著信息化的不斷發(fā)展,政府和企事業(yè)單位的內(nèi)部辦公和對外業(yè)務(wù)受理已基本實(shí)現(xiàn)了計(jì)算機(jī)應(yīng)用系統(tǒng)化。隨之而來的系統(tǒng)數(shù)量增加、應(yīng)用規(guī)模擴(kuò)大的需求,需要由服務(wù)器、存儲、網(wǎng)絡(luò)設(shè)備和安全設(shè)備等基礎(chǔ)設(shè)置的不斷擴(kuò)容來提供底層支撐,同時(shí)網(wǎng)絡(luò)環(huán)境也變得更為復(fù)雜,運(yùn)維工作量不斷增加。此時(shí),傳統(tǒng)的運(yùn)維方式已經(jīng)無法滿足日益增長的軟硬件運(yùn)維需求,并逐漸暴露出其弱點(diǎn)。傳統(tǒng)運(yùn)維主要靠人工方式完成,很難規(guī)避人為的誤操作,無法確保運(yùn)維的質(zhì)量;另一方面,人工一對一“串行”的運(yùn)維方式,運(yùn)維效率得不到提升。隨著運(yùn)維事務(wù)的增加,“事必躬親”的傳統(tǒng)運(yùn)維模式下,總體運(yùn)維效率已很難滿足當(dāng)下的計(jì)算機(jī)應(yīng)用規(guī)模,只有通過計(jì)算機(jī)應(yīng)用技術(shù),對應(yīng)用系統(tǒng)進(jìn)行計(jì)算機(jī)化的運(yùn)維,才能提高運(yùn)維效率、提升運(yùn)維質(zhì)量。而選用Python作為運(yùn)維的語言工具,絕非偶然。在很多操作系統(tǒng)中,Python是標(biāo)準(zhǔn)的系統(tǒng)組件,大多數(shù)Linux發(fā)行版都預(yù)裝集成了Python,可以在終端下直接運(yùn)行。同時(shí),Python豐富的類庫很好地滿足了網(wǎng)絡(luò)運(yùn)維以及操作系統(tǒng)運(yùn)維必要的功能需求,運(yùn)維復(fù)雜度也較選用shell、perl、ruby等語言來的簡單易用。
Python是一種跨平臺的計(jì)算機(jī)程序設(shè)計(jì)語言,是一個高層次的、結(jié)合了解釋性、編譯性、互動性和面向?qū)ο蟮哪_本語言。最初被設(shè)計(jì)用于編寫自動化腳本(shell),隨著版本的不斷更新和語言新功能的添加,越來越多被用于獨(dú)立的、大型項(xiàng)目的開發(fā)。
如果把一次編程比作生產(chǎn)一輛汽車,對使用C語言而言,就好比要自主研發(fā)生產(chǎn)發(fā)動機(jī)、底盤、車身和電器設(shè)備,最后進(jìn)行組裝。而對于Python則是拿來主義,我們并不需要開發(fā)各類配件,可以直接使用第三方的“發(fā)動機(jī)”、“底盤”等類庫即可,Python開發(fā)關(guān)心的是各類配件組裝的邏輯效果,而不關(guān)心程序本身運(yùn)行的速度。作為“膠水語言”,Python的強(qiáng)大來自全世界各行各業(yè)的開發(fā)者,他們把不同領(lǐng)域的對象進(jìn)行類庫化,把優(yōu)點(diǎn)進(jìn)行了整合。目前主要應(yīng)用領(lǐng)域有web開發(fā)、網(wǎng)絡(luò)爬蟲、計(jì)算與數(shù)據(jù)分析、人工智能、自動化運(yùn)維、云計(jì)算和網(wǎng)絡(luò)編程等方面,截至當(dāng)前,TIOBE編程社區(qū)Python穩(wěn)居前三,排名如圖1所示。
每一種語言的誕生,都有他適用的場景,Python因其豐富類庫、較強(qiáng)的可移植性、易于維護(hù)的源代碼和可嵌入等優(yōu)點(diǎn),實(shí)際生產(chǎn)中被各領(lǐng)域廣泛的使用[1]。
圖1 TIOBE Index for July 2020
在政府和企事業(yè)單位網(wǎng)絡(luò)運(yùn)維工作中,我們通常面向大量的網(wǎng)絡(luò)交換機(jī)和路由器的運(yùn)維,此類工作具有大量的重復(fù)性,采用傳統(tǒng)的人工維護(hù)方式,會浪費(fèi)大量的時(shí)間和人力成本。因此網(wǎng)絡(luò)運(yùn)維人員可以利用Python程序語言,編寫維護(hù)腳本,代替人工對網(wǎng)絡(luò)交換機(jī)和路由器的運(yùn)行狀態(tài)進(jìn)行檢測和維護(hù)。
本文以定期備份華為或華三網(wǎng)絡(luò)交換機(jī)的配置為例,說明Python為運(yùn)維工作帶來的便捷可靠性,同時(shí)結(jié)合Python多線程并發(fā)技術(shù),將該任務(wù)以一定的并發(fā)量分批執(zhí)行,即便運(yùn)維人員面對大量設(shè)備的配置備份需求時(shí),該項(xiàng)運(yùn)維工作依然保持高效可靠。
考慮到python2官方已停止維護(hù),以下代碼部分均基于python3編寫。
本例主程序主要使用了paramiko模塊和multiprocessing.pool模塊分別實(shí)現(xiàn)自動ssh登錄和多線程并發(fā),通過模擬登錄交換機(jī)運(yùn)行display current-configuration命令獲取到每臺網(wǎng)絡(luò)交換機(jī)設(shè)備的配置。接下來具體分析每個部分的實(shí)現(xiàn)代碼。
2.2.1 datafile為數(shù)據(jù)部分,主要是登錄交換機(jī)所必需的信息,數(shù)據(jù)格式為字典。示例如下:
#!/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 導(dǎo)入各類所需的模塊。
#!/usr/bin/python3
#coding:utf-8
import paramiko
import os, sys importtime,datetime
from datafile import *
frommultiprocessing.pool import ThreadPool
2.2.3 定義ssh登錄函數(shù),獲取交換機(jī)登錄歡迎信息,發(fā)送交互命令,返回交互結(jié)果。
defsshconfig(ip, port, username, password, cmd, PS1):
# 實(shí)例化SSHClient
client = paramiko.SSHClient()
# 自動添加策略,保存服務(wù)器的主機(jī)名和密鑰信息
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 連接SSH服務(wù)端,以用戶名和密碼進(jìn)行認(rèn)證
client.connect(hostname=ip, username=username,password=password, look_for_keys=False)
#獲取登陸shell,并設(shè)置超時(shí)時(shí)間
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 ----’
# 循環(huán)獲取數(shù)據(jù)
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 定義獲取交換機(jī)配置函數(shù),以時(shí)間、key和.config結(jié)合作為文件名保存配置文件[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 以多線程執(zhí)行交換機(jī)配置備份,線程池并發(fā)數(shù)為5。
result1 = []
if __name__ == “__main__”:
# 多線程部分定義線程池,即以5線程同時(shí)獲取5臺交換機(jī)設(shè)備的配置。
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 備份結(jié)果和備份文件部分內(nèi)容。
圖2 備份結(jié)果
圖3 備份文件內(nèi)容節(jié)選
比較單任務(wù)和多任務(wù)執(zhí)行的結(jié)果,雖然多任務(wù)執(zhí)行備份的任務(wù)量增加了,但執(zhí)行時(shí)間上來說,跟單任務(wù)執(zhí)行的時(shí)間上是相當(dāng)?shù)模s44s左右),兩次配置文件備份的大小也一樣,說明是完整的[3]。
本次多線程并發(fā)執(zhí)行是成功的。
2.3.1 單任務(wù)時(shí),耗時(shí)44.429942秒,如下圖。
2.3.2 5任務(wù)并發(fā)時(shí),耗時(shí)44.22秒。
python自動化運(yùn)維可以在提高運(yùn)維效率的同時(shí),降低運(yùn)維成本和運(yùn)維工作的出錯率,再結(jié)合多線程技術(shù)的應(yīng)用,可以使具體工作任務(wù)完成得更為高效,從而大大地提高運(yùn)維交付的速度。本文是python在網(wǎng)絡(luò)運(yùn)維工作中的一個應(yīng)用案例,旨在說明多線程技術(shù)為網(wǎng)絡(luò)運(yùn)維工作帶來的高效性,同時(shí)python在諸如系統(tǒng)運(yùn)維等工作中也有著廣闊的應(yīng)用前景,有待我們深入的學(xué)習(xí)和研究。