Un container cu două rețele alege gateway-ul greșit
Două atașări, o singură rută implicită, iar rețeaua greșită câștigă mereu. Fixați ieșirea cu Compose gw_priority și confirmați-o din interiorul containerului.
Containerul dvs. răspunde în continuare pe puntea sa de control, dar fiecare pachet de ieșire pleacă prin macvlan-ul biroului. Nimic nu a eșuat. Două atașări oferă fiecare câte un gateway, iar singura rută implicită a mers către rețeaua la care nu vă gândeați, așa că serviciul continuă să funcționeze în timp ce traficul lui ia o cale mai lungă. Când cineva observă, dovada este un tabel de rutare și nu un mesaj de eroare.
Explicația obișnuită este că Docker a ales rețeaua din greșeală. În practică, decizia veche urma ordinea alfabetică a numelor rețelelor atașate, ceea ce transforma rutarea într-un efect secundar al unei etichete. gw_priority înlocuiește asta cu un număr pe care îl alegeți intenționat, iar adoptarea durează aproximativ un minut după ce schema este scrisă.
De ce ruta implicită ajunge pe rețeaua greșită
Fiecare rețea în care intră un serviciu poate oferi propriul gateway, iar containerul rămâne totuși cu exact o rută implicită. Înainte de Compose 2.33.1 egalitatea se decidea sortând numele rețelelor, așa că o etichetă precum control, care vine înaintea lui office, decidea unde merge traficul. Nimic din interiorul containerului nu înregistrează că decizia a fost arbitrară, motiv pentru care trece de revizia codului și apare mai târziu ca o cale ciudată. A pune o politică în fișierul compose este singurul mod de a face alegerea inspectabilă.
Două lucruri schimbă cu adevărat ce rețea câștigă: valorile gw_priority pe care le atribuiți și ce rețele sunt atașate. Adăugați o a treia rețea și mulțimea candidaților crește; scoateți macvlan-ul și nu mai rămâne nimic care să concureze cu puntea. Niciuna dintre mișcări nu apare în jurnalele aplicației, pentru că o rută implicită greșită rar rupe conexiunea de tot. Face doar ca răspunsurile să sosească de la o adresă pe care cealaltă parte poate nu o așteaptă.
Fixați gateway-ul cu gw_priority
Compose expune gw_priority pe fiecare atașare serviciu-la-rețea începând cu versiunea 2.33.1, iar numărul cel mai mare câștigă. Nu există o cheie de gateway pentru fiecare serviciu, așa că valoarea aparține blocului networks al serviciului. Exemplul de mai jos oferă ruta implicită lui control, lăsând office accesibil pentru LAN-ul său conectat direct.
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
Citiți blocul ca două controale separate: gw_priority decide ruta implicită, iar secțiunea ipam decide adresarea. Schimbarea doar a subnetului lasă alegerea ieșirii neatinsă, și acesta este cel mai obișnuit mod în care această corecție este aplicată pe jumătate. Țineți prioritățile lângă rețeaua pe care o guvernează, ca următorul cititor să nu trebuiască să caute decizia.
Nu confundați gw_priority cu proprietatea priority simplă de alături. Aceea ordonează crearea conexiunilor și nu spune nimic despre rutare, deci nu poate alege un gateway implicit și nu repară numele interfețelor. Dacă cineva recomandă ridicarea priority pentru a direcționa traficul, recomandarea este greșită chiar și atunci când ordinea rezultată pare corectă din întâmplare.
Verificați ce rețea poartă într-adevăr ruta implicită
Verificați în interiorul containerului care rulează, pentru că tabelul de rutare al gazdei descrie gazda și nu spațiul de nume folosit de serviciu. Rulați mai întâi verificarea configurației ca o greșeală de tastare să eșueze înainte de o repornire, apoi citiți ruta pe care containerul a instalat-o efectiv.
docker compose config --quiet
docker exec vpn ip -4 route show default
docker exec vpn cat /proc/net/route
Un rezultat corect numește dispozitivul de punte și 172.30.50.1; unul greșit numește 192.168.120.1 și dispozitivul macvlan. Dacă imaginea nu include pachetul iproute2, fișierul /proc raportează totuși ruta implicită, cu destinația 00000000 și octeții gateway-ului inversați. Comparați coloana interfeței cu docker inspect atunci când numele dispozitivelor nu sunt clare.
Macvlan este un port fizic, nu o clonă a punții
Macvlan oferă containerului o a doua identitate pe cablu, și exact asta face ca accesul la dispozitivele locale să funcționeze. Înseamnă și că portul comutatorului și hipervizorul trebuie să accepte o adresă MAC suplimentară, iar multe rețele de cloud refuză asta în tăcere. Testați un container înainte de a planifica o flotă, pentru că un MAC refuzat apare de obicei ca o legătură care este sus și nu lasă nimic să treacă.
Setarea macvlan_mode: bridge este un mod al driverului macvlan, nu puntea software a Docker, iar passthru este un mod specializat separat și nu o valoare implicită. Linux împiedică de asemenea un container macvlan să ajungă la propria gazdă prin același părinte, și acesta este motivul pentru care puntea de control este păstrată în loc să se aștepte ca o singură atașare să facă ambele sarcini.
Numiți părintele VLAN înainte ca Compose să-l vadă
Docker tratează un părinte cu punct precum eno1.120 ca o subinterfață 802.1Q și creează el însuși dispozitivul VLAN. Acest confort are limite: numele derivat depinde de numele interfeței fizice, iar numele lungi pot împinge rezultatul dincolo de ce așteaptă uneltele din jur. Crearea unei interfețe VLAN cu nume în configurația de rețea a gazdei și îndreptarea parent către ea păstrează ambele capete previzibile.
Amintiți-vă că cheia de sub networks este un nume Compose, nu un dispozitiv Linux. Căutarea pe gazdă a unei interfețe numite office va eșua, pentru că nucleul vede doar interfața părinte și perechea veth din spatele containerului.
Faceți loc pentru VPN deasupra
Un client VPN se atașează după ce aceste rețele există, deci poate adăuga rute mai specifice, reguli de politică și filtre indiferent de gw_priority. Planificați prefixele la distanță față de ambele subneturi locale, inclusiv răspunsurile de care are nevoie calea de control. Când un prefix la distanță se suprapune cu LAN-ul biroului, corectați planul de adrese în loc să smulgeți un interval privat întreg din tunel.
Verificați din nou adresele, rutele și calea serviciului după ce pornește VPN-ul și încă o dată după ce se reconectează, pentru că la o reconectare dispare o rută adăugată manual. Scrieți tabelul așteptat înainte de primul test, ca comparația de după să fie un diff și nu un exercițiu de memorie. Păstrați proprietatea persistentă asupra rețelei în Compose și lăsați configurația VPN să dețină doar propria politică.