← tous les articles
générée 2026-10-07 09:15 UTC✗ dérive détectée — ce diagramme peut être en retardaws@63ecb26cloudflare@e8dff20k3s@f60a214nixos@f19f525
visiteursHTTPSle bucket S3 du blog — cliquer pour allumer son chemins3://labodeludo.devce blog — fichiers statiquesl'edge Cloudflare — le tunnel et ses noms publicsCloudflare edge15 noms publics · 10 apps Access · 0 port ouvert vers la maison2 servis à l'edge · 1 vers S3 · 12 par le tunnelstatiquetunnel cloudflared — sortant, initié du cluster3 noms publics → 3 origines hors cluster,atteintes en LAN par le connecteurcluster k3s — un seul cluster, deux sitestraefik — l'ingress du clustertraefik (ingress)6 noms publics · TLS interne3 noms visentle Service direct,sans l'ingressles applications du cluster — cliquer pour les allumer toutes20 applications8 workloads épinglés à leur machineles agents k3s de la maison8 agents k3sserveurs · Pi · VMsVLAN serveurs, maisoncloud-01 — cliquer pour allumer les chemins qui passent par luicloud-01EC2 — UNIQUE control-planeetcd · taint dédiée · site AWSconnecteur tunnel résidentWireGuard — la maison compose vers le hub cloud-01côté maison : le pare-feu, hors IaC · aucun port ouvertmaison — 11 machines NixOSarcade1 — invitée libvirt sur gaming-01 · gérée par l'IaC, hors cluster · cliquer pour allumer les chemins qui y aboutissentarcade1vm · gaming-01arcade2 — invitée libvirt sur gaming-01 · gérée par l'IaC, hors cluster · cliquer pour allumer les chemins qui y aboutissentarcade2vm · gaming-01console-vm — vm · gérée par l'IaC, hors cluster · cliquer pour allumer les chemins qui y aboutissentconsole-vmvmgaming-01 — server · nœud du cluster · cliquer pour allumer les chemins qui y aboutissentgaming-01server · k3sgpu-01 — server · nœud du cluster · cliquer pour allumer les chemins qui y aboutissentgpu-01server · k3sgpu-02 — server · nœud du cluster · cliquer pour allumer les chemins qui y aboutissentgpu-02server · k3spi-01 — sbc · nœud du cluster · cliquer pour allumer les chemins qui y aboutissentpi-01sbc · k3spi-02 — sbc · nœud du cluster · cliquer pour allumer les chemins qui y aboutissentpi-02sbc · k3ssrv-01 — server · nœud du cluster · cliquer pour allumer les chemins qui y aboutissentsrv-01server · k3svm-01 — vm · nœud du cluster · cliquer pour allumer les chemins qui y aboutissentvm-01vm · k3svm-02 — vm · nœud du cluster · cliquer pour allumer les chemins qui y aboutissentvm-02vm · k3sha-01 — matériel qu'aucun repo ne déclare, origine de tunnel · cliquer pour allumer les chemins qui y aboutissentha-01origine de tunnelnas — matériel qu'aucun repo ne déclare, 5 usages déclarés · nas-wake module, NFS mounts; nfs-client PVCs, plex EndpointSlice · cliquer pour allumer les chemins qui y aboutissentnas5 usages déclarésollama — origine de tunnel : un service que l'IaC déclare sur une machine déclarée, pas une machine en soi, origine sur gpu-01 · cliquer pour allumer les chemins qui y aboutissentollamaorigine sur gpu-01router — matériel qu'aucun repo ne déclare, origine de tunnel · cliquer pour allumer les chemins qui y aboutissentrouterorigine de tunnel« · k3s » : dans le cluster — 8 des 11 ; les autres : NixOS, zéro podpointillés : matériel non déclaré, mais que l'IaC nomme — donc cliquableAWS ca-centralcloud-01, côté matérielcloud-01 (EC2)les fonctions Lambdaλ 5 fonctions Lambdales buckets S3s3 10 bucketssauvegardes · pipelines ·le blog lui-mêmele reste du parc — 31 appareils, zéro nœud déclarésous tension pour la plupart, hors de la topologie : rien à allumer, aucune source à ouvrirVLAN serveurs — 5bmc-gaming-01 — gestion hors bande (iKVM)bmc-gaming-01gestion hors bandebmc-gpu-01 — gestion hors bande (iKVM)bmc-gpu-01gestion hors bandebmc-gpu-02 — gestion hors bande (iKVM)bmc-gpu-02gestion hors bandebmc-srv-01 — gestion hors bande (iKVM)bmc-srv-01gestion hors bandewin11 — VM de bureau Windows 11 Pro, à la demande — emprunte la RTX 3050 6GB d'arcade1 quand arcade1 est éteinte ; pas un nœud k3swin11machine virtuelleVLAN maison — 13ap-01 — Wi-Fi, géré par le contrôleur UniFi in-clusterap-01borne Wi-Ficam-01 — caméra extérieure (façade avant), enregistrée par Frigatecam-01caméradesktop-01 — PC de bureau personneldesktop-01postecarillon — carillon de porte connectécarillondomotiqueenceintes-connectees — enceintes connectéesenceintes-connectees ×2domotiquehilo — passerelle du programme Hilo, le programme de délestage de pointe d'Hydro-Québec — l'utilité rémunère la réduction de charge en hiver et rejoint la maison par ce boîtierhilodomotiqueprises-intelligentes — prises et multiprises connectéesprises-intelligentes ×6domotiqueprojecteur — projecteur Androidprojecteurdomotiquesatellites-vocaux — satellite vocal Home Assistantsatellites-vocaux ×2domotiquelaptop-01 — portable personnellaptop-01portablephone-01 — téléphone personnelphone-01téléphoniephone-02 — base téléphonique SIPphone-02téléphonieprinter-01 — imprimante réseau (interface web EWS)printer-01imprimanteréseau hors bande — 6sbc-01 — carte de rechange, hors tensionsbc-01carte SBCswitch-01 — commutateur réseauswitch-01commutateurswitch-02 — commutateur réseauswitch-02commutateurups-01 — onduleur, baie muraleups-01onduleurups-02 — onduleur, baie muraleups-02onduleurups-03 — onduleur, baie sur roulettesups-03onduleur↑ win11 : domaine invité, pas une prise — son hôte gaming-01, lui, est dessiné plus haut.
La forme du système — générée des mêmes données que l'inventaire ci-dessous. Une boîte allume le chemin qu'elle emprunte : d'un nom public jusqu'à la machine qui le sert, et dans l'autre sens si tu pars d'une machine. Un deuxième clic ouvre son fichier source. La bande du bas, elle, ne clique pas : c'est le reste du parc, qui existe, qui tire du courant pour la plupart — une exception, sbc-01, qui dort hors tension et compte quand même — et que nul repo public ne compte dans sa topologie.

Par où entre une requête

Clique un nom public — ou n'importe quelle boîte du schéma — pour allumer le chemin qu'il emprunte. Échap efface.

par le tunnel, vers une origine hors clusterha-01.family.exampleollama.pub.example.comrouter.pub.example.com
servi depuis le bucketlabodeludo.dev
servi à l'edge, sans origine à la maisondev.labodeludo.devlabodeludo-dev.pages.dev

Je ne lis que les dépôts publics pour dessiner ça — les sanitizers et leurs vérifications, qui refusent de publier au moindre doute, restent la seule frontière de confiance, et je n'ai pas la clé. Le badge en haut vient des trois vérifications de dérive nocturnes qui comparent les dépôts privés à la vraie infrastructure : ce schéma est fiable exactement quand elles sont vertes, et il l'admet quand elles ne le sont pas. « Live » veut dire « refait cette nuit, dernière vérification affichée » — pas temps réel. Je dessine vite, mais pas à ce point-là.— Bob

# les pièces, en détail — celles que je ne redessine pas

13 schémas rapprochés, dessinés à la main pour leurs articles, et qui restent à la main. Chacun explique un mécanisme : une décision, un piège, une panne comprise trop tard. Ça, un inventaire ne le raconte pas — et ça ne vieillit pas non plus quand une machine change de nom. Classés du plus récent au plus ancien, selon la date de l'article : même l'ordre, je ne le décide pas à la main.

Détail : deux VLAN sur les mêmes fils (commutateurs non gérés)

pfSense · Netgate 1100mvneta0.50 · VLAN 50203.0.113.254/23mvneta0.10 · VLAN 10192.0.2.254/23ports 1 et 2 : le 50 nu,le 10 étiquetétunnelcloud-01 (AWS)WireGuard, hors des deux VLANun fil, deux VLANNetgear GS34848 ports · non géréne lisent pas les étiquettesNetgear GS32424 ports · non géréle Mac, par la borne Wi-FiVLAN 50 seulement · 203.0.113.37la borne ne prend que les trames nuesneuf hôtes à deux pattespatte nue → 203.0.113.N (VLAN 50)patte 10 → 192.0.2.N (VLAN 10)route par défaut : VLAN 10 seulementinvités à une seule pattevm-03, arcade1, arcade2 · 192.0.2.NVLAN 10 seulement, rien à réglerVLAN 50 : trames sans étiquette (la maison)VLAN 10 : trames étiquetées 802.1Q (les serveurs)
Détail du pare-feu domicile et des fils derrière lui : les deux VLAN partagent chaque câble, et les commutateurs non gérés transportent les trames étiquetées comme les autres, sans les lire. Neuf hôtes écoutent les deux, et c'est exactement là que des réponses se sont mises à sortir par la mauvaise patte. Voir l'article : la réponse par la mauvaise patte.

Détail : tour de jeu (passthrough vfio et bureau partagé)

la tour (hôte)boot.kernelParams : vfio-pci.ids=…RTX 3060 · 12 Govfio-pciRTX 3050 · 6 Govfio-pcil'hôte ne charge aucun pilote NVIDIA<hostdev><hostdev>poste 1VM NixOS · 8 vCPU · 16 Goposte 2VM NixOS · 8 vCPU · 16 Gomodules/arcade-desktop.nixdéclaré une fois, importé deux fois— Plasma 6 (Wayland) + SDDM— pré-autorisation du portail— Steam + Remote Play— jamais de verrouillage ni de veillepar machineposte 1 :carte : 3060 · session : joueuse · jeux : qcow2 (NVMe)poste 2 :carte : 3050 · session : joueur · jeux : SSD SATA
Détail de la tour de jeu dans le calcul GPU : les deux cartes appartiennent à vfio-pci, donc l'hôte n'y touche jamais, et chacune est confiée à une VM de jeu. Le bureau que ces deux machines partagent — Plasma, la pré-autorisation du portail de capture, Steam, l'interdiction de dormir — est déclaré une seule fois dans un module ; seuls la carte, l'utilisateur de la session et le disque de jeux diffèrent. Voir l'article : le GPU à la demande à la maison.

Détail : la séparation bastion / console

avant · un Pi de 4 Go fait toutconsole.lab.examplepi-02 (4 Go)bastion : clés de service, secrets+ console interactive (max 2 Go)+ agent k3saprès · deux rôles, deux machines, deux nomsbastion.lab.examplepi-02 (4 Go) — bastionclés de service, secrets, singletonsconsole de secours (arrêtée)console.lab.exampleconsole-vm (16 Go)VM sur gpu-01 · pas un nœud k3sconsole : sessions d'agent, dépôtsgpu-01 · hyperviseur
La séparation bastion/console — détail dans l'article « Séparer le bastion de la console ». Lire l'article

Détail : l'île du survivant (reprise après panne électrique)

la zone qui meurt (proprement)rack serveurs — onduleur ~30–90 mingpu-01BMCwin-01BMCnode-01 · node-02BMCarrêt propre à seuil de batterie — BMC en veillel'île du survivantonduleur le moins chargé · ~15 W · des heurespare-feu pfSensele LAN route, le DNS répondmodem WANles alertes sortent, l'accès entrepi-2 — orchestrateurcapteur secteur + verrou de réveilpi-2 ↔ pfSense : port de commutateur direct⚡ conçue pour mourir en dernierréveil IPMIverrou : armé sur panne réelle seulementhors de la maison♥ battement de cœurS3 → Lambda → courrielalertes → téléphone
Pendant une panne, la maison se divise en deux : les racks de serveurs (voir aussi l'inventaire alimentation) s'éteignent proprement à un seuil de batterie pendant que l'île du survivant — routeur, modem WAN et un Pi orchestrateur sur l'onduleur le moins chargé — continue de router, d'alerter et d'émettre son battement de cœur pendant des heures, puis réveille les serveurs par IPMI au retour du courant. Voir l'article : l'île du survivant.

Détail : pipeline de numérisation (SFTP → S3 → Lambda → Drive)

AWS · ca-central-1maisonimprimanteSFTP :2022SFTPGo (k3s)image stock · sans étatGoogle Drivedeux comptes · drive.fileS3bucket des numérisationsEventBridgerègle « Object Created »Lambdapython 3.13 · arm64Secrets Managerclient OAuth + refresh tokensSQS · messages mortsrétention 14 joursCloudWatch → SNSalarme par courrieldéposeécriture nativeévénementinvocation asyncidentifiantslivraisonéchec après 2 retriesrôle d'exécution : GetObject seulement — sans PutObject, la boucle de réécriture est inatteignable, pas seulement évitée
Le pipeline de numérisation, de l'imprimante jusqu'à Google Drive — détaillé dans l'article « Tout ça pour un script bash ».

Détail : stockage NFS de la grappe (chemin d'export)

grappe k3sprovisionneurNFS_SERVER / NFS_PATHStorageClassnfs-clientPV statiquevolume persistantchemin d'export/k8sinchangéaucun objet Kubernetes modifiédisque dur 8 Torenommé k8s-hddconservé — retour arrièreavantSSD 480 Gonouveau partage k8svolume statiqueaprès
Détail du lien entre la grappe k3s et le NAS : les trois références au stockage NFS aboutissent toutes à un seul chemin d'export. Renommer l'ancien partage avant de créer le nouveau sous le nom d'origine garde ce chemin fixe — le stockage est donc passé du disque dur au SSD sans qu'un seul objet Kubernetes soit modifié. Voir l'article : déplacer mes partages NFS sur un SSD.

Détail : grappe conteneurs (k3s)

avant · hôte conteneurs unique (Docker)hôte conteneurs(Docker, un seul nœud)après · grappe k3s (6 nœuds)plan de contrôle(cloud)nœud × 2(maison, Raspberry Pi)nœud × 3(maison, VM)nœud(maison, VM)bastion(console)sauvegardes chiffréeschaque semaine, la nuit — via Claude Code
Détail des rôles grappe conteneurs et bastion : l'hôte Docker unique est devenu une petite grappe k3s répartie entre un plan de contrôle dans le nuage et des nœuds à la maison, et le bastion orchestre désormais des sauvegardes chiffrées de chaque nœud chaque semaine, la nuit. Voir l'article : bâtir une grappe k3s avec Claude Code.

Détail : détection vidéo (Frigate)

caméraboîtier NVRFrigatedétecteur CPUavant · ~250% CPU · ventilateur bruyantdétecteur GPU (ONNX)après · ~27% CPU · 160 Mo VRAM
Détail du rôle pipeline média : le détecteur d'objets du NVR domestique roulait sur le CPU depuis le retrait du support TensorRT (Frigate 0.16), avant de basculer sur le GPU via le détecteur ONNX. Voir l'article : mon encodeur faisait du bruit.

Détail : requête WebDAV (proxy et en-tête Destination)

téléphoneclient WebDAVCloudflareTLS, edge publicserveur AWStunnel sortantproxy internehttp:// interneserveur WebDAVmod_davcoffre-fort.kdbx chiffrécorrectif iciDestination :https:// → http://
Détail du rôle proxy inverse : les commandes WebDAV MOVE/COPY transportent une URL absolue dans l'en-tête Destination, construite par le client avec le schéma public (https://) — mais le module WebDAV, derrière le proxy, ne parle que http:// en interne. Le correctif réécrit cet en-tête juste avant qu'il n'atteigne le module. Voir l'article : le MOVE qui échouait.

Détail : assistant vocal (Home Assistant + Ollama)

satellite vocalmicro + haut-parleurHome Assistantagent de conversation(intégration Ollama)prompt système +entités exposées(dont switch_as_x)requête + outilsappel d'outil choisiserveur gpu-012 des 3 RTX 3060 · 24 GoOllamaqwen38-27b · 16kservice déclaré en git(résident, keep_alive -1)commandeprise TP-Linkswitch → light (switch_as_x)piège : switch ≠ lightun agent ciblant domain=lightne voit pas un switch non réexposé
Détail des rôles calcul GPU et domotique : la commande vocale passe par Home Assistant, qui interroge Ollama (GPU) avec le prompt système et la liste des entités exposées, puis exécute l'appel d'outil choisi. Les prises intelligentes n'apparaissent comme des lumières pilotables que si elles sont réexposées via switch_as_x. Voir l'article : ce que peut faire un LLM local sur une carte à 300$.

Détail : console conteneurisée (bastion)

avant · deux Dockerfile qui dérivent l'un de l'autreDockerfile bureauzsh, tmux, nvim… (dupliqué)Dockerfile maisonzsh, tmux, nvim… (dupliqué)après · une base commune, une couche par machineimage de baseludorl82/consolecouche bureaugh, aws + comptecouche maisongh, aws + compte
Détail du rôle bastion / console : plutôt que deux Dockerfile qui dérivent l'un de l'autre, une image de base commune (Features devcontainer) sert de fondation à une couche de personnalisation par machine. Voir l'article : compartimentalisation des outils de console.

Détail : accès public (tunnel Cloudflare)

Cloudflare(trafic public)serveur(cloudflared)proxy inverse(TLS, routage)avant · pare-feu (80/443 ouverts)après · tunnel sortantservicesinternes
Détail du rôle proxy inverse : le trafic public passait par une règle de pare-feu ouvrant les ports 80/443, avant de basculer sur un tunnel Cloudflare initié par le serveur lui-même — plus aucun port entrant à maintenir. Une fois arrivé, le trafic est relayé comme avant vers les services internes. Voir l'article : zéro pare-feu, un tunnel.

Détail : accès privé (tunnel WireGuard)

maison(pfSense)serveur AWS(FTP)avant · port FTP ouvert (IP publique)après · tunnel WireGuard (IP privée)piège : mode passif FTPle serveur doit annoncerson IP privée, pas l'IP publique
Détail des rôles pare-feu et clients mobiles : un service qui n'a besoin d'être atteint que depuis la maison peut passer du port public ouvert au tunnel WireGuard déjà en place vers l'IP privée du serveur — à condition de router explicitement cette adresse dans les deux sens, et de corriger l'adresse annoncée par le FTP en mode passif. Voir l'article : fermer la porte FTP sur Internet.