Container med to nettverk velger feil gateway
To tilkoblinger, én standardrute, og feil nettverk vinner hver gang. Fest utgangen med Compose gw_priority og bekreft den inne i containeren.
Containeren din svarer fortsatt på kontrollbroen sin, men hver utgående pakke forlater nettverket via kontor-macvlanen. Ingenting har feilet. To tilkoblinger gir hver sin gateway, og den eneste standardruten gikk til nettverket du ikke mente, så tjenesten fortsetter å virke mens trafikken tar en lengre vei. Når noen oppdager det, er beviset en rutetabell og ikke en feilmelding.
Den vanlige forklaringen er at Docker valgte nettverket ved et uhell. I praksis fulgte den gamle avgjørelsen den alfabetiske rekkefølgen til de tilkoblede nettverksnavnene, noe som gjorde ruting til en bivirkning av en etikett. gw_priority erstatter det med et tall du velger med vilje, og å ta det i bruk tar omtrent ett minutt når oppsettet er skrevet ned.
Hvorfor standardruten ender på feil nettverk
Hvert nettverk en tjeneste blir med i kan tilby sin egen gateway, og containeren ender likevel med nøyaktig én standardrute. Før Compose 2.33.1 ble uavgjort avgjort ved å sortere nettverksnavnene, så en etikett som control som kommer før office bestemte hvor trafikken gikk. Ingenting inne i containeren registrerer at avgjørelsen var vilkårlig, og derfor overlever den kodegjennomgang og dukker senere opp som en merkelig vei. Å legge en policy i compose-filen er den eneste måten å gjøre valget etterprøvbart.
To ting endrer faktisk hvilket nettverk som vinner: gw_priority-verdiene du tildeler, og hvilke nettverk som er tilkoblet i det hele tatt. Legg til et tredje nettverk og kandidatsettet vokser; fjern macvlanen og det er ingenting igjen å konkurrere med broen. Ingen av de to grepene vises i applikasjonsloggen, fordi en feil standardrute sjelden bryter forbindelsen helt. Den gjør bare at svar kommer fra en adresse den andre siden kanskje ikke forventer.
Fest gatewayen med gw_priority
Compose eksponerer gw_priority på hver tjeneste-til-nettverk-tilkobling fra versjon 2.33.1, og det høyeste tallet vinner. Det finnes ingen gateway-nøkkel per tjeneste, så verdien hører under tjenestens networks-blokk. Eksemplet nedenfor gir standardruten til control mens office forblir tilgjengelig for sitt direkte tilkoblede 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
Les blokken som to separate kontroller: gw_priority avgjør standardruten, og ipam-delen avgjør adressering. Å endre bare subnettet lar utgangsvalget stå urørt, og det er den vanligste måten denne rettelsen blir halvveis brukt. Hold prioritetene ved siden av nettverket de styrer, slik at neste leser ikke må lete etter avgjørelsen.
Ikke forveksle gw_priority med den vanlige priority-egenskapen ved siden av. Den ordner opprettelsen av forbindelser og sier ingenting om ruting, så den kan ikke velge en standardgateway og retter ikke opp grensesnittnavn. Hvis noen anbefaler å heve priority for å styre trafikken, er anbefalingen feil selv når den resulterende rekkefølgen tilfeldigvis ser riktig ut.
Verifiser hvilket nettverk som faktisk bærer standardruten
Sjekk inne i den kjørende containeren, fordi vertens rutetabell beskriver verten og ikke navnerommet tjenesten bruker. Kjør konfigurasjonssjekken først slik at en skrivefeil feiler før en omstart, og les deretter ruten containeren faktisk installerte.
docker compose config --quiet
docker exec vpn ip -4 route show default
docker exec vpn cat /proc/net/route
Et riktig resultat navngir broenheten og 172.30.50.1; et galt navngir 192.168.120.1 og macvlan-enheten. Hvis image ikke inneholder iproute2-pakken, rapporterer /proc-filen fortsatt standardruten, med mål 00000000 og gateway-bytene reversert. Sammenlign grensesnittkolonnen med docker inspect når enhetsnavnene er uklare.
Macvlan er en fysisk port, ikke en klone av broen
Macvlan gir containeren en annen identitet på kabelen, og det er nettopp dette som gjør tilgang til lokale enheter mulig. Det betyr også at svitsjporten og hypervisoren må godta en ekstra MAC-adresse, og mange skynettverk avviser det i stillhet. Test én container før du planlegger en flåte, fordi en avvist MAC vanligvis viser seg som en lenke som er oppe og ikke slipper noe gjennom.
Innstillingen macvlan_mode: bridge er en modus i macvlan-driveren, ikke Dockers programvarebro, og passthru er en egen spesialisert modus og ikke en standard. Linux hindrer også en macvlan-container i å nå sin egen vert gjennom samme forelder, og det er grunnen til å beholde kontrollbroen i stedet for å forvente at én tilkobling gjør begge jobbene.
Navngi VLAN-forelderen før Compose ser den
Docker behandler en forelder med punktum som eno1.120 som et 802.1Q-undergrensesnitt og oppretter VLAN-enheten selv. Den bekvemmeligheten har grenser: det avledede navnet avhenger av navnet på det fysiske grensesnittet, og lange navn kan skyve resultatet ut over det verktøyene rundt forventer. Å opprette et navngitt VLAN-grensesnitt i vertens nettverkskonfigurasjon og peke parent dit holder begge endene forutsigbare.
Husk at nøkkelen under networks er et Compose-navn, ikke en Linux-enhet. Å lete etter et grensesnitt som heter office på verten vil feile, fordi kjernen bare ser foreldregrensesnittet og veth-paret bak containeren.
Lag plass til VPN-en på toppen
En VPN-klient kobles til etter at disse nettverkene finnes, så den kan legge til mer spesifikke ruter, policyregler og filtre uavhengig av gw_priority. Planlegg fjernprefiksene mot begge lokale subnett, inkludert svarene kontrollveien trenger. Når et fjernprefiks overlapper kontor-LAN-et, rett opp adresseplanen i stedet for å rive et helt privat område ut av tunnelen.
Kontroller adresser, ruter og tjenestebanen på nytt etter at VPN-en starter og igjen etter at den kobler til på nytt, fordi det er ved en gjenoppkobling en håndlagt rute forsvinner. Skriv ned den forventede tabellen før første test, slik at sammenligningen etterpå er en diff og ikke en huskeøvelse. Behold den varige nettverkseierskapen i Compose og la VPN-konfigurasjonen bare eie sin egen policy.