Skip to content

Networking modes for Slicer microVMs

The Firecracker, QEMU, and Cloud Hypervisors use TAP devices for networking. A Linux TAP operates at Layer 2 (Data Link Layer), one end is attached to the microVM, and the other end is attached to the host system.

Slicer supports multiple networking modes for microVMs, each with their own pros and cons. Generally, you should use the default option (Bridge Networking) unless you have specific requirements that need a different mode.

See slicer new --help to generate a Slicer config with bridge-based networking. You can also provide a CIDR block to allocate IP addresses from, if you need to run Slicer across different machines and have them all be routable on the local network.

How do you pick?

  • Bridge networking is the default - use it when you want to get started. It lets VMs talk to each other, so it's ideal for K3s where nodes need direct IP to IP access. The host can ingress to VMs via their IP.

  • Macvtap networking places VMs directly on your LAN as if they were physical machines. Use it for homelab clusters, appliances like Pi-hole, or any long-running services that need to be first-class citizens on your network. Supports both DHCP (router-assigned IPs) and static IP pools. Note that the host itself cannot reach VMs by IP in this mode.

  • Isolated networking is best when you're running appliances that are connected to the Internet, and can run untrusted workloads, or for other multi-tenant services. You can block VMs from egressing to specific IPs or entire CIDRs like your LAN i.e. 192.168.0.0/24. There is no ingress available other than via slicer forward or via network tunnels such as Inlets.

  • CNI mode is generally not recommended or required, but enables additional networking modes, and shares a single pool of IPs across all Slicer daemons running in this mode.

Bridge Networking

The default for Slicer is to use create a Linux bridge per Slicer daemon, and to attach all microVMs within that hostgroup to the bridge. This allows microVMs to communicate with each other and with the host system.

The bridge also makes the microVMs routable from outside the host system on the local network, subject to the other machine having direct access to the machine where the Slicer daemon is running, and adding a route to the microVM subnet.

Pros:

  • Default mode, and best tested option
  • Easy to route to microVMs from outside the host system
  • Allocate a fixed set of IP addresses, or allocate from a larger subnet

Cons:

  • microVMs can communicate with the host, and the rest of the LAN, which may not be desirable in some use-cases
  • There can be learning delays with a Linux bridge, so occasionally a microVM may boot up and not be able to resolve DNS for a few seconds

Example with IPs allocated from the subnet automatically:

slicer new vm \
  --count=3 \
  --cidr=192.168.137.0/24

This generates:

config:
  host_groups:
  - name: vm
    count: 3
    network:
      bridge: brvm0
      tap_prefix: vmtap
      gateway: 192.168.137.1/24

To specify a custom IP range within the subnet, use the --range flag:

slicer new vm \
  --count=3 \
  --cidr=192.168.137.0/24 \
  --range=192.168.137.20-192.168.137.80

This adds a range: 192.168.137.20-192.168.137.80 field to the network configuration in the YAML.

Alternatively, to assign from a static list of IP addresses, use the addresses field in YAML:

config:
  host_groups:
  - name: vm
    count: 3
    network:
      bridge: brvm0
      tap_prefix: vmtap
      gateway: 192.168.137.1/24
      addresses:
      - 192.168.137.2/24
      - 192.168.137.3/24
      - 192.168.137.4/24

CNI Networking

Container Network Interface (CNI) is a popular networking standard in the container ecosystem, and is used by OpenFaaS Edge (faasd), Kubernetes, and various other low-level projects.

Slicer ships with a CNI configuration that acts in a similar way to the bridge mode. Just like with the bridge mode, microVMs can communicate with each other and with the host system, and are routable from outside the host system on the local network.

The combination of bridge, and firewall CNI plugins are used in the default configuration, however you can also change this as needed for instance to bypass the bridge plugin and use something simpler like ptp.

Pros:

  • Network addresses are allocated from a large, fixed pool defined in a config file

Cons:

  • Reliance on CNI to manage networking
  • microVMs can communicate with the host, and the rest of the LAN, which may not be desirable in some use-cases
  • May also have learning delays like the bridge mode

Example:

config:
  host_groups:
    - name: vm
  network_name: "slicer"

To use CNI, leave off the network section of the hostgroup.

The slicer network is defined at: /etc/cni/net.d/51-slicer.conflist and can be edited. Additional named configs can be created and selected by changing the network_name field in the hostgroup config.

Isolated Mode Networking

In this mode, each microVM's TAP is created in a private network namespace, then connected to the host via a veth pair. Each VM is fully isolated from the others, from the host, and from the LAN.

Pros:

  • Built-in mechanism to block / drop all traffic to specific destinations
  • microVMs cannot communicate with each other
  • microVMs cannot communicate with the host system
  • microVMs cannot communicate with the rest of the LAN

Cons:

  • Newer mode, less tested than bridge or CNI modes
  • Additional complexity in managing the network namespaces and cleaning up all resources in error conditions or crashes
  • Maximum node group name including the suffix - and a number, can't be longer than 15 characters. I.e. agents-1 up to agents-1000 is fine, but isolated-agents-1 would not fit.

Quick start

The easiest way to use isolated mode is with slicer new — no IP range is needed:

slicer new sandbox --net=isolated

This generates a minimal config with no range: field. Slicer automatically derives a /22 subnet within 169.254.0.0/16 from the hostgroup name. Each /22 provides 256 usable /30 blocks (one per VM).

To add firewall rules at generation time:

slicer new sandbox --net=isolated --drop 192.168.1.0/24

The generated YAML looks like:

config:
  host_groups:
    - name: sandbox
      network:
        mode: "isolated"
        drop: ["192.168.1.0/24"]

This is safe to use with multiple Slicer daemons running on the same host — each hostgroup name hashes to a different subnet, and Slicer checks for IP collisions on host interfaces before assigning each /30 block, skipping any that are already in use.

Specifying an explicit range

If you prefer to control the exact subnet, you can specify a range: field. This is useful when you want deterministic IP assignments or need to coordinate ranges across many host groups manually.

config:
  host_groups:
    - name: sandbox
      network:
        mode: "isolated"
        range: "169.254.100.0/22"
        drop: ["192.168.1.0/24"]

A /22 range gives 256 usable /30 blocks. Each /30 contains 4 IPs: network, gateway, host (microVM), and broadcast.

When using explicit ranges with multiple host groups or multiple Slicer daemons on the same host, use non-overlapping subnets:

  • 169.254.100.0/22
  • 169.254.104.0/22
  • 169.254.108.0/22
  • 169.254.112.0/22

When Slicer is running on different hosts, you can re-use the same subnet ranges on different machines.

You can also pass an explicit range via slicer new:

slicer new sandbox --net=isolated --isolated-range 169.254.100.0/22

Drop and allow rules

The drop list contains CIDR blocks that should be blocked for all microVMs in this hostgroup. In the example above, all microVMs will have all traffic to the standard LAN network 192.168.1.0/24 dropped before it has a chance to leave the private network namespace.

Firewall

There is both a drop and an allow list that can be given in the networking section.

When only drop is given, all other traffic is allowed which hasn't been explicitly blocked.

When only allow is given, all other traffic is blocked which hasn't been explicitly allowed.

When neither drop, nor allow are given, then all traffic is allowed.

Additional configuration for Netplan

On Ubuntu 22.04 (Server), netplan can take over the veth pair that Slicer creates for the isolated network mode. NetworkManager doesn't tend to have this issue and ships with Ubuntu Desktop.

If you run into issues (confirmed by ip addr showing no IP on the ve- interfaces), run the following:

cat <<EOF | sudo tee /etc/systemd/network/00-veth-ignore.network > /dev/null
[Match]
Name=ve-* veth*
Driver=veth

[Link]
Unmanaged=yes

[Network]
KeepConfiguration=yes
EOF

Update /etc/systemd/networkd.conf as per the following:

cat <<EOF | sudo tee /etc/systemd/networkd.conf > /dev/null
[Network]
KeepConfiguration=yes
ManageForeignRoutes=no
#SpeedMeter=no
#SpeedMeterIntervalSec=10sec
#ManageForeignRoutingPolicyRules=yes
#ManageForeignRoutes=yes
#RouteTable=
#IPv6PrivacyExtensions=no

[DHCPv4]
#DUIDType=vendor
#DUIDRawData=

[DHCPv6]
#DUIDType=vendor
#DUIDRawData=
EOF

Then reload and restart Slicer and the isolated network mode microVMs:

sudo chmod 644 /etc/systemd/network/00-veth-ignore.network
sudo systemctl restart systemd-networkd

Macvtap Networking (Direct LAN Access)

Macvtap mode connects VMs directly to your LAN, making them appear as native network devices alongside your physical machines. The VMs can obtain IP addresses from your router's DHCP server, or you can configure a static IP pool managed by Slicer.

This mode works well for:

  • K3s Kubernetes clusters - Single-node or multi-node clusters that need stable, long-running infrastructure
  • Network appliances - Pi-hole for ad-blocking and DNS, DNS servers, DHCP servers
  • Authentication and identity services - Keycloak, LDAP servers, Active Directory
  • Server-type workloads - Any service that benefits from being a native LAN device

Pros:

  • VMs appear as native devices on your LAN with direct IP addresses
  • Works with existing network infrastructure (router DHCP, DNS)
  • No need to configure routes on other LAN devices to reach VMs
  • Supports both DHCP and static IP allocation
  • Stable MAC addresses enable DHCP reservations

Cons:

  • Host cannot directly reach VMs via their network IP (macvtap architecture limitation)

Requirements and Configuration

Image Requirements:

Macvtap networking requires standard Slicer images. Min images do not contain the DHCP client package (isc-dhcp-client on Ubuntu) by default. While the package can be added if needed, the standard image is preferred for this networking mode.

Both arm64 and x86_64 architectures are supported.

Parent Network Interface:

Macvtap requires a parent host network interface to attach VMs to your LAN. By default, Slicer automatically selects the host's primary network interface by querying the kernel routing table to determine which interface is used for outbound internet traffic.

If you need to explicitly select a different interface, you can override the automatic selection:

  • In YAML: Add parent: eth1 to the network: section
  • With slicer new: Use the --parent=eth1 flag

Example overriding the parent interface:

slicer new lan \
  --net=macvtap \
  --parent=eth1 \
  --count=1 \
> lan.yaml

This generates:

config:
  host_groups:
    - name: lan
      count: 1
      network:
        mode: macvtap
        parent: eth1

DHCP mode

In DHCP mode, your router's DHCP server assigns IP addresses to VMs automatically. The VMs appear as regular network devices on your LAN.

To generate a config with DHCP mode:

slicer new lan \
  --net=macvtap \
  --count=1 \
> lan.yaml

sudo -E slicer up lan.yaml

The generated YAML:

config:
  host_groups:
    - name: lan
      count: 1
      network:
        mode: macvtap

After the VMs boot, use slicer list to see the IP addresses assigned by your router's DHCP server.

Static IP pool mode

Static IP pool mode gives you predictable, stable IP addresses for your VMs.

When you specify a gateway CIDR, Slicer automatically allocates IPs from the .220-.254 range (35 addresses) at the end of your subnet. This range can be overridden using the --range flag to specify a custom pool.

# Example LAN: 192.168.1.0/24, gateway: 192.168.1.1
# Slicer will allocate 192.168.1.220-192.168.1.254
slicer new lan \
  --net=macvtap \
  --cidr=192.168.1.0/24 \
  --count=1 \
> lan.yaml

sudo -E slicer up lan.yaml

The generated YAML:

config:
  host_groups:
    - name: lan
      count: 1
      network:
        mode: macvtap
        gateway: 192.168.1.1/24

To use a custom range, add the --range flag with a start-end format (e.g., --range=192.168.1.100-192.168.1.200) which will add a range: field to the generated YAML.

Important: - Make sure the IP range is outside your router's DHCP pool to avoid conflicts - Replace 192.168.1.0/24 with your actual LAN CIDR in the command above - slicer new assumes the gateway is at .1 of the supplied CIDR. If your router's gateway uses a different address (e.g., .254), edit the gateway: field in the generated YAML before running slicer up

For full control over IP allocation, you can manually specify each IP address using the addresses: field:

config:
  host_groups:
    - name: lan
      count: 3
      network:
        mode: macvtap
        gateway: 192.168.1.1/24
        addresses:
          - 192.168.1.200
          - 192.168.1.201
          - 192.168.1.202

MAC address reservations

Slicer generates stable MAC addresses for each VM based on the VM's hostname. This means the same VM name always gets the same MAC address across restarts.

Once you know a VM's MAC address, you can create a DHCP reservation in your router to make the IP address "static" even when using DHCP mode. This gives you the flexibility of DHCP with the predictability of static IPs.

To find a VM's MAC address: - Check your router's DHCP client list - Run ip link inside the VM to view network interface details