De switch die je niet koopt
Een Proxmox-cluster van drie nodes met Ceph wil een snel netwerk tussen de nodes. Het gebruikelijke antwoord is een switch van 100 Gbit, en het gebruikelijke bezwaar is wat die kost.
Er is voor drie nodes een ander antwoord: draad ze rechtstreeks aan elkaar in een driehoek en routeer eroverheen. Helemaal geen switch in het opslagpad.
Het goedkoopste onderdeel in elk ontwerp is dat wat je niet koopt, en het is het enige dat nooit stukgaat.
Dat levert vier dingen op.
De kosten van de switch verdwijnen. Je hebt netwerkkaarten en drie kabels nodig, geen switch van 100 of 200 Gbit met het bijbehorende aantal poorten.
Het datapad heeft geen enkel punt waar alles op stukloopt. Een switch die uitvalt of herstart neemt al het oost-westverkeer van het hele cluster mee. Nodes die rechtstreeks aan elkaar zijn gedraad kan het niet schelen wat er elders in het gebouw met een switch gebeurt.
Het zware verkeer zit op eigen draden. Live migratie en Ceph-replicatie blijven op het mesh in plaats van te concurreren met kantoor- en beheerverkeer.
Uitbreiden is draadwerk, geen kwestie van poortbudget. Er is geen centrale bak die als plafond voor bandbreedte of aantal poorten optreedt, dus de fabric groeit zolang elke server een vrij PCIe-slot heeft. OpenFabric routeert zelf over nieuwe links.
En één eerlijke grens, want die doet meer ter zake dan de vier voordelen. Een volledig mesh heeft een kabel tussen elk paar nodes nodig. Drie nodes is drie kabels. Vier is zes. Vijf is tien. Het draadwerk groeit sneller dan het aantal nodes, en dit ontwerp overleeft een klein cluster niet zonder over te stappen op iets met switches, zoals leaf-spine.
Drie nodes is precies waar een volledig mesh zin heeft. Daarboven, met twee meshpoorten per node, is wat je nog kunt bouwen een ring — en die heeft één ding nodig dat deze bouw verder juist vermijdt, hieronder behandeld.
Wat er wordt gebouwd
Drie Proxmox VE-hosts, elk met twee eigen interfaces van 100 Gbit, in een driehoek gedraad zodat elke node twee directe buren heeft.
Proxmox SDN doet de routering. OpenFabric is het protocol: het rekent het beste pad over het mesh uit, en als er een kabel wordt losgetrokken of een link wegvalt, routeert het via het overgebleven pad. Niemand hoeft in te loggen.
De fabric woont in 10.10.10.0/24, gereserveerd voor het mesh en niets anders — geen beheer, geen gasten, geen opslagadressering, niets externs.
| Node | Meshadres | Meshinterfaces |
|---|---|---|
| mesh1 | 10.10.10.1/32 | nic1, nic2 |
| mesh2 | 10.10.10.2/32 | nic1, nic2 |
| mesh3 | 10.10.10.3/32 | nic1, nic2 |
Elke node krijgt een /32, geen stuk van het subnet.
Dat is het punt van een gerouteerd mesh in plaats van een gebrugd. Het adres identificeert de node, OpenFabric kondigt het aan, en de twee fysieke links zijn slechts paden om hem te bereiken.
Proxmox maakt een dummy-loopbackinterface om het adres te dragen.
Het draadwerk
Actieve glasvezel-DAC-kabels, in een driehoek, met jumboframes aan op beide meshinterfaces op elke node.
| Kabel | Van | Naar |
|---|---|---|
| DAC-01 | mesh1 nic1 | mesh2 nic1 |
| DAC-02 | mesh2 nic2 | mesh3 nic1 |
| DAC-03 | mesh3 nic2 | mesh1 nic2 |
Actieve glasvezel in plaats van koperen DAC, om twee redenen die over het rack gaan en niet over het netwerk:
- Kabelbeheer. Actieve glasvezel-DAC’s zijn dunner en veel flexibeler dan koper, dus ze lopen netjes en stapelen zich niet op achter de servers.
- Luchtstroom. Minder kabelmassa achter de kast betekent minder verstoring van de luchtstroom van voor naar achter, en dat doet ertoe als er meerdere snelle links in dezelfde paar rackunits landen.
Twee netwerken, niet één
Het mesh is niet het enige netwerk, en het mag er ook geen worden.
Elke node heeft nic0 op een switch van 2,5 Gbit, aan Proxmox aangeboden als de brug vmbr0.
Die draagt de webinterface, beheertoegang en clientverkeer. Het is ook het pad dat je gebruikt terwijl je de fabric bouwt, en daarom moet het onafhankelijk daarvan zijn.
nic0 blijft met opzet buiten de fabric. Alleen nic1 en nic2 worden geselecteerd bij het aanmaken van de fabricnodes.
Het mesh draagt drie dingen:
- Ceph. Replicatie, herstel en backfill van node naar node voor de hyperconvergente opslag.
- Virtueel netwerk voor clients. VNets op VXLAN rekken gastnetwerken over alle drie de nodes, met het gerouteerde mesh als onderlaag.
- Corosync, als tweede pad. Verkeer voor clusterlidmaatschap loopt over het beheernetwerk en over het mesh, zodat quorum niet afhangt van het overleven van één van de twee.
De regel die het waard is op het wijzigingsticket te schrijven: beheer- en clienttoegang blijven altijd beschikbaar via de switch van 2,5 Gbit, in welke toestand de interfaces van 100 Gbit ook zijn.
Alles via de webinterface
Deze bouw gebeurt volledig in de webinterface van Proxmox. Dat is een bewuste keuze, geen beperking van het gereedschap.
Met opzet niet gebruikt:
/etc/network/interfacesmet de hand bewerken.- FRR-configuratiebestanden met de hand bewerken.
vtyshals bouwmethode.
Proxmox genereert de onderliggende netwerk- en routeringsconfiguratie uit de SDN-objecten die je definieert. Kan iets echt niet in de interface worden gezet, dan is dat het waard als voorwaarde te benoemen in plaats van stil op de opdrachtregel op te lossen. De volgende die de webinterface opent weet niet dat je dat hebt gedaan.
Uitvoer van de opdrachtregel staat hieronder alleen als bewijs, nooit als bouwstap.
De bouw
1. Open de webinterface van Proxmox en ga naar Datacentre → SDN → Fabrics.

2. Voeg de fabric toe. Geef hem een naam, geef hem de meshprefix, en zet de timers.

Hello- en CSNP-intervallen van 1 werken de toestand zo snel mogelijk bij zodra er iets verandert, en dat is wat je op een fabric van deze omvang wilt.
De kosten zijn meer gebabbel in het besturingsvlak. Onbelangrijk op drie nodes met elk twee links, een tweede gedachte waard als de fabric ooit groeit.
3. Voeg elke node toe met Add node. Geef hem een adres uit het meshbereik en vink de interfaces aan die meedoen.

Merk op wat niet is aangevinkt: nic0 blijft eruit, en vmbr0 houdt het beheeradres.
Gebruik Create another voor de eerste twee nodes en Create op de laatste.
4. Kijk het resultaat na voordat je het toepast.

Drie nodes, drie adressen, nic1, nic2 op elk, allemaal gemarkeerd als new — er is nog niets weggeschreven.
5. Pas de SDN-configuratie toe.

Er staat een Dry-Run naast Apply als je liever eerst ziet wat het van plan is.
Weten dat het gelukt is
De statusweergave hoort zowel de zone- als de fabricregels ok te tonen op alle drie de nodes, en geen wachtende wijzigingen meer om toe te passen.

Kijk de fabric dan na vanuit het gezichtspunt van een node zelf.
Eerst de routes — elke node hoort een /32 naar elk van de andere te hebben, en de kolom Via vertelt je welke buur hij gebruikt.

Dan de buren. Twee, allebei Up, op een driehoek van drie nodes.

Dan de interfaces, en daar komt de vorm van het geheel naar boven: dummy_Mesh als de loopback die het routeradres draagt, en nic1 en nic2 als Point-To-Point in plaats van broadcastsegmenten.

Bewijs het ten slotte van begin tot eind.

Geen verlies, en gemiddelden van 0,134 ms en 0,141 ms. Beide buren zijn één directe hop weg, en dat is wat een driehoek je geeft.
De controle die het waard is en die geen schermafbeelding kan laten zien: trek één kabel los en bevestig dat alles nog bereikbaar is. Dat is de hele reden om voor een gerouteerd mesh te kiezen boven een paar punt-tot-puntlinks. Het is dan ook de enige test die uitmaakt.
Voorbij drie nodes: de ring
Een driehoek is een volledig mesh. Elke node heeft een directe kabel naar elke andere node, elke hop is één hop, en geen node draagt ooit verkeer dat niet van hemzelf is.
Die eigenschap is wat twee meshpoorten per node je bij drie nodes opleveren, en het is precies wat je bij vier verliest. Niet een deel ervan. Alles. Een volledig mesh van vier nodes heeft drie poorten per stuk nodig. Met twee is het meeste wat je kunt draden een ring.
Een ring verandert het verkeersmodel. Nodes die naast elkaar liggen hebben nog een directe kabel, maar nodes aan weerszijden van de ring niet — hun verkeer moet een tussenliggende node oversteken. En die node moet bereid zijn pakketten tussen zijn twee meshinterfaces door te sturen, en dat doet Linux standaard niet. De kernel documenteert ip_forward als “Forward Packets between interfaces” met een “Default: 0 (disabled)”.
Zet het aan voor de meshinterfaces, en alleen die:
# /etc/sysctl.d/99-mesh-forwarding.conf
net.ipv4.conf.nic1.forwarding = 1
net.ipv4.conf.nic2.forwarding = 1
sysctl --system
Lees ze terug in plaats van het aan te nemen:
sysctl net.ipv4.conf.nic1.forwarding net.ipv4.conf.nic2.forwarding
De instelling per interface is hier de juiste omvang, en hij werkt op zichzelf. De globale net.ipv4.ip_forward is geen voorwaarde. De doorstuurbeslissing van de kernel leest de eigen waarde van de ontvangende interface:
#define IN_DEV_FORWARD(in_dev) IN_DEV_CONF_GET((in_dev), FORWARDING)
IN_DEV_CONF_GET geeft de instelling van dat apparaat terug, niet een EN met de globale. Zo sturen nic1 en nic2 doorgaand verkeer voor de fabric door, terwijl nic0 en vmbr0 precies blijven wat ze horen te zijn: hostinterfaces die niet routeren. De globale schakelaar aanzetten zou elke interface op de bak tot router maken, ook die naar je kantoornetwerk. Dat is niets wat dit ontwerp nodig heeft.
Eén ding om te weten over de globale IPv4-schakelaar, ook al zet je hem niet: net.ipv4.ip_forward zet in bulk, en daarom waarschuwt de kerneldocumentatie dat hem wijzigen “resets all configuration parameters to their default state”. Schrijft iets anders op de host hem ooit, dan overschrijft dat deze waarden per interface. Goed om te weten voordat je een middag besteedt aan waarom doorgaand verkeer is gestopt.
IPv6 is de uitzondering, en het is de enige plek waar de globale schakelaar thuishoort. De kerneldocumentatie zegt het rechtstreeks onder conf/all/forwarding:
Enable global IPv6 forwarding between all interfaces. IPv4 and IPv6 work differently here; the
force_forwardingflag must be used to control which interfaces may forward packets.
Er is dus geen IPv6-equivalent van de nette aanpak per interface hierboven. Draagt de fabric IPv6, dan zet je doorsturen globaal aan en begrens je het daarna met force_forwarding, gedocumenteerd als “Enable forwarding on this interface only — regardless of the setting on conf/all/forwarding”. Merk op dat hetzelfde overschrijven omgekeerd geldt: conf.all.forwarding op 0 zetten reset force_forwarding op elke interface.
De bouw hierboven laat de IPv6-prefix van de fabric leeg, dus niets daarvan geldt hier — het doet alleen ter zake als je er een toevoegt.
Merk op wat doorsturen niet verandert: OpenFabric kondigde de /32 van elke node al aan en rekende het pad over de ring al uit. Doorsturen is de ontbrekende toestemming, niet het ontbrekende verstand. De routeringstabel had de hele tijd al gelijk. De kernel weigerde simpelweg als router op te treden.
Wat de ring kost, vergeleken met de driehoek:
- Doorgaand verkeer. Op een ring van vier nodes steken de twee diagonale paren een tussenliggende node over, dus hun verkeer verbruikt ook de linkbandbreedte van die node. Ceph merkt dit als eerste, want replicatie is van allen naar allen in plaats van van buur naar buur.
- Een extra hop latency op die paden, boven op de gebruikelijke cijfers onder de milliseconde van het ontwerp zonder switch.
- Minder ruimte voor uitval. Eén gebroken link maakt van een ring een keten: nog volledig verbonden, maar met langere paden en meer doorgaand verkeer. Een tweede breuk splitst het cluster. Een driehoek verdraagt één breuk zonder enig doorgaand verkeer.
En het wordt slechter op een manier die makkelijker te tekenen dan te beschrijven is. Voeg een vijfde node toe en de helft van elk nodepaar in het cluster hangt af van iemand anders die doorstuurt:
Dat is het echte plafond van dit ontwerp, en het is niet het routeringsprotocol. OpenFabric gaat er prima mee om. Het is dat het aantal poorten per node vast is, dus voorbij drie nodes maakt elke nieuwe bak meer van jouw verkeer tot iemand anders zijn doorgaand verkeer.
En de eerlijke aantekening, want die doet ter zake bij een bouw die tot hier alleen de webinterface heeft gebruikt: een sysctl is geen actie in de webinterface. Volgens de regel die eerder is gesteld maakt dat het een voorwaarde om te benoemen in plaats van iets om stil op de opdrachtregel op te lossen — schrijf het in het draaiboek, want de volgende die het SDN-paneel opent ziet een gezonde fabric en geen enkele hint dat een ring van een bestand in /etc/sysctl.d afhangt.
Terugdraaien
Verwijderen is de bouw in omgekeerde volgorde, in dezelfde interface: verwijder de SDN-objecten die voor het mesh zijn gemaakt, pas de configuratie toe, en bevestig dat de beheertoegang onaangeroerd is.
Die laatste stap is waarom nic0 en de switch van 2,5 Gbit bestaan. Als het terugdraaien van het mesh je de webinterface zou kunnen kosten, was het ontwerp al verkeerd voordat je begon.
Voordat je begint
- Beheertoegang is echt onafhankelijk van het mesh. Kijk het na, neem het niet aan.
- Alle drie de nodes zijn gezond voordat er een SDN-wijziging komt.
- Nodenamen, interfacenamen en het draadwerk staan opgeschreven, want
nic1op de ene host dienic2op de andere is, is een slechte middag. - Jumboframes staan op beide meshinterfaces, en de MTU houdt rekening met de overhead van VXLAN op de onderlaag.
- Het meshbereik is gereserveerd en nergens anders in gebruik.
Bronnen
- Proxmox VE — Software-Defined Network — de documentatie over SDN Fabrics. Fabrics “provide automated routing between nodes in a cluster”, OpenFabric is “based on IS-IS and optimized for the spine-leaf topology common in data centers”, elke node heeft een uniek Router-ID nodig, en “a dummy ’loopback’ interface with the router-id is automatically created”
- Proxmox VE — Cluster Manager — het netwerk van Corosync en redundante links, achter het ontwerp met lidmaatschap over twee paden
- Proxmox VE — Deploy Hyper-Converged Ceph Cluster — de netwerkverwachtingen voor een hyperconvergent cluster
- Linux kernel — IP sysctl documentation —
ip_forwarden de standaard van 0, de doorstuurbesturing per interface, en de waarschuwing dat het wijzigen van de globale schakelaar de configuratie per interface reset