NVX runs Azure Linux 3.0 userland on its own Linux kernel. It builds one
artifact, initramfs-azurelinux.cpio.gz, which nvx.py run --guest azurelinux
boots for an interactive shell or a workload. The artifact boots no Azure Linux
kernel, firmware, or systemd, and it does not change the
machine and device ABI.
Build, Run, and the command-line reference cover the commands. This chapter describes how the pieces fit together and why.
The Azure Linux initramfs is a workload guest, not a sandbox control
environment. Alpine remains the default guest of run and the only control
environment of sandbox:
- the initramfs omits the sandbox init agent, so the common
/initrefuses sandbox mode; - the microVM test harness rejects the sandbox-control scenarios for Azure Linux; and
build-distro-layeraccepts only Ubuntu, so there is no Azure Linux sandbox layer.
A restore takes the guest from the captured RAM and machine contract, so run
rejects --guest azurelinux together with --restore-snapshot.
The initramfs boots the same build/vmlinux as Alpine and Ubuntu. The
Ubuntu chapter describes what that kernel
provides and omits. Azure Linux support therefore means Azure Linux userland
under the NVX kernel policy, not compatibility with every Azure Linux
workload.
The initramfs is built only with Docker: build-initramfs --guest azurelinux
and build-guest with Azure Linux selected use the Docker build, and
build-guest --native refuses Azure Linux. The
Dockerfile defines the build from pinned inputs:
- Base image: the Azure Linux 3.0
base/corecontainer image from MCR, pinned by digest.SOURCE-MANIFEST.jsonrepeats the release, image, and package-lock digest, andscripts/nvx.py verifyfails when they disagree with the build constants. - Supplemental packages from the lock in
azurelinux/packages.lock.json, which addsbusyboxandutil-linux, the source ofsetpriv, with their dependencies. Each entry records the RPM's name, version, release, architecture, URL, and SHA-256. The lock must name the same release, architecture, and base image as the build, and every URL must point into the Azure Linux 3.0 base repository onpackages.microsoft.com.
The build then:
- downloads each locked RPM and verifies its SHA-256;
- inside the pinned base image, imports the Microsoft RPM signing key,
checks every RPM signature, installs the RPMs, and requires
ldd,setpriv, and BusyBox to be present; - records the installed RPM inventory for the package manifest;
- installs the common NVX
/init, the guest scripts it needs, and statically linked helpers built fromguest/common, so the helpers do not depend on Azure Linux libraries; - links the BusyBox applets that the shared guest scripts expect, including
/bin/sh; every other command resolves to the Azure Linux packages; - gives the
nobodyaccount, UID 65534, the empty home/nonexistentinstead of/dev/null, because workload identities need an existing home directory; and - removes the RPM and package-manager databases and caches, which record install-time state.
The archive is packed with root ownership, timestamps set to the Unix epoch, a sorted file order, and no compression timestamp, so a rebuild from the same inputs is intended to be byte-identical. Unlike the Ubuntu artifacts, no automated check compares two Azure Linux rebuilds.
The Azure Linux initramfs boots like the Alpine one at the machine level:
OpenVMM loads the kernel and initramfs through the
Linux direct MP-table loader,
and the common /init runs as PID 1. It runs the
same boot steps as for the other guests, including the
time ABI boot step, and then runs an nvx_exec
workload, starts the managed agent, or opens a shell. The managed agent runs
the workload directly in the initramfs root, not in a separate layer. On the
shell path, /init reads the guest identity from /etc/os-release, stops on
an unknown one, prints NVX-GUEST-BOOT-OK: azurelinux, and starts the
BusyBox shell.
The guest defaults to 512 MiB, like Ubuntu, because the kernel unpacks the initramfs into a RAM filesystem capped at half of guest memory; see Run.
The package manifest initramfs-azurelinux.cpio.gz.packages.json records the
release, architecture, base image, input digest, and artifact SHA-256. Each
package entry names the RPM's version, release, architecture, license, and
source RPM. The manifest also records the source and binary digests of the
freestanding device-I/O helper. The input digest is a domain-separated SHA-256
over the release, architecture, base image, and the checkout files that define
the build: the Dockerfile, the package lock, the build modules that download
the RPMs and compute the digest, and guest/common.
Release staging rejects a manifest that does not match the artifact, the base
image, or the current inputs. Only binary-only packages carry the two Azure
Linux files; the published platform releases are binary-only, and download
installs them. collect-sources does not collect Azure Linux corresponding
source, so package --include-source omits the guest; see
Package and source delivery and the
release layout.
CI rebuilds the initramfs in Docker when its inputs change. The microVM test workflow runs Azure Linux boot, identity, console exit, network, network snapshot, workload identity, and managed lifecycle scenarios with one processor on every backend. Azure Linux is not part of the performance gates.