↓ Aller au contenu

Un pas de plus vers l'immuabilité avec Flatcar Container Linux

Romain Boulanger
Auteur
Romain Boulanger
Architecte Infra/Cloud avec une touche de DevSecOps
Sommaire
Flatcar Container Linux - Cet article fait partie d'une série.
Partie 1: Cet article

Du CoreOS d’origine à l’écosystème CNCF
#

Si vous êtes familier avec Talos Linux, vous connaissez déjà les concepts associés à l’immuabilité et la gestion déclarative d’un état bien souvent as-code. J’ai eu l’occasion de vous parler de ces concepts dans le cas de la mise en place de clusters Kubernetes, néanmoins, il reste une partie de l’infrastructure souvent mise de côté : les services dits satellites, ceux qui tournent en dehors de Kubernetes et qui méritent eux aussi le même niveau de rigueur. C’est exactement là qu’entre en scène Flatcar Container Linux.

Pour comprendre Flatcar, il faut remonter quelques années en arrière. Tout commence avec CoreOS Container Linux, une distribution Linux pensée dès le départ pour faire tourner des conteneurs à grande échelle.

CoreOS a introduit des concepts assez révolutionnaires par rapport aux distributions dites “classiques” : un système de fichiers racine en lecture seule, des mises à jour atomiques par partition A/B et une configuration déclarative lors du boot.

Malheureusement, Red Hat a racheté CoreOS en 2018 avant d’en annoncer la fin de vie deux ans plus tard, pour privilégier sa propre distribution sous Fedora et ses outils maison comme Podman. C’était sans compter sur la startup berlinoise Kinvolk qui a forké le projet pour lui donner une seconde vie sous le nom de Flatcar Container Linux. Microsoft a ensuite racheté Kinvolk en 2021, avant que Flatcar ne rejoigne la Cloud Native Computing Foundation (CNCF) en 2024 en phase d’incubation.

Ce statut CNCF est important. Il garantit la neutralité du projet vis-à-vis des acteurs commerciaux, assure une gouvernance ouverte et offre une visibilité à long terme comparable à d’autres projets comme containerd, Argo CD, ou encore Cluster API lui-même.

La philosophie de Flatcar est directement héritée de CoreOS : en finir avec les serveurs “pets” (vus comme des animaux de compagnie), ces machines dont on prend soin, patchées au fil des mois, dont personne ne sait vraiment dans quel état elles se trouvent. À la place, Flatcar adopte le modèle “cattle” (vu comme un troupeau) : des serveurs jetables, interchangeables, dont la configuration est définie au démarrage et qui ne dérivent pas par rapport à leur état initial.

Flatcar Container Linux vs Talos Linux : deux visions de l’immuabilité
#

Si vous lisez cet article après la série sur Cluster API avec Talos Linux, une question s’impose naturellement : pourquoi utiliser Flatcar si on a déjà Talos ? La réponse est assez simple et dépend du contexte d’utilisation.

Talos Linux est pensé exclusivement pour Kubernetes. Pas de shell SSH, pas de gestionnaire de paquets, pas d’accès direct au système : toute l’administration passe par talosctl et son API gRPC.

C’est une posture radicale qui garantit un niveau de sécurité et d’immuabilité extrême, mais qui implique que Talos ne fait qu’une seule chose : faire tourner des nœuds Kubernetes. Néanmoins, la version 1.15 devrait changer la donne avec un support élargi au-delà de votre orchestrateur de conteneurs préféré, mais ce n’est pas encore le cas à l’heure actuelle.

Flatcar Container Linux adopte une approche différente. C’est un OS immuable généraliste pour conteneurs. Le système de fichiers /usr est en lecture seule, les mises à jour sont atomiques, mais l’accès SSH reste possible et un conteneur de débogage éphémère (toolbox) est disponible pour les interventions ponctuelles. Flatcar supporte Docker et containerd, gère ses unités via systemd et s’adresse à tous les workloads conteneurisés. Il est d’ailleurs supporté par exemple par kubespray et Cluster API pour créer des clusters Kubernetes.

En pratique, les cas d’usage se distinguent assez clairement :

  • Talos Linux est minimaliste et est pensé pour Kubernetes avant tout autre chose. C’est donc le choix à privilégier pour avoir une surface d’attaque minimaliste et un très haut niveau de sécurité.
  • Flatcar permet d’adresser tous les cas d’usage à base de conteneurs avec un fonctionnement immuable moins restrictif que Talos. Il a l’avantage de se rapprocher des systèmes d’exploitation traditionnels, tout en apportant un système de mise à jour automatique bien pensé.

Voici quelques points très brefs pour comparer ces deux univers, on rentrera dans le détail un peu plus bas :

CritèreTalos LinuxFlatcar Container Linux
Accès SSHNonOui
ConfigurationgRPC via talosctlButane et Ignition
Gestionnaire d’initmachined (API gRPC)systemd
Mécanisme de mise à jourImage-based via API : déclenchée explicitement par appel gRPC (talosctl upgrade)Service autonome OTA : orchestré par vagues automatiques via update_engine + Nebraska
PortéeKubernetes uniquementPlutôt généraliste axé conteneurs
Runtimes supportéscontainerd uniquementcontainerd et Docker préinstallés
Extensions de l’OSTalos System Extensionssystemd-sysext / Flatcar sysext bakery
Empreinte disque de base Très réduite (~100 à 120 Mo pour le rootfs)Modérée (~1 à 2 Go selon le partitionnement A/B)

Les deux outils sont complémentaires plutôt que concurrents. On peut très bien avoir une infrastructure où Talos gère les clusters Kubernetes pendant que Flatcar héberge les services d’infrastructure qui les entourent.

Maintenant place aux caractéristiques principales…

Sous le capot, l’architecture technique
#

Le partitionnement A/B et les mises à jour atomiques
#

C’est un des points qui fait la différence de Flatcar. Le disque est partitionné en deux slots identiques, USR-A et USR-B. À un instant donné, le système démarre depuis l’un d’eux, pendant que l’autre reste inactif. Lors d’une mise à jour, la nouvelle version est écrite dans le slot inactif. La bascule vers ce nouveau slot n’intervient qu’au prochain redémarrage.

Ce qui rend le mécanisme particulièrement robuste, c’est le comportement en cas d’échec. Si le nouveau système ne parvient pas à démarrer correctement après un nombre de tentatives défini, le bootloader bascule automatiquement vers l’ancien slot. Il n’y a pas d’état semi-mis-à-jour, pas de configuration corrompue à mi-chemin : soit le système a démarré correctement sur la nouvelle version, soit il est revenu sur l’ancienne.

La partition /usr est montée en lecture seule. Il est donc impossible d’y installer des paquets ou d’y modifier des fichiers directement. C’est une contrainte volontaire qui garantit que l’état du système correspond toujours à ce qui a été défini lors de son provisioning.

Les mises à jour OTA avec Nebraska et le protocole Omaha
#

Les mises à jour Over-The-Air de Flatcar reposent sur le protocole Omaha, le même que celui utilisé par les Chromebooks et Google Chrome, et sur un serveur de mise à jour appelé Nebraska. C’est update_engine, le service responsable des mises à jour, qui interroge régulièrement Nebraska pour savoir si une nouvelle version est disponible.

Flatcar propose quatre canaux de distribution :

  • Stable : le canal recommandé pour la production, avec les versions les plus testées ;
  • Beta : pour valider les nouvelles versions avant de les pousser en stable ;
  • Alpha : les versions les plus récentes, pour du test ou du développement ;
  • LTS (Long Term Support) : pour les environnements qui privilégient la stabilité sur la durée.

Il est possible de déployer son propre serveur Nebraska pour contrôler précisément quand et quelles machines se mettent à jour, ce qui est indispensable en production.

Pour ce qui est du redémarrage lorsque nécessaire, notamment dans le cas d’un cluster Kubernetes, Flatcar Update Operator ou le traditionnel Kured peuvent être installés pour drainer et coordonner le redémarrage des nœuds.

Dans le cas de machines autonomes, il est possible de configurer au sein du update_engine une fenêtre de redémarrage automatique.

Une surface d’attaque réduite
#

Flatcar ne dispose d’aucun gestionnaire de paquets traditionnel de type apt ou yum. Il n’est pas possible d’installer des outils supplémentaires directement sur le système hôte à moins d’utiliser des partitions spécifiques comme /opt.

Cette contrainte, qui peut sembler gênante au premier abord, est en réalité une garantie de sécurité : un attaquant qui parviendrait à accéder au système ne pourrait pas y installer d’outils supplémentaires via les mécanismes classiques.

En cas de problème…
#

Pour les situations qui nécessitent quand même une intervention en cas d’erreur ou de besoin de faire du troubleshooting, Flatcar propose deux mécanismes :

  • La commande flatcar-reset permet de réinitialiser complètement le système à son état initial, en effaçant les données de la partition utilisateur. C’est l’équivalent d’un reprovisioning sans avoir à recréer la machine.

  • L’autre option est toolbox avec la commande du même nom, qui est un conteneur éphémère donnant accès à un environnement complet avec tous les outils de diagnostic habituels (tcpdump, strace, etc.), sans que ces outils ne soient forcément installés sur le système hôte. En réalité, cette commande exécute un script qui instancie un conteneur avec des droits privilégiés et en montant le système de fichiers directement à l’intérieur.

Extensions de l’OS
#

Le fait que /usr soit monté en lecture seule pose une question intéressante : comment installer des outils ou des composants supplémentaires sans briser le modèle immuable ?

La réponse de Flatcar passe par systemd-sysext, un mécanisme natif de systemd qui permet de superposer des images de système de fichiers sur /usr au démarrage. Ces images, appelées system extensions ou sysext, sont des fichiers SquashFS (.raw) qui s’activent par-dessus la partition système classique. Cela donne l’impression d’avoir ces binaires et configurations directement installés au sein de l’OS alors que l’image de base ne bouge pas.

Flatcar propose le projet sysext-bakery qui regroupe des recettes et des images prêtes à l’emploi pour des outils courants comme Keepalived ou encore Kubernetes. Les extensions sont placées dans /etc/extensions/ ou /var/lib/extensions/, et le service ensure-sysext.service se charge de leur activation au démarrage.

De plus, il est possible d’aller plus loin avec systemd-sysupdate pour gérer les mises à jour des extensions de façon autonome, indépendamment du cycle de mise à jour de l’OS lui-même.

La configuration déclarative avec Ignition
#

Flatcar utilise Ignition pour sa configuration initiale. On en parle en détail dans la section suivante, mais l’idée est simple : toute la configuration du système (utilisateurs, clés SSH, fichiers, unités systemd) est définie avant le premier démarrage et appliquée une seule fois, de manière atomique, lors de l’amorçage de la machine virtuelle.

Le provisioning
#

Qu’est-ce qu’Ignition ?
#

Ignition est le système de configuration initiale de Flatcar Container Linux. Sa particularité fondamentale est son moment d’exécution : il s’exécute dans l’initramfs, se chargeant de préparer et monter les disques, avant même de pivoter vers le système de fichiers racine. Cela signifie qu’au moment où systemd démarre pour la première fois, le système est déjà entièrement configuré et prêt à l’emploi.

Cette approche se distingue fortement de cloud-init, qui s’exécute après le démarrage du système, avec la possibilité de laisser la machine dans un état partiellement configuré en cas d’erreur.

Avec Ignition, c’est tout ou rien : si la configuration est invalide ou si une ressource déclarée est inaccessible, la machine ne démarre tout simplement pas. Il n’y a pas d’état intermédiaire, pas de configuration appliquée à moitié. C’est un comportement déterministe qui simplifie considérablement le débogage et garantit la cohérence de l’état.

Ignition vs cloud-init
#

Je vous propose ce petit récapitulatif pour avoir les idées claires entre ces deux modes de fonctionnement :

CritèreIgnitioncloud-init
Moment d’exécutioninitramfs (avant bascule vers /)Après démarrage du système
AtomicitéTout ou rienPas garantie
En cas d’erreurLa machine ne démarre pasÉtat semi-configuré possible
FormatJSON (compilé depuis YAML Butane)YAML
Ré-exécutionJamais (une seule fois)Parfois (selon les modules)
Partitionnement racineFormatage et partitionnement possibles du disque contenant l’OS avant de le monterLimité (le disque système est déjà monté et en cours d’utilisation)
Installation de paquetsUniquement via extensionsGéré nativement (apt-get, yum install, etc.)
Compatibilité OSSpécifique (Flatcar, Fedora CoreOS, RHCOS)Universel (Ubuntu, Debian, RHEL, CentOS, Alpine…)

De Butane vers Ignition
#

Personne n’écrit du JSON sans faire de fautes… Alors faire du JSON Ignition à la main, ce serait limite cauchemardesque !

Néanmoins, pour avoir un format plus lisible, il est possible d’utiliser Butane, un outil permettant de compiler du YAML vers un format JSON Ignition valide sans aucune accolade manquante !

Voici un exemple un peu plus parlant qui ajoute une clé SSH à l’utilisateur par défaut core et modifie le hostname de la machine virtuelle :

variant: flatcar
version: 1.1.0

passwd:
  users:
    - name: core
      ssh_authorized_keys:
        - ssh-ed25519 AAAA...

storage:
  files:
    - path: /etc/hostname
      contents:
        inline: mon-serveur
      mode: 0644

On convertit le tout avec cette commande :

butane --pretty --strict config.bu > config.ign

Le JSON Ignition produit est ensuite passé à la machine via son mécanisme de provisioning (variable userdata, URL HTTP, etc.). Il est lu une seule fois au premier démarrage et n’est jamais ré-appliqué, comme dit plus haut :

{
  "ignition": {
    "version": "3.4.0"
  },
  "passwd": {
    "users": [
      {
        "name": "core",
        "sshAuthorizedKeys": [
          "ssh-ed25519 AAAA..."
        ]
      }
    ]
  },
  "storage": {
    "files": [
      {
        "path": "/etc/hostname",
        "contents": {
          "compression": "",
          "source": "data:,mon-serveur"
        },
        "mode": 420
      }
    ]
  }
}

Plus facile comme ça non ?

Un mot en guise de conclusion
#

Flatcar Container Linux s’inscrit parfaitement dans une philosophie d’infrastructure moderne : des machines dont l’état est entièrement défini à la source, qui ne doivent pas dériver de leur configuration initiale, et dont le cycle de mise à jour est atomique et réversible. Plus de patching nocturne, plus de configuration manuelle accumulée au fil des mois, plus d’interrogations sur ce qui tourne réellement sur une machine.

Pour ceux qui souhaitent aller plus loin dans l’écosystème CNCF, Flatcar dispose également de ses providers pour Cluster API en utilisant le format Ignition. De plus, il est tout à fait possible de provisionner des nœuds Kubernetes immuables avec Flatcar comme système d’exploitation de base, en utilisant le bootstrap provider kubeadm.

C’est une alternative intéressante à Talos Linux pour les équipes qui souhaitent un OS immuable avec un accès SSH et une compatibilité plus large avec l’écosystème Kubernetes traditionnel.

Dans un prochain article, je vous propose de déployer une instance Flatcar Container Linux as-code, qu’en pensez-vous ?

Flatcar Container Linux - Cet article fait partie d'une série.
Partie 1: Cet article

Articles connexes