Ihr Container antwortet weiterhin auf seiner Steuerungsbrücke, doch jedes ausgehende Paket verlässt ihn über das Büro-macvlan. Nichts ist ausgefallen. Zwei Anbindungen liefern je ein Gateway, und die einzige Standardroute ging an das Netz, das Sie nicht gemeint hatten, sodass der Dienst weiterläuft, während sein Verkehr einen längeren Weg nimmt. Bis es jemandem auffällt, ist der Beweis eine Routing-Tabelle und keine Fehlermeldung.

Die übliche Erklärung lautet, Docker habe das Netz zufällig gewählt. Tatsächlich folgte die alte Entscheidung der alphabetischen Reihenfolge der angebundenen Netznamen, was Routing zu einem Nebeneffekt eines Etiketts machte. gw_priority ersetzt das durch eine Zahl, die Sie bewusst wählen, und die Umstellung dauert etwa eine Minute, sobald das Layout niedergeschrieben ist.

Warum die Standardroute im falschen Netz landet

Jedes Netz, dem ein Dienst beitritt, kann sein eigenes Gateway anbieten, und der Container erhält trotzdem genau eine Standardroute. Vor Compose 2.33.1 wurde der Gleichstand durch Sortieren der Netznamen entschieden, sodass ein Etikett wie control, das vor office kommt, bestimmte, wohin der Verkehr geht. Nichts im Container hält fest, dass die Entscheidung willkürlich war, weshalb sie die Codeprüfung übersteht und später als seltsamer Pfad auftaucht. Eine Richtlinie in der compose-Datei ist der einzige Weg, die Wahl überprüfbar zu machen.

Zwei Dinge ändern wirklich, welches Netz gewinnt: die gw_priority-Werte, die Sie vergeben, und welche Netze überhaupt angebunden sind. Fügen Sie ein drittes Netz hinzu, wächst die Kandidatenmenge; entfernen Sie das macvlan, bleibt nichts, was mit der Brücke konkurriert. Keine der beiden Bewegungen erscheint in Anwendungsprotokollen, weil eine falsche Standardroute eine Verbindung selten ganz abbricht. Sie sorgt nur dafür, dass Antworten von einer Adresse kommen, die die andere Seite vielleicht nicht erwartet.

Legen Sie das Gateway mit gw_priority fest

Compose stellt gw_priority seit Version 2.33.1 an jeder Dienst-zu-Netz-Anbindung bereit, und die höchste Zahl gewinnt. Einen Gateway-Schlüssel pro Dienst gibt es nicht, der Wert gehört daher unter den networks-Block des Dienstes. Das folgende Beispiel gibt die Standardroute an control, während office für sein direkt verbundenes LAN erreichbar bleibt.

services:
  vpn:
    networks:
      control:
        gw_priority: 1
      office:
        gw_priority: 0

networks:
  control:
    driver: bridge
    ipam:
      config:
        - subnet: 172.30.50.0/24
  office:
    driver: macvlan
    driver_opts:
      parent: eno1.120
      macvlan_mode: bridge
    ipam:
      config:
        - subnet: 192.168.120.0/24
          ip_range: 192.168.120.192/27
          gateway: 192.168.120.1

Lesen Sie den Block als zwei getrennte Steuerungen: gw_priority entscheidet die Standardroute, und der ipam-Abschnitt entscheidet die Adressierung. Nur das Subnetz zu ändern lässt die Ausgangswahl unberührt, und das ist der häufigste Weg, diese Korrektur halb anzuwenden. Halten Sie die Prioritäten neben dem Netz, das sie steuern, damit der nächste Leser die Entscheidung nicht suchen muss.

Verwechseln Sie gw_priority nicht mit der einfachen priority-Eigenschaft daneben. Diese ordnet den Aufbau von Verbindungen und sagt nichts über Routing, kann also kein Standard-Gateway auswählen und behebt keine Interface-Namen. Wenn jemand empfiehlt, priority zu erhöhen, um Verkehr zu lenken, ist die Empfehlung falsch, selbst wenn die resultierende Reihenfolge zufällig richtig aussieht.

Prüfen Sie, welches Netz die Standardroute wirklich trägt

Prüfen Sie im laufenden Container, denn die Routing-Tabelle des Hosts beschreibt den Host und nicht den Namensraum, den der Dienst nutzt. Führen Sie zuerst die Konfigurationsprüfung aus, damit ein Tippfehler vor einem Neustart auffällt, und lesen Sie dann die Route, die der Container tatsächlich installiert hat.

docker compose config --quiet
docker exec vpn ip -4 route show default
docker exec vpn cat /proc/net/route

Ein korrektes Ergebnis nennt das Brückengerät und 172.30.50.1; ein falsches nennt 192.168.120.1 und das macvlan-Gerät. Wenn das Image kein iproute2-Paket enthält, meldet die /proc-Datei die Standardroute trotzdem, mit Ziel 00000000 und umgekehrten Gateway-Bytes. Vergleichen Sie die Schnittstellenspalte mit docker inspect, wenn die Gerätenamen unklar sind.

Macvlan ist ein physischer Port, kein Brückenklon

Macvlan gibt dem Container eine zweite Identität auf dem Draht, und genau das macht den Zugriff auf lokale Geräte möglich. Es bedeutet auch, dass der Switch-Port und der Hypervisor eine zusätzliche MAC-Adresse annehmen müssen, und viele Cloud-Netze verweigern das stillschweigend. Testen Sie einen Container, bevor Sie eine Flotte planen, denn eine abgelehnte MAC erscheint meist als Verbindung, die oben ist und nichts durchlässt.

Die Einstellung macvlan_mode: bridge ist ein Modus des macvlan-Treibers, nicht Dockers Software-Brücke, und passthru ist ein eigener spezialisierter Modus und kein Standard. Linux hält einen macvlan-Container auch davon ab, seinen eigenen Host zu erreichen über denselben Parent, und das ist der Grund, die Steuerungsbrücke zu behalten, statt zu erwarten, dass eine Anbindung beide Aufgaben erledigt.

Benennen Sie den VLAN-Parent, bevor Compose ihn sieht

Docker behandelt einen Parent mit Punkt wie eno1.120 als 802.1Q-Subinterface und legt das VLAN-Gerät selbst an. Diese Bequemlichkeit hat Grenzen: der abgeleitete Name hängt vom Namen der physischen Schnittstelle ab, und lange Namen können das Ergebnis über das hinausdrücken, was die umgebende Werkzeugkette erwartet. Eine benannte VLAN-Schnittstelle in der Netzwerkkonfiguration des Hosts anzulegen und parent darauf zu zeigen hält beide Enden vorhersagbar.

Denken Sie daran, dass der Schlüssel unter networks ein Compose-Name ist, kein Linux-Gerät. Die Suche nach einer Schnittstelle namens office auf dem Host schlägt fehl, weil der Kernel nur das Parent-Interface und das veth-Paar hinter dem Container sieht.

Schaffen Sie Platz für das VPN darüber

Ein VPN-Client hängt sich an, nachdem diese Netze bestehen, kann also unabhängig von gw_priority spezifischere Routen, Richtlinienregeln und Filter hinzufügen. Planen Sie die entfernten Präfixe gegen beide lokalen Subnetze, einschließlich der Antworten, die der Steuerungspfad braucht. Wenn ein entferntes Präfix das Büro-LAN überlappt, korrigieren Sie den Adressplan, statt einen ganzen privaten Bereich aus dem Tunnel zu reißen.

Prüfen Sie Adressen, Routen und den Dienstpfad erneut, nachdem das VPN startet, und noch einmal, nachdem es sich neu verbindet, denn beim Neuverbinden verschwindet eine von Hand hinzugefügte Route. Schreiben Sie die erwartete Tabelle vor dem ersten Test auf, damit der Vergleich danach ein Diff ist und keine Gedächtnisübung. Behalten Sie die dauerhafte Netzeigentümerschaft in Compose und lassen Sie die VPN-Konfiguration nur ihre eigene Richtlinie besitzen.

Ähnliche Artikel