虛擬化與容器

裝置直通(device passthrough)

多數虛擬裝置都是軟體幻象,這很有彈性,但會帶來額外負擔。裝置直通是另一個極端:你拿一塊真實的、實體的硬體——一顆 GPU、一張網路卡、一顆 NVMe 磁碟——「直接」交給某一個客體,於是客體自己的驅動程式跟實際的矽晶片對話,超管理器大致退出資料路徑之外。客體從那個裝置得到接近原生、裸機的效能,因為中間沒有一層模擬。

這帶來的危險是記憶體安全,而解決它的硬體是 IOMMU(I/O 記憶體管理單元)。一個真實裝置會做直接記憶體存取——它自己用實體位址讀寫 RAM。若無保護,一個被客體控制的直通裝置可能被指使去讀寫「任何」主機記憶體,砸碎隔離。IOMMU 坐在裝置與記憶體之間,把每個裝置的記憶體存取加以轉譯、並限制在那個客體被允許的分頁之內——這是裝置版的分頁表。在 Linux 上,這透過 VFIO 框架接起來,它安全地把裝置從主機解綁、在 IOMMU 之後指派給客體。一個相關的技術 SR-IOV(單根 I/O 虛擬化)讓一張實體卡把自己呈現為許多輕量的虛擬功能(virtual function),於是單一一張網路卡能同時直通給好幾個客體,每個各拿到自己的一片真硬體。

為何以及何時用它:直通是你給一台虛擬機一顆真 GPU 來做機器學習或繪圖、或是給它毫無 virtio 負擔的線速網路的方式。但誠實的取捨是真實存在的。一個直通裝置被綁在一個客體上,通常無法共享(除非它支援 SR-IOV);它讓即時遷移變複雜,因為客體如今依賴特定的實體硬體;而且它擴大了對該裝置及其驅動的信任。直通以「犧牲了當初讓虛擬化吸引人的那份彈性」為代價,買到原始速度——這是一個刻意的取捨,不是免費的升級。

要給一台虛擬機一顆真正的 NVIDIA GPU,你在主機上把它綁到 vfio-pci 驅動、啟用 IOMMU(Intel VT-d 或 AMD-Vi)、再把它指派給客體。客體接著載入 NVIDIA 自己的驅動,以近乎原生的速度使用這張卡;主機就再也看不到那顆 GPU 了。

一顆真 GPU 在 IOMMU 之後被直接交給一個客體——原生速度,但綁死在那個客體上。

直通需要 IOMMU 來阻止一個受客體控制的裝置對任意主機記憶體做 DMA;沒有它,隔離就被破壞了。它也把裝置綁在一個客體上、讓即時遷移變複雜——用彈性換來的速度。

又稱
PCI passthroughVFIOSR-IOVdevice assignment直通 / 裝置指派