Flatcar Container Linux on Azure User Guide
Overview
This guide covers the deployment, verification and day one operation of Flatcar Container Linux on Microsoft Azure, using the cloudimg virtual machine image from the Azure Marketplace.
Flatcar Container Linux is a minimal, immutable Linux distribution purpose-built to run containers. It is a friendly, actively maintained continuation of the CoreOS Container Linux lineage, developed in the open under the Cloud Native Computing Foundation (CNCF). Flatcar is designed to be operated as cattle, not pets: the operating system is read-only, it updates itself atomically, and everything you run on top of it runs in a container. This image ships the stable channel, version 4593.2.4, with Docker and containerd already present.
The defining characteristics are the main thing to understand before you deploy it:
/usris read-only. The operating system image is mounted read-only and delivered as a single verified unit. You do not patch it package by package — there is no package manager at all (nodnf,apt,yum,zypper,apkoremerge). You extend the system with containers, systemd units and configuration under the writable/etc,/optand/var.- It updates itself. Flatcar's
update_enginedownloads each new release to an inactive A/B partition and switches to it on reboot. This image leaves that mechanism on and pinned to the stable channel, so the machine stays current automatically without ever changing channels. - You provision it at boot. Azure's agent injects your SSH key into the
coreuser. No Ignition or customData is required for a normal SSH deployment.
What is included:
- Flatcar Container Linux stable 4593.2.4, the channel's current release, imported unmodified from the Flatcar project's own official Azure image (SHA-512 verified before import)
update_engineauto-update enabled and pinned to the stable channel, so the OS self-updates atomically via A/B partitions- Docker and containerd built in, ready to run containers immediately
- Secure by default: SSH is key-only (no password authentication), the root account password is locked, and only port 22 is reachable on the network
- SELinux enabled
- Per-virtual-machine identity: the machine ID and all SSH host keys are generated uniquely on each virtual machine's first boot — nothing is shared between customers
- No baked password, no bundled SSH key, no shared SSH host key and no swap on the operating system disk
- Generation 2 Hyper V (UEFI) virtual machine support
- 24/7 cloudimg support
Platform: Microsoft Azure (Generation 2 Hyper V / UEFI)
Default user: core
Default shell: /bin/bash
Recommended size: Standard_B2s (2 vCPU, 4 GB RAM) or larger
Licensing
Flatcar Container Linux is open-source software. The Flatcar project itself is licensed under Apache-2.0; the userland is assembled from open-source components under their individual OSI-approved licences (Apache-2.0, MIT, BSD, GPL, LGPL and others). Running Flatcar requires no licence key, no paid subscription, no registration and no support contract.
How this image is provisioned
Unlike a traditional distribution, Flatcar does not use cloud-init. On Azure the current image provisions through the Azure Linux Agent (waagent), which reads the SSH public key you supply at deployment and installs it for the core user. That means standard Azure provisioning works normally — including Azure VM extensions and az vm run-command, which are available on this image. If you prefer to drive provisioning declaratively you can also supply an Ignition configuration, but it is not required for SSH access.
Prerequisites
Before deploying this image, ensure you have:
- An active Microsoft Azure subscription
- Access to the Azure Portal or the Azure CLI
- An SSH key pair for Linux virtual machine access
- Familiarity with Azure virtual machine management and with running containers
Step 1: Deploy the virtual machine
Option A: Azure Portal
- Open the Azure Marketplace and search for "Flatcar Container Linux cloudimg"
- Select the image and click Create
- Configure the basics:
- Subscription: your Azure subscription
- Resource group: create a new one or select an existing one
- Virtual machine name: a name of your choosing
- Region: your preferred Azure region
- Size:
Standard_B2sor larger - Authentication type: SSH public key
- Username:
core - SSH public key source: use an existing key or let Azure generate one
- On the Disks tab choose your preferred OS disk type
- On the Networking tab allow inbound SSH (port 22) from your own address range only
- Review and create
Option B: Azure CLI
az vm create \
--resource-group myResourceGroup \
--name my-flatcar-vm \
--image <cloudimg-flatcar-container-linux-offer-urn> \
--size Standard_B2s \
--admin-username core \
--generate-ssh-keys \
--public-ip-sku Standard
Open SSH to your own address range only:
az vm open-port --resource-group myResourceGroup --name my-flatcar-vm --port 22
Step 2: Connect over SSH
The default user is core, and it has passwordless sudo:
ssh core@<public-ip>
sudo id
Step 3: Confirm which release and channel you are running
cat /etc/os-release
cat /usr/share/flatcar/release
uname -sr
Confirm the update channel this image is pinned to:
cat /etc/flatcar/update.conf
Step 4: Confirm the operating system is immutable
/usr is mounted read-only. This is the core property of the platform, and you can prove it:
mount | grep ' /usr '
There is no package manager, by design:
for pm in dnf apt yum zypper apk emerge; do command -v $pm >/dev/null 2>&1 && echo "present: $pm" || echo "absent: $pm"; done
You extend the system with containers and with configuration under the writable /etc, /opt and /var — not by installing packages into the OS.
Step 5: Confirm the automatic update mechanism
Flatcar keeps itself current by downloading each new stable release to an inactive partition and switching to it on reboot. Confirm the update engine is running:
systemctl is-active update-engine.service
update_engine_client -status
CURRENT_OP=UPDATE_STATUS_IDLE means the machine is up to date and watching for the next stable release. Because this is an image-based A/B update, there is no per-package upgrade list — the whole OS moves forward as one verified unit.
Step 6: Review the secure by default posture
Confirm the effective SSH configuration, which is what sshd actually applies:
sudo sshd -T | grep -E '^(passwordauthentication|permitrootlogin|kbdinteractiveauthentication|pubkeyauthentication) '
Password authentication is off and public key authentication is on. Confirm the root account has no usable password (the L status means locked):
sudo passwd -S root
Confirm the SSH host keys are unique to this virtual machine — they were generated on this machine at its first boot, not baked into the image, so no other customer's machine shares them:
for f in /etc/ssh/ssh_host_*_key.pub; do ssh-keygen -lf "$f"; done
Confirm the per-machine identifier is set:
cat /etc/machine-id
Confirm there is no swap on the operating system disk:
cat /proc/swaps
Now confirm what is actually listening on the network. The only externally reachable TCP port is 22; the loopback-only entries (systemd-resolved on 53, chrony on 323) are local services, not network-facing:
ss -tlnp
Confirm SELinux is enabled:
getenforce
Step 7: Run a container
Flatcar is a container host — Docker and containerd are already installed. Confirm the runtime and that the daemon is healthy:
docker --version
containerd --version
sudo docker info --format 'Server version: {{.ServerVersion}} | Containers: {{.Containers}} | Storage driver: {{.Driver}}'
List running containers (empty on a fresh image):
sudo docker ps
To run your own workload, pull and run any image, for example sudo docker run -d --name web -p 8080:80 nginx, and open the corresponding port in your network security group.
Step 8: Restrict SSH access
The image ships with SSH hardened, but the network boundary is yours to set. Restrict port 22 to your own address range in the network security group rather than leaving it open to the internet:
az network nsg rule update \
--resource-group myResourceGroup \
--nsg-name my-flatcar-vmNSG \
--name default-allow-ssh \
--source-address-prefixes <your-ip>/32
Step 9: Managing updates
By default this image self-updates within the stable channel and reboots when a new release is staged. Confirm the update configuration:
cat /etc/flatcar/update.conf
If you operate a cluster and want to coordinate reboots, Flatcar provides update_engine together with a reboot manager. To check the current update status at any time:
update_engine_client -status
To pause automatic reboots on a single machine (updates still download, but the reboot is deferred to you):
sudo systemctl stop locksmithd.service 2>/dev/null; echo "reboot coordination stopped on this machine; the staged update applies on your next manual reboot"
Keeping the default behaviour is recommended so the operating system stays patched automatically.
Step 10: Serial console recovery
The Azure serial console is available as an out of band recovery path. Confirm the kernel is booted with a serial console:
cat /proc/cmdline
To use it, open your virtual machine in the Azure Portal and select Help → Serial console. Because this image ships with no password set for any account (the secure default), the serial console offers a login prompt that no password will satisfy until you set one. If you want serial console recovery as an option, set a password for the core user with sudo passwd core before you need it. SSH password authentication stays off regardless, so the password is only usable on the serial console.
Troubleshooting
Cannot connect over SSH. Confirm the network security group allows port 22 from your address, and that you are using the private key matching the public key you gave Azure at deployment, connecting as core. This image never accepts passwords over SSH, so an authentication prompt means your key was not offered.
I want to install a package with apt or dnf. Flatcar has no package manager — that is intentional. Run additional software as containers (docker run ...), which is what the platform is built for. For persistent system tooling, systemd sysext extension images or a toolbox container are the Flatcar-native approaches.
The machine rebooted on its own. Flatcar applied a staged stable-channel update and rebooted into the new release. This is the designed behaviour and keeps the OS patched. See Step 9 to coordinate or defer reboots.
systemctl works but my package-based runbook does not. Flatcar is systemd-based, so systemctl and journalctl behave normally, but there is no package manager to call. Translate any apt/dnf install steps to container workloads or systemd units.
Where did my change to /usr go. /usr is read-only. Put configuration in /etc, data in /var or /opt, and applications in containers.
Support
cloudimg provides 24/7 support for this image. Contact support@cloudimg.co.uk with your Azure subscription ID and virtual machine name.
Flatcar Container Linux itself is a CNCF community project. Upstream documentation is at flatcar.org/docs, and the project source is at github.com/flatcar.