linux虛擬網絡設備--虛擬機網卡和linux bridge上tap設備的關係(七)

1. 虛擬機進程

使用ps –ef |grepkvm可以看到虛擬機進程信息如下:
/usr/libexec/qemu-kvm -nameinstance-0000001d -S -machine pc-i440fx-rhel7.1.0,accel=kvm,usb=off -cpuBroadwell,+abm,+pdpe1gb,+hypervisor,+rdrand,+f16c,+osxsave,+vmx,+ss,+ds,+vme -m64 -realtime mlock=off -smp 1,sockets=1,cores=1,threads=1 -uuid 687fd29c-13c2-433b-941c-2414da556bdb-smbios type=1,manufacturer=Fedora Project,product=OpenStackNova,version=12.0.0-1.el7,serial=a373d218-fea2-4c1c-b255-26714654fdbe,uuid=687fd29c-13c2-433b-941c-2414da556bdb,family=VirtualMachine -no-user-config -nodefaults -chardevsocket,id=charmonitor,path=/var/lib/libvirt/qemu/instance-0000001d.monitor,server,nowait-mon chardev=charmonitor,id=monitor,mode=control -rtc base=utc,driftfix=slew-global kvm-pit.lost_tick_policy=discard -no-hpet -no-shutdown -boot strict=on-device ich9-usb-ehci1,id=usb,bus=pci.0,addr=0x5.0x7 -deviceich9-usb-uhci1,masterbus=usb.0,firstport=0,bus=pci.0,multifunction=on,addr=0x5-device ich9-usb-uhci2,masterbus=usb.0,firstport=2,bus=pci.0,addr=0x5.0x1-device ich9-usb-uhci3,masterbus=usb.0,firstport=4,bus=pci.0,addr=0x5.0x2-device virtio-serial-pci,id=virtio-serial0,bus=pci.0,addr=0x6 -drivefile=rbd:vms/687fd29c-13c2-433b-941c-2414da556bdb_disk:id=cinder:key=AQBqCA9X18xZOxAAWVDkhAOsKZIQY6oAf9cjlg==:auth_supported=cephx;none:mon_host=192.168.44.130:6789,if=none,id=drive-virtio-disk0,format=raw,cache=none-devicevirtio-blk-pci,scsi=off,bus=pci.0,addr=0x7,drive=drive-virtio-disk0,id=virtio-disk0,bootindex=1-drivefile=rbd:vms/687fd29c-13c2-433b-941c-2414da556bdb_disk.config:id=cinder:key=AQBqCA9X18xZOxAAWVDkhAOsKZIQY6oAf9cjlg==:auth_supported=cephx;none:mon_host=192.168.44.130:6789,if=none,id=drive-ide0-1-1,readonly=on,format=raw,cache=none-device ide-cd,bus=ide.1,unit=1,drive=drive-ide0-1-1,id=ide0-1-1 -netdev tap,fd=25,id=hostnet0,vhost=on,vhostfd=26 -device virtio-net-pci,netdev=hostnet0,id=net0 ,mac=fa:16:3e:36:c0:a7,bus=pci.0,addr=0x3-chardevfile,id=charserial0,path=/var/lib/nova/instances/687fd29c-13c2-433b-941c-2414da556bdb/console.log-device isa-serial,chardev=charserial0,id=serial0 -chardev pty,id=charserial1-device isa-serial,chardev=charserial1,id=serial1 -chardevspicevmc,id=charchannel0,name=vdagent -devicevirtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,id=channel0,name=com.redhat.spice.0-chardev socket,id=charchannel1,path=/var/lib/libvirt/qemu/org.qemu.guest_agent.0.instance-0000001d.sock,server,nowait-devicevirtserialport,bus=virtio-serial0.0,nr=2,chardev=charchannel1,id=channel1,name=org.qemu.guest_agent.0-device usb-tablet,id=input0 -vnc 0.0.0.0:0 -k en-us -spiceport=5901,addr=0.0.0.0,disable-ticketing,disable-copy-paste,disable-agent-file-xfer,seamless-migration=on-k en-us -deviceqxl-vga,id=video0,ram_size=67108864,vram_size=67108864,vgamem_mb=16,bus=pci.0,addr=0x2-device AC97,id=sound0,bus=pci.0,addr=0x4 -devicevirtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x8 -msg timestamp=on

關注其中的網卡配置參數:

  • 從HOST角度:-netdev tap,fd=25,id=hostnet0,vhost=on,vhostfd=26
  • 從GUEST角度:-devicevirtio-net-pci,netdev=hostnet0,id=net0,mac=fa:16:3e:36:c0:a7,bus=pci.0,addr=0x3

可以看到,host上使用tap類型的網卡,開啓了vhost-net技術。

vhost-net技術是在半虛擬化技術virtio上提出的,而virtio則是基於全虛擬化技術而言的。所以在瞭解vhost-net技術之前,需要先了解一下tun/tap工作原理、全虛擬化技術、virtio技術。

2. Tap/Tun工作原理

TUN/TAP虛擬網絡設備的原理比較簡單,他在Linux內核中添加了一個TUN/TAP虛擬網絡設備的驅動程序和一個與之相關連的字符設備/dev/net/tun,字符設備tun作爲用戶空間和內核空間交換數據的接口。用戶空間的應用程序可以通過這個設備文件來和內核中的驅動程序進行交互,其操作方式和普通的文件操作無異。當內核將數據包發送到虛擬網絡設備時,數據包被保存在設備相關的一個隊列中,直到用戶空間程序通過打開的字符設備tun的描述符讀取時,它纔會被拷貝到用戶空間的緩衝區中,其效果就相當於,數據包直接發送到了用戶空間。通過系統調用write發送數據包時其原理與此類似。

從結構上來說,Tun/tap驅動並不單純是實現網卡驅動,同時它還實現了字符設備驅動部分。以字符設備的方式連接用戶態和核心態。下面是示意圖:
在這裏插入圖片描述

Tun/tap 驅動程序中包含兩個部分,一部分是字符設備驅動,還有一部分是網卡驅動部分。利用網卡驅動部分接收來自TCP/IP協議棧的網絡分包併發送或者反過來將接收到的網絡分包傳給協議棧處理,而字符驅動部分則將網絡分包在內核與用戶態之間傳送,模擬物理鏈路的數據接收和發送。Tun/tap驅動很好的實現了兩種驅動的結合。

3. Tap/Tun Device在libvirt中的應用

  • 將guest system的網絡和host system的網絡連在一起。
  • 通過TUN/TAP adapter,會生成一個在host system上的虛擬網卡tap
  • tun建立了point to point的網絡設備,使得guest system的網卡和tap虛擬網卡成爲一對
  • 從而guest system的所有網絡包,host system都能收到。

Tun/tap驅動程序中包含兩個部分,一部分是字符設備驅動,還有一部分是網卡驅動部分
在這裏插入圖片描述

  • 虛擬機將網絡包通過字符設備寫入/dev/net/tun(Host上);
  • 字符設備驅動將數據包寫入虛擬網卡驅動;
  • 虛擬網卡驅動將包通過TCP/IP協議棧寫給Host上的虛擬網卡tap0;
  • 在HOST上通過路由規則(通過網橋(東西向流量)、網橋和路由器(南北向流量)),包從eth0出去。

4. Linux全虛擬機網絡橋接模型

KVM 客戶機網絡連接有兩種方式:

用戶網絡(User Networking):讓虛擬機訪問主機、互聯網或本地網絡上的資源的簡單方法,但是不能從網絡或其他的客戶機訪問客戶機,性能上也需要大的調整。NAT方式。

虛擬網橋(Virtual Bridge):這種方式要比用戶網絡複雜一些,但是設置好後客戶機與互聯網,客戶機與主機之間的通信都很容易。Bridge方式。

Bridge方式即虛擬網橋的網絡連接方式,是客戶機和子網裏面的機器能夠互相通信。可以使虛擬機成爲網絡中具有獨立IP的主機。橋接網絡(也叫物理設備共享)被用作把一個物理設備複製到一臺虛擬機。網橋多用作高級設置,特別是主機多個網絡接口的情況。

在這裏插入圖片描述
在Linux中的虛擬機的網卡都包含前半段和後半段,前半段在虛擬機上,後半段在宿主機上。上圖eth0爲虛擬機上的網卡,對應的後半段爲vnet0,vnet0爲tap設備。在虛擬機上所有發往eth0的數據就直接發往vnet0了,也可以將vnet0看作一塊網卡。

在宿主機中創建一個橋設備,把宿主機的eth0放在橋上,這樣虛擬機上的eth0將報文發給vnet0,再直接發給宿主機上的eth0,將源地址改爲宿主機上的eth0的地址

當響應報文到達物理機上的eth0時如何判斷此響應報文是發給虛擬機的還是物理機自己的?

物理機會先創建一個虛擬網卡,在物理機上打開混雜模式(無論mac地址是不是自己的都將接收響應報文),如果mac地址是自己的則轉發給虛擬網卡,如果不是自己的則轉發給vnet0,這就是橋接模型,因爲物理機的網卡具有橋的功能所以叫做橋接模型。

5. Qemu全虛擬化網橋模式下的VM的收發包的流程

在這裏插入圖片描述
如圖中所示,紅色箭頭表示數據報文的入方向,步驟:

  1. 網絡數據從 Host 上的物理網卡接收,到達網橋;
  2. 由於 eth0 與 tap1 均加入網橋中,根據二層轉發原則,br0 將數據從tap1 口轉發出去,即數據由 Tap設備接收;
  3. Tap 設備通知對應的 fd 數據可讀; fd 的讀動作通過 tap
  4. 設備的字符設備驅動將數據拷貝到用戶空間,完成數據報文的前端接收。

6. 準虛擬化(Para-virtualizaiton) I/O 驅動 virtio

KVM/QEMU 的 vitio 實現採用在 Guest OS 內核中安裝前端驅動 (Front-end driver)和在 QEMU 中實現後端驅動(Back-end)的方式。前後端驅動通過 vring 直接通信,這就繞過了經過 KVM 內核模塊的過程,達到提高 I/O 性能的目的。純軟件模擬的設備和 Virtio 設備的區別:virtio 省去了純模擬模式下的異常捕獲環節,Guest OS 可以和 QEMU 的I/O 模塊直接通信。Vitio需要讓客戶機知道自己運行在虛擬化環境中。

使用Virtio的完整虛擬機I/O流程:
在這裏插入圖片描述
Host 數據發到 Guest:

  1. KVM 通過中斷的方式通知 QEMU 去獲取數據,放到 virtio queue 中

  2. KVM 再通知 Guest 去 virtio queue 中取數據。

7. Vhost-net驅動

virtio在宿主機中的後端處理程序(backend)一般是由用戶空間的QEMU提供的,然而如果對於網絡 I/O 請求的後端處理能夠在在內核空間來完成,則效率會更高,會提高網絡吞吐量和減少網絡延遲。在比較新的內核中有一個叫做 “vhost-net” 的驅動模塊,它是作爲一個內核級別的後端處理程序,將virtio-net的後端處理任務放到內核空間中執行(在Host Kernel中直接實現了virtio設備的模擬),減少內核空間到用戶空間的切換,從而提高效率。

virtio-net 和 vhost-net的比較:
在這裏插入圖片描述

備註:當客戶機通過DMA (Direct Memory Access)訪問大塊I/O時,QEMU 模擬程序將不會把結果放進共享頁中,而是通過內存映射的方式將結果直接寫到客戶機的內存中,然後通知KVM模塊告訴客戶機DMA操作已經完成。

8. 結論:

綜上,虛擬機網卡eth0存在於虛擬機上(即guest),網橋tap設備則存在於宿主機(即host)上,是兩個設備。這兩個設備是一對設備,同時出現、同時消失,組合在一起完成虛擬機和外部的通信。兩個設備通過host上的/dev/net/tun設備、內核網卡驅動、共享隊列實現數據包的通信。
在這裏插入圖片描述
原文鏈接:https://blog.csdn.net/xiakewudi/article/details/76851076

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章