← Back to posts
comparison guide self-hosted · · 12 min read

Talos Linux vs Flatcar vs Bottlerocket: Best Immutable Container OS 2026

Compare Talos Linux, Flatcar Container Linux, and Bottlerocket — the top three immutable, container-optimized operating systems for self-hosted Kubernetes and container workloads in 2026.

OS
Editorial Team

When running containerized workloads at scale, the traditional general-purpose Linux distribution — with its package manager, shell access, and mutable filesystem — is more of a liability than an asset. Immutable operating systems eliminate entire classes of problems: configuration drift, unauthorized changes, unnecessary attack surfaces, and unpredictable updates.

This guide compares the three leading immutable, container-optimized OS options for self-hosted kubernetes and container infrastructure: Talos Linux, Flatcar Container Linux, and Bottlerocket OS.

What Is an Immutable Operating System?

An immutable OS is designed so that the root filesystem is read-only at runtime. Updates are applied atomically — typically via A/B partitioning — meaning the system either boots into the new version or falls back to the previous one. Key characteristics include:

  • No package manager — you cannot install arbitrary software with apt or yum
  • No SSH by default — configuration happens through declarative APIs or config files
  • Minimal attack surface — only the components needed for running containers are present
  • Atomic updates — updates are applied to the inactive partition and take effect on reboot, with automatic rollback on failure

This design makes these OSes ideal for running Kubernetes nodes, container orchestrators, and other infrastructure where predictability and security matter more than customizability.

Comparison Table: Talos Linux vs Flatcar vs Bottlerocket

FeatureTalos LinuxFlatcar Container LinuxBottlerocket OS
DeveloperSidero LabsFlatcar e.V. (Linux Foundation)Amazon Web Services
GitHub Stars10,283+1,129+9,568+
Last UpdatedApril 2026April 2026April 2026
LicenseMPL 2.0Apache 2.0 / BSDApache 2.0 / MIT
LanguageGoC (CoreOS heritage)Rust
Container Runtimecontainerdcontainerdcontainerd + docker (via admin)
Init SystemCustom (no systemd)systemdsystemd
ConfigurationMachine config (YAML) via APIIgnition / Butane (YAML)Settings API (TOML)
KubernetesBuilt-in (self-hosting)Bring your ownBring your own (EKS optimized)
Management Tooltalosctl CLIcoreos-installer + Ignitionbottlerocket-update-operator
A/B PartitioningYesYesYes
FIPS ModeYesYesYes
Cloud ProvidersAWS, GCP, Azure, VMware, bare metalAWS, GCP, Azure, VMware, OpenStack, bare metalAWS (ECS/EKS), VMware
Best ForKubernetes-first clustersGeneral container workloadsAWS-native deployments

Talos Linux

Talos Linux is a purpose-built Linux distribution for Kubernetes. It has no package manager, no SSH daemon, and no general-purpose userland. The entire OS is designed around one goal: run Kubernetes reliably and securely.

Architecture

Talos replaces many traditional Linux components with custom Go implementations:

  • No systemd — uses a custom machined init system
  • containerd runs as a managed service with a defined set of images
  • API server (apid) exposes the control plane for cluster management via talosctl
  • Kernel is patched with security hardening and seccomp profiles
  • Everything is declarative — machine configuration is applied as a single YAML document

The OS is approximately 12 binaries and a handful of services. The attack surface is minimal compared to a standard Linux distribution.

Deployment Example

Talos can be deployed on bare metal, VMware, AWS, or any major cloud provider. For bare-metal provisioning, you may want to combine Talos with a network boot solution — see our iPXE vs netboot.xyz vs FOG Project guide for details on PXE booting infrastructure. Here is the typical workflow for a bare-metal deployment:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# 1. Install talosctl
curl -sL https://talos.dev/install | sh

# 2. Generate cluster configuration
talosctl gen config my-cluster https://<control-plane-ip>:6443 \
  --output-dir ./clusterconfig

# 3. Apply configuration to nodes
talosctl apply-config --insecure --nodes <node-ip> --file ./clusterconfig/controlplane.yaml
talosctl apply-config --insecure --nodes <worker-ip> --file ./clusterconfig/worker.yaml

# 4. Bootstrap the Kubernetes cluster
talosctl bootstrap --nodes <control-plane-ip>

# 5. Get the kubeconfig
talosctl kubeconfig --nodes <control-plane-ip> .

For a cloud-based deployment on AWS, the talosctl can generate cloud-config or user-data that boots the instance directly into a configured node:

1
2
3
4
talosctl gen config my-cluster https://10.0.0.10:6443

# Upload ISO or AMI and boot
# After boot, the node is managed entirely through talosctl

Machine Configuration

Talos machine configuration is a single YAML file that declares everything about the node:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
version: v1alpha1
machine:
  type: controlplane
  token: <machine-token>
  certSANs:
    - 10.0.0.10
  network:
    hostname: control-plane-1
    interfaces:
      - interface: eth0
        dhcp: true
  kubelet:
    extraArgs:
      feature-gates: RotateKubeletServerCertifica[ory](https://www.ory.sh/)true
  install:
    disk: /dev/sda
    image: factory.talos.dev/installer/xxx
    wipe: false
cluster:
  name: my-cluster
  controlPlane:
    endpoint: https://10.0.0.10:6443
  clusterName: cluster.local
  network:
    podSubnets:
      - 10.244.0.0/16
    serviceSubnets:
      - 10.96.0.0/12

Upgrading

Talos supports zero-downtime upgrades with rolling node updates:

1
2
3
4
5
# Upgrade the OS image
talosctl upgrade --nodes <node-ip> --image factory.talos.dev/installer/xxx:v1.9.0

# Upgrade Kubernetes version
talosctl upgrade-k8s --to 1.31.0

Security Features

  • All communication is mTLS — every API call uses mutual TLS authentication
  • No root shell — there is no SSH daemon; access is only through talosctl
  • Read-only filesystem — the root filesystem is mounted read-only
  • Seccomp profiles — all system calls are restricted by default
  • Kernel lockdown — the kernel runs in lockdown mode, preventing module loading

Flatcar Container Linux

Flatcar is the community-maintained continuation of CoreOS Container Linux, now maintained by the Flatcar e.V. under the Linux Foundation umbrella. It provides a reliable, immutable base for running containers at scale.

Architecture

Flatcar retains the CoreOS heritage with systemd-based init and Ignition for first-boot configuration:

  • systemd as the init system (familiar to most Linux administrators)
  • Ignition for provisioning — reads a JSON config at first boot and configures disks, users, systemd units, and files
  • Butane — a YAML front-end that compiles to Ignition JSON configs
  • Update Engine (update_engine) — handles automatic OS updates with A/B partitioning
  • Locksmith — manages reboot coordination for rolling updates across a cluster

Flatcar is more general-purpose than Talos. It can run any containerized workload, not just Kubernetes.

Deployment with Ignition and Butane

Flatcar uses Butane (YAML) configs that compile to Ignition (JSON) for provisioning:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# butane-config.bu (YAML input for Butane)
variant: flatcar
version: 1.1.0
passwd:
  users:
    - name: core
      ssh_authorized_keys:
        - ssh-ed25519 AAAA... admin@server
storage:
  files:
    - path: /etc/hostname
      mode: 0644
      contents:
        inline: flatcar-node-1
systemd:
  units:
    - name: docker.service
      dropins:
        - name: proxy.conf
          contents: |
            [Service]
            Environment=HTTP_PROXY=http://proxy.example.com:3128
    - name: etcd-member.service
      enabled: true
1
2
3
4
5
6
7
8
9
# Compile Butane to Ignition
butane butane-config.bu -o ignition.json

# Deploy via coreos-installer (bare metal)
coreos-installer install /dev/sda \
  --ignition-file ignition.json \
  --copy-network

# Or on cloud providers, pass ignition.json as user-data

Automatic Updates

Flatcar’s update engine handles A/B partitioning automatically:

1
2
3
4
5
6
7
8
# Check current OS version
cat /usr/share/flatcar/update.conf

# View update status
update_engine_client -status

# Reboot coordination (Locksmith)
locksmithctl status

To control the update channel:

1
2
# Set the update channel (stable, beta, alpha, edge)
update_engine_client -switch-channel stable

Running Containers

Flatcar ships with containerd. You can manage containers via systemd units:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
# /etc/systemd/system/my-app.service
[Unit]
Description=My Containerized App
Requires=containerd.service
After=containerd.service

[Service]
Restart=always
ExecStartPre=-/usr/bin/docker pull ghcr.io/myorg/myapp:latest
ExecStart=/usr/bin/docker run \
  --name myapp \
  --rm \
  -p 8080:80 \
  ghcr.io/myorg/myapp:latest
ExecStop=/usr/bin/docker stop myapp

[Install]
WantedBy=multi-user.target

Bottlerocket OS

Bottlerocket is an open-source Linux distribution built by Amazon Web Services specifically for running containers. It is optimized for AWS workloads (ECS and EKS) but also supports VMware vSphere and bare metal.

Architecture

Bottlerocket is written primarily in Rust and follows a clean separation between the OS and its configuration:

  • API daemon (apiclient) — a local HTTP API for changing OS settings
  • Settings model — all configuration is stored in TOML and applied through the API
  • Two partitions (A/B) — updates are downloaded to the inactive partition and activated on reboot
  • No SSH daemon — access is via the SSM agent (AWS) or bottlerocket-shell container
  • var and data volumes — separate writable volumes for container data and Kubernetes state

Unlike Talos, Bottlerocket does not include Kubernetes components. It is designed as a general-purpose container host that integrates well with orchestration systems.

Deployment on AWS (EKS)

Bottlerocket is available as an EKS-optimized AMI. Creating a Bottlerocket node group is straightforward:

1
2
3
4
5
6
7
8
9
# Create an EKS managed node group with Bottlerocket
aws eks create-nodegroup \
  --cluster-name my-cluster \
  --nodegroup-name bottlerocket-nodes \
  --node-role arn:aws:iam::123456789:role/eks-node-role \
  --subnets subnet-xxx subnet-yyy \
  --instance-types t3.large \
  --ami-type BOTTLEROCKET_x86_64 \
  --scaling-config minSize=2,maxSize=5,desiredSize=3

Deploying on VMware or Bare Metal

For non-AWS deployments, Bottlerocket is distributed as an OVA (VMware) or image files. If you are running a self-hosted virtualization platform like Proxmox or XCP-ng, see our Proxmox vs XCP-ng vs oVirt guide for details on deploying VM-based infrastructure.

1
2
3
4
5
6
# Deploy via OVA on vSphere
govc import.ova -ds datastore1 -pool /cluster/Resources \
  bottlerocket-vmware-k8s-1.30-x86_64-v1.20.0.ova

# Configure via the Bottlerocket API after first boot
# The API is accessed through the admin container

Configuration via Settings API

All Bottlerocket configuration is managed through TOML settings:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# settings.toml — applied via the API
[settings.kubernetes]
api-server = "https://my-eks-cluster.eks.amazonaws.com"
cluster-certificate = "base64-encoded-cert"
cluster-name = "my-cluster"

[settings.host-containers.admin]
enabled = true
source = "public.ecr.aws/bottlerocket/bottlerocket-admin:latest"

[settings.network]
hostname = "bottlerocket-node-1"
1
2
3
4
5
6
7
# Apply settings via apiclient
apiclient set -e settings.toml

# Or via the API directly from a container
curl -X PATCH http://localhost/api/settings \
  -H "Content-Type: application/json" \
  -d '{"settings": {"motd": "Welcome to Bottlerocket"}}'

Updates

Bottlerocket updates are managed by the update operator:

1
2
3
4
5
6
7
8
# Check for available updates
apiclient update check

# Download an update
apiclient update apply

# Reboot into the new version
reboot

On EKS, the Bottlerocket Update Operator manages rolling updates across the node group automatically.

Key Decision Factors

Choose Talos Linux If:

  • You are running Kubernetes exclusively and want the tightest possible integration
  • You prefer a single tool (talosctl) for managing both the OS and the cluster
  • You want the smallest possible attack surface with zero SSH access
  • You need built-in Kubernetes bootstrapping and lifecycle management

If you are also evaluating lightweight Kubernetes distributions, see our k3s vs k0s vs Talos Linux guide — while that article compares Talos as a Kubernetes distro, this piece focuses on the OS-level architecture differences.

Choose Flatcar Container Linux If:

  • You need a general-purpose container OS that works across multiple cloud providers
  • You want systemd compatibility and familiarity for existing Linux teams
  • You run workloads beyond Kubernetes (e.g., custom Docker Compose stacks, legacy services)
  • You prefer Ignition-based provisioning with well-established tooling

Choose Bottlerocket If:

  • Your primary infrastructure is on AWS and you run EKS or ECS
  • You want deep AWS integration (SSM, IAM, CloudWatch) out of the box
  • You prefer Rust-based OS components for memory safety
  • You need FIPS-compliant deployments in regulated environments

Performance and Resource Usage

All three OSes are significantly lighter than general-purpose Linux distributions:

MetricTalos LinuxFlatcarBottlerocket
Image Size~300 MB~500 MB~400 MB
Boot Time~5-10 seconds~15-20 seconds~10-15 seconds
Memory (idle)~50 MB~150 MB~100 MB
Disk (minimal)~10 GB~10 GB~10 GB
Processes (idle)~15~80+ (systemd)~40

Talos has the smallest footprint by design — it eliminates systemd and most traditional Linux services. Flatcar, being systemd-based, runs more background services but offers greater compatibility with existing Linux tooling.

Security Comparison

Security FeatureTalos LinuxFlatcarBottlerocket
mTLS for all APIsYesNoPartial
No SSH daemonYesNo (SSH available)Yes (SSM only)
Read-only root fsYesYesYes
Seccomp profilesYesBasicYes
Kernel lockdownYesOptionalYes
SELinux / AppArmorAppArmorSELinuxSELinux
Automatic updatesManual (via talosctl)Yes (update_engine)Yes (apiclient)
FIPS 140-2YesYesYes

Talos provides the strongest security posture out of the box, with mandatory mTLS and no interactive shell access. Bottlerocket matches this with its API-only management model. Flatcar allows SSH access (though it is not recommended for production) and relies on standard Linux security mechanisms.

FAQ

What does “immutable operating system” mean?

An immutable OS has a read-only root filesystem that cannot be modified at runtime. Changes and updates are applied to a separate partition, and the system boots into the new version on reboot. This prevents configuration drift, unauthorized modifications, and makes every node in a cluster identical and predictable.

Can I SSH into these operating systems?

Talos Linux and Bottlerocket do not include an SSH daemon by default. Talos is managed entirely through talosctl (CLI), while Bottlerocket uses the AWS SSM agent or its internal API. Flatcar does include SSH (configured via Ignition at first boot), but best practice is to use coreos-installer and Ignition for all configuration changes instead of SSH.

Which immutable OS is best for self-hosted Kubernetes?

Talos Linux is purpose-built for Kubernetes and provides the tightest integration — the OS manages the Kubernetes control plane, handles upgrades, and provides a single management interface. However, Flatcar and Bottlerocket both work excellently with Kubernetes; they just require you to bring your own Kubernetes distribution (kubeadm, k3s, etc.).

Do these OSes support automatic updates?

Flatcar and Bottlerocket include built-in automatic update systems. Flatcar’s update_engine downloads updates to the inactive partition and reboots safely with Locksmith coordination. Bottlerocket’s update operator checks for and applies updates, with automatic rollback on failure. Talos requires manual upgrade commands via talosctl, giving operators full control over timing.

Can I run Docker on these operating systems?

All three OSes ship with containerd as the default container runtime. Flatcar also includes a Docker socket compatibility layer. Bottlerocket allows running Docker via its admin container. Talos strictly uses containerd and does not support Docker natively — this is intentional, as Kubernetes itself has deprecated Docker support in favor of containerd.

What happens if an update fails?

All three OSes use A/B partitioning. The update is downloaded to the inactive partition, and the system only switches to it after a successful reboot. If the new partition fails to boot, the bootloader automatically falls back to the previous working version. This ensures that a bad update never takes a node permanently offline.

Are these OSes free and open source?

Yes. Talos Linux is licensed under MPL 2.0, Flatcar under Apache 2.0 and BSD licenses, and Bottlerocket under Apache 2.0 and MIT. All three are fully open source and available on GitHub. Bottlerocket is developed by AWS but is not tied to any paid service.

Advertise here