Virtio es un controlador paravirtualizado, lo que significa que el sistema operativo y el controlador saben que no es un dispositivo físico. El controlador es realmente una API entre el invitado y el hipervisor, por lo que su velocidad está totalmente desconectada de cualquier dispositivo físico o estándar de Ethernet.
Esto es bueno ya que es más rápido que el hipervisor que finge ser un dispositivo físico y aplica un concepto arbitrario de "velocidad de enlace" para fluir.
La máquina virtual simplemente descarga tramas en un bus y es el trabajo del anfitrión ocuparse de los dispositivos físicos; no es necesario que la VM sepa o se preocupe por la velocidad de enlace de los dispositivos físicos del host.
Una de las ventajas de esto es que cuando los paquetes se mueven entre 2 VM en el mismo host, pueden enviar paquetes tan rápido como la CPU del host puede moverlos de un conjunto de memoria a otro, establecer una "velocidad de enlace" aquí solo pone un límite de velocidad innecesario.
Esto también permite que el host haga equipos de adaptadores y distribuya el tráfico a través de múltiples enlaces sin que cada máquina virtual deba configurarse explícitamente para obtener el ancho de banda completo de la configuración.
Si desea saber qué tan rápido puede transferir datos desde su VM a otra ubicación, debe realizar pruebas de rendimiento real con herramientas como iperf
.
Para extenderme un poco en esto porque recientemente entré en esto y también estaba medio confundido por la falta de detalles de velocidad al ejecutar ethtool
en una máquina virtual:
$ ethtool eth0
Settings for eth0:
Link detected: yes
Cuando investigué lshw
salida:
$ lshw -class network -short
H/W path Device Class Description
==========================================================
/0/100/3 network Virtio network device
/0/100/3/0 eth0 network Ethernet interface
Esto nos dice que el controlador de dispositivo que se usa para esta VM está virtualizado, en este caso, se trata de una VM que se ejecuta en KVM, por lo que la VM usa los controladores virtio_* para todas sus interacciones con el "hardware".
$ lsmod | grep virt
virtio_rng 13019 0
virtio_balloon 13864 0
virtio_net 28096 0
virtio_console 28066 1
virtio_scsi 18453 2
virtio_pci 22913 0
virtio_ring 22746 6 virtio_net,virtio_pci,virtio_rng,virtio_balloon,virtio_console,virtio_scsi
virtio 14959 6 virtio_net,virtio_pci,virtio_rng,virtio_balloon,virtio_console,virtio_scsi
Estos módulos del kernel están disponibles para ciertos sistemas operativos (Linux, BSD y Windows). Con estos controladores instalados en su VM, el kernel de su VM tiene acceso especial al hardware subyacente a través del kernel que se ejecuta en su hipervisor.
Recuerde que con los hipervisores hay 2 tipos distintos. ESX/vsphere se consideran de tipo 1. Recordatorio sobre los tipos:
- Hipervisores tipo 1, nativos o bare-metal
- Tipo 2 o hipervisores alojados
KVM es más parecido a un tipo 2, pero tiene algunos elementos, como virtio_*, que hacen que se comporte y funcione más como un tipo 1, al exponer a la virtualización el kernel Linux subyacente del hipervisor de tal manera que las máquinas virtuales puede tener acceso semi-directo a ella.
¿La velocidad de mi NIC?
Dado que está ejecutando en un hipervisor paravirtualizado, debe acceder al hipervisor real para averiguar la velocidad teórica de su NIC usando ethtool
. En lugar de eso, solo puede averiguarlo haciendo algo como usar iperf
para comparar la NIC bajo carga y descubrir experimentalmente cuál parece ser la velocidad de la NIC.
Por ejemplo, aquí tengo 2 servidores que se ejecutan en 2 hipervisores diferentes. Usando iperf
en ambos servidores:
$ sudo yum install iperf
Luego, ejecutar un servidor como un iperf
servidor en host1 VM:
host1$ iperf -s
------------------------------------------------------------
Server listening on TCP port 5001
TCP window size: 85.3 KByte (default)
------------------------------------------------------------
Luego, en un cliente VM host2:
host2$ iperf -c 192.168.100.25
------------------------------------------------------------
Client connecting to 192.168.100.25, TCP port 5001
TCP window size: 85.0 KByte (default)
------------------------------------------------------------
[ 3] local 192.168.100.101 port 55854 connected with 192.168.100.25 port 5001
[ ID] Interval Transfer Bandwidth
[ 3] 0.0-10.0 sec 10.0 GBytes 8.60 Gbits/sec
En la salida de host1 verás esto:
$ iperf -s
------------------------------------------------------------
Server listening on TCP port 5001
TCP window size: 85.3 KByte (default)
------------------------------------------------------------
[ 4] local 192.168.100.25 port 5001 connected with 192.168.100.101 port 55854
[ ID] Interval Transfer Bandwidth
[ 4] 0.0-10.0 sec 10.0 GBytes 8.60 Gbits/sec
Aquí podemos ver que la NIC pudo subir a 8,60 Gbits/seg.