Connecting a Cloud Hypervisor guest to the internet using NAT
Cloud Hypervisor is a Virtual Machine Monitor (VMM) for modern cloud workloads. Recently, I found myself in the need of a simple way to connect a Cloud Hypervisor guest to the internet. Unfortunately, no such method has been documented in the in-tree documentation. So, I set out experimenting with iptables and NAT (network address translation). After playing around with the iptables rules required to set this up I finally arrived at a simple setup that worked.
For this to work, Cloud Hypervisor needs to be started with the --net
argument like so:
cloud-hypervisor \
--kernel ./vmlinux.bin \
--cmdline "console=ttyS0 root=/dev/vda1 rw" \
--disk path=/home/cloud/focal-server-cloudimg-amd64.raw path=/home/cloud/ubuntu-cloudinit.img \
--cpus boot=8 \
--memory size=0 \
--memory-zone id=mem0,size=4G,host_numa_node=0 \
--net "tap=,mac=12:34:56:78:90:ab,ip=192.168.249.1,mask=255.255.255.0" \
--serial tty \
--console off
When tap=
is left empty, Cloud Hypervisor will create a tap device with the default naming vmtapN
where N is 0,1,2,3 and so on. mac=
can be any valid MAC address. The ip=
value will later be the default gateway IP for the guest.
Let's say the host is connected to the internet via the eth0 interface. We need to define iptables rules to enable traffic to be routed between vmtap0 and eth0. Here are the rules:
sudo iptables -A INPUT -i vmtap0 -j ACCEPT
sudo iptables -A INPUT -i vmtap0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A FORWARD -i eth0 -o vmtap0 -j ACCEPT
sudo iptables -A FORWARD -i vmtap0 -o eth0 -j ACCEPT
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
Next, configure a static IP for the guest via cloud-init
. Here are the contents of my cloud-init
network-config
file:
version: 2
ethernets:
id0:
match:
macaddress: 12:34:56:78:90:ab
addresses: [192.168.249.55/24]
gateway4: 192.168.249.1
The above file configures 192.168.245.55 as the guest IP.
The last thing to do is to configure a DNS server in the guest (/etc/resolv.conf
). Configure any public DNS server you like.
And that's it! The guest should now be able to connect to the internet.
Comments
Post a Comment