L’ingénieur « bus factor » : quand une personne détient tout le système

Cet article vous a aidé ?

Il est 02:17. Le pager hurle, les budgets d’erreur s’évaporent et le tableau de bord ressemble à un champ de bataille. Quelqu’un demande : « Qui sait comment ça marche ? » La pièce se fige. Puis un nom apparaît. Un seul nom.

Si votre système de production dépend d’une personne spécifique qui doit rester employée, en bonne santé, joignable et éveillée, vous n’avez pas de fiabilité. Vous avez une trêve fragile avec la physique et les RH.

Ce que « bus factor » signifie vraiment en production

Le bus factor est le nombre de personnes qui pourraient disparaître (accident, maladie, démission, promotion, acquisition, vie) avant que votre projet n’aille au ralenti ou que votre service n’arrive plus à se rétablir. On en rit parfois morbide ; les équipes d’exploitation le vivent comme une ligne budgétaire.

En pratique, le bus factor n’est rarement « une seule personne sait tout ». C’est généralement « une personne connaît les points sensibles ». Le flag non documenté. La raison pour laquelle on a figé cette version du kernel. Le sens réel d’un label Prometheus personnalisé qui conditionne les alertes. La poignée secrète pour importer des snapshots dans le cluster de secours. La règle de routage du pager qui était « temporaire » il y a dix-huit mois.

Le bus factor n’est pas que de la connaissance. C’est aussi l’autorité (une seule personne peut approuver les changements), l’accès (une seule personne a les bons tokens) et la confiance (les autres ont peur d’y toucher). Si vous améliorez la documentation mais laissez l’accès verrouillé sur un seul laptop, vous gérez toujours une négociation d’otage, juste avec du Markdown plus propre.

Une citation à garder en tête quand vous êtes tenté de « demander à Alex » au lieu d’écrire :

Attribué à Gene Kim (idée paraphrasée) : L’objectif est le flux rapide et la stabilité ; les actions héroïques sont le signe que votre système et vos processus échouent.

Deux clarifications importantes :

  • Un bus factor élevé n’implique pas un faible niveau de compétence. Cela peut signifier une forte spécialisation. Le problème survient lorsque la spécialisation devient un point de défaillance unique non testé.
  • Le bus factor est un problème systémique. L’« ingénieur bus factor » fait souvent la chose rationnelle dans une organisation irrationnelle : livrer, patcher, éteindre les incendies et absorber le contexte parce que personne d’autre n’a le temps d’apprendre.

Blague #1 : L’ingénieur bus factor n’est pas « irremplaçable ». Il est remplaçable ; le système facture juste des frais de consultation en cas d’incident.

Pourquoi cela arrive (et pourquoi des équipes brillantes y tombent quand même)

1) Les incitations récompensent la rapidité, pas le transfert

La plupart des organisations promeuvent la personne qui débloque les lancements, pas celle qui s’assure que les lancements peuvent se faire sans elle. Si votre système d’évaluation valorise « l’impact », l’impact visible le plus facile est de devenir un goulot d’étranglement. Vous vous retrouvez soudainement dans toutes les réunions, toutes les revues, tous les incidents. Votre calendrier devient l’architecture.

2) L’« exception temporaire » devient une infrastructure permanente

Les changements d’urgence sont acceptables. Les changements d’urgence permanents sont un signe. L’ingénieur bus factor est souvent le seul qui se souvient pourquoi nous avons contourné le pipeline normal « juste cette fois ». Ce contournement devient ensuite le pipeline.

3) La complexité s’accumule là où il est facile de changer

L’endroit où les changements sont rapides devient l’endroit où les changements sont faits. Si une personne détient les privilèges et le contexte, le système évolue autour de son flux de travail. Avec le temps, ce flux de travail devient une dépendance. Voilà comment on se retrouve avec une automatisation de production qui nécessite un humain en SSH pour exécuter une commande depuis l’historique du shell.

4) La documentation échoue quand elle est traitée comme de la prose

Des docs qui disent « redémarrer le service » ne sont pas de la documentation ; ce sont des impressions. Une vraie documentation d’exploitation est exécutable, vérifiable et liée à la réalité : commandes exactes, sortie attendue et décision suivante.

5) La peur est contagieuse

Si le système a mordu des gens auparavant — perte de données, kernel panic, « corruption mystérieuse » — l’équipe apprend à ne pas y toucher. Avec le temps, la seule personne qui y touche devient la seule qui peut y toucher. C’est ainsi que des piles de stockage fragiles sont « possédées » par un seul ingénieur pendant des années.

Faits et contexte historique qui expliquent le schéma

Le bus factor semble moderne parce qu’on en parle en termes GitHub, mais le schéma est ancien : spécialisation plus vitesse plus interfaces fragiles. Quelques éléments de contexte qui aident à comprendre pourquoi cela se répète :

  1. Le terme « bus factor » est un cousin de l’ancien terme « truck factor » utilisé dans les équipes logiciels pour décrire le même risque ; la métaphore a évolué, le mode de défaillance non.
  2. Les designs « single string » vs « dual string » de la NASA (chemins de contrôle simples vs redondants) ont popularisé l’idée que la redondance n’est pas optionnelle dans les systèmes à haut enjeu ; les personnes font partie du système.
  3. À l’époque de la téléphonie et des mainframes, la « connaissance d’opérateur » était littérale. Les runbooks existaient parce que les systèmes nécessitaient des étapes manuelles ; quand la connaissance restait piégée dans des personnes, la disponibilité en souffrait.
  4. L’apparition des rotations on-call en web ops a forcé les équipes à formaliser le savoir tribal, car les incidents ne se programment pas autour des vacances du seul expert.
  5. Le mouvement « DevOps » n’a pas seulement plaidé pour la collaboration dev+ops ; il a implicitement combattu la propriété en boîte noire et le gardiennage héroïque comme modèle d’échelle.
  6. La culture des postmortems (sans blâme ou non) s’est répandue parce que les organisations avaient besoin d’un outil pour convertir les incidents en apprentissages partagés au lieu de stocker le savoir en privé.
  7. La gestion de configuration (CFEngine, Puppet, Chef, Ansible) a été en partie une réponse aux « serveurs flocon de neige » que seul un admin comprenait ; codifier l’état est un antidote au bus factor.
  8. Les structures modernes de commandement d’incident (style ICS) ont dépassé les urgences parce que séparer « qui fait » de « qui sait » rend la réponse scalable et enseignable.
  9. Les systèmes de gestion des secrets existent parce que « le mot de passe est dans la tête de Steve » n’est pas de la sécurité ; c’est un déni de service en attente.

Diagnostiquer le risque de bus factor : signaux mesurables

Le bus factor est émotionnel — les équipes se disputent la propriété et la confiance — mais il est aussi mesurable. Si vous voulez le réduire, arrêtez de débattre et commencez à observer.

Signal 1 : Qui fusionne les changements ?

Si une personne approuve ou fusionne la majorité des changements d’un système, vous avez déjà centralisé la connaissance et l’autorité. Cela peut être justifié pour la sécurité, mais dans ce cas vous avez besoin d’un second approbateur avec compétence et accès équivalents.

Signal 2 : Qui reçoit les pages et qui répare ?

Regardez les timelines d’incident. Si la même personne apparaît systématiquement comme « join et résolu », elle n’est pas seulement experte ; elle est la seule personne autorisée à agir. Ce n’est pas un compliment. C’est un mode de défaillance que vous normalisez.

Signal 3 : La documentation « c’est dans Slack »

Si le runbook est « cherche dans le canal et retrouve le thread de l’année dernière », vous n’avez pas de runbook. Vous faites de l’archéologie.

Signal 4 : Asymétrie d’accès

Si le modèle IAM permet à une seule personne d’ouvrir la porte sur la production, vous avez un point de défaillance unique. Si vous ne pouvez pas accorder plus d’accès, vous avez besoin d’un processus break-glass strict, audité et documenté que tout on-call peut exécuter.

Signal 5 : La récupération est un rituel

Quand la restauration dépend de « faire ces sept étapes dans le bon ordre et ne demande pas pourquoi », vous êtes dans un piège de connaissance. Les systèmes qui ne peuvent être restaurés que par rituel ne seront pas restaurés sous contrainte.

Signal 6 : Le système est stable… jusqu’à ce qu’il ne le soit plus

Le risque bus factor se cache dans les systèmes stables parce qu’ils ne demandent pas d’attention. Puis quelque chose change — mise à jour du kernel, firmware, comportement API cloud, rotation de certificat — et vous découvrez que le système était stable uniquement parce qu’une personne pratiquait des comportements compensatoires.

Playbook de diagnostic rapide : trouver le goulot d’étranglement vite

Ceci est la checklist « entrer dans une pièce en feu ». Il s’agit de trouver le goulot le plus probable en quelques minutes, pas de composer une dissertation pendant que la base de données brûle.

Première étape : identifier le domaine de défaillance et arrêter de l’empirer

  1. Confirmer l’étendue : un hôte, une AZ, une région, une dépendance, un segment de clients.
  2. Geler les déploiements risqués : interrompre les pipelines, arrêter l’auto-scaling qui thrash, stopper les jobs batch si ils saturent la production.
  3. Vérifier la saturation évidente : CPU, mémoire, IO disque, réseau, descripteurs de fichiers.

Deuxième étape : vérifier la plomberie « ennuyeuse »

  1. DNS et certificats : des certificats expirés et des échecs DNS imitent étonnamment bien des pannes applicatives.
  2. Heure : une dérive NTP peut casser l’auth, les logs, la coordination distribuée et votre santé mentale.
  3. État du stockage : des blocages IO se font passer pour une « lenteur applicative » jusqu’à ce que quelqu’un vérifie les disques.

Troisième étape : trouver le limiteur actuel

  1. Comptabilité du budget de latence : le temps est-il passé dans l’app, la base, le réseau ou en attente d’IO ?
  2. Chercher la croissance des files : pools de threads, pools de connexions, brokers de messages, run queue du kernel, files IO.
  3. Confirmer le chemin de rollback / basculement : si vous pouvez alléger la charge ou basculer en toute sécurité, faites-le tôt plutôt que de débattre une heure.

Le twist bus-factor : si les étapes de « diagnostic rapide » exigent une personne spécifique pour les interpréter, votre observabilité est décorative. Corrigez cela avant le prochain incident.

Trois mini-récits d’entreprise issus du terrain

Mini-récit n°1 : L’incident causé par une fausse hypothèse

Une entreprise SaaS de taille moyenne exploitait une passerelle de stockage interne devant l’object storage. La passerelle mettait en cache des métadonnées localement pour la vitesse. Ça fonctionnait suffisamment bien pour que personne ne s’en inquiète ; l’ingénieur d’origine était passé à une autre équipe mais « possédait » encore la passerelle en pratique.

Pendant une fenêtre de maintenance, un autre ingénieur a fait pivoter les certificats d’hôte et redémarré les nœuds de la passerelle un par un. Sur le papier : sûr. En réalité : le cache de métadonnées n’était pas juste un cache. Il contenait l’état faisant autorité pour des uploads multipart en cours, et le job de « réhydratation » qui reconstruisait l’état depuis l’object storage avait été désactivé des mois plus tôt après avoir provoqué des pics de charge.

La mauvaise hypothèse était subtile : « Si c’est un cache, ça se reconstruit. » C’est vrai jusqu’à ce que quelqu’un ajoute en douce un état « temporaire mais critique » et oublie de mettre à jour le modèle mental.

Après le redémarrage, les clients ont commencé à réessayer les uploads. Les réessais ont amplifié le trafic, le trafic a amplifié la latence, et la passerelle a commencé à rater les health checks. L’auto-healing a remplacé des nœuds, ce qui a effacé davantage de « cache », ce qui a effacé encore plus d’état. Le système n’a pas seulement échoué ; il s’est détruit lui-même.

La correction n’a pas été héroïque. Ils ont réactivé le job de réhydratation avec des limites de débit, écrit un runbook énonçant explicitement quelles données vivaient où, et ajouté un test de reboot canari dans le CI pour l’AMI de la passerelle. Surtout, ils ont défini les « sémantiques de cache » comme un contrat documenté et mis deux ingénieurs en rotation pour les changements de stockage.

Mini-récit n°2 : L’optimisation qui a mal tourné

Une plateforme d’analytics de trading disposait d’un cluster Postgres sur NVMe rapides. Un ingénieur—brillant, privé de sommeil et digne de confiance—avait décidé d’« aider le kernel » en réglant le writeback des pages sales et les paramètres du scheduler IO. Il a réduit la latence lors des benchmarks et a déclaré victoire.

Le changement vivait dans un fichier sysctl personnalisé sur les hôtes de la base, pas dans la gestion de configuration, parce que c’était « juste un ajustement rapide ». Des mois plus tard, la société a mis à jour l’image OS. Le nouveau kernel gérait le writeback différemment. Les anciennes valeurs sysctl sont devenues pathologiques sous la charge réelle : des rafales d’écritures s’accumulaient, puis se déversaient en énormes pics qui bloquaient les lectures. Les requêtes ne ralentissaient pas progressivement ; elles se heurtaient à des murs.

On-call a vu du CPU inactif et a supposé que la base était « correcte ». Les ingénieurs applicatifs ont cherché du côté des pools de connexions. Pendant ce temps, la couche de stockage subissait une souffrance synchronisée. La seule personne qui comprenait le tweak sysctl était dans un vol transatlantique.

Quand l’expert a atterri, il a annulé le sysctl et le système s’est rétabli immédiatement. Le postmortem a été inconfortable : l’optimisation était réelle, mais couplée au comportement du kernel, non documentée, non testée et effectivement sans propriétaire dans l’équipe.

La remédiation durable a été de traiter le tuning du kernel comme du code applicatif : configuration versionnée, propriétaires explicites, hôte canari, tests de régression de performance et règle stricte que les réglages « rapides » doivent avoir un plan de rollback et une raison claire.

Mini-récit n°3 : La pratique ennuyeuse mais correcte qui a sauvé la mise

Une entreprise de santé exploitait du NFS sur ZFS pour de l’analytics interne. Rien de glamour. L’ingénieur stockage insistait sur un calendrier de scrub hebdomadaire, des exercices de restauration mensuels et un petit runbook avec commandes exactes et captures d’écran des sorties attendues. Tout le monde le taquinait pour être old-school.

Un jeudi, un bug de firmware dans un lot de SSD a commencé à renvoyer des erreurs de lecture intermittentes. ZFS a détecté des mismatches de checksum et a commencé à réparer depuis la redondance. Des alertes se sont déclenchées, mais le service est resté majoritairement sain. L’équipe on-call ne paniquait pas parce que le runbook expliquait ce qu’un scrub fait, ce que signifie « errors: No known data errors » et quand escalader.

Ils ont remplacé les disques défaillants pendant une fenêtre contrôlée, vérifié l’avancement du resilver et effectué un exercice de restauration depuis les snapshots les plus récents. Pas de drame, pas de « on pense que c’est bon », pas d’attente pour que le spécialiste se réveille.

Le point n’était pas la magie de ZFS. Le point était la mémoire opérationnelle : l’équipe avait pratiqué les étapes ennuyeuses, et ces étapes étaient écrites de façon à rendre un non-expert dangereux dans la bonne direction.

Blague #2 : Chaque équipe a « ce système que personne n’ose toucher ». C’est comme une pièce de musée, sauf qu’il vous page de temps en temps.

Tâches pratiques : commandes, sorties et décisions (12+)

Ce ne sont pas des « conseils ». Ce sont des vérifications concrètes qui transforment un système sous bus-factor en un système d’équipe. Chaque tâche inclut une commande, ce que la sortie signifie et la décision que vous prenez à partir de cela.

Task 1: Identify who has production access (Linux host)

cr0x@server:~$ getent group sudo
sudo:x:27:root,alice,bob,oncall

Ce que cela signifie : Cet hôte permet à root, alice, bob et oncall d’escalader les privilèges.

Décision : Si le break-glass en production dépend d’une personne nommée, ajoutez un groupe basé sur les rôles (comme oncall) avec des membres audités et un calendrier de revue des accès.

Task 2: Verify SSH keys and last logins (find “only Pat can log in” situations)

cr0x@server:~$ sudo last -a | head
reboot   system boot  6.5.0-21-generic Mon Jan 29 03:12   still running  -  server
alice    pts/0        10.0.2.14        Mon Jan 29 03:20   still logged in -  10.0.2.14
bob      pts/1        10.0.3.19        Mon Jan 29 02:55 - 03:40  (00:45)  -  10.0.3.19

Ce que cela signifie : Qui accède réellement à la machine et depuis où. Si vous ne voyez qu’un seul nom d’utilisateur, vous pourriez avoir un problème de propriété fantôme.

Décision : Exiger des comptes personnels + comptes de rôle partagés pour l’accès d’urgence, et requérir qu’au moins deux personnes puissent se connecter pendant un incident.

Task 3: Confirm secrets aren’t “in someone’s home directory”

cr0x@server:~$ sudo grep -R --line-number "BEGIN PRIVATE KEY" /home 2>/dev/null | head
/home/alice/.ssh/id_rsa:1:-----BEGIN PRIVATE KEY-----

Ce que cela signifie : Vous avez trouvé une clé privée dans un répertoire home. Cela peut être légitime pour SSH utilisateur, mais souvent c’est une clé de service ou un identifiant de déploiement qui est devenu « le problème d’Alice ».

Décision : Déplacez les identifiants de service dans un coffre géré ; révoquez et faites tourner les clés compromises/surexploitées ; documentez l’accès et la rotation.

Task 4: Check whether services are configured by hand (drift detection)

cr0x@server:~$ sudo systemctl cat nginx | sed -n '1,25p'
# /lib/systemd/system/nginx.service
[Unit]
Description=A high performance web server and a reverse proxy server
After=network-online.target remote-fs.target nss-lookup.target

[Service]
Type=forking
ExecStartPre=/usr/sbin/nginx -t -q -g 'daemon on; master_process on;'
ExecStart=/usr/sbin/nginx -g 'daemon on; master_process on;'

Ce que cela signifie : Le fichier de service est standard. Bien. Si vous voyez des overrides dans /etc/systemd/system/nginx.service.d/override.conf qui ne sont pas dans Git, c’est du drift.

Décision : Mettez les overrides dans la gestion de configuration ; ajoutez une vérification de drift dans le CI ou un audit planifié.

Task 5: Confirm what is actually listening (catch “mystery ports” owned by one engineer)

cr0x@server:~$ sudo ss -lntp
State  Recv-Q Send-Q Local Address:Port  Peer Address:Port Process
LISTEN 0      4096   0.0.0.0:443         0.0.0.0:*     users:(("nginx",pid=1321,fd=6))
LISTEN 0      4096   127.0.0.1:9000      0.0.0.0:*     users:(("gatewayd",pid=2104,fd=12))

Ce que cela signifie : Il y a un service local sur 9000 nommé gatewayd. Si personne ne peut l’expliquer sans pinguer une personne, c’est le bus factor rendu visible.

Décision : Cartographiez chaque port écouté vers un propriétaire, un repo et un runbook. Si vous ne pouvez pas, planifiez un court « inventaire de services » avant que l’incident réel n’arrive.

Task 6: Check disk health quickly (SRE triage, storage edition)

cr0x@server:~$ lsblk -o NAME,SIZE,TYPE,MOUNTPOINT,FSTYPE,MODEL
sda    1.8T disk              Samsung_SSD_860
├─sda1 512M part /boot        ext4
└─sda2 1.8T part /            ext4

Ce que cela signifie : Inventaire de base. Si le système dépend d’un modèle/firmware de disque spécifique connu d’une seule personne, vous voulez que cela soit visible.

Décision : Enregistrez les modèles/firmware et standardisez. Les flottes hétérogènes vont bien jusqu’à ce que vous ayez besoin d’un comportement de défaillance cohérent.

Task 7: Look for IO pressure (is the system slow because storage is slow?)

cr0x@server:~$ iostat -xz 1 3
Linux 6.5.0-21-generic (server)  02/02/2026  _x86_64_ (8 CPU)

avg-cpu:  %user %nice %system %iowait  %steal   %idle
          12.31  0.00    4.22   25.80    0.00   57.67

Device            r/s     w/s   rkB/s   wkB/s  await  %util
sda              80.0   120.0  6400.0  9800.0  38.2   98.7

Ce que cela signifie : %iowait est élevé et le %util du disque est proche de 100% avec await élevé. Classique : « les apps semblent lentes, le CPU semble libre ».

Décision : Limitez les jobs batch, réduisez l’amplification d’écriture (logs, compactions) ou basculez vers un stockage moins chargé. Ouvrez un fil d’incident centré sur le stockage ; n’autorisez pas tout le monde à chasser des fantômes applicatifs.

Task 8: Check filesystem capacity and inode exhaustion

cr0x@server:~$ df -h /
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda2       1.8T  1.7T   55G  97% /

cr0x@server:~$ df -i /
Filesystem       Inodes   IUsed    IFree IUse% Mounted on
/dev/sda2      120586240 119900000 686240 100% /

Ce que cela signifie : Vous êtes à court d’inodes. Cette panne ressemble à des erreurs d’écriture « aléatoires » même avec de l’espace libre sur le disque.

Décision : Trouvez et supprimez les répertoires à grand nombre de fichiers (cache, tmp, fragments de logs). Ajoutez de la surveillance d’utilisation d’inodes. Mettez à jour le runbook : « disque plein » inclut les inodes.

Task 9: Detect “kernel is the bottleneck” via run queue and load

cr0x@server:~$ uptime
 02:21:10 up 17 days,  6:14,  2 users,  load average: 24.18, 23.77, 20.06

cr0x@server:~$ vmstat 1 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
18  6      0 128000  52000 910000    0    0   820  2400 4100 8200 13  5 55 27  0

Ce que cela signifie : La charge est élevée, et b (bloqué) plus wa (IO wait) suggèrent que des processus attendent de l’IO.

Décision : Traitez cela comme un goulot IO / backing store, pas un problème de montée CPU. Escaladez vers le stockage, réduisez l’IO et identifiez les plus gros consommateurs d’IO.

Task 10: Find top IO consumers (prove who is hurting the disk)

cr0x@server:~$ sudo iotop -boPa -n 3 | head -n 12
Total DISK READ: 120.00 M/s | Total DISK WRITE: 85.00 M/s
PID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN     IO>    COMMAND
2104 be/4  app       65.00 M/s  12.00 M/s  0.00 %  15.20 %  gatewayd --cache /var/lib/gw
1887 be/4  postgres  40.00 M/s  60.00 M/s  0.00 %  12.30 %  postgres: checkpointer

Ce que cela signifie : Vous avez une preuve : gatewayd et Postgres dominent l’IO.

Décision : Pour un soulagement immédiat : ajustez le comportement des checkpoints, réduisez le churn du cache ou désactivez temporairement les charges non critiques. Pour le bus factor : documentez ce qu’est gatewayd et qui possède son profil IO.

Task 11: Validate ZFS pool health (if you run ZFS, you must know this)

cr0x@server:~$ sudo zpool status -x
all pools are healthy

Ce que cela signifie : Pas de problèmes connus de pool actuellement.

Décision : Si vous ne voyez pas et ne comprenez pas régulièrement cette sortie, planifiez une formation. ZFS n’est pas « set and forget » ; c’est « set and verify ».

Task 12: If ZFS is unhealthy, read it like a decision tree

cr0x@server:~$ sudo zpool status tank
  pool: tank
 state: DEGRADED
status: One or more devices has experienced an error resulting in data corruption.
action: Replace the device and run 'zpool clear'.
  scan: scrub repaired 0B in 00:12:11 with 0 errors on Mon Jan 29 01:00:01 2026
config:

        NAME                        STATE     READ WRITE CKSUM
        tank                        DEGRADED     0     0     0
          mirror-0                  DEGRADED     0     0     0
            ata-SAMSUNG_SSD_860-1   ONLINE       0     0     0
            ata-SAMSUNG_SSD_860-2   FAULTED      0     0    12

Ce que cela signifie : Le membre du miroir a des erreurs de checksum et est faulted. Le scrub montre 0 réparé mais des erreurs de checksum existent : considérez le périphérique suspect.

Décision : Remplacez le disque défaillant, confirmez le resilver, puis clear les erreurs. Surtout : assurez-vous que la procédure de remplacement figure dans un runbook qu’un non-spécialiste peut exécuter sous supervision.

Task 13: Confirm scrubs and snapshots exist (boring, correct, lifesaving)

cr0x@server:~$ sudo zpool get scrubby tank
NAME  PROPERTY  VALUE  SOURCE
tank  scrubby   -      default

cr0x@server:~$ sudo zfs list -t snapshot | head
NAME                 USED  AVAIL  REFER  MOUNTPOINT
tank/data@daily-001  128M      -  1.2T   -
tank/data@daily-002  130M      -  1.2T   -

Ce que cela signifie : Vous avez des snapshots (bien), mais scrubby n’est pas une propriété standard ; cette sortie vous indique que les scrubs ne sont pas suivis via une propriété ici. Vous devez encore vérifier le calendrier des scrubs ailleurs (cron/systemd timers).

Décision : Assurez-vous qu’il existe un calendrier connu et des alertes pour la fin et les erreurs de scrub. Si les scrubs « arrivent quand quelqu’un les lance », c’est un risque bus-factor pur.

Task 14: Check replication / backup job status (prove recoverability)

cr0x@server:~$ systemctl status zfs-replication.service --no-pager
● zfs-replication.service - ZFS snapshot replication
     Loaded: loaded (/etc/systemd/system/zfs-replication.service; enabled)
     Active: active (exited) since Mon 2026-02-02 01:00:02 UTC; 1h 22min ago
    Process: 4421 ExecStart=/usr/local/sbin/replicate-tank.sh (code=exited, status=0/SUCCESS)

Ce que cela signifie : L’unité de réplication a récemment tourné avec succès.

Décision : Si le succès de la réplication se réduit à « status=0 », ajoutez une vérification : lister le dernier snapshot sur la destination et tester un chemin de restauration. Faire confiance, mais vérifier avec des preuves.

Task 15: Confirm what version and config you’re really running (no “works on my kernel” mysteries)

cr0x@server:~$ uname -a
Linux server 6.5.0-21-generic #21-Ubuntu SMP PREEMPT_DYNAMIC x86_64 GNU/Linux

cr0x@server:~$ dpkg -l | egrep 'zfs|linux-image' | head
ii  linux-image-6.5.0-21-generic  6.5.0-21.21   amd64  Signed kernel image generic
ii  zfsutils-linux                2.2.2-0ubuntu1 amd64  command-line tools to manage ZFS filesystems

Ce que cela signifie : Vous pouvez voir les versions du kernel et de ZFS. C’est important car le comportement change selon les versions, et le tuning tribal suppose souvent une version spécifique.

Décision : Enregistrez les versions dans le runbook et les templates d’incident. Exigez une mise à jour canari et un plan de rollback pour les changements du kernel/stack de stockage.

Task 16: Identify “only one person knows” cron jobs and timers

cr0x@server:~$ sudo systemctl list-timers --all | head -n 15
NEXT                         LEFT        LAST                         PASSED       UNIT                         ACTIVATES
Mon 2026-02-02 03:00:00 UTC  37min left  Mon 2026-02-02 02:00:00 UTC  22min ago    logrotate.timer              logrotate.service
Mon 2026-02-02 04:00:00 UTC  1h 37min    Mon 2026-02-02 01:00:00 UTC  1h 22min ago apt-daily-upgrade.timer      apt-daily-upgrade.service

Ce que cela signifie : Les timers montrent l’automatisation planifiée. Si vos tâches critiques n’y figurent pas — ou ne sont pas dans un système d’orchestration connu — elles peuvent être des rituels manuels.

Décision : Convertissez les étapes opérationnelles manuelles en timers/jobs avec logs, alertes et propriétaire. Un job qui ne s’exécute que quand « quelqu’un s’en souvient » est un bug de fiabilité.

Erreurs courantes : symptôme → cause racine → correctif

1) Symptom: “We can’t deploy because only one person can approve”

Cause racine : La politique d’approbation remplace les contrôles techniques ; le risque est géré socialement, pas techniquement.

Fix : Remplacez l’approbation personnelle par des contrôles automatisés (tests, policy-as-code), et exigez deux approbateurs formés en rotation. Conservez un override d’urgence mais auditez-le.

2) Symptom: “On-call can’t restore, but the expert can in 10 minutes”

Cause racine : Le chemin de récupération est non documenté, non testé et implique probablement du contexte privé (dépendances cachées, ordre implicite).

Fix : Rédigez un runbook de restauration avec commandes et sorties attendues, puis organisez des drills trimestriels de restauration avec des non-experts pendant que l’expert observe en silence jusqu’à ce qu’il soit nécessaire.

3) Symptom: “The service is stable; we don’t need to touch it”

Cause racine : La stabilité est assurée par les habitudes d’une personne (vérifications manuelles, évitement soigneux), pas par la conception du système.

Fix : Forcez des changements sûrs et petits : reboots canari, vérifications des pins de dépendance, tests périodiques de basculement. La stabilité doit être démontrée sous changement contrôlé.

4) Symptom: “Docs exist, but nobody trusts them”

Cause racine : Les docs sont obsolètes, non exécutables et écrites en récit plutôt qu’en procédure.

Fix : Faites des docs orientées commandes : « Exécuter X, voir Y, puis faire Z. » Attachez les docs aux pages d’alerte et aux templates d’incident. Ajoutez un propriétaire de doc et des dates de revue.

5) Symptom: “We have automation, but it’s brittle and only one person debugs it”

Cause racine : L’automatisation est un système personnalisé sans tests, avec une pauvre observabilité et des hypothèses implicites.

Fix : Traitez l’automatisation comme du code de production : tests, logs, métriques et un second mainteneur. Si ça ne peut pas être testé, simplifiez jusqu’à ce que ça le puisse.

6) Symptom: “We can’t rotate secrets/certs without downtime”

Cause racine : Le système n’a jamais été conçu pour la rotation ; les secrets sont embarqués dans des configs ou des chemins de code qui nécessitent un redémarrage et une coordination manuelle.

Fix : Ajoutez le hot-reload quand possible, réduisez la prolifération des secrets, utilisez des identifiants de courte durée et répétez la rotation comme un déploiement.

7) Symptom: “Storage incidents are terrifying and slow to resolve”

Cause racine : Le stockage a un fort rayon d’impact et une faible observabilité ; l’équipe manque de mémoire opérationnelle pour les étapes sûres (scrub, resilver, snapshot, restore).

Fix : Standardisez les stacks de stockage ; ajoutez des tableaux de bord de santé clairs ; entraînez les procédures de remplacement et de restauration ; créez un playbook « incident stockage » séparé des playbooks applicatifs.

8) Symptom: “We always wait for the same person to join the incident”

Cause racine : Une seule personne est habilitée à agir, ou tout le monde a peur d’empirer la situation.

Fix : Définissez les droits de décision (ce que l’on-call peut faire sans permission), créez des mitigations sûres (shedding de trafic, feature flags) et organisez des game days qui récompensent l’apprentissage.

Checklists / plan pas à pas

Plan pas à pas pour réduire le bus factor en 30–60 jours

  1. Inventaire du système : services, hôtes, cron/timers critiques, pools de stockage, bases de données et dépendances. Si ça écoute sur un port, ça a besoin d’un nom et d’un propriétaire.
  2. Rédiger le runbook « break glass » : comment obtenir l’accès, comment auditer l’accès, comment revenir en arrière sur l’accès. C’est la différence entre résilience et théâtre.
  3. Créer un runbook incident minimal par service :
    • À quoi ressemble la santé (métriques, logs, status) ?
    • Top 3 des modes de défaillance et comment les mitiger en sécurité.
    • Commandes exactes et sorties attendues.
  4. Choisir deux non-experts et planifier une session de « shadow restore » de 60 minutes où ils exécutent le runbook pendant que l’expert observe.
  5. Standardiser les identifiants : sortir les secrets des machines personnelles ; imposer la rotation ; s’assurer que l’on-call peut accéder aux secrets via des contrôles basés sur les rôles.
  6. Introduire la sûreté des changements : canaris, feature flags, déploiements par étapes et un vrai chemin de rollback. Le bus factor prospère là où le rollback est mythique.
  7. Rendre la propriété explicite : définir des propriétaires primaires/secondaires pour chaque composant. Le secondaire doit pouvoir « opérer et restaurer », pas seulement être en copie.
  8. Ajouter des revues de readiness opérationnelle pour les nouveaux systèmes : « Qui peut le gérer à 3h du matin ? » est un critère de lancement, pas une suggestion.
  9. Organiser au moins un game day axé sur le sous-système effrayant (stockage, réseau, auth). L’objectif est la confiance, pas le chaos.
  10. Mesurer l’amélioration : suivre les incidents où l’expert était requis ; suivre le temps de mitigation en son absence ; suivre l’utilisation et la correction des runbooks.

À éviter (parce que ça paraît productif et ne l’est pas)

  • Ne pas punir l’ingénieur bus factor. Il n’a pas créé seul la structure d’incitation. Corrigez le système, pas le bouc émissaire.
  • Ne pas écrire un roman wiki de 40 pages. Écrivez un runbook de 2 pages avec commandes et décisions, puis développez si nécessaire.
  • Ne pas exiger que « tout le monde sache tout ». Vous visez la récupérabilité et l’opérabilité, pas l’expertise universelle.
  • Ne pas confondre partage d’accès et résilience. Si deux personnes utilisent le même mot de passe, vous avez juste doublé le rayon d’impact et conservé le bus factor.

Une « Definition of Done » pratique pour dé-risquer un sous-système

  • Au moins deux personnes peuvent déployer, rollbacker et restaurer sans demander d’aide.
  • Les runbooks contiennent des commandes exactes, des sorties attendues et des points de décision.
  • L’accès se fait via des groupes basés sur les rôles avec logs d’audit et revue périodique.
  • Les backups/réplications sont vérifiés par restauration, pas seulement par « job succeeded ».
  • Au moins un test d’injection de panne ou game day a été réalisé au cours du dernier trimestre.

FAQ

1) Is bus factor just another word for “key person risk”?

Oui, mais les ingénieurs ont besoin d’une mise en cadre opérationnelle. « Key person risk » ressemble à une diapositive de management. « Bus factor » évoque un incident à venir, ce qui est plus précis.

2) What’s an acceptable bus factor?

Pour les systèmes critiques en production, visez au moins 2 pour l’exploitation et la récupération, et 3 pour le développement soutenu. Si votre système ne survit pas à l’indisponibilité d’une personne, il n’est pas prêt pour la production.

3) We have documentation. Why is bus factor still high?

Parce qu’une documentation non exécutable n’est qu’une histoire. Les runbooks doivent inclure commandes, sorties attendues et points de décision. De plus : l’accès et l’autorité comptent autant que la connaissance.

4) Isn’t specialization unavoidable for storage, networking, and security?

La spécialisation est acceptable. Les points de défaillance uniques ne le sont pas. L’objectif est « les spécialistes construisent et améliorent », tandis que « l’on-call peut opérer et restaurer en sécurité via des runbooks et des garde-fous ».

5) How do we reduce bus factor without slowing down delivery?

Vous ralentirez un peu maintenant ou de façon catastrophique plus tard. L’astuce : traiter le transfert de connaissance comme partie intégrante de la livraison : chaque changement met à jour le runbook, les dashboards et les étapes de rollback.

6) What if the bus factor engineer refuses to share knowledge?

Parfois c’est du gatekeeping, parfois de l’épuisement, parfois la peur de perdre du statut. Dans tous les cas, réglez cela structurellement : imposez la propriété partagée, faites tourner l’on-call et assurez du temps pour la documentation et la formation.

7) How do we handle “only one person has the credentials” without weakening security?

Utilisez le contrôle d’accès basé sur les rôles, un break-glass audité, des tokens de courte durée et des approbations avec traçabilité. La sécurité n’est pas « une personne possède les clés ». La sécurité, c’est un accès contrôlé avec traçabilité.

8) What’s the fastest win?

Choisissez un type d’incident critique (restauration, basculement, rotation de certificat) et écrivez un runbook basé sur des commandes. Faites ensuite exécuter ce runbook par un non-expert lors d’un drill. Le premier drill sera chaotique ; c’est voulu.

9) How do you measure bus factor improvement?

Suivez qui résout les incidents, combien de temps prend la mitigation en l’absence de l’expert, à quelle fréquence les runbooks sont utilisés et corrigés, et combien de services ont des propriétaires primaire/secondaire avec accès testé.

10) Does automation fix bus factor?

Seulement si elle est compréhensible et opérable par l’équipe. Une automatisation que seul un individu peut déboguer n’est qu’un moyen plus rapide de rester bloqué.

Conclusion : prochaines étapes concrètes

Si vous suspectez la présence d’un ingénieur bus-factor, vous en avez probablement un. L’indice n’est pas sa brillance. C’est la dépendance de l’équipe à sa présence pour la récupération et le changement.

Faites ceci ensuite, dans l’ordre :

  1. Choisissez le chemin de récupération le plus effrayant (restauration de base de données, resilver de stockage, basculement de région) et transformez-le en runbook avec commandes, sorties et décisions.
  2. Faites un drill où quelqu’un d’autre suit le runbook. L’expert peut observer et prendre des notes, pas diriger.
  3. Corrigez les accès : assurez-vous que l’on-call peut faire les mitigations sûres et les étapes break-glass avec des traces d’audit.
  4. Standardisez et testez : changements canari, chemins de rollback et vérifications routinières comme les scrubs et les tests de restauration.
  5. Rendez la propriété réelle : propriétaires primaires et secondaires, avec attentes explicites et temps alloué pour le transfert.

La fiabilité n’est pas un trait de personnalité. C’est une propriété d’un système qui suppose que les humains sont faillibles, parfois indisponibles, et ne devraient pas être des points de défaillance uniques — peu importe la qualité de leur historique de shell.

← Précédent
PostgreSQL vs Percona Server : mythes de performance — pourquoi « c’est plus rapide » dépend de la charge
Suivant →
Vdevs ZFS : la règle qu’on enfreint une fois et regrette pour toujours

Laisser un commentaire