# Multi-instance & fédération > **Unité d'apprentissage.** Moule : ① concept → ② Set-OPS → ③ transférable → ④ à toi de jouer. --- ## ① Le concept *(générique)* Un même **moteur** peut opérer **plusieurs écosystèmes** (organisations, clients, environnements). Trois questions se posent : - **Isolation** — chaque écosystème (*tenant*) doit être étanche : ses données, son identité, son réseau ne touchent pas ceux des autres. - **Cohabitation sans collision** — si plusieurs tenants partagent une infrastructure physique (mêmes switches, même hyperviseur), leurs adresses et VLAN doivent être **uniques globalement**, sinon le réseau se marche dessus. - **Découverte** — comment le système sait-il *quels* écosystèmes existent ? Par un **registre** central (qu'il faut tenir à jour) ou par **convention** (ils se reconnaissent d'eux-mêmes) ? --- ## ② Comment Set-OPS le fait **Un dépôt par écosystème.** L'écosystème actif est celui que pointe le symlink `instance/`. Les autres sont des **dépôts frères** (`../OPS-Chezlepro`, `../OPS-Technolibre`…). **Découverte par convention, pas de registre.** Une instance *est* un dossier frère avec un `plan/nomenclature.yml` portant un `index`. Le code fait `glob('../*/plan/nomenclature.yml')` — rien à inscrire nulle part. Déposer une instance à côté des autres suffit. **Le seed garantit l'unicité.** Chaque tenant a un `index` distinct → adressage dérivé sans chevauchement possible : VLAN `1000+index×10+zone` (les VLAN de deux index différents ne peuvent *mathématiquement* pas se croiser). Plafond : **245** écosystèmes fédérés (borne IPv4). **Gérer la flotte :** - `make instances` — la vue d'ensemble : qui existe, l'active (★), index, VLAN, **collision** ; - `make instance-utiliser NOM=…` ou le bouton **« Activer »** de la GUI (vue Réseau) — basculer ; - `make instance-creer NOM=… MODELE=…` — créer une instance depuis un modèle ; - `make model-creer …` — créer/promouvoir un **modèle** (le produit). **Garde-fous.** `federe: false` exclut un bac à sable local du réseau convergé. La **preuve P21** échoue si deux instances fédérées partagent un `index`. **Qui route les tenants : deux mondes.** L'adressage dérive toujours du seed `index`, mais *qui* l'applique se déclare — `underlay.routage_tenants` : | | `switch` | `sdn` | |---|---|---| | Passerelle d'une zone | **SVI** sur le commutateur L3 | **anycast** sur chaque hyperviseur | | Isolation inter-tenant | ACL de commutateur | **VRF** (une zone EVPN par tenant) | | Sur le fil | VLAN étiquetés par zone | **VXLAN** — aucun VLAN de tenant ne circule | | Inter-tenant | bloqué par ACL | sort du VRF → **passe par la frontière** | Le `.1` d'une passerelle ne change pas d'adresse d'un monde à l'autre : il **change de porteur**. C'est la même dérivation, appliquée ailleurs. **Le devis du commutateur.** `make devis-reseau` dérive la config à coller. En mode `switch` : VLAN par zone, SVI, ACL d'isolation. En mode `sdn` : rien de tout ça — le commutateur redevient un **transport IP** qui achemine du VXLAN sans le lire, et le devis dit à sa place pourquoi ces sections ont disparu. **Le devis de la frontière.** `make devis-opnsense` dérive la politique de bordure du **même** registre des flux — les flux `pair: externe`, que le pare-feu d'hôte saute justement parce qu'ils relèvent de la bordure. Rien n'y est saisi : ni port, ni adresse, ni nom d'hôte. **Le dialecte de CLI.** Toutes les CLI de commutateur ne se ressemblent pas. Set-OPS génère par défaut du **Cisco**, mais connaît aussi le **Binardat**, qui diffère sur des détails capables de faire *passer un VLAN mais fuir un tenant* : | | Cisco | Binardat | |---|---|---| | Masque d'ACL | **inversé** (wildcard `0.0.255.255`) | **normal** (`255.255.0.0`) | | Commentaire d'ACL | `remark …` | **absent** (omis) | | Route statique | `ip route ` | **CIDR** : `ip route 0.0.0.0/0 ` | *(Le SVI `ip address … 255.255.255.0` est en masque normal sur les deux.)* Le dialecte est un **intrant** — section *Fabric* du panneau — surchargeable par `--dialecte` ou `SETOPS_DIALECTE`. **Le dépôt public reste générique** (`cisco`). > **La leçon qui vaut au-delà de Set-OPS.** Trois de ces formes ont été *supposées* avant d'être > confrontées au matériel ; deux étaient fausses. La pire ne levait aucune erreur : > `switchport trunk allowed vlan **add** …` *ajoute* à la liste courante, et sur un port neuf > qui autorise déjà tout, elle ne retranchait rien. La configuration avait l'air d'isoler et > n'isolait pas. **Une commande acceptée n'est pas une commande qui fait ce qu'on croit.** **L'underlay — le sous-sol.** Les VLAN tenant (`1000+index×10+zone`) sont les *overlays*. En dessous vit la **fabric physique** partagée par toute la flotte : management des switches et de Proxmox/OOB, iSCSI, Ceph (public + cluster). Elle **n'appartient à aucun tenant** et ne dérive d'aucun `index`. On la décrit dans `underlay.yml`, qui vit dans le dépôt de **l'hébergeur** (ses switches, ses câbles) et que le moteur monte par symlink à sa racine — comme il monte le plan par `instance/`. Ce lien ne suit pas `make instance-utiliser` : la fabric reste celle de l'hébergeur, quel que soit le tenant actif. Gabarit : `underlay.yml.example`. | Underlay | VLAN | Sous-réseau | Fabric | |---|---|---|---| | management (commutateurs, Proxmox, OOB) | 10 | `10.0.0.0/24` | principale | | **transit** vers la frontière | 40 | `10.0.4.0/29` | principale | | stockage / iSCSI | 20 | `10.0.1.0/24` | stockage | | ceph-public | 30 | `10.0.2.0/24` | stockage | | ceph-cluster | 31 | `10.0.3.0/24` | stockage | Deux choses à retenir de cette table. **Les fabrics.** Tous les réseaux ne partagent pas les mêmes câbles. Le stockage jumbo peut vivre sur ses propres commutateurs ; le devis de l'une ne déclare alors rien de l'autre, et le dit — `HORS PERIMETRE`. Un devis est une configuration qu'on applique, pas un inventaire. **Le transit.** C'est le lien entre le routeur et la frontière, et **sans lui la flotte n'a ni sortie ni chemin de retour**. Il vit dans l'underlay parce qu'il est *partagé* : la frontière route vers tous les tenants par ce même saut, il ne peut donc dériver d'aucun `index`. > **Le piège qui a coûté une passe de déploiement.** La route *aller* ne suffit pas. Sans route > de **retour** vers le réseau d'administration, la réponse d'une VM sort par une autre > interface que celle où l'état a été créé, et le pare-feu la jette **en silence** — ni réponse, > ni message d'erreur. Symptôme déroutant : la passerelle répond au ping, aucun hôte derrière > elle n'est joignable. On cherche une règle de pare-feu ; c'est une route manquante à l'autre > bout. En mode `sdn`, ces réseaux transportent du VXLAN : leur **MTU doit atteindre 1550** au minimum, sinon le ping passe et les transferts échouent. `make underlay` le refuse. `make underlay` l'affiche et le **valide** : VLAN < 1000 et sous-réseaux hors des supernets tenant (`10.(10+index).0.0/16`) — **aucune collision possible** avec les overlays. `make devis-reseau` en émet la config (section 0) et l'ajoute au trunk. La **preuve P23** garde la règle ; elle est *sautée* si aucun `underlay.yml` n'est défini. --- ## ③ Pourquoi c'est transférable | Set-OPS | Équivalents ailleurs | |---|---| | un moteur, N tenants | **multi-tenancy** SaaS, *cloud accounts/projects* | | isolation par VRF (zone EVPN) | VRF matériel, VPC, *namespaces* Kubernetes | | découverte par convention | *convention over configuration* (Rails, etc.) | | tenants NetBox | modèle de source de vérité multi-tenant | Tu as appris **le multi-tenant, l'isolation réseau, la convention plutôt que la configuration** — pas « le symlink de Set-OPS ». --- ## ④ À toi de jouer 1. **Vois la flotte.** `make instances` : l'active (★), les index, les VLAN, le statut fédéré/local. Repère qui est en **production**. 2. **Bascule.** GUI, vue **Réseau**, bouton **« Activer »** sur une autre instance (ou `make instance-utiliser NOM=…`). Toutes les vues suivent — sans redémarrer. 3. **Crée une instance.** `make instance-modeles` (les modèles dispo), puis `make instance-creer NOM=OPS-Test MODELE=socle INDEX=4`. Un écosystème neuf, en une commande. 4. **Éprouve le garde-fou de collision.** Essaie de créer une instance avec un `index` **déjà pris** : refus *avant* toute copie. Puis `make prouver` → **P21** veille sur la fédération. 5. **Casse & répare.** Donne à deux instances fédérées le **même** index (édite une nomenclature), `make instances` : la **bannière de collision** s'allume ; `make prouver` : P21 échoue. Corrige l'index : tout redevient vert. 6. **(Avancé) Promeus un produit.** Une instance qui *tourne et se prouve* peut devenir un modèle vendable : `make model-creer MODE=instance SOURCE=OPS-… NOM=…` — elle est **généralisée** (identité → `exemple.*`, secrets retirés) et **validée**. --- ## Pour aller plus loin *(dépôt)* - Le guide complet : `docs/multi-instances.md`. - Le seed et la dérivation : unité **[Le plan & l'adressage dérivé](Le-plan-et-l-adressage-dérivé)**. - L'isolation réseau (VLAN, ACL, OPNsense) : `make devis-reseau` + `scripts/devis_reseau.py`. - Les garde-fous prouvés : unité **[La preuve](La-preuve)** (P21).