Kairos : traiter le système d'exploitation comme une image de conteneur
Un système immuable construit, versionné et distribué comme une image OCI. Démarrage réseau, montée de version atomique avec retour arrière, K3s intégré : l'approche qui rend la périphérie gérable.
Gérer cent serveurs dans un centre de données est un problème résolu. Gérer cent serveurs répartis dans cent sites, sans administrateur sur place et parfois derrière une liaison instable, ne l'est pas.
Les outils de configuration classiques supposent un système mutable qu'on fait converger. Sur un parc en périphérie, cette hypothèse se retourne : au bout de deux ans, chaque machine a dérivé différemment, et personne ne sait exactement ce qui tourne où.
Kairos renverse la logique. Le système d'exploitation devient une image de conteneur : construite par une chaîne d'intégration, versionnée dans un registre, distribuée et démarrée telle quelle. La machine ne se configure plus, elle se remplace.
Le principe
# Le système d'exploitation se décrit dans un Dockerfile
FROM quay.io/kairos/ubuntu:24.04-standard-amd64-generic-v3.6.0-k3sv1.31.4-k3s1
# Paquets spécifiques au site
RUN apt-get update && apt-get install -y --no-install-recommends chrony lldpd smartmontools nvme-cli && rm -rf /var/lib/apt/lists/*
# Agent interne de supervision
COPY --chmod=0755 agent-supervision /usr/local/bin/agent-supervision
COPY agent-supervision.service /etc/systemd/system/
RUN systemctl enable agent-supervision.service
# Durcissement appliqué à la construction, pas au démarrage
COPY durcissement/ /etc/
RUN /usr/local/bin/appliquer-durcissement.sh
# Autorité de certification interne
COPY pki/ca-interne.crt /usr/local/share/ca-certificates/
RUN update-ca-certificatesCette image se construit dans GitLab CI, se signe, se pousse dans le registre interne. Chaque machine du parc démarre exactement la même — au bit près.
La conséquence la plus utile. « Quelle version tourne sur le site de Lyon ? » devient une question à réponse unique : l'empreinte de l'image. Plus de dérive possible.
L'installation sans intervention
Kairos démarre depuis une image ISO, une clé USB ou le réseau, puis lit sa configuration dans un fichier de type cloud-init.
#cloud-config
install:
device: "auto"
auto: true
reboot: true
image: "oci:registry.interne/edge/socle-k3s:v3.6.0-r12"
grub_options:
extra_cmdline: "rd.neednet=1 console=tty1 console=ttyS0,115200"
users:
- name: exploitation
groups: ["admin"]
ssh_authorized_keys:
- "ssh-ed25519 AAAAC3Nza... exploitation@pi-groupe"
lockPasswd: true # aucune connexion par mot de passe
k3s:
enabled: true
args:
- --disable=traefik
- --disable=servicelb
- --flannel-backend=wireguard-native # chiffrement entre nœuds
- --node-label=site=lyon-usine-2
- --node-label=topologie=peripherie
- --kubelet-arg=eviction-hard=memory.available<200Mi
- --tls-san=k3s.lyon-usine-2.interne
kairos:
network_token: "{{ jeton_reseau_p2p }}" # maillage chiffré entre nœuds du site
stages:
boot:
- name: "Attendre l'horloge"
commands:
- chronyc waitsync 30 0.1 || true # certificats invalides sans heure juste
network:
- name: "Déclarer la machine à l'inventaire"
commands:
- |
curl -sf --retry 5 --retry-delay 10 -H "Authorization: Bearer ${JETON_INVENTAIRE}" -X POST https://inventaire.interne/api/noeuds -d "{\"serie\":\"$(dmidecode -s system-serial-number)\",\"site\":\"lyon-usine-2\"}"L'étape de synchronisation d'horloge n'est pas cosmétique. Un serveur en périphérie dont la pile de la carte mère est morte démarre en 1970. Tous les certificats TLS sont alors invalides, et le nœud ne rejoint jamais le cluster. Cette panne représente une part étonnante des incidents d'installation.
La montée de version atomique
C'est l'apport décisif de Kairos. Deux partitions système coexistent : l'active et la passive. La mise à jour écrit dans la passive, bascule le chargeur de démarrage, redémarre. En cas d'échec, le retour arrière se fait tout seul.
apiVersion: upgrade.cattle.io/v1
kind: Plan
metadata:
name: montee-socle-v3-7
namespace: system-upgrade
spec:
concurrency: 2 # deux machines à la fois sur tout le parc
nodeSelector:
matchExpressions:
- { key: topologie, operator: In, values: ["peripherie"] }
- { key: canal-maj, operator: In, values: ["stable"] }
serviceAccountName: system-upgrade
cordon: true
drain:
force: true
skipWaitForDeleteTimeout: 60
upgrade:
image: quay.io/kairos/kairos-upgrade
args:
- "--source=oci:registry.interne/edge/socle-k3s:v3.7.0-r3"
- "--verify-signature"
envs:
- name: COSIGN_PUBLIC_KEY
valueFrom: { secretKeyRef: { name: cle-signature, key: cosign.pub } }La vérification de signature avant bascule est indispensable. Sans elle, quiconque peut pousser dans le registre décide du système qui démarre sur vos sites.
La progressivité l'est tout autant. concurrency: 2 sur un parc de quatre-vingts machines étale la montée sur plusieurs heures. Une régression se détecte sur deux sites, pas sur quatre-vingts.
Le canal de déploiement
Le déploiement progressif par étiquette reprend le schéma éprouvé des mises à jour de flotte.
| Canal | Parc | Délai après publication |
|---|---|---|
canari | 2 sites non critiques | immédiat |
stable | 70 % du parc | 7 jours |
conservateur | sites critiques | 21 jours |
kubectl label node edge-lyon-01 edge-nantes-03 canal-maj=canari --overwriteVingt et un jours entre le canari et les sites critiques laissent le temps de découvrir ce qu'aucun test ne révèle : l'incompatibilité avec un automate industriel, le pilote réseau qui régresse, la carte qui n'aime pas le nouveau noyau.
L'immuabilité en pratique
Le système de fichiers racine est monté en lecture seule. Ce que vous devez conserver se déclare explicitement.
install:
bind_mounts:
- /var/lib/rancher
- /var/lib/kubelet
- /var/lib/donnees-metier
ephemeral_mounts:
- /tmp
- /var/tmpCette contrainte force une hygiène salutaire. Si une charge écrit dans un chemin non déclaré, elle perd ses données au redémarrage — et vous le découvrez en recette plutôt qu'en production. Le système documente ce qui compte.
Ce qu'il faut accepter
Le dépannage change de nature. Impossible d'installer un paquet pour diagnostiquer. Prévoyez vos outils dans l'image, ou un conteneur de dépannage prêt à l'emploi.
Le poids de l'image compte. Un socle avec K3s tourne autour de 1,2 Gio. Sur un site en 4 Mbit/s, la montée de version prend quarante minutes. Soignez vos couches, ou prévoyez un miroir local.
La construction devient un élément critique. Votre chaîne d'intégration produit désormais le système d'exploitation de votre parc. Elle mérite le même niveau de protection que la production.
Le bilan
Le gain n'est pas technique, il est organisationnel. Un parc en périphérie sous Kairos se raisonne comme un déploiement applicatif : une version, un canal, un déploiement progressif, un retour arrière.
Les questions qui empoisonnaient l'exploitation — quelle version, quel correctif, quelle configuration — trouvent une réponse unique et vérifiable. Sur cent sites, cela change tout.