郝慧杰,肖 建,張 糧,洪 聰
(南京郵電大學,江蘇 南京 210023)
網絡功能虛擬化(network function virtualization,NFV)是一種實現軟硬件解耦的新技術。NFV技術[1-3]一直以來都受到業界的廣泛關注,其核心是通過特定的虛擬化技術,將通信網元功能分層解耦,實現網絡自動化從而提升網絡效益。虛擬網絡功能(VNF)是虛擬機中封裝的網絡功能設備的軟件實現,位于商用硬件NFV基礎設施之上。VNF是NFV的核心部分,眾所周知NFV的基礎是虛擬網絡功能和軟件,能夠降低成本并獲得對網絡運營的全面控制,同時具備靈活性和敏捷性的優勢。NFV的大部分運營都集中在VNF如何在NFV基礎設施中服務,未來,NFV中的重大進展將僅與VNF有關。虛擬網絡功能作為NFV虛擬網絡層的關鍵部分,實現對虛擬網絡功能生命周期的管理,對NFV技術發展來說具有重大意義[4]。
目前在國內,研究VNF生命周期管理的公司也有許多(包括AT&T,思科,戴爾,微軟,甲骨文,Verizon,Juniper等),但是大多數用于管理VNF生命周期實例化、監測、修復、縮放、更新和備份的方法成本高昂、繁瑣和耗時。所以,目前VNF生命周期管理系統的研究在很多方面還不夠完善和靈活。
基于以上問題,本系統在保證各個功能單位模塊化的前提下,以標準的Linux的環境、接口、工具為基礎,依托容器環境,通過VNF架構分析和軟件模塊化設計,實現了對Docker的狀態的管理監控,包括安裝、啟動、停止、卸載、資源分配和釋放等生命周期管理行為。
該生命周期管理系統的功能需求如圖1所示,軟件部分包括用戶交互層(命令行客戶端)、業務控制層(生命周期管理核心算法)、數據支撐層(開源Redis數據庫)。用戶交互層用來下發用戶指令,并及時響應用戶請求,完成用戶操作;業務控制層主要是實現虛擬網絡生命周期管理狀態監控和行為功能;數據支撐層實現整個系統的數據持久化,主要負責各模塊進行相關數據的存儲和查詢。

圖1 平臺框架
本項目以標準的Linux的環境、接口、工具為基礎,基于容器環境完成vnfc(虛擬化的網絡功能模塊組件)的開發,采用開源的高性能key-value數據庫Redis來實現數據的存儲和調度,使用Thrift軟件框架,用來進行可擴展跨語言的服務開發實現RPC客戶端和服務器通信。
Thrift是一個可伸縮的,并且跨語言的服務性的開發部署框架。Thrift通過一個中間語言IDL(interface definition language,接口定義語言)來定義RPC的數據類型和接口,然后通過特殊的編譯器生成不同語言的代碼,生成的代碼中不但包含目標語言的接口定義、方法、數據類型,還包含有RPC協議層和傳輸層的實現代碼。Thrift的架構如圖2所示,Thrift實際上是一種C/S模式,通過多語言生成工具將Thrift文件轉換成特定語言的接口文件,包括客戶端部分和服務器部分,從而實現服務端和客戶端跨語言的支持。用戶根據實際需求,編寫客戶端或服務端代碼[5]。用戶定義好Thrift的IDL文件后,使用Thrift的編譯器來生成相應語言的代碼文件,之后服務器端提供服務,客戶端調用服務。

圖2 Thrift架構
選用Thrift通信機制的優勢包括:支持非常多的語言綁定;Thrift文件生成目標代碼,簡單易用;消息定義文件支持注釋;數據結構與傳輸表現的分離,支持多種消息格式;包含完整的客戶端/服務端堆棧,可快速實現RPC;支持同步和異步通信。
Thrift可以說它是現在最優秀的分布式通信機制,實現了在大型分布式集群中各獨立模塊之間的高效協同。該框架具有可擴展性,能夠支持跨編程語言的服務開發[6],能夠高效創建服務接口,因此符合本系統高并發、大數據量的要求。
Redis(remote dictionary server)[7]是一個開源的、支持網絡、基于內存、支持Key-Value等多種數據結構、可持久化的高性能存儲系統。它提供字符串,哈希,列表,隊列,集合結構直接存取,支持原子性的操作,所以通常被稱為數據結構服務器。可用于會話緩存,事件發布或訂閱,數據庫和消息中間件等場景。
Redis的持久化機制十分完備,所有數據都是保存在內存中,然后通過異步方式不定期地保存到磁盤上,也可以把每一次數據變化都寫入到一個append only file里面。Redis支持master-slave模式的數據備份,可以通過復制功能自動實現同步的過程。當從數據庫崩潰重啟后,主數據庫會自動同步數據,保證數據不丟失。而當主數據庫崩潰時,將從數據庫提升成主數據庫繼續提供服務,并在原來的主數據庫啟動后將其設置成新的主數據庫的從數據庫,將數據同步回來。數據同步提高了讀取操作的可擴展性。Redis能讀的速度是110 000次/s,寫的速度是81 000次/s,所以性能非常高。
在實際應用中,當用戶請求到達Redis服務器時,只是對業務數據進行讀寫,而沒有對數據庫進行任何的操作,這樣就能大大提高讀寫的速度,從而達到高速響應的需求。這些緩存的數據仍然需要持久化,也就是存入數據庫之中,所以在一個請求操作完Redis的讀/寫之后,會去判斷該高速讀/寫的業務是否結束,如果不成立,則不會操作數據庫;如果成立,則觸發事件將Redis的緩存的數據以批量的形式一次性寫入數據庫,從而完成持久化的工作。Redis數據請求操作如圖3所示。

圖3 Redis數據請求操作
Go語言作為編譯型語言,在數據類型上也支持得非常全面,除了傳統的整型、浮點型、字符型、數組、結構等類型外,從實用性上考慮,也對字符串類型、切片類型、字典類型、復數類型、錯誤類型、管道類型、甚至任意類型進行了原生支持,并且用起來非常方便。比如字符串、切片類型,操作簡便性幾乎和python類似。與其他傳統語言相比,Go語言通過豐富的內置類庫實現了大量的接口函數,極大程度地簡化了開發工作,開發者們只需調用相應的類庫即可實現相關的功能[8-9]。
在異步的并發編程過程中,只能方便、快速地啟動協程還不夠。協程之間的消息通信,也是非常重要的,否則,各個協程不能協作無法控制。Go自誕生之日起就表明自己是為了簡化多并發編程,Go既支持共享內存也支持消息傳遞的通信方式[10]。在Go語言中,使用基于消息傳遞的通信方式進行協程間通信,并且將消息管道(channel)作為基本的數據類型,使用類型關鍵字(chan)進行定義,并發操作時線程安全。
真正的高效率開發,是配置化的,并不需要寫太多的代碼,甚至根本就不需要寫代碼,即可完成邏輯實現,而這種方式對于后期的維護成本也是最優的,因為做到了高度的統一。Go的語言描述效率毋庸置疑(見圖4),對上述所有公共組件的實現,均未超過1 000行代碼,十分少的工作量就解決了通信上的問題。

圖4 Go語言開發效率
本項目用Go語言編寫一個客戶端通過與服務端通信快速實現對容器的數據查詢,數據存儲,并可以進行資源調度和狀態監控,大大提升了業務開發效率,節省了開發成本。
由于虛擬機是一種十分笨重的虛擬化技術[11],在有限的物理資源條件下無法實現大規模節點伸縮,因而極大地降低了在大規模部署場景下的應用能力。而Docker容器技術具有輕量、隔離和快速部署的特點。容器相互之間不會有任何接口,完全使用沙箱機制。容器擁有獨立的文件系統,安全且相互隔離的運行環境[12]。容器里的進程,使用到的資源都是虛擬的,這樣與底層系統是完全隔離的。
Docker讓用戶可以輕松打包應用程序的代碼、配置和依賴關系,然后移植到其他機器上,也實現虛擬化。容器可以幫助保證應用程序快速、可靠、一致地部署,其間不受部署環境的影響。容器可以方便地進行版本管理、隨時修改、快速分享。
利用Docker的自身優勢,可以實現環境一致性、運營效率、開發人員生產力和版本控制等目標。Docker相比于傳統虛擬化方式具有更多的優勢,不僅可以解決硬件管理的問題,也改變了虛擬化的方式。所以本項目選擇Docker作為生命周期管理的實體。Docker生命周期如圖5所示。

圖5 Docker生命周期
VNF管理[13-15]主要是為了保證虛擬網絡服務的正常運行和資源合理分配,從而對VNF進行一系列的相關操作。這些操作實現對網絡生命周期管理,包括安裝、啟動、停止、卸載、資源分配和釋放等。
本系統的實現如下:首先用戶通過Thrift命令行客戶端下發VNF生命周期管理的請求(包括安裝、啟動、停止、卸載、資源分配和釋放),系統利用RPC通信將消息傳遞到Thrift的服務端,然后服務端對請求進行一系列的合法性檢查,驗證失敗返回error。如果驗證通過,程序會繼續進行相應的業務邏輯處理下發,即對Docker鏡像文件的安裝、Docker的啟動和終止等等,同時將當前數據存入Redis數據庫中,最后將執行結果返回到客戶端進行展示。系統流程如圖6所示。

圖6 VNF生命周期管理
通過簡單的實驗來測試VNF生命周期管理系統的運行,驗證Redis數據庫存儲和Thrift通信接口測試,使用的測試環境如表1所示。

表1 實驗環境和工具
在本項目中,Redis數據庫有著不可替代的作用,數據庫為系統的管理、運行、查詢和實現數據存儲等提供空間。數據庫最常見的有兩種問題,這兩種問題導致的錯誤為數據一致性錯誤和輸出錯誤。數據一致性錯誤來源于使用者提交的信息數據格式不正確,另外一種輸出錯誤一般是網絡和程序設計過程中的問題等導致,對于以上兩種問題,將分別測試。測試項目如表2所示。

表2 數據庫測試
生命周期管理系統服務端與命令行客戶端通過Thrift調用方式進行通信,因此需要對所有接口進行測試調用,以保證程序的正確運行。客戶端下發VNF生命周期管理的請求(包括安裝、啟動、狀態查看、停止、卸載、資源分配和釋放)都需要進行測試,圖7為下發命令進行狀態查看。

圖7 Docker狀態查看測試
通過實驗所有支持的命令行都能夠通過Thrift通信接口下發成功,并返回預期的結果。
對系統的性能,利用客戶端調用做最簡單的阻塞式多次調用壓力測試。用多個客戶端多連接,多個線程,模擬發送請求。總共發送10 000 request 100client并發,執行五次時間如下:681 ms,543 ms,604 ms,542 ms,576 ms;平均時間:589.2 ms,16 972 request/s。
實驗得出,Redis數據庫可以實現在任務執行過程中高效獲取共享數據的分布式緩存,解決共享數據的存儲問題。在并發性上,Thrift支持多進程,可以同時啟用多個客戶端,下發request服務端并發處理請求,耗時少,性能高。通過實驗得出該方案在實用性、可擴展性、通用性等方面都有所改進,但是在客戶端界面實現等方面還是存在一些問題需要再進行完善。
該系統主要借鑒前人經驗,努力克服當前VNF生命周期管理系統中存在的缺點和限制,開發設計一套成本低、耗時少、簡單易操作的生命周期管理系統。該系統以標準的Linux的環境、接口、工具為基礎,基于容器環境完成vnfc(虛擬化的網絡功能模塊組件)的開發,采用開源的高性能key-value數據庫Redis來實現數據的存儲和調度,采用Thrift軟件框架,用來進行可擴展跨語言的服務開發實現RPC客戶端和服務器通信,實現對Docker的狀態進行監控和生命周期管理。容器是操作系統級的一種虛擬化形式,它將應用程序依賴關系、所需的庫和配置封裝在同一操作系統的其他容器隔離的包中。容器能讓應用程序以獨立的方式運行,并且可以輕松遷移。隨著向云原生的遷移,VNF微服務部署在容器中是發展的趨勢。該系統將為Docker平臺的普及發展提供助力,提高Docker平臺的應用、開發、部署及運維應用的效率。