郭小崗 徐益強
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在諸如系統運維等工作中也有著廣闊的應用前景,有待我們深入的學習和研究。