feat: add guest network autoconfiguration via Firecracker MMDS
Introduces optional per-clone IP assignment using the Firecracker Microvm
Metadata Service (MMDS). A background daemon (fc-net-init) is baked into
the rootfs during init and captured in the golden snapshot — on clone
resume it polls 169.254.169.254 and applies the IP/GW/DNS config injected
by the orchestrator immediately after snapshot restore.
- config.go: add AutoNetConfig bool (FC_AUTO_NET_CONFIG=1)
- orchestrator.go: embed fc-net-init daemon + MMDS link-local route in
init script; set AllowMMDS: true on golden NIC; spawnOne/SpawnSingle
accept net bool and propagate it via FC_AUTO_NET_CONFIG in proxy env
- console.go: set AllowMMDS: true on clone NIC; call configureMmds()
after m.Start() when AutoNetConfig is enabled
- network.go: add configureMmds() — PUT /mmds with ip/gw/dns over the
clone's Firecracker Unix socket
- serve.go: POST /clones accepts optional {"net": bool} body to override
the global AutoNetConfig default per-request
- web/terminal.html: spawn button always sends {"net": true}
- docs/commands.md: document manual config + MMDS autoconfiguration
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -35,8 +35,9 @@ All tunables are set via environment variables. Every variable has a default; no
|
||||
| `FC_MEM_MIB` | `128` | Memory per VM in MiB |
|
||||
| `FC_BRIDGE` | `fcbr0` | Host bridge name. Set to `none` to disable all networking |
|
||||
| `FC_BRIDGE_CIDR` | `172.30.0.1/24` | IP address and prefix assigned to the host bridge |
|
||||
| `FC_GUEST_PREFIX` | `172.30.0` | IP prefix for guest address allocation |
|
||||
| `FC_GUEST_GW` | `172.30.0.1` | Default gateway advertised to guests |
|
||||
| `FC_GUEST_PREFIX` | `172.30.0` | IP prefix for guest address allocation (used with `FC_AUTO_NET_CONFIG`) |
|
||||
| `FC_GUEST_GW` | `172.30.0.1` | Default gateway advertised to guests (used with `FC_AUTO_NET_CONFIG`) |
|
||||
| `FC_AUTO_NET_CONFIG` | _(unset)_ | Set to `1` to automatically assign guest IPs via MMDS on clone start |
|
||||
|
||||
Kernel boot arguments are hardcoded and not user-configurable:
|
||||
|
||||
@@ -95,10 +96,49 @@ When `FC_BRIDGE` is not `none` (the default), a Linux bridge and per-VM TAP devi
|
||||
└── fctapN (clone N)
|
||||
```
|
||||
|
||||
Each clone receives a unique TAP device and MAC address (`AA:FC:00:00:XX:XX`). IP assignment inside the guest is the guest OS's responsibility (the rootfs init script only brings `eth0` up; no DHCP server is included).
|
||||
Each clone receives a unique TAP device and MAC address (`AA:FC:00:00:XX:XX`). The host-side bridge has NAT masquerading enabled so guests can reach the internet through the host's default route.
|
||||
|
||||
Set `FC_BRIDGE=none` to skip all network configuration. VMs will boot without a network interface.
|
||||
|
||||
### Guest IP assignment
|
||||
|
||||
The rootfs init script brings `eth0` up at the link layer only. Guests have no IP address by default. There are two ways to configure networking inside a VM:
|
||||
|
||||
#### Manual configuration (inside the VM console)
|
||||
|
||||
```sh
|
||||
# Pick an unused IP in the bridge subnet — e.g. .11 for clone 1, .12 for clone 2
|
||||
ip addr add 172.30.0.11/24 dev eth0
|
||||
ip route add default via 172.30.0.1
|
||||
echo "nameserver 1.1.1.1" > /etc/resolv.conf
|
||||
ping 1.1.1.1 # verify
|
||||
```
|
||||
|
||||
Manual config is ephemeral — it is lost when the clone is stopped. Use the automatic option below for persistent configuration.
|
||||
|
||||
#### Automatic configuration via MMDS (`FC_AUTO_NET_CONFIG=1`)
|
||||
|
||||
When `FC_AUTO_NET_CONFIG=1` is set, the orchestrator uses the Firecracker **Microvm Metadata Service (MMDS)** to inject per-clone network config immediately after the VM starts. A small background daemon embedded in the rootfs (`/sbin/fc-net-init`) polls `169.254.169.254` and applies the config automatically — no manual steps needed.
|
||||
|
||||
IPs are assigned deterministically from `FC_GUEST_PREFIX`:
|
||||
|
||||
```
|
||||
clone 1 → 172.30.0.11/24
|
||||
clone 2 → 172.30.0.12/24
|
||||
…
|
||||
clone N → 172.30.0.(10+N)/24
|
||||
```
|
||||
|
||||
Usage:
|
||||
|
||||
```sh
|
||||
sudo FC_AUTO_NET_CONFIG=1 ./fc-orch start
|
||||
```
|
||||
|
||||
Within ~1–2 seconds of clone start, `eth0` inside the VM will have the assigned IP, default route, and DNS (`1.1.1.1`) configured.
|
||||
|
||||
> **Note:** `FC_AUTO_NET_CONFIG` requires `fc-orch init` and `fc-orch golden` to have been run (or re-run) after this feature was added, so that the `fc-net-init` daemon is present in the golden snapshot.
|
||||
|
||||
---
|
||||
|
||||
## `init`
|
||||
@@ -511,13 +551,27 @@ The following steps are performed once for each requested clone. Let `{id}` be t
|
||||
|
||||
Restoration time (from `m.Start` call to return) is measured and logged.
|
||||
|
||||
11. **Record PID**
|
||||
11. **Inject network config via MMDS** (only when `FC_AUTO_NET_CONFIG=1` and networking is enabled)
|
||||
|
||||
Immediately after the snapshot is restored, the orchestrator configures the MMDS for this clone via two API calls to the clone's Firecracker socket:
|
||||
|
||||
```
|
||||
PUT /mmds/config
|
||||
{"version": "V1", "network_interfaces": ["1"]}
|
||||
|
||||
PUT /mmds
|
||||
{"ip": "172.30.0.{10+id}/24", "gw": "172.30.0.1", "dns": "1.1.1.1"}
|
||||
```
|
||||
|
||||
The `fc-net-init` daemon already running inside the guest (started during golden VM boot, captured in the snapshot) polls `169.254.169.254` via a link-local route and applies the config to `eth0` within ~1 second of clone resume.
|
||||
|
||||
12. **Record PID**
|
||||
|
||||
```sh
|
||||
echo {pid} > /tmp/fc-orch/pids/clone-{id}.pid
|
||||
```
|
||||
|
||||
12. **Register clone in memory**
|
||||
13. **Register clone in memory**
|
||||
|
||||
The running clone is tracked in an in-process map keyed by clone ID, holding the Firecracker SDK handle, context cancel function, and TAP device name. This allows `kill` to cleanly terminate clones started in the same process invocation.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user