Aller au contenu
Conteneurs & Orchestration medium

Incus OS : mises à jour A/B et rollback

11 min de lecture

logo incus

La promesse la plus forte d'Incus OS, c'est sa mise à jour atomique A/B : la nouvelle image s'installe sur une seconde partition pendant que le système continue de tourner, puis le nœud bascule au reboot, avec un retour arrière automatique si le démarrage échoue. Ce guide montre comment lire les versions, régler la politique de mise à jour, déclencher une bascule et mettre à jour un cluster sans coupure, le tout via l'API, sans jamais ouvrir de shell. Public visé : administrateurs qui exploitent un parc Incus OS.

  • Lire l'état des versions A/B d'un nœud (os_version, os_version_alternate, os_version_next).
  • Consulter et modifier la politique de mise à jour (canal, fréquence, reboot automatique).
  • Forcer une vérification et appliquer une bascule au reboot.
  • Mettre à jour un cluster un nœud à la fois sans perdre le quorum.
  • Comprendre le mécanisme de rollback et quand il se déclenche.
  • Un ou plusieurs nœuds Incus OS en service. Voir Incus OS sans interface pour l'installation et l'établissement de la confiance.
  • Un client Incus dont le certificat est approuvé par les nœuds, avec un remote configuré vers chaque nœud à administrer.
  • Pour la partie cluster, un cluster Incus OS d'au moins trois nœuds.

Incus OS n'expose aucun shell. Toute l'administration passe par son API REST, préfixée par /os, que l'on interroge avec la commande incus query. Chaque nœud publie sa propre API OS locale : contrairement à l'API Incus classique qui a une vue cluster, les commandes de mise à jour ci-dessous ciblent un nœud précis via son remote.

Un système immuable ne se met pas à jour paquet par paquet. Il garde deux emplacements système côte à côte, appelés A et B. À un instant donné, un seul est actif : c'est celui sur lequel le nœud a démarré. Quand une nouvelle version arrive, elle est écrite sur l'emplacement inactif, sans toucher au système en cours d'exécution. Le reboot fait basculer l'activité vers cet emplacement fraîchement peuplé.

Ce schéma donne deux garanties : la mise à jour est atomique (le nœud tourne sur l'ancienne version jusqu'au redémarrage, il n'y a pas d'état intermédiaire bancal), et le retour arrière est immédiat puisque l'ancienne version reste intacte sur l'autre emplacement. C'est le même principe que les OS immuables de mobile ou de conteneur.

Par défaut, Incus OS vérifie les mises à jour toutes les 6 heures. Deux canaux existent : stable (au moins une mise à jour hebdomadaire, dernier noyau stable et correctifs de sécurité) et testing (builds quotidiens). Le canal stable est le défaut.

La racine de l'API OS d'un nœud renvoie son environnement, dont les trois champs qui décrivent le cycle A/B :

Fenêtre de terminal
incus query node3:/os/1.0
{
"environment": {
"hostname": "node3.lab",
"os_name": "IncusOS",
"os_version": "202607010319",
"os_version_alternate": "202607011621+3-0",
"os_version_next": "202607011621",
"system_is_ready": true,
"uptime": 109027
}
}

Trois champs racontent tout l'état de la bascule. os_version est la version active, celle sur laquelle le nœud a démarré. os_version_alternate est ce qui se trouve sur l'emplacement inactif. os_version_next indique la version qui sera active au prochain reboot. Ici, os_version_next diffère de os_version : une nouvelle image (202607011621, un build du 1er juillet) a déjà été téléchargée et posée sur l'emplacement inactif, prête à prendre le relais. Le numéro de version est un horodatage de build au format AAAAMMJJHHMM.

L'endpoint system/update expose la configuration et l'état des mises à jour du nœud :

Fenêtre de terminal
incus query node3:/os/1.0/system/update
{
"config": {
"auto_reboot": false,
"channel": "stable",
"check_frequency": "6h"
},
"state": {
"last_check": "2026-07-02T16:14:34Z",
"needs_reboot": true,
"status": "Update check completed"
}
}

Le champ state.needs_reboot à true est le signal clé : une mise à jour est installée et en attente, il ne manque qu'un redémarrage pour l'appliquer. Le champ config.auto_reboot à false explique pourquoi rien ne s'est passé tout seul : le nœud a téléchargé et préparé la nouvelle image, mais il attend une décision de l'administrateur pour rebooter. C'est le comportement recommandé en cluster, où l'on veut orchestrer les redémarrages un à un.

Pour modifier cette politique, on envoie un PUT avec l'objet config. Par exemple, passer un nœud de laboratoire sur le canal testing avec une vérification quotidienne :

Fenêtre de terminal
incus query -X PUT node3:/os/1.0/system/update \
-d '{"config":{"auto_reboot":false,"channel":"testing","check_frequency":"1d"}}'

Sans attendre le cycle de 6 heures, on déclenche une vérification manuelle. Elle vide le cache du fournisseur d'images, cherche une version plus récente et la télécharge sur l'emplacement inactif si elle existe :

Fenêtre de terminal
incus query -X POST node3:/os/1.0/system/update/:check

La réponse est vide en cas de succès. Interrogez ensuite system/update : si une image a été récupérée, state.needs_reboot passe à true et os_version_next reflète la nouvelle version. On peut restreindre la recherche au seul système d'exploitation en passant {"os_only": true} dans le corps de la requête, ce qui ignore les mises à jour d'applications.

Une fois needs_reboot à true, la bascule se déclenche par un simple redémarrage du nœud, commandé par l'API :

Fenêtre de terminal
incus query -X POST node3:/os/1.0/system/:reboot

Le nœud redémarre sur l'emplacement inactif. Après quelques secondes d'indisponibilité, il répond de nouveau et les champs de version ont permuté :

{
"environment": {
"hostname": "node3.lab",
"os_version": "202607011621",
"os_version_alternate": "202607010319",
"os_version_next": "202607011621",
"system_is_ready": true,
"uptime": 156
}
}

La lecture confirme la réussite. os_version affiche désormais la nouvelle version, 202607011621. L'ancienne version, 202607010319, est passée dans os_version_alternate : elle occupe maintenant l'emplacement inactif et reste disponible comme filet de sécurité. Côté system/update, state.needs_reboot est retombé à false. Le tableau ci-dessous résume la permutation observée sur ce nœud.

ChampAvant rebootAprès reboot
os_version (actif)202607010319202607011621
os_version_alternate (inactif)202607011621202607010319
needs_reboottruefalse

Sur un cluster, chaque nœud reçoit et prépare la mise à jour indépendamment, mais on ne les redémarre jamais tous en même temps. Un cluster Incus OS de trois nœuds conserve le quorum tant que deux membres de base de données restent en ligne. La règle est donc de procéder un nœud à la fois, en vérifiant le retour de chacun avant de passer au suivant.

  1. Vérifier l'état global avant de commencer. Tous les nœuds doivent être ONLINE et afficher needs_reboot: true (mise à jour prête).

    Fenêtre de terminal
    incus cluster list node1:
  2. Rebooter un membre non-leader en premier, puis attendre son retour sur la nouvelle version.

    Fenêtre de terminal
    incus query -X POST node3:/os/1.0/system/:reboot

    Pendant l'indisponibilité de ce nœud, les deux autres maintiennent le quorum et le service reste assuré.

  3. Confirmer la bascule du nœud rebooté et sa réintégration au cluster.

    Fenêtre de terminal
    incus query node3:/os/1.0 | grep os_version
    incus cluster list node1:
  4. Passer au nœud suivant et répéter. Terminer par le leader de base de données : à son redémarrage, un autre nœud prend automatiquement le rôle database-leader.

    Fenêtre de terminal
    incus query -X POST node1:/os/1.0/system/:reboot

Quand on redémarre l'ancien leader, l'API du cluster reste disponible via les autres nœuds : interrogez le cluster avec un remote pointant vers un membre encore en ligne (par exemple incus cluster list node2:) pour suivre la réélection. Une fois le dernier nœud revenu, tous les membres affichent la même version et le cluster est de nouveau homogène.

Le retour arrière d'Incus OS n'est pas une commande que l'on tape après coup : c'est un filet automatique intégré au démarrage. Le chargeur d'amorçage compte les tentatives de boot sur le nouvel emplacement. Si le système ne parvient pas à démarrer correctement, il retombe sur l'emplacement précédent, celui qui figure dans os_version_alternate et qui est resté intact. Aucune intervention n'est requise pour ce cas.

C'est précisément l'intérêt du schéma A/B : une mise à jour qui casse le boot ne transforme pas le nœud en brique. L'ancienne version, connue comme fonctionnelle, reprend la main automatiquement. Après un tel retour, le nœud redémarre sur l'ancienne image et needs_reboot reste à false jusqu'à ce qu'une nouvelle version saine soit proposée.

SymptômeCause probableSolution
needs_reboot reste à false après une vérificationAucune version plus récente sur le canal, ou check_frequency réglé sur neverVérifier config.channel et forcer un :check manuel
Le PUT sur system/update renvoie invalid update check frequencyCorps incomplet, check_frequency videEnvoyer un objet config complet avec les trois champs
incus query nodeX: échoue avec not authorizedCertificat client non approuvé sur ce nœudRétablir la confiance, voir le guide Incus OS sans interface
Le cluster passe en OFFLINE sur plusieurs nœudsTrop de nœuds redémarrés en même temps, quorum perduAttendre le retour des nœuds ; à l'avenir, rebooter un seul membre à la fois
  • Incus OS met à jour en A/B : la nouvelle image va sur l'emplacement inactif, la bascule a lieu au reboot.
  • Trois champs suivent l'état : os_version (actif), os_version_alternate (filet), os_version_next (prochain boot).
  • La vérification a lieu toutes les 6 h par défaut, canal stable ; ajustable par PUT sur system/update.
  • auto_reboot: false est le bon défaut en cluster : l'administrateur orchestre les redémarrages.
  • On applique une bascule avec POST /os/1.0/system/:reboot, ciblé sur un nœud.
  • En cluster, on met à jour un nœud à la fois pour préserver le quorum ; le leader se termine en dernier.
  • Le rollback est un filet automatique du chargeur d'amorçage, pas une commande manuelle.

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracking. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn