f-50: lab: résultats d'E5, contrôle DHCP de s1 sur les couples MAC/IP, perte du route reflector #50

Signed-off-by: GnomeZworc <nicolas.boufidjeline@g3e.fr>
This commit is contained in:
GnomeZworc 2026-10-04 21:17:48 +02:00
commit 909b4110c2
Signed by: nicolas.boufideline
GPG key ID: 4406BBBF8845D632
4 changed files with 47 additions and 13 deletions

View file

@ -94,9 +94,21 @@ l'adresse du lien en secondaire et la loopback sur ``lo1`` :
- up des deux côtés
* - sessions des deux hyperviseurs vers ``10.255.255.1``
- Established, voisins dynamiques, iBGP AS 64600, famille L2VPN EVPN négociée
* - routes EVPN échangées
- aucune : rien à annoncer tant que two n'a pas créé de VXLAN — voir
:doc:`premier-hyperviseur`
* - routes EVPN échangées, VM ↔ VM entre deux hyperviseurs
- routes de type 3 échangées, ping et MTU 1500 de bout en bout — à partir de la release
``0.2.0rc003``, qui pose l'adresse VTEP locale des VXLAN
(`#51 <https://git.g3e.fr/syonad/two/issues/51>`_)
.. warning::
**Les tunnels ne survivent pas à la perte du route reflector.** Mesuré dans le lab
(2026-10-04, FRR 10.7.1, un seul route reflector, sans ``graceful-restart``) : à l'arrêt de
FRR sur le route reflector, la session EVPN des hyperviseurs tombe aussitôt, FRR retire les
routes apprises et, avec elles, le VTEP distant et l'entrée d'inondation du VXLAN — **plus
aucun paquet ne passe** entre hyperviseurs, à 30 s comme à 90 s. Au redémarrage de FRR sur le
route reflector, VTEP distant et trafic reviennent **31 s** plus tard. Le trafic entre VM d'un
même hyperviseur n'est pas concerné. La redondance (deux route reflectors) ou
``graceful-restart`` sont les deux leviers ; ni l'un ni l'autre n'est encore qualifié.
Le routeur du lab n'est qu'une configuration minimale écrite pour l'essai, pas celle des routeurs
de cluster (:doc:`routeurs`).
@ -109,9 +121,8 @@ de cluster (:doc:`routeurs`).
lancer sur n'importe quel hyperviseur), et s'il s'agit d'une VM créée par l'agent comme les
autres ou d'un cas particulier — l'image, elle, est l'image golden de :doc:`image-qcow2` ;
* la redondance : une seule VM route reflector, ou deux, et sur quels hyperviseurs ;
* la procédure de reconstruction, et l'état du cluster pendant que le route reflector est
absent — les tunnels déjà établis continuent-ils de fonctionner, et pendant combien de
temps ;
* la procédure de reconstruction — l'état du cluster pendant l'absence du route reflector est
mesuré ci-dessus : plus de trafic entre hyperviseurs ;
* la procédure d'amorçage : ce qui fonctionne, et dans quel ordre, quand on démarre un cluster
entier depuis zéro — le premier hyperviseur n'a pas de session FRR établie tant que cette VM
n'existe pas, cf. :doc:`premier-hyperviseur`.

View file

@ -725,6 +725,29 @@ scénario envoie des blocs de shell aux nœuds par ``on <nœud> [VAR=valeur…]
elle n'est réussie que si le SSH vers la VM a fonctionné **et** que la commande y a échoué — un
SSH en panne ne passe jamais pour une isolation.
Résultats du 2026-10-04 sur le serveur de lab, release ``0.2.0rc003``, hv1 sur le DHCP intégré et
hv2 sur dnsmasq — toute la série en 8 minutes :
.. code-block:: text
$ scripts/lab/scenario.sh all | grep -E '^(=== s[0-9].* : |INFO)'
INFO: MAC de sn-s1a : 00:22:33:00:00:0a 00:22:33:00:00:0b ; de sn-s1b : 00:22:33:00:00:0a 00:22:33:00:00:0b
=== s1-dhcp-two : 37 réussi(s), 0 échoué(s)
=== s2-gateway : 22 réussi(s), 0 échoué(s)
=== s3-isolation-local : 12 réussi(s), 0 échoué(s)
=== s4-evpn : 14 réussi(s), 0 échoué(s)
=== s5-isolation-evpn : 13 réussi(s), 0 échoué(s)
INFO: 30 s après l'arrêt du route reflector : 0 réponses dans les 10 dernières secondes (50 si le trafic passe intégralement)
INFO: VTEP distant encore connu : 0 ; entrée d'inondation : 0
INFO: 90 s après l'arrêt : 0 réponses dans les 10 dernières secondes
INFO: retour du VTEP distant et du trafic 31 s après le redémarrage de FRR
=== s6-rr-loss : 8 réussi(s), 0 échoué(s)
Dans ce run, le contrôle « uniquement les MAC de son subnet » de ``s1`` ne prouvait rien : two
dérive la MAC du rang de l'IP, et les VM ``.10``/``.11`` des deux subnets avaient les mêmes MAC.
Vérifié à la main sur le lab, chaque serveur DHCP ne connaissait que les couples MAC/IP de son
subnet ; le scénario compare désormais ces couples.
Les VM sont accessibles depuis le netns de leur VPC, sur l'hyperviseur, avec l'utilisateur
``syonad`` créé par les métadonnées de two :

View file

@ -146,6 +146,6 @@ while not buf.endswith(b"\n"):
break
buf += c
state = json.loads(buf).get("state") or {}
print(" ".join(sorted(h["mac"].lower() for h in state.get("hosts") or [])))
print(" ".join(sorted(h["mac"].lower() + "=" + h["ip"] for h in state.get("hosts") or [])))
PY
}

View file

@ -25,10 +25,10 @@ for vm in 10.210.1.10:10.210.1.1 10.210.1.11:10.210.1.1 10.210.2.10:10.210.2.1 1
check "${ip} : route vers la VPC via ${gw}" route_via vp-s1 "${ip}" 10.210.0.0/16 "${gw}"
check "${ip} : route /32 vers les métadonnées via ${gw}" route_via vp-s1 "${ip}" 169.254.169.254 "${gw}"
done
mac () { vm_ssh vp-s1 "${1}" 'cat /sys/class/net/ens3/address'; }
A_MACS=$(printf '%s\n' "$(mac 10.210.1.10)" "$(mac 10.210.1.11)" | sort | tr '\n' ' ' | sed 's/ $//')
B_MACS=$(printf '%s\n' "$(mac 10.210.2.10)" "$(mac 10.210.2.11)" | sort | tr '\n' ' ' | sed 's/ $//')
info "MAC de sn-s1a : ${A_MACS} ; de sn-s1b : ${B_MACS}"
check "probe sn-s1a : uniquement les MAC de sn-s1a" test "$(dhcp_hosts vp-s1_br-s1a)" = "${A_MACS}"
check "probe sn-s1b : uniquement les MAC de sn-s1b" test "$(dhcp_hosts vp-s1_br-s1b)" = "${B_MACS}"
vm_host () { echo "$(vm_ssh vp-s1 "${1}" 'cat /sys/class/net/ens3/address')=${1}"; }
A_HOSTS=$(printf '%s\n' "$(vm_host 10.210.1.10)" "$(vm_host 10.210.1.11)" | sort | tr '\n' ' ' | sed 's/ $//')
B_HOSTS=$(printf '%s\n' "$(vm_host 10.210.2.10)" "$(vm_host 10.210.2.11)" | sort | tr '\n' ' ' | sed 's/ $//')
info "sn-s1a : ${A_HOSTS} ; sn-s1b : ${B_HOSTS}"
check "probe sn-s1a : uniquement les couples MAC/IP de sn-s1a" test "$(dhcp_hosts vp-s1_br-s1a)" = "${A_HOSTS}"
check "probe sn-s1b : uniquement les couples MAC/IP de sn-s1b" test "$(dhcp_hosts vp-s1_br-s1b)" = "${B_HOSTS}"
NODE