En préparant le déplacement des VTEP, la lecture des interfaces a montré que `underlay.yml` annonçait 9000 alors que vmbr3 est à 1500. La garde P23 exigeait >= 1550 et passait parce que le fichier mentait. Une garde qui valide une déclaration plutôt qu'une réalité donne un faux confort — pire qu'une garde absente, qui au moins n'endort personne. Le seuil ne peut pas être fixe non plus : 1550 aurait rejeté à tort un transport à 1500 portant un overlay à 1450, qui tient exactement. Il dérive d'un `mtu_overlay` déclaré : transport >= overlay + 50. Exercé. Trouvé aussi : vmbr3 n'est pas VLAN-aware. L'adresse du VTEP y est non étiquetée et vit dans le VLAN natif du port. Déplacer le VTEP n'est donc pas un changement d'adresse — il faut un VLAN natif 10 ou une interface étiquetée dédiée. C'est pourquoi le déplacement n'a pas été effectué. Preuves : 24 OK, 0 échec. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
177 lines
9.7 KiB
Markdown
177 lines
9.7 KiB
Markdown
# SDN EVPN : le routage passe aux hyperviseurs
|
|
|
|
> **Décision d'architecture du 2026-08-02.** Elle remplace le routage inter-zone sur les
|
|
> commutateurs L3 par des zones EVPN de Proxmox SDN. Complète `docs/frontiere-opnsense.md`
|
|
> (la bordure, inchangée) et `underlay.yml.example` (la fabric, très allégée).
|
|
>
|
|
> **Décidé le 2026-08-03** : une zone EVPN **par tenant** ; le routage **et le filtrage**
|
|
> entre les VLAN d'un même tenant se font à ce niveau ; le trafic **inter-tenant passe
|
|
> obligatoirement par l'OPNsense**.
|
|
|
|
## 1. Ce que la décision résout
|
|
|
|
Les commutateurs Binardat ne savent pas lier une ACL à une interface de routage : l'isolation
|
|
inter-tenant ne pouvait pas vivre sur la fabric. On l'a d'abord assumé — tout sur les nftables
|
|
d'hôte — en notant ce qu'on perdait : **le plan de gestion n'avait plus de protection réseau
|
|
contre les tenants**, une VM émettant vers `10.0.0.x` étant routée localement vers le mgmt des
|
|
commutateurs, celui de Proxmox et l'OOB/IPMI.
|
|
|
|
**Une zone EVPN est un VRF.** Le tenant n'a plus de route vers l'underlay — celui-ci n'est pas
|
|
dans sa table de routage. Son seul chemin vers l'extérieur passe par le nœud de sortie, donc
|
|
par l'OPNsense, qui filtre. Le plan de gestion redevient protégé **par construction**, pas par
|
|
une règle qu'on pourrait oublier.
|
|
|
|
C'est le VRF qu'on regrettait de ne pas avoir dans le matériel, obtenu en logiciel.
|
|
|
|
## 2. La projection du modèle
|
|
|
|
Vérifiée sur les deux tenants fédérés, elle ne demande **aucun changement de dérivation** :
|
|
|
|
| Objet Proxmox SDN | Vient de | Exemple (Chezlepro, zone Services-infra) |
|
|
|---|---|---|
|
|
| **zone** (un VRF) | le tenant | `CHEZ17` |
|
|
| **VNet** | la zone de sécurité | `chez17-services-infra` |
|
|
| **tag** (VNI) | `vlan_de(index, zone)` | `1174` |
|
|
| **subnet** | `sous_reseau_de(index, zone)` | `10.27.19.0/24` |
|
|
| **gateway** | `passerelle_de(index, zone)` | `10.27.19.1` |
|
|
|
|
Le seed `index` reste la source unique. Le `.1` ne change pas d'adresse, il **change de
|
|
porteur** : du SVI d'un commutateur vers la passerelle **anycast** du VNet, présente sur
|
|
chaque hyperviseur — donc plus proche de la VM, et sans point unique de défaillance.
|
|
|
|
Effet de bord favorable : un VNI est codé sur 24 bits là où un VLAN plafonne à 4094. La limite
|
|
du nombre de tenants n'est plus l'espace de VLAN mais le second octet IPv4 du supernet — le
|
|
plafond de 245 tenants reste, sa cause change.
|
|
|
|
## 3. Le partage des responsabilités
|
|
|
|
| Trafic | Où il est routé | Où il est filtré |
|
|
|---|---|---|
|
|
| **entre zones d'un même tenant** | zone EVPN du tenant (VRF, sur les hyperviseurs) | **au même endroit** |
|
|
| **entre tenants** | sort du VRF → nœud de sortie → **OPNsense** | la frontière, et elle seule |
|
|
| **vers l'extérieur** | idem | la frontière |
|
|
| **de service à service, sur un hôte** | — | nftables d'hôte, `policy drop` |
|
|
|
|
Deux conséquences qui méritent d'être dites.
|
|
|
|
**L'inter-tenant ne peut plus être « oublié ».** Il ne circule pas latéralement : il doit
|
|
sortir du VRF, donc traverser la bordure, qui est en `block` par défaut. Un flux inter-tenant
|
|
légitime devra être **déclaré** pour exister — le registre des flux n'a pas encore de mot-clé
|
|
pour ça, c'est un point ouvert.
|
|
|
|
**Le commutateur ne voit plus rien du trafic tenant.** Il transporte du VXLAN qu'il ne lit
|
|
pas. Y chercher une trace d'un problème applicatif serait perdre son temps : le miroir utile
|
|
est sur l'hyperviseur.
|
|
|
|
## 4. Ce que le devis switch devient
|
|
|
|
C'est fait, et piloté par `underlay.routage_tenants: sdn`. Disparaissent : les VLAN tenants, les SVI de zone, les ACL d'isolation,
|
|
et les VLAN tenants dans les trunks. En EVPN, **aucun VLAN de tenant ne circule sur le fil** —
|
|
seulement du VXLAN encapsulé dans de l'IP.
|
|
|
|
Restent : les VLAN d'underlay, le SVI de management, les trunks qui ne portent plus qu'eux,
|
|
les routes, le spanning-tree. La fabric redevient ce qu'elle aurait dû être — un **transport
|
|
IP**.
|
|
|
|
`underlay.routeur` garde son sens, mais son rôle se réduit : il route l'underlay, plus les
|
|
tenants.
|
|
|
|
## 5. Ce que ça change ailleurs
|
|
|
|
**Le nœud de sortie remplace le prochain saut.** En EVPN, le trafic quitte le VRF par un ou
|
|
plusieurs *exit nodes* désignés. Ce sont eux, et non plus le commutateur, que l'OPNsense voit
|
|
comme voisins.
|
|
|
|
C'est **appliqué** : en mode `sdn`, le devis frontière n'émet plus le SVI du commutateur comme
|
|
prochain saut des routes tenants — il émet le marqueur `<NOEUD-DE-SORTIE-EVPN>` et dit
|
|
pourquoi. Une route pointée vers le SVI arriverait sur un équipement qui n'a aucun chemin vers
|
|
le tenant : c'est le genre de configuration qui s'applique sans erreur et ne fonctionne pas.
|
|
|
|
À noter : `underlay.passerelle_sortie` **garde** son sens — c'est l'adresse du pare-feu sur le
|
|
lien de transit, donc la sortie de l'**underlay**, indépendante du routage tenant. Ce sont
|
|
deux choses distinctes qu'il ne faut pas confondre.
|
|
|
|
**L'overlay est plafonné à 1450** (décision du 2026-08-03) parce que le transport réel — le
|
|
pont `vmbr3` des hyperviseurs — est à **1500** : 1450 + 50 de VXLAN y tient exactement. Conséquence à ne pas manquer : sous 1500, **tout ce qui traverse la frontière dépend de
|
|
la découverte de MTU de chemin**, qui a besoin de l'ICMP « fragmentation nécessaire ».
|
|
|
|
Or le registre des flux ne connaissait que TCP et UDP : ce message ne pouvait pas être
|
|
*déclaré*, et la bordure en `block` l'aurait jeté. Symptôme : la connexion s'établit, les
|
|
petites requêtes passent, les grosses réponses restent suspendues. `protocole: icmp` est
|
|
désormais admis — le champ `port` porte alors le **type** (`frag-needed`) — et le socle déclare
|
|
les deux sens.
|
|
|
|
**Le MTU du transport est un prérequis vérifié, pas un conseil.** VXLAN ajoute 50 octets ; `make underlay`
|
|
**refuse** un réseau de transport sous 1550 dès que `routage_tenants: sdn`. C'est le premier
|
|
mur, et le plus déroutant : il ne casse pas franchement, il casse **partiellement** — le ping
|
|
passe, les transferts échouent.
|
|
|
|
**Ce qui ne change pas** : le plan, le registre des flux, les nftables d'hôte, la frontière
|
|
OPNsense et ses règles dérivées, la voûte, les preuves. La cible d'émission change ; le modèle
|
|
non.
|
|
|
|
## 6. Ce qui reste à éprouver — avant toute génération
|
|
|
|
Le principe du dépôt s'applique : **éprouver l'outil avant d'écrire le rôle.** L'EVPN est la
|
|
partie la plus jeune de Proxmox SDN, et c'est là que vivent les bogues.
|
|
|
|
Un tenant de labo, une zone EVPN, deux VNet, une VM dans chacun — et vérifier dans l'ordre :
|
|
|
|
1. le MTU de bout en bout, avec des paquets pleins et le bit *don't fragment* ;
|
|
2. le routage **entre VNet d'une même zone** (c'est ce qui remplace le SVI du commutateur) ;
|
|
3. l'**absence** de route vers l'underlay depuis le tenant — c'est le gain principal, il se
|
|
vérifie par une tentative qui doit échouer ;
|
|
4. la sortie par le nœud de sortie, jusqu'à la bordure ;
|
|
5. le comportement à la **perte d'un nœud** : la passerelle anycast est censée survivre.
|
|
|
|
Ce n'est qu'après que la question « comment générer cette configuration » se pose.
|
|
|
|
## 7. L'état réel du cluster (reconnaissance du 2026-08-03)
|
|
|
|
Lecture seule par l'API Proxmox. **Le plan de contrôle existe, le plan de données non.**
|
|
|
|
| | |
|
|
|---|---|
|
|
| Proxmox | 8.4.19 — `asgard`, `gandalf`, `vishnu` |
|
|
| Contrôleur | `EVPN0017`, ASN 65000 |
|
|
| Zones | `VRF0011`, `VRF0017` — un VRF par tenant, VNI = index, MTU 1450 |
|
|
| VNets | **aucun** |
|
|
| Nœuds de sortie | **aucun** |
|
|
|
|
### Deux blocages à lever avant d'aller plus loin
|
|
|
|
**Les VTEP sont adressés dans un tenant.** `vmbr3` porte `10.27.19.{41,43,47}` — le
|
|
sous-réseau *Services-infra de Chezlepro*. Le transport du cluster dérive donc de l'index d'un
|
|
tenant : un changement d'index le casse, une migration l'emporte. Et une VM de cette zone
|
|
partage son sous-réseau avec les trois VTEP, ce qui perce l'isolation à l'endroit même que
|
|
l'EVPN devait fermer.
|
|
|
|
Le modèle **refuse d'ailleurs d'exprimer cet état** : déclarer `10.27.19.0/24` comme réseau
|
|
d'underlay ferait échouer **P23**, qui interdit tout chevauchement avec un supernet tenant. La
|
|
garde détecte la faute avant qu'on ne la documente.
|
|
|
|
`underlay.yml` déclare donc les trois hyperviseurs à leur adresse **cible** — `10.0.0.{41,43,47}`,
|
|
dernier octet conservé comme sur `vmbr0`. Le déplacement réel de l'adresse sur les nœuds reste
|
|
à faire : c'est une modification du réseau d'un hyperviseur en service.
|
|
|
|
**Le pont `vmbr3` n'est pas *VLAN-aware*** (pas de `bridge_vlan_aware`, contrairement à
|
|
`vmbr2`). L'adresse du VTEP y est donc **non étiquetée** : elle vit dans le VLAN natif du port
|
|
de commutateur. Déplacer le VTEP vers l'underlay suppose soit un VLAN natif 10, soit une
|
|
interface étiquetée dédiée (`bond3.10`) — ce n'est pas qu'un changement d'adresse.
|
|
|
|
**`vishnu` n'est pas câblé.** Son `vmbr3` n'a **aucun port physique** : le pont existe, porte
|
|
une adresse, et ne mène nulle part. Un pair VXLAN pointé sur lui ne fonctionnera jamais.
|
|
|
|
## 8. Ce qui reste à trancher
|
|
|
|
- **Où vit la configuration SDN.** Elle est *par cluster*, donc propriété de l'hébergeur —
|
|
comme `underlay.yml`, et par le même raisonnement.
|
|
- **Le contrôleur EVPN** : ASN, voisins, et si l'on fait du BGP avec la bordure ou des routes
|
|
statiques comme aujourd'hui.
|
|
- **Le nombre de nœuds de sortie** et leur redondance.
|
|
- **Le mot-clé d'un flux inter-tenant** dans le registre. Aujourd'hui aucun ne l'exprime, donc
|
|
tout inter-tenant tombe dans le `block` de la bordure — un défaut sûr, mais qui rend
|
|
impossible de *déclarer* une exception légitime.
|
|
- **La migration depuis l'existant** : le tenant Chezlepro tourne déjà sur des VLAN. Passer à
|
|
EVPN est un changement de plan de transport pour des VM en service — la recette de
|
|
`docs/migration-tenant.md` s'applique-t-elle, ou faut-il un chemin plus court ?
|