Twoja kontener nadal odpowiada na swoim moście kontrolnym, ale każdy pakiet wychodzący opuszcza sieć przez biurowy macvlan. Nic nie zawiodło. Dwa podłączenia dają po jednej bramie, a jedyna trasa domyślna trafiła do sieci, której nie miałeś na myśli, więc usługa nadal działa, a jej ruch idzie dłuższą drogą. Zanim ktoś to zauważy, dowodem jest tablica routingu, a nie komunikat błędu.

Zwykłe wyjaśnienie jest takie, że Docker wybrał sieć przypadkiem. W praktyce stara decyzja podążała za alfabetyczną kolejnością nazw podłączonych sieci, co czyniło routingu skutkiem ubocznym etykiety. gw_priority zastępuje to liczbą, którą wybierasz świadomie, a wdrożenie zajmuje około minuty, gdy układ jest już zapisany.

Dlaczego trasa domyślna ląduje w złej sieci

Każda sieć, do której dołącza usługa, może zaproponować własną bramę, a kontener i tak kończy z dokładnie jedną trasą domyślną. Przed Compose 2.33.1 remis rozstrzygało sortowanie nazw sieci, więc etykieta taka jak control, która wypada przed office, decydowała, dokąd trafi ruch. Nic w kontenerze nie zapisuje, że decyzja była dowolna, dlatego przechodzi przegląd kodu i później wychodzi jako dziwna ścieżka. Zapisanie polityki w pliku compose to jedyny sposób, by wybór był sprawdzalny.

Dwie rzeczy naprawdę zmieniają to, która sieć wygrywa: przypisane wartości gw_priority oraz to, które sieci są w ogóle podłączone. Dodaj trzecią sieć, a zbiór kandydatów rośnie; usuń macvlan i nie ma już z czym konkurować most. Żaden z tych ruchów nie pojawia się w logach aplikacji, bo zła trasa domyślna rzadko zrywa połączenie całkowicie. Powoduje tylko, że odpowiedzi przychodzą z adresu, którego druga strona może się nie spodziewać.

Przypnij bramę przez gw_priority

Compose udostępnia gw_priority na każdym podłączeniu usługi do sieci od wersji 2.33.1 i wygrywa największa liczba. Nie ma osobnego klucza bramy dla usługi, więc wartość należy do bloku networks tej usługi. Poniższy przykład oddaje trasę domyślną sieci control, pozostawiając office osiągalną dla jej bezpośrednio podłączonej sieci LAN.

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

Czytaj ten blok jako dwie osobne kontrole: gw_priority decyduje o trasie domyślnej, a sekcja ipam o adresacji. Zmiana samego subnetu pozostawia wybór wyjścia nietknięty, i to jest najczęstszy sposób zastosowania tej poprawki połowicznie. Trzymaj priorytety obok sieci, którą rządzą, aby następny czytelnik nie musiał szukać tej decyzji.

Nie myl gw_priority ze zwykłą właściwością priority obok. Tamta porządkuje tworzenie połączeń i nic nie mówi o routingu, więc nie może wybrać bramy domyślnej i nie naprawia nazw interfejsów. Jeśli ktoś radzi podnieść priority, by sterować ruchem, rada jest błędna, nawet gdy wynikowa kolejność przypadkiem wygląda poprawnie.

Sprawdź, która sieć naprawdę niesie trasę domyślną

Sprawdzaj wewnątrz działającego kontenera, bo tabela routingu hosta opisuje host, a nie przestrzeń nazw używaną przez usługę. Najpierw uruchom kontrolę konfiguracji, aby literówka ujawniła się przed restartem, a potem odczytaj trasę, którą kontener faktycznie zainstalował.

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

Poprawny wynik wymienia urządzenie mostu i 172.30.50.1; błędny wymienia 192.168.120.1 i urządzenie macvlan. Jeśli obraz nie zawiera pakietu iproute2, plik /proc nadal raportuje trasę domyślną, z celem 00000000 i bajtami bramy odwróconymi. Porównaj kolumnę interfejsu z docker inspect, gdy nazwy urządzeń nie są jasne.

Macvlan to port fizyczny, a nie klon mostu

Macvlan daje kontenerowi drugą tożsamość na kablu i właśnie to umożliwia dostęp do lokalnych urządzeń. Oznacza to także, że port przełącznika i hiperwizor muszą przyjąć dodatkowy adres MAC, a wiele sieci chmurowych po cichu tego odmawia. Przetestuj jeden kontener, zanim zaplanujesz flotę, bo odrzucony MAC zwykle wygląda jak łącze, które jest włączone i niczego nie przepuszcza.

Ustawienie macvlan_mode: bridge to tryb sterownika macvlan, a nie programowy most Dockera, a passthru to osobny wyspecjalizowany tryb, a nie wartość domyślna. Linux uniemożliwia też kontenerowi macvlan dotarcie do własnego hosta przez tego samego rodzica, i dlatego zachowuje się most kontrolny, zamiast oczekiwać, że jedno podłączenie wykona oba zadania.

Nazwij rodzica VLAN, zanim Compose go zobaczy

Docker traktuje rodzica z kropką, takiego jak eno1.120, jako podinterfejs 802.1Q i sam tworzy urządzenie VLAN. Ta wygoda ma granice: pochodna nazwa zależy od nazwy interfejsu fizycznego, a długie nazwy mogą wypchnąć wynik poza oczekiwania otaczających narzędzi. Utworzenie nazwanego interfejsu VLAN w konfiguracji sieci hosta i wskazanie na niego parent zachowuje przewidywalność obu końców.

Pamiętaj, że klucz pod networks to nazwa Compose, a nie urządzenie Linux. Szukanie na hoście interfejsu o nazwie office nie powiedzie się, bo jądro widzi tylko interfejs rodzica i parę veth za kontenerem.

Zrób miejsce dla VPN na wierzchu

Klient VPN podłącza się po powstaniu tych sieci, więc może dodać bardziej szczegółowe trasy, reguły polityki i filtry niezależnie od gw_priority. Zaplanuj prefiksy zdalne względem obu lokalnych subnetów, łącznie z odpowiedziami potrzebnymi ścieżce kontrolnej. Gdy prefiks zdalny pokrywa się z biurową siecią LAN, popraw plan adresacji, zamiast wyrywać cały zakres prywatny z tunelu.

Sprawdź ponownie adresy, trasy i ścieżkę usługi po starcie VPN, a potem jeszcze raz po ponownym połączeniu, bo właśnie przy ponownym połączeniu ginie trasa dodana ręcznie. Zapisz oczekiwaną tabelę przed pierwszym testem, aby późniejsze porównanie było diffem, a nie ćwiczeniem pamięci. Utrzymuj trwałe właścicielstwo sieci w Compose i pozwól konfiguracji VPN posiadać tylko własną politykę.

Powiązane artykuły