A simple network setup
While networking infrastructure is out of scope for the microvm.nix flake, here is some guidance for providing the MicroVMs on your NixOS machine with internet access.
Use this for your local LAN where IP addresses are free and plentiful. If not, head over to the advanced networking page.
Because we already use systemd for MicroVM startup, let's pick
systemd-networkd
:
networking.useNetworkd = true;
A bridge to link TAP interfaces
To make your MicroVM reachable, the host will place its Ethernet port (eno1
)
on a bridge (br0
). This bridge will have the MicroVM's TAP interface attached
to it - directly placing the MicroVM on your local network.
Note that the addresses provided below are examples and you must adjust these
for your network settings. Also note that the eno1
must be attached to the
bridge with the vm-*
TAP interfaces that you will specify in the MicroVM
definition.
systemd.network.enable = true;
systemd.network.networks."10-lan" = {
matchConfig.Name = ["eno1" "vm-*"];
networkConfig = {
Bridge = "br0";
};
};
systemd.network.netdevs."br0" = {
netdevConfig = {
Name = "br0";
Kind = "bridge";
};
};
systemd.network.networks."10-lan-bridge" = {
matchConfig.Name = "br0";
networkConfig = {
Address = ["192.168.1.2/24" "2001:db8::a/64"];
Gateway = "192.168.1.1";
DNS = ["192.168.1.1"];
IPv6AcceptRA = true;
};
linkConfig.RequiredForOnline = "routable";
};
Now that the host is configured, you can define a MicroVM to have a static IP address with:
microvm = {
#...add additional MicroVM configuration here
interfaces = [
{
type = "tap";
id = "vm-test1";
mac = "02:00:00:00:00:01";
}
];
};
systemd.network.enable = true;
systemd.network.networks."20-lan" = {
matchConfig.Type = "ether";
networkConfig = {
Address = ["192.168.1.3/24" "2001:db8::b/64"];
Gateway = "192.168.1.1";
DNS = ["192.168.1.1"];
IPv6AcceptRA = true;
DHCP = "no";
};
};
Docker and systemd-network
If you use the above systemd.network
bridge config and wish to run
Docker containers inside your microvms using virtualisation.docker
,
you may need to add the following snippet to stop systemd-networkd
from
managing the bridged veth*
interfaces Docker creates for each container.
Without this, network access inside the containers will be broken.
systemd.network.networks."19-docker" = {
matchConfig.Name = "veth*";
linkConfig = {
Unmanaged = true;
};
};
Advanced: Improving Performance
If you prioritize network performance over inter-VM communication on the virtual bridge, have a look into these alternatives:
-
Network interfaces with
type = "macvtap"
are supported in microvm.nix. While they're technically tap devices, they attach to an external Ethernet port, eliminating thebr0
bridge. -
Server Ethernet cards support SR-IOV: setup Virtual Function devices for PCI passthru into MicroVMs.