I/O虛擬化


note:這裏主要記錄我對IO虛擬化的理解,希望這篇文章對想了解虛擬化IO的同學有點幫助。這是我在看論文[vale,a switched ethernet for virtual machines]的時候總結的有關io虛擬化技術,概括性的和思考結果比較多,細節內容比較少。


        我們假設現在大部分的計算機服務都遷移到了虛擬化環境中(其實是事實),帶來的主要好處是資源共享並減少開銷。虛擬機也是需要訪問外圍設備的,比如磁盤和網絡。即使在非虛擬化環境中訪問網絡也是很有挑戰性的技術(應用程序使用系統調用),所以到了虛擬機這一層面,訪問網絡,要達到硬件的速度很困難。所以要怎麼處理虛擬化I/O呢?主要有三種方法來虛擬化I/O,分別是全虛擬化,半虛擬化以及Direct I/O accsss。他們在處理guest和hypervisor通信以及hypervisor和host架構上分別採用了不同的處理方式。


全虛擬化

        最簡單的方法就是給guest操作系統一個虛擬網絡接口。然後由hypervisor攔截下虛擬機的Accesses (to critical resources),並且hypervisor中用一個模塊來模擬網卡硬件的功能(emulator)。這種方法很直觀易懂,在歷史上來說,這也是第一種I/O虛擬化方式,最開始由VMware 和QEMU採納。
(這只是最基本的解釋了,至於說怎麼寫一個模擬器?我沒寫過,感興趣的可以google~~)

        當hypervisor截取到guest的packet之後,如果要發送到網絡上(這裏可以既包括內部網絡也包括外部網絡),就需要使用host的網絡棧了,比如TCP/UDP sockets(封裝)。

        全虛擬化看起來直觀易懂,很容易使用,環境配置簡單。只是模擬的開銷會很大,一般來說,那是一個非常龐大的系統(所以寫個模擬器工作量很大……)。


半虛擬化

        上面講了全虛擬化,和全虛擬化相對的就是半虛擬化,半虛擬化的意思就是說guest操作系統能夠感知到自己是虛擬機。那麼對於I/O系統來說,只要guest的驅動能夠和hypervisor進行溝通,。不同的hypervisor使用不同的技術來實現半虛擬化。比如說xen,就是通過事件通道,授權表以及共享內存的機制來使得虛擬機中的驅動(前端驅動)和host中的驅動(後端驅動)來通信。最後由設備域的標準linux內核來處理IO。

        另外kvm使用virtio,和xen的半虛擬化網絡驅動原理差不多。還有就是比如VMware的Guest tools,和xen的半虛擬化機制應該也很相似,一通百通。
那麼半虛擬化相對全虛擬化有什麼好處?雖然和全虛擬化一樣,都是使用軟件完成虛擬化工作,但是由於機制不一樣,這種方式由於不像模擬器那麼複雜,軟件處理起來不至於那麼慢,所以有更高的帶寬,更好的性能。但是還是存在性能問題,仍然達不到硬件的速度。

break
到此爲止,提一個問題,爲什麼軟件實現的性能不好?比如達不到有硬件支持(下面會提到)的速度?難道硬件支持就一定快,軟件就一定慢?能不能設計出一種軟件比有硬件支持的更快呢?(這個問題邊想邊繼續看吧,到文章的結尾處我會給出我的認識)

Direct I/O Access

前面的兩種方式,無論是模擬還是溝通方式,都需要guest和hypervisor的交互,而這裏要講的這種方式是爲了避免guest和hypervisor的溝通,使得guest能夠直接將流量發到硬件上面。看起來很奇怪是不是,但是這種方式應該怎麼做?host或hypervisor怎麼將網卡的控制權轉移給host?有沒有一個網卡可以轉移給多個虛擬機使用呢?(這只是一點提示問題,你可能還可以想出更多的問題來。)爲了解決這些問題,需要一套機制支持,這裏主要表現在硬件的支持。

首先考慮一個簡單的情形,將一個NIC分配給一個guest(host和其他guest都不能看到這個NIC),現在的方法是通過pci passthrough技術。現在一般一個網卡是一個pci設備,當系統識別這個網卡後,在內存會分配一塊對應的pci配置空間,爲了支持pci passthrough,現代的cpu架構會提供一種機制將這塊pci物理地址映射到guest操作系統的內存。比如intel的vt-d和amd的iommu(cpu對虛擬化的硬件支持)。然後通過軟件比如,pci passthrough命令來使用一次這塊硬件,實現映射的功能。但是是不是一定要用到CPU的虛擬化支持呢,我想只要你牛逼,寫個有映射功能和隔離機制的軟件也可以做到同樣的功能吧。

另外如果要將一個NIC分配給多個guest,我想就是SR-IOV技術了。就是將一個網卡虛擬出多個VF,然後將每個VF通過pci passthrough分配給不同的guest。這裏除了cpu的虛擬化支持,比如intel的vt-d,也還需要網卡本身的虛擬化技術,需要虛擬出多個vf功能,以及郵箱機制等功能(我做不了硬件的虛擬化,只講功能需求)。

關於這三種方式,我的瞭解程度都不一樣。雖然三種我都用過。全虛擬化的方式採用模擬器(寫一個模擬器的難度太大,沒有嘗試過寫,也沒有讀過代碼);xen的半虛擬化機制看過源碼,調用它的api實現過一些功能。至於pci passthrough我曾經使用82599網卡的SRIOV功能,將網卡虛擬化爲多個vf,再將多個vf分配給多個虛擬機進行實驗,這樣虛擬機的帶寬確實很高。


break:對於那個問題,私以爲軟件運行的速度不一定比純硬件慢。軟件歸根結底也是表現在cpu上運行(推薦看看csapp《深入理解計算機系統》)。同樣一個功能,軟件的不同設計導致運行的速度很可能不同。有的快,有的慢。當軟件的設計很完美的時候,這個時候影響軟件運行的瓶頸就是CPU頻率和內存帶寬。對於實現交換機功能這樣的軟件,如果這個交換機設計合理,基本上能達到cpu的頻率,如果對應的物理網卡的帶寬小於這個值,那麼這個軟件交換機相對於物理網卡而言,設計很棒,我們會覺得虛擬機的網絡IO性能真的是相當棒。
另外如果網卡帶寬大於cpu主頻或內存帶寬的時候,此時如果交換機軟件也設計相當棒的時候,瓶頸就表現在cpu主頻上。


p.s.由於比較懶,沒有畫圖,希望不影響理解,有些觀點沒有展開,細節講的過少,有些沒有重點。會慢慢修改補充,歡迎評論與建議:-I 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章