/gvisor-tap-vsock

Primary LanguageGoApache License 2.0Apache-2.0

gvisor-tap-vsock

A replacement for VPNKit, written in pure Go.

How it works

Internet access

schema

  1. A tap network interface is running in the VM. It's the default gateway.
  2. User types curl redhat.com
  3. Linux kernel sends raw Ethernet packets to the tap device.
  4. Tap device sends these packets to a process on the host using vsock
  5. The process on the host maintains both internal (host to VM) and external (host to Internet endpoint) connections. It uses regular syscalls to connect to external endpoints.

Expose a port

schema

  1. The process on the host binds the port 80.
  2. Each time, a client sends a http request, the process creates and sends the appropriate Ethernet packets to the VM.
  3. The tap device receives the packets and injects them in the kernel.
  4. The http server receives the request and send back the response.

Build

make

Run

Host

Windows prerequisites

$service = New-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Virtualization\GuestCommunicationServices" -Name "00000400-FACB-11E6-BD58-64006A7986D3"
$service.SetValue("ElementName", "gvisor-tap-vsock")

More docs: https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/user-guide/make-integration-service

In the VM, be sure to have hv_sock module loaded.

Linux prerequisites

On Fedora 32, it worked out of the box. On others distros, you might have to look at https://github.com/mdlayher/vsock#requirements.

For CRC, the driver should be compiled with this patch: crc-org/machine-driver-libvirt#45.

macOS prerequisites

Please locate the hyperkit state (there is a file called connect inside) folder and launch host with the following env variable: VM_DIRECTORY=path_to_connect_directory

For CRC, the driver should be compiled with this patch: crc-org/machine-driver-hyperkit#12.

Run

(host) $ sudo bin/host -debug -logtostderr

VM

(host) $ scp bin/vm crc:
(host) $ scp setup.sh crc:
(vm terminal 1) $ sudo ./vm -debug -logtostderr
(vm terminal 2) $ ping -c1 192.168.127.1
(vm terminal 2) $ curl http://redhat.com

Internal DNS

Activate it by changing the /etc/resolv.conf file inside the VM with:

nameserver 192.168.127.1

Performance

Using iperf3, running the server on the host and the client in the VM, it can achieve 600Mbits/s.