Der Switch, den du nicht kaufst
Ein Proxmox-Cluster aus drei Knoten mit Ceph will ein schnelles Netz zwischen den Knoten. Die übliche Antwort ist ein 100-Gbit-Switch, und der übliche Einwand ist, was der kostet.
Für drei Knoten gibt es eine andere Antwort: verkabele sie direkt im Dreieck miteinander und route darüber. Überhaupt kein Switch im Speicherweg.
Das billigste Bauteil in jedem Entwurf ist das, das du nicht kaufst, und es ist das einzige, das nie ausfällt.
Das bringt vier Dinge.
Die Kosten des Switch verschwinden. Du brauchst Netzwerkkarten und drei Kabel, keinen Switch mit 100 oder 200 Gbit und der passenden Portzahl.
Der Datenweg hat keinen einzelnen Ausfallpunkt. Ein Switch, der ausfällt oder neu startet, nimmt den ganzen Ost-West-Verkehr des Clusters mit. Knoten, die direkt miteinander verkabelt sind, ist es gleich, was mit einem Switch anderswo im Gebäude passiert.
Der schwere Verkehr liegt auf eigenen Drähten. Live-Migration und Ceph-Replikation bleiben auf dem Mesh, statt mit Büro- und Verwaltungsverkehr zu konkurrieren.
Es zu vergrößern ist Kabelarbeit, keine Frage des Portbudgets. Es gibt keine zentrale Kiste, die eine Decke für Bandbreite oder Portzahl setzt, das Fabric wächst also, solange jeder Server einen freien PCIe-Slot hat. OpenFabric routet von allein über neue Verbindungen.
Und eine ehrliche Grenze, denn sie zählt mehr als die vier Vorteile. Ein Full Mesh braucht ein Kabel zwischen jedem Knotenpaar. Drei Knoten sind drei Kabel. Vier sind sechs. Fünf sind zehn. Die Verkabelung wächst schneller als die Knotenzahl, und dieser Entwurf übersteht nichts über einen kleinen Cluster hinaus, ohne auf etwas Geswitchtes wie Leaf-Spine zu wechseln.
Drei Knoten sind genau die Stelle, an der ein Full Mesh Sinn hat. Darüber hinaus lässt sich mit zwei Mesh-Ports pro Knoten noch ein Ring bauen — und der braucht eine Sache, die dieser Aufbau sonst vermeidet, siehe unten.
Was gebaut wird
Drei Proxmox-VE-Hosts, jeder mit zwei fest zugeordneten 100-Gbit-Schnittstellen, so ins Dreieck verkabelt, dass jeder Knoten zwei direkte Nachbarn hat.
Proxmox SDN erledigt das Routing. OpenFabric ist das Protokoll: es rechnet den besten Weg über das Mesh aus, und wenn ein Kabel gezogen wird oder eine Verbindung wegfällt, routet es über den verbleibenden Weg um. Niemand muss sich anmelden.
Das Fabric wohnt in 10.10.10.0/24, reserviert für das Mesh und nichts anderes — nicht für die Verwaltung, nicht für Gäste, nicht für Speicheradressen, nicht für irgendetwas von außen.
| Knoten | Mesh-Adresse | Mesh-Schnittstellen |
|---|---|---|
| mesh1 | 10.10.10.1/32 | nic1, nic2 |
| mesh2 | 10.10.10.2/32 | nic1, nic2 |
| mesh3 | 10.10.10.3/32 | nic1, nic2 |
Jeder Knoten bekommt ein /32, keine Scheibe des Subnetzes.
Das ist der Sinn eines gerouteten Mesh statt eines gebrückten. Die Adresse bezeichnet den Knoten, OpenFabric verkündet sie, und die zwei physischen Verbindungen sind bloß Wege, ihn zu erreichen.
Proxmox legt eine Dummy-Loopback-Schnittstelle an, die sie hält.
Die Verkabelung
Aktive Glasfaser-DAC-Kabel, im Dreieck, mit Jumbo Frames auf beiden Mesh-Schnittstellen jedes Knotens.
| Kabel | Von | Nach |
|---|---|---|
| DAC-01 | mesh1 nic1 | mesh2 nic1 |
| DAC-02 | mesh2 nic2 | mesh3 nic1 |
| DAC-03 | mesh3 nic2 | mesh1 nic2 |
Aktive Glasfaser statt Kupfer-DAC, aus zwei Gründen, die eher mit dem Rack als mit dem Netz zu tun haben:
- Kabelführung. Aktive Glasfaser-DACs sind dünner und weit biegsamer als Kupfer, sie lassen sich also sauber verlegen und stapeln sich nicht hinter den Servern.
- Luftstrom. Weniger Kabelmasse hinter dem Gehäuse heißt weniger Störung des Luftstroms von vorn nach hinten, und das zählt, wenn mehrere schnelle Verbindungen in denselben paar Höheneinheiten landen.
Zwei Netze, nicht eines
Das Mesh ist nicht das einzige Netz, und es darf nicht zu einem werden.
Jeder Knoten hat nic0 an einem 2,5-Gbit-Switch, Proxmox gegenüber als Brücke vmbr0 dargestellt.
Die trägt die Weboberfläche, den Verwaltungszugang und den Client-Verkehr. Sie ist auch der Weg, den du beim Bauen des Fabric nutzt, und deshalb muss sie davon unabhängig sein.
nic0 wird bewusst aus dem Fabric herausgelassen. Beim Anlegen der Fabric-Knoten werden nur nic1 und nic2 ausgewählt.
Das Mesh trägt drei Dinge:
- Ceph. Replikation, Wiederherstellung und Backfill von Knoten zu Knoten für den hyperkonvergenten Speicher.
- Virtuelles Client-Netz. VXLAN-gestützte VNets ziehen Gastnetze über alle drei Knoten und nutzen das geroutete Mesh als Unterlage.
- Corosync, als zweiter Weg. Der Verkehr für die Cluster-Mitgliedschaft läuft über das Verwaltungsnetz und das Mesh, das Quorum hängt also nicht davon ab, dass eines von beiden allein überlebt.
Die Regel, die es wert ist, auf das Änderungsticket zu schreiben: Verwaltung und Client-Zugang bleiben jederzeit über den 2,5-Gbit-Switch verfügbar, in welchem Zustand die 100-Gbit-Schnittstellen auch sind.
Alles über die Weboberfläche
Dieser Aufbau geschieht vollständig in der Proxmox-Weboberfläche. Das ist eine bewusste Wahl, keine Grenze der Werkzeuge.
Bewusst nicht genutzt:
/etc/network/interfacesvon Hand bearbeiten.- FRR-Konfigurationsdateien von Hand bearbeiten.
vtyshals Baumethode.
Proxmox erzeugt die darunterliegende Netz- und Routing-Konfiguration aus den SDN-Objekten, die du festlegst. Wenn etwas sich wirklich nicht in der Oberfläche setzen lässt, ist das es wert, als Voraussetzung genannt zu werden, statt es still auf der Kommandozeile zu richten. Der Nächste, der die Weboberfläche öffnet, wird nicht wissen, dass du das getan hast.
Ausgaben von der Kommandozeile erscheinen unten nur als Beleg, nie als Bauschritt.
Der Aufbau
1. Öffne die Proxmox-Weboberfläche und geh auf Datacenter → SDN → Fabrics.

2. Leg das Fabric an. Gib ihm einen Namen, das Mesh-Präfix und die Zeitgeber.

Hello- und CSNP-Intervalle von 1 bringen den Zustand so schnell wie möglich nach, wenn sich etwas ändert, und genau das willst du auf einem Fabric dieser Größe.
Der Preis ist mehr Geplauder auf der Steuerebene. Auf drei Knoten mit je zwei Verbindungen belanglos, einen zweiten Gedanken wert, falls das Fabric je wächst.
3. Füge jeden Knoten mit Add node hinzu. Gib ihm eine Adresse aus dem Mesh-Bereich und häkle die Schnittstellen an, die mitmachen.

Achte darauf, was nicht angehäkelt ist: nic0 bleibt draußen, und vmbr0 behält die Verwaltungsadresse.
Nutze Create another für die ersten zwei Knoten und Create beim letzten.
4. Prüf das Ergebnis, bevor du es anwendest.

Drei Knoten, drei Adressen, nic1, nic2 auf jedem, alle als new markiert — es ist noch nichts geschrieben.
5. Wende die SDN-Konfiguration an.

Neben Apply gibt es ein Dry-Run, wenn du erst sehen willst, was es vorhat.
Wissen, dass es geklappt hat
Die Statusansicht sollte auf allen drei Knoten sowohl den Zonen- als auch den Fabric-Eintrag als ok zeigen, und keine ausstehenden Änderungen mehr.

Dann prüf das Fabric aus der Sicht eines Knotens selbst.
Zuerst die Routen — jeder Knoten sollte ein /32 zu jedem anderen haben, und die Spalte Via sagt dir, welchen Nachbarn er dafür nutzt.

Dann die Nachbarn. Zwei, beide Up, auf einem Dreieck aus drei Knoten.

Dann die Schnittstellen, und dort zeigt sich die Gestalt der Sache: dummy_Mesh als Loopback, der die Router-Adresse hält, und nic1 und nic2 als Point-To-Point statt als Broadcast-Segmente.

Zum Schluss der Beweis von Ende zu Ende.

Kein Verlust, und Mittel von 0,134 ms und 0,141 ms. Beide Nachbarn sind einen direkten Sprung entfernt, und das ist, was ein Dreieck dir gibt.
Die Prüfung, die es wert ist und die kein Bildschirmfoto zeigen kann: zieh ein Kabel und stell fest, dass alles weiter erreichbar ist. Das ist der ganze Grund, ein geroutetes Mesh statt zweier Punkt-zu-Punkt-Verbindungen zu wählen. Damit ist es die einzige Prüfung, auf die es ankommt.
Über drei Knoten hinaus: der Ring
Ein Dreieck ist ein Full Mesh. Jeder Knoten hat ein direktes Kabel zu jedem anderen, jeder Sprung ist ein Sprung, und kein Knoten trägt je Verkehr, der nicht sein eigener ist.
Diese Eigenschaft kaufen dir zwei Mesh-Ports pro Knoten bei drei Knoten, und genau die verlierst du bei vier. Nicht einen Teil davon. Alles. Ein Full Mesh aus vier Knoten braucht drei Ports pro Knoten. Mit zwei ist das Meiste, was du verkabeln kannst, ein Ring.
Ein Ring ändert das Verkehrsmodell. Nachbarknoten haben weiter ein direktes Kabel, aber Knoten auf gegenüberliegenden Seiten des Rings nicht — ihr Verkehr muss über einen Knoten dazwischen. Und dieser Knoten muss bereit sein, Pakete zwischen seinen zwei Mesh-Schnittstellen weiterzuleiten, und das tut Linux standardmäßig nicht. Der Kernel dokumentiert ip_forward als „Forward Packets between interfaces“ mit „Default: 0 (disabled)“ — also aus.
Schalte es für die Mesh-Schnittstellen ein, und nur für die:
# /etc/sysctl.d/99-mesh-forwarding.conf
net.ipv4.conf.nic1.forwarding = 1
net.ipv4.conf.nic2.forwarding = 1
sysctl --system
Lies sie zurück, statt es anzunehmen:
sysctl net.ipv4.conf.nic1.forwarding net.ipv4.conf.nic2.forwarding
Die Einstellung pro Schnittstelle ist hier der richtige Umfang, und sie wirkt für sich. Das globale net.ipv4.ip_forward ist keine Voraussetzung. Die Entscheidung des Kernels über das Weiterleiten liest den Wert der empfangenden Schnittstelle:
#define IN_DEV_FORWARD(in_dev) IN_DEV_CONF_GET((in_dev), FORWARDING)
IN_DEV_CONF_GET gibt die Einstellung dieses Geräts zurück, kein UND mit der globalen. Also leiten nic1 und nic2 Transitverkehr für das Fabric weiter, während nic0 und vmbr0 genau das bleiben, was sie sein sollen: Host-Schnittstellen, die nicht routen. Den globalen Schalter anzuwerfen würde jede Schnittstelle der Kiste zum Router machen, auch die, die zu deinem Büronetz zeigt. Das braucht dieser Entwurf nicht.
Eine Sache über den globalen IPv4-Schalter, obwohl du ihn nicht setzt: net.ipv4.ip_forward ist ein Massensetzer, und deshalb warnt die Kernel-Dokumentation, dass eine Änderung daran „resets all configuration parameters to their default state“ — alle Konfigurationsparameter auf ihren Vorgabezustand zurücksetzt. Wenn irgendetwas anderes auf dem Host ihn je schreibt, überschreibt es diese Werte pro Schnittstelle. Gut zu wissen, bevor du einen Nachmittag damit verbringst, warum der Transit aufgehört hat.
IPv6 ist die Ausnahme, und die einzige Stelle, an die der globale Schalter gehört. Die Kernel-Dokumentation sagt es direkt unter 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.
Auf Deutsch: globales IPv6-Weiterleiten zwischen allen Schnittstellen einschalten; IPv4 und IPv6 arbeiten hier verschieden, und mit dem Flag force_forwarding wird gesteuert, welche Schnittstellen Pakete weiterleiten dürfen.
Es gibt also kein IPv6-Gegenstück zum sauberen Vorgehen pro Schnittstelle von oben. Trägt das Fabric IPv6, schaltest du das Weiterleiten global ein und begrenzt es dann mit force_forwarding, dokumentiert als „Enable forwarding on this interface only — regardless of the setting on conf/all/forwarding“, also Weiterleiten nur auf dieser Schnittstelle, unabhängig von der Einstellung unter conf/all/forwarding. Beachte, dass dasselbe Überschreiben umgekehrt gilt: conf.all.forwarding auf 0 zu setzen setzt force_forwarding auf jeder Schnittstelle zurück.
Der Aufbau oben lässt das IPv6-Präfix des Fabric leer, davon gilt hier also nichts — es zählt nur, wenn du eines hinzufügst.
Achte darauf, was das Weiterleiten nicht ändert: OpenFabric hat das /32 jedes Knotens schon verkündet und den Weg über den Ring schon ausgerechnet. Weiterleiten ist die fehlende Erlaubnis, nicht der fehlende Verstand. Die Routing-Tabelle war die ganze Zeit richtig. Der Kernel hat sich bloß geweigert, als Router zu handeln.
Was der Ring gegenüber dem Dreieck kostet:
- Transitverkehr. Auf einem Ring aus vier Knoten überqueren die zwei diagonalen Paare einen Knoten dazwischen, ihr Verkehr verbraucht also die Bandbreite dieses Knotens zusätzlich zu seiner eigenen. Ceph merkt das zuerst, weil Replikation von allen zu allen läuft und nicht von Nachbar zu Nachbar.
- Ein zusätzlicher Sprung Latenz auf diesen Wegen, obendrauf auf die üblichen Werte unter einer Millisekunde eines Entwurfs ohne Switch.
- Weniger Luft für Ausfälle. Eine kaputte Verbindung macht aus einem Ring eine Kette: noch vollständig verbunden, aber mit längeren Wegen und mehr Transit. Ein zweiter Bruch teilt den Cluster. Ein Dreieck verträgt einen Bruch ganz ohne Transit.
Und es wird auf eine Weise schlimmer, die leichter zu zeichnen als zu beschreiben ist. Nimm einen fünften Knoten dazu, und die Hälfte aller Knotenpaare im Cluster hängt davon ab, dass jemand anderes weiterleitet:
Das ist die echte Decke dieses Entwurfs, und es ist nicht das Routing-Protokoll. OpenFabric kommt gut zurecht. Es ist, dass die Ports pro Knoten festliegen, und deshalb macht über drei Knoten hinaus jede neue Kiste mehr von deinem Verkehr zum Transit eines anderen.
Und die ehrliche Anmerkung, denn für einen Aufbau, der bis hierher nur über die Weboberfläche lief, zählt sie: ein sysctl ist keine Handlung in der Weboberfläche. Nach der Regel von oben ist das damit eine Voraussetzung, die genannt werden muss, und nicht etwas, das man still auf der Kommandozeile richtet — schreib es ins Runbook, denn der Nächste, der das SDN-Fenster öffnet, sieht ein gesundes Fabric und keinen Hinweis darauf, dass ein Ring von einer Datei in /etc/sysctl.d abhängt.
Rückbau
Der Rückbau ist der Aufbau in umgekehrter Richtung, in derselben Oberfläche: lösche die SDN-Objekte, die für das Mesh angelegt wurden, wende die Konfiguration an und stell fest, dass der Verwaltungszugang unberührt ist.
Dieser letzte Schritt ist der Grund, warum nic0 und der 2,5-Gbit-Switch da sind. Wenn das Zurückrollen des Mesh dich die Weboberfläche kosten könnte, war der Entwurf falsch, bevor du angefangen hast.
Bevor du anfängst
- Der Verwaltungszugang ist wirklich unabhängig vom Mesh. Prüf es, nimm es nicht an.
- Alle drei Knoten sind gesund, bevor irgendeine SDN-Änderung kommt.
- Knotennamen, Schnittstellennamen und Verkabelung sind aufgeschrieben, denn wenn
nic1auf einem Hostnic2auf einem anderen ist, wird das ein schlechter Nachmittag. - Jumbo Frames sind auf beiden Mesh-Schnittstellen gesetzt, und die MTU rechnet den Overhead von VXLAN auf der Unterlage mit ein.
- Der Mesh-Bereich ist reserviert und wird nirgends sonst genutzt.
Quellen
- Proxmox VE — Software-Defined Network — die Dokumentation zu SDN Fabrics. Fabrics „provide automated routing between nodes in a cluster“, OpenFabric ist „based on IS-IS and optimized for the spine-leaf topology common in data centers“, jeder Knoten braucht eine eigene Router-ID, und „a dummy ’loopback’ interface with the router-id is automatically created“
- Proxmox VE — Cluster Manager — das Netz für Corosync und redundante Links, hinter dem Entwurf mit zwei Wegen für die Mitgliedschaft
- Proxmox VE — Deploy Hyper-Converged Ceph Cluster — die Netzerwartungen eines hyperkonvergenten Clusters
- Linux-Kernel — IP sysctl documentation —
ip_forwardund seine Vorgabe 0, die Steuerungforwardingpro Schnittstelle und die Warnung, dass eine Änderung am globalen Schalter die Konfiguration pro Schnittstelle zurücksetzt