Custom Network Configuration
Limited Access
Custom network configuration is a new feature which is available to enterprise customers, and is coming soon to the hosted platform. If you would like to try it out now, please reach out to the Unikraft Cloud Discord or send an email to support@unikraft.com.
By default, Unikraft Cloud gives every instance a single network interface, allocated from the platform's address and TAP device pool. Custom network configuration lets you take control of this setup. It allows you to attach up to four interfaces, supply your own IP addresses, MAC addresses, and TAP devices, or take an interface with no address at all. You can also override the gateway and nameserver that the guest uses.
This is the building block for private networking between your instances, and for the network shield and relay.
Dedicated unikraft CLI subcommands for custom network configuration are coming soon.
In the meantime, configure custom network configuration through the API, which you can invoke with curl or the unikraft api command.
How it works
You describe an instance's networking when you create it, through three optional fields:
network_interfaces: a list of one to four interfaces to attach.gateway: the default gateway to configure inside the guest.nameserver: the DNS resolver to configure inside the guest.
The first interface in the list is the primary interface. It has a special role:
- The
private_ipfield reported for the instance always comes from the primary interface. - The proxy forwards incoming traffic to the IP of the primary interface.
- The controller ignores any port announcements from the guest that aren't for the primary interface's IP.
Leaving out network_interfaces is the same as requesting a single pool-allocated interface, so "network_interfaces": [{}] and omitting the field entirely behave identically.
Creating an instance with custom interfaces
Add a network_interfaces array to your POST /instances request:
Code
Each entry in network_interfaces accepts the following fields:
| Field | Required | Description |
|---|---|---|
name | No | The interface name. If omitted, Unikraft Cloud generates one as <instance-name>-ethX, falling back to eth-<suffix> when the instance name is too long. |
ip | No | The interface IP address in CIDR notation. |
mac | No | The interface MAC address as hh:hh:hh:hh:hh:hh, see custom MAC addresses. |
tap_name | No | The TAP device to attach the interface to (15 characters or less), which on its own gives you an interface without an address. |
autoconfig | No | Whether the platform configures the interface inside the guest, as described under autoconfiguration. |
relay | No | An object that routes all traffic through another interface, as described under network shield and relay. |
An ip and a mac each require a tap_name, while a tap_name on its own is enough.
When you omit all three, Unikraft Cloud allocates the interface, its address, and its MAC from the platform's own pools.
Each value you supply has to stay outside the matching pool: the platform's address ranges for an ip, its 12:b0: prefix for a mac, and its TAP device names for a tap_name.
The TAP device itself is yours to create: Unikraft Cloud attaches the interface to a device that already exists.
Nothing caps a custom network at a /30, though a /31 or a /32 leaves the platform no address to derive a gateway or nameserver from.
The top-level gateway and nameserver fields override the values configured inside the guest.
If you omit them, Unikraft Cloud derives them from the last usable address in the IP network of the first pool-allocated interface.
An instance whose interfaces are all custom gets neither, so supply both fields or configure them in the guest.
Like other object names, an interface name is global to your account, not local to the instance.
This lets you reference one instance's interface from another.
Custom MAC addresses
By default the platform sets an interface's MAC address.
Pass the mac field to pick the address yourself, so a guest that derives its licensing, clustering, or peer identity from its MAC address stays recognizable across recreations of the instance:
Code
Write the address as hh:hh:hh:hh:hh:hh, without shorthand groups or surrounding whitespace, and observe two rules:
- The address has to be unicast, so its first octet has to be even.
- The address has to sit outside the platform's own pool, so it must not start with
12:b0:.
A mac requires a tap_name.
Whether you pick the address or leave it to the platform, GET /instances reports the address each interface ended up with as the mac field of its entry in network_interfaces.
Interfaces without an address
An interface that carries a tap_name but no ip gives the guest a link on your TAP device with no address on it:
Code
This is what a fully customer-managed network needs—an external IPAM, a CNI plugin, or a virtual appliance that handles its own addressing. Your side provides the TAP device and decides the addressing on it, and the platform only attaches the guest's interface to that device.
A CNI plugin can also supply the link's addressing without requiring your application or image to configure it.
Write the plugin's result into the instance's unikraft.com/cni annotation, and the guest matches the addresses in it to this interface by MAC address and configures them itself.
Such an interface differs from an addressed one in three ways:
autoconfighas to befalse, because the platform has no address to configure in the guest.- The interface reports no
private_ip, and neither does the instance when the address-less interface is its primary one. - The platform keeps the interface out of the internal DNS and routes no service traffic to it.
The platform also never derives a gateway or nameserver from a custom interface's network.
Set the instance-level gateway and nameserver fields, or configure both inside the guest.
Autoconfiguration
autoconfig decides whether the platform configures the interface inside the guest.
With it on, the platform hands the guest the interface's address—together with the gateway, nameserver, and hostname—at boot, and the guest brings the interface up with them.
With it off, the platform passes nothing and skips the interface, so your app or image sets up networking on its own.
It defaults to on for the default pool-allocated interface and for any interface with an ip.
An interface without one has to keep it off, because the platform then has no address to configure in the guest.
Network shield and relay
An interface can route all its traffic through another instance's interface, which is how the network shield filters a workload's traffic and injects secrets on its behalf.
Configure it with the relay field of a network_interfaces entry.
Both ends of a relay have to be interfaces that Unikraft Cloud allocates, meaning entries where you set no ip, mac, or tap_name of your own.
Error handling
| Error message | Cause |
|---|---|
Insufficient license. Please make sure your license is valid and includes custom network configurations | Your account's license doesn't include custom network configuration. |
Network interface IP and MAC address require a TAP device | You set ip or mac without a tap_name, so either add the TAP device or drop the address. |
Network interface IP address cannot be from the platform's address pool | The ip overlaps the platform's managed address pool. Use an address outside it. |
Network interface TAP device cannot be from the platform's device pool | The tap_name refers to a platform-managed TAP device. Use one of your own. |
Invalid MAC address '<value>' | The mac isn't a hh:hh:hh:hh:hh:hh address, or it's all-zero, which the platform reads as an omitted field. |
Network interface MAC address must be a unicast address | The mac has its multicast bit set, so choose an address whose first octet is even. |
Network interface MAC address cannot be from the platform's address pool | The mac starts with 12:b0:, which the platform reserves for the addresses it derives itself. |
Network interface without an IP address cannot be auto-configured in the guest | You set autoconfig to true on an interface without an ip, which has to keep autoconfiguration off. |
Network interface without an IP address cannot use a relay | You configured a relay on an interface without an ip, and the relay datapath keys on the client interface's address. |
Invalid relay '<interface>'. Please make sure the relay exists and does not create a circular dependency | The interface named as the relay doesn't exist, already relays through another interface, or is itself a custom interface. |
Unknown member 'network_interfaces' | Your account lacks the net_manager permission required for this feature. |
Limitations
- An instance can have at most four network interfaces.
- The feature requires the
net_managerpermission and a license that includes it (see the note at the top of this page). - Creating a template from an instance drops its network configuration, since binding a template to a specific TAP device or IP defeats the purpose of cloning many instances from it.
- You currently can't branch or checkpoint an instance with more than one interface.
- The relay feature works between pool-allocated interfaces only, on both ends.
- The create call sets the configuration once; no PATCH support exists yet.
Learn more
- Network shield and relay: route an instance's traffic through another instance that filters it and injects credentials.
- Annotations: hand a CNI result to the guest through the
unikraft.com/cniannotation, and let it address its own interfaces. - Kubernetes: how Kraftlet runs the CNI plugins of your cluster for Unikraft Cloud instances.
- Instances: how instances work, including their lifecycle and configuration.
- Branching and Checkpoints: create independent copies and reusable restore points of running instances.
- Instance templates: reusable images that you clone into new instances.
- Unikraft Cloud's REST API reference, in particular the section on instances.