張寒冰 毛 明 史國振 李建鵬
1(西安電子科技大學通信工程學院 陜西 西安 710071)2(北京電子科技學院 北京 100070)
云計算是對并行計算、分布式計算、網格計算等高性能計算理論的延續與發展,它是一種以按需分配為業務模式,具備動態擴展等特點的新型計算模式[1],通過將資源抽象成一個虛擬化、動態化的資源池,來為用戶提供高性能、低成本的服務,它提供了一種可以靈活配置計算資源的彈性服務,可以根據需求對資源進行動態調整[2]。
云計算作為信息技術領域當中的一次重大變革,正在潛移默化地影響著我們的生活。由于其高可靠性、高擴展性、高靈活性等諸多優勢,越來越多的傳統應用開始向云端遷移[3],越來越多的企業開始構建自己的云計算平臺。傳統的密碼服務主要是通過部署物理密碼機來實現,這只能適用于具有長期穩定需求的系統,而在新環境下,面對海量數據和大規模的業務,需求可能不斷變化,如果在線服務過程中,業務需求發生改變但當前部署的設備無法滿足相應需求時,就需要先中止當前所有的密碼服務,然后更換相應的物理設備重新部署,這樣勢必會降低整個系統的服務效率,所以這種相對固定的密碼設備部署方法已經無法滿足動態多樣的需求,需要一種虛擬化的方法來實現密碼計算資源的動態配置,減少資源浪費,提升服務效率。
本文以QEMU-KVM技術為核心,通過添加資源監管模塊,構建虛擬密碼設備(Virtual Cryptography Machine,VCM),采用Virtio技術實現VCM與物理機的高效數據傳輸,通過Libvirt庫提供的命令行與API對VCM進行資源管理,以此實現密碼計算資源的虛擬化。
針對密碼計算資源虛擬化的問題,不少學者進行了分析與研究,已經提出了若干解決方案。
文獻[4]提出了一種由密碼資源調度系統、密碼服務資源池、密碼服務代理三部分組成的密碼資源池架構。其中服務資源池由虛擬密碼機與統一管理接口組成,利用硬件虛擬化技術將物理密碼設備虛擬成相互獨立的虛擬密碼機,虛擬密碼機內部配置密鑰管理、密碼服務等功能接口,用來抽象底層資源。但是該文獻只提出了一個框架,沒有給出明確的設計方法,不能很好地應用于實際工程。
文獻[5]提出了一種基于宿主機的密碼機及密碼運算實現方法,主要方法是在部署有物理密碼模塊的宿主機上配置多個虛擬機,各虛擬機的虛擬IP不同,用于接收不同的密碼運算請求,虛擬機通過添加虛擬密碼模塊與密碼服務模塊來處理運算結果。但是該方法沒有提供外部身份驗證的功能,僅利用不同的虛擬網卡作為區分不同虛擬密碼設備的手段,容易造成安全隱患,攻擊者只要獲得虛擬機的IP,就可能導致DDoS攻擊。
文獻[6]提出了一種在虛擬化環境中提供密碼服務的方法,主要方法是在宿主機上配置虛擬密碼機來提供虛擬密碼服務,通過虛擬機自省方式檢查密碼服務請求的有效性,虛擬機不能訪問計算過程中的密鑰及敏感狀態,密鑰以文件形式存儲在宿主機磁盤中。該方法通過虛擬機中的模擬接口來調用虛擬密碼設備,但是缺少對底層計算資源的統一描述,因而不適用于資源異構的環境。
針對傳統云計算領域,已經存在幾種主流的虛擬化解決方案。
Vmware采用全虛擬化技術,在虛擬機與硬件之間添加了一個軟件層Hypervisor作為虛擬機監控器(Virtual Machine Monitor,VMM)[7],以純軟件的方式模擬了一套硬件環境,需要占用一定資源。Xen是由劍橋大學計算機系在32位的X86上開發出的一個開源虛擬機監視器項目,采用半虛擬化技術,VMM作為客戶操作系統與硬件資源之間的訪問接口直接運行在硬件上[8]。它創建了一個能夠直接訪問硬件資源的特權操作系統“Domain 0”和若干普通客戶操作系統,由于該技術需要對客戶操作系統進行修改,所以無法應用于閉源操作系統。KVM是以色列創業公司Qumranet開發的一款基于Linux內核的全虛擬化解決方案,內核通過加載模塊創建VMM,無需對客戶操作系統進行修改[9],虛擬機與其使用的虛擬CPU都以常規Linux進程存在,可由內核的調度程序進行管理,減少了額外的開發工作。運行于內核空間的KVM完成硬件虛擬化和打開虛擬化模式,本身并不進行任何模擬,運行于用戶空間的QEMU通過KVM提供的接口完成整套虛擬化。
KVM在Linux2.6.20之后與內核集成在一起,隨Linux內核同步更新[10]。QEMU于2018年12月正式發布3.1.0版本,對ARM、MIPS等架構進行了更新,增加了對KVM內存巨頁技術(huge page)等功能的支持[11]。近幾年來,不少學者針對QEMU-KVM技術進行了研究與應用。文獻[12]提出了一種在ARM64位服務器系統中實現QEMU-KVM虛擬化的方法。文獻[13]在QEMU-KVM框架中添加了一個虛擬機管理緩存HyperCache,用于提高QEMU的I/O虛擬化能力。文獻[14]基于QEMU提出了一種創建用戶自定義虛擬硬件設備的步驟和方法,并為這些新設備開發了對應的驅動程序。文獻[15]基于QEMU-KVM技術設計了一種GPU的全虛擬化解決方案G-KVM。文獻[16]基于QEMU技術提出了一種用于檢測Linux應用異常通信行為的方法。上述研究成果也為本文利用該技術實現密碼計算資源虛擬化方法提供了思路。
本文采用QEMU-KVM技術對密碼計算資源進行虛擬化,通過在宿主機中部署資源監管模塊對虛擬密碼設備進行管理,通過添加身份驗證模塊對作業包的合法性進行驗證,通過構建多級隊列支持任務的優先級調度,通過對資源進行統一化描述實現計算節點的動態配置。
密碼計算資源的虛擬化框架如圖1所示,主要分為五個部分,即身份驗證模塊、VCM、作業隊列、計算模塊及計算資源監管模塊。

圖1 資源虛擬化框架
身份驗證模塊,主要負責對外來作業包進行身份驗證并將合法作業包發往相應的VCM進行下一階段的數據處理。該模塊中記錄了合法用戶與其分配的VCM之間的映射關系,由計算資源監管模塊對其進行維護,該模塊根據此映射關系將作業包分發給相應的VCM進行處理。
VCM,虛擬密碼設備,每一個用戶對應一個VCM,VCM之間相互獨立,在VCM內部可用于保存用戶在使用密碼服務過程中產生的臨時數據,便于虛擬設備的動態遷移。VCM內部主要由資源分配單元與VCM監管單元組成。資源分配單元主要根據服務種類將不同類型的作業包發往不同的處理接口,并負責從相應接口將處理好的數據返回給用戶;VCM監管單元主要為外部的計算資源監管模塊提供VCM的內部資源信息,同時可以根據外部命令對VCM內部資源進行相應調整。
作業隊列,是VCM與計算模塊之間的數據緩沖區,主要由優先級隊列與作業上下行隊列組成,結構組成如圖2所示。優先級隊列與VCM一一對應,作業上下行隊列與計算節點一一對應。從VCM接收到的作業包,會根據作業包的相關標識分發到相關的優先級隊列,再根據作業分發單元中的調度策略將其分發到相應的作業下行隊列中,然后由計算單元對其進行處理,最后通過作業上行隊列將結果返回給VCM。
計算模塊,主要由計算節點組成,這些計算節點是實際計算單元經過抽象得到的,實際計算單元既可以是軟件實現也可以是硬件設備。
計算資源監管模塊,主要負責對整個系統的計算資源,如內存、CPU、磁盤等信息進行監管,也包括對各作業隊列的負載信息與各計算節點的運行信息等進行監管。通過監控這些資源既便于管理員了解系統運行情況,也便于資源的動態配置。

圖2 作業隊列
2.2.1身份驗證
為保證密碼服務系統的安全性,用戶在使用密碼服務之前需要在該系統注冊,只有合法用戶才能使用密碼服務。用戶注冊時,由計算資源監管模塊根據用戶需求與當前系統計算資源的使用情況為用戶分配對應的計算資源,創建相應的VCM,同時為VCM分配獨有的虛擬IP,該IP與用戶形成一對映射關系。驗證步驟如下:
Step1用戶向系統發送帶有用戶標識碼信息的連接請求包;
Step2驗證模塊取出用戶標識碼,并將其與本地數據庫進行比對,如果驗證成功,則執行下一步,否則返回錯誤;
Step3從數據庫中得到為該用戶分配的VCM的IP地址,并與其建立連接,形成內部通路;
Step4驗證模塊返回連接成功信息,然后負責外部與VCM之間的數據轉發,直到用戶斷開連接。
因此,該系統對外只有一個交互接口,隱藏了系統的內部數據通道與資源的分配情況。
2.2.2VCM
虛擬密碼設備VCM是基于QEMU-KVM技術創建的KVM虛擬機,與用戶一一對應。
通過虛擬機的配置文件,可以為虛擬機靈活分配內存、CPU、外設等。在Linux環境下,配置文件位于/etc/libvirt/qemu/下,由xml文件定義。虛擬機的基本信息如下:
其中:由屬性type指定使用的虛擬化技術為KVM;元素name指定創建的虛擬機名稱為vcm1;元素uuid指定當前虛擬機的唯一標識符;元素memory指定虛擬機啟動時所分配的內存大小;KVM虛擬機中的內存管理采用內存氣球(Ballooning)技術[17],便于內存的動態調整,元素currentMemory指定使用該技術動態調整后的內存大小;元素vcpu指定為虛擬機分配的虛擬CPU數量;元素os指定虛擬機的系統信息。
身份驗證模塊與VCM之間通過Socket套接字進行通信,每個VCM擁有各自獨立的IP地址,建立數據通道后,各用戶之間的數據收發互不影響。
針對I/O虛擬化,KVM一般使用純軟件的方式模擬I/O設備[18]。當客戶機發出I/O請求時,KVM內核模塊中的I/O操作捕獲代碼攔截該請求,對其進行相應處理后將請求信息放到I/O共享頁中,并通知QEMU程序,QEMU獲得請求信息后,使用硬件模擬代碼模擬此次I/O操作,最后將結果放回I/O共享頁,KVM內核模塊捕獲到該結果之后返回給客戶機。這樣做會導致每次I/O請求時出現多次上下文切換,考慮到本框架中的KVM與作業隊列之間需要進行頻繁的數據交互,采用這種方法的處理性能較差。
Virtio技術是一種I/O半虛擬化的解決方案,它在客戶操作系統中安裝前端驅動(Front-end driver),在QEMU中安裝后端驅動(Back-end driver),前后端之間通過環形緩沖區Vring直接通信,這樣就不需要KVM內核模塊參與,進而提升數據的交互性能。它的實現被稱為Virtio-serial,是一種傳輸協議,用于客戶與宿主間的簡單通信[19]。所以,在VCM與作業隊列之間采用Virtio技術建立數據通道可以大大提升數據傳輸效率。修改VCM對應的xml文件即可添加相應設備,如下所示:
VCM啟動后,在路徑/dev/virtio-ports下會新增一個名為vcm.recv的字符設備,通過對該設備進行文件讀寫即可實現對Virtio通道的數據收發。相應地,該設備在宿主機當中被映射成一個套接字文件vcm_send.data,位于/var/lib/libvirt/qemu/路徑下,采用Socket套接字方法即可完成對Virtio通道的讀寫。這樣,就實現了VCM與宿主機之間的高效數據交互。
2.2.3作業隊列
作業隊列主要作為VCM與計算模塊之間的數據緩沖區。為了能夠使作業包按照任務優先級進行處理,將下行隊列分為兩層:優先級隊列與作業下行隊列;對于計算模塊,只要數據處理完畢后就會將處理結果放入上行隊列,這意味著先處理先返回,所以只需要一層上行隊列。相應的隊列管理進程負責管理隊列之間的作業交互。針對這3類不同功能的作業隊列,隊列管理進程也分為3類:
(1) 接收進程,管理VCM與優先級隊列之間的數據通路,負責將來自VCM的作業包根據作業優先級標識放入對應的優先級隊列中。
(2) 作業分發進程,作用相當于作業分發單元,管理優先級隊列與作業下行隊列之間的數據通路,對作業包進行調度。對于每種優先級隊列,均設定一個閾值,該閾值可以由作業包的平均等待時間或隊列中的作業包數決定。以作業包數為例,當各優先級隊列的負載均低于閾值時,實行遍歷調度的策略,即從高優先級到低優先級依次調度;當某級隊列的負載超過了閾值,則先切換到該級隊列進行調度,直到其負載低于閾值,再返回原隊列繼續;如果有多個隊列同時出現超過閾值的狀況,則按照優先級由高到低的策略進行調度。該閾值可以根據實際情況在資源管理平臺中修改。
(3) 發送進程,管理作業上行隊列與VCM之間的數據通路,負責將作業上行隊列中的作業包發送給VCM。
為防止使用不同密碼算法服務的數據在傳輸過程當中互相影響,對于每一種密碼服務,VCM都分配有對應的Virtio收發通道,對于每一個計算節點,每種密碼服務都分配有對應的作業上下行隊列。配置不同的Virtio收發通道保證了在數據分發及處理的過程中,單一密碼服務類型的數據存在于單一類型的數據通道當中,相比于使用公用通道,不需要每次從通道中取出數據時進行分類,因而便于對其中某個單一密碼算法流程進行全局管理,有效提高了處理效率。通過配置獨立的作業上下行隊列,便于計算節點的動態配置,如果需要添加或者刪除計算節點時,只需要打開或者關閉相應的隊列即可。
對于每一個作業包,可定義如下包頭對作業進行區分:
struct data_head
{
int priority;
//作業包優先級
int type;
//算法服務標識
int id;
//作業包ID
int len;
//作業包長度
};
其中:priority標識作業包的優先級,type標識作業包的類型,id用于與其他作業進行區分,len指定作業包的長度。
作業隊列在處理數據時主要分為以下4個步驟:
Step1接收進程通過Virtio通道從VCM中取出數據,并根據包頭中的priority字段將其放入相應的優先級隊列中;
Step2作業分發進程按照當前調度策略從某個優先級隊列中取出作業包,然后根據包頭中的type字段將其放入相應的作業下行隊列;
Step3計算模塊中的計算節點從對應的作業下行隊列中取走數據,待數據處理完畢后,直接放入相應的作業上行隊列;
Step4發送進程發現某作業上行隊列中存在數據后,就會通過相應的Virtio通道將其發給VCM。
2.2.4計算資源監管
為了對計算資源進行合理分配,需要構建計算資源監管模塊,負責對計算資源的使用情況進行實時監控,用于作業的分配與調度。
(1) 通過Libvirt庫對VCM進行管理。
Libvirt是一款針對Linux虛擬化平臺進行管理的開源API[20],它提供了一套統一的虛擬化管理接口,同時提供了一個libvirtd服務和virsh命令行管理工具,便于直接對虛擬機進行管理。常用virsh命令如表1所示。

表1 常用virsh命令
(2) 通過共享內存實時監管作業隊列與計算節點。
共享內存是一種用于進程之間傳遞消息的方式。通過創建一塊固定的內存區域,使得多個進程都可以將其連接到它們自己的地址空間,再通過增加同步機制保證共享內存區內數據的正確性。各作業隊列與計算節點可以將其負載信息同步到共享內存中,便于計算資源監管模塊對它們進行監管。與數據庫記錄穩定且更新頻率低的數據相比,共享內存提供了對臨時且更新頻率高的數據進行記錄的方法,便于實時狀態的更新與反饋。
2.2.5計算節點
為了實現計算資源虛擬化,需要將傳統意義上的軟硬件計算單元抽象成計算節點,通過統一的描述語言構建底層的計算資源池。針對用于密碼運算的底層計算單元,可以用一個多元組來表示:
nodei=R(Ei,Bi,A1,A2,…,Aj)
(1)
式中:Ei表示節點ID,用于區別其他節點;Bi表示屬主ID,用于表示當前節點所屬的VCM標識;Aj用于表示本節點的計算能力,包括密碼服務類型Tj、處理速度Pj及狀態信息Sj,即:
Aj={Tj,Pj,Sj}
(2)
對只提供一種密碼算法的節點有如下表示:
nodei=R(Ei,Bi,{T,P,S})
(3)
計算節點經過抽象后以這種多元組的形式{node1,node2,…,noden}儲存在數據庫當中。隊列管理進程通過這些信息,將作業包分發到最優節點;監管模塊則通過這些信息實現對計算節點的動態配置。
基于本文所描述的密碼計算資源虛擬化方法,通過在Linux系統中搭建相關環境,實現了計算資源虛擬化的原型系統。通過對系統進行測試,可以證明所提出的虛擬化方法能夠對密碼計算資源進行動態配置,滿足所提出的需求。
使用兩臺PC進行測試,一臺作為用戶端,一臺作為服務器端,二者通過Socket建立連接,在服務器端部署整個虛擬化系統,用戶端通過服務器端提供的API接口進行交互。
為方便進行功能測試,底層計算單元通過調用OpenSSL軟件庫實現密碼運算,且只提供SM3雜湊算法服務。選用MySQL作為系統的核心數據庫,用于記錄用戶的注冊信息、VCM及各計算節點的資源信息。利用Linux系統提供的消息隊列機制構建作業隊列。
數據庫的基本字段如表2所示。其中,為方便處理,對計算節點進行了量化處理,規定:節點SM3的實際處理速率為1 kbit/s時對應的sm3rate為1,即P=1;屬主ID為0時表示該節點未被分配;服務類型為1時表示提供SM3雜湊算法服務;狀態信息為1時表示當前節點可用。

表2 數據庫字段
這里定義4個不同速率的計算節點,即:
node1=R(1,1,{1,1,1})
(4)
node2=R(2,0,{1,1,1})
(5)
node3=R(3,0,{1,2,1})
(6)
node4=R(4,0,{1,2,1})
(7)
其中,只有node1被分配給了ID為1的VCM,其余節點都處于未分配狀態。
資源監管平臺如圖3所示。通過資源監管平臺界面,可以實時監視當前系統已注冊的用戶、為當前用戶所分配的VCM信息以及為VCM所分配的計算節點狀態信息。由圖3可知,當前系統注冊用戶只有1個,所分配的VCM的ID為1,為該VCM分配的計算節點ID為1,其SM3處理速率為1,與式(4)定義相符。

圖3 資源監管平臺
通過該平臺除了可以看到當前活躍的計算節點,也能看到未分配的節點信息,如圖4所示。

圖4 計算節點信息
由圖4可以看到,當前系統存在4個計算節點,節點的狀態與式(4)-式(7)所定義的一致。針對這4個節點,可以對其進行動態配置。通過配置可以自由搭配節點,用戶端所得到的SM3運算速率變化如圖5所示,橫坐標中用括號括起來的數據表示當前參與計算的節點ID。

圖5 節點組合測試
由圖5可以看到,用戶在使用過程中,根據用戶需求,可以通過對節點動態配置調整用戶所擁有的計算能力。理論上對于SM3雜湊算法服務,不同節點組合所獲得的處理能力應是這幾個節點的處理能力之和,圖中的數據表明實際計算能力與理論相符。由于配置的是抽象出來的計算節點而不是具體的物理計算資源,因而在用戶使用過程中,如果需要調整底層的物理資源,可以用已配置好的計算節點替換當前節點,而不需要中止當前服務,也就是說,通過計算節點屏蔽了底層的物理資源,滿足虛擬化的要求。
針對多計算節點同時參與計算,需要考慮各計算節點的負載均衡。作業隊列管理進程是根據各計算節點速度的量化數據分配作業包,也就是基于計算節點的處理能力分配作業包,因而在理論上保證了計算節點間的負載均衡。實際測試如圖6所示。可以看出,各節點所處理的作業包個數與其處理能力成正比,具有相同能力的節點所處理的作業包個數相同,這樣既保證了負載隨節點處理能力的增加而增加,也保證了具有相同處理能力的節點具有相同的負載。

圖6 節點負載分布
本文基于QEMU-KVM技術,提出了一種密碼計算資源的虛擬化方法,設計了一個虛擬化框架。通過將物理資源抽象成計算節點構建資源虛擬化池,通過配置優先級隊列使得作業可以根據任務的優先級進行處理,通過為每個節點配置獨立的作業上下行隊列保證計算節點動態添加或刪除的可行性,通過添加身份驗證模塊保證整個虛擬化系統的安全。仿真實驗證明了本方法的正確性和可行性,利用該框架可以對密碼計算資源進行虛擬化,實現對密碼計算資源的動態配置。