虛擬化與容器

virtio(半虛擬化裝置標準)

/ VEER-tee-oh /

當一台虛擬機需要磁碟或網路卡時,慢的做法是逐個暫存器去模擬一個真實的實體裝置,好讓未經修改的客體驅動以為自己在跟真硬體對話——但每戳一下暫存器都引發一次昂貴的 VM-exit。virtio 是被廣泛採用、用來為裝置解決這個問題的標準:它不去模仿真硬體,而是定義一個小巧、對虛擬化友善的裝置,由客體與超管理器雙方共同理解、彼此配合。它就是套用在 I/O 上的半虛擬化,而且被標準化了,所以同一個客體驅動能跨許多超管理器運作。

virtio 的核心是一個叫做 virtqueue 的共享佇列(建立在一個叫 vring 的結構之上)。客體與主機都能在記憶體裡看見這個緩衝區環。要送資料時,客體把緩衝區填上——比方說網路封包或磁碟區塊——把它們的描述符加進環裡,然後「踢(kick)」一下主機——一次通知——說有工作在等。主機從這個共享環裡成批處理整批工作,做完後回頭發訊號。因為大量資料就住在共享記憶體裡、只有那一下「踢」跨越了邊界,數以千計的逐操作退出便塌縮成寥寥幾次通知。標準在這之上定義了各種裝置型別:用於網路的 virtio-net、用於區塊儲存的 virtio-blk、virtio-scsi、用於記憶體氣球的 virtio-balloon 等等。

它為何成了預設:virtio 以一個乾淨、廠商中立的介面提供了近乎裸機的 I/O 效能,而現代 Linux 內建(in-tree)virtio 驅動,所以一個客體在 KVM、QEMU 及其同類上「就是能動」。它也是 Firecracker microVM 這類現代輕量虛擬化的 I/O 骨幹。誠實的定位是:virtio 不是什麼神奇的隔離、也不是一個 CPU 功能——它是一個設計良好的「配合式」I/O 協定,而且它倚賴客體擁有(或內建)virtio 驅動。CPU 仍然可以在硬體裡被完整、透明地虛擬化;virtio 只是把「裝置」那一側變得配合而快速。

一台使用 virtio-net 的 KVM 客體,把 64 個要送出的封包排進共享的 virtqueue,再踢主機一次。主機從共享記憶體裡一口氣成批排空全部 64 個——一次通知,取代了 64 次裝置暫存器退出。

virtio 的共享 virtqueue 把許多「逐封包」的裝置退出,變成一次成批的踢。

virtio 加速的是 I/O、不是 CPU,而且它需要客體裡備有 virtio 驅動(現代 Linux 內建;某些其他作業系統需要另外加裝)。它是一個配合式協定,不是硬體隔離功能——別把安全邊界歸功於它,那個邊界來自超管理器本身。

又称
virtio devicesparavirtualized device standard半虛擬化 I/O 框架