Containerar svarar på kontor-LAN-et, og sluttar å svare i det augneblinken bedrifts-VPN-en koplar til. Ingenting i containeren er endra: ingen omstart, ingen oppdatering av image, ingen konfigurasjonsendring. Det som er endra, er rutingtabellen til verten, der ei rute som tunnelen la til no dekkjer adressa Docker delte ut. Før du endrar eit subnett eller ber om eit VPN-unntak, legg begge adresseplanane side ved side, fordi reparasjonane kostar svært ulikt med tid.

Les ruta før du endrar konfigurasjonen

Start med nettverket Docker faktisk bygde. IPAM-blokka er adresseplanen, og subnettet er linja som betyr noko:

docker network inspect project_default --format '{{json .IPAM.Config}}'
# [{"Subnet":"172.18.0.0/16","Gateway":"172.18.0.1"}]

Compose tildeler eit /16 til kvart nytt prosjekt som standard, så to tenester kan liggje innanfor eit område på 65,536 adresser. Det er denne breidda som gjer overlapp vanleg: eit tilfeldig valt /16 er stort nok til å sluke ein stad du når gjennom tunnelen, og ingen merkar det før tunnelen kjem opp.

Samanlikn så rutevalet for éi containeradresse, éin gong med tunnelen nede og éin gong med han oppe:

ip route get 172.18.0.7
# 172.18.0.7 dev br-3f2a9c src 172.18.0.1

To svarformer fører til ulike stader. Viss utskrifta namngjev tun0, wg0 eller eit anna tunneleining, er eit VPN-prefiks minst like spesifikt som bru-ruta, og pakken når aldri fram til containeren. Viss ho framleis namngjev brua, kan verten nå containeren, og feilen din er filtrering, DNS eller ein returveg som sviktar berre i éi retning.

Kvifor ein /16-kollisjon er lett å treffe

Docker hentar bru-nettverk frå dei private poolane, og standardpoolen kjem frå 172.16.0.0/12-blokka i /16-bit. Bedriftsnettverk brukar ofte same private rom, og ein fjernaksess-VPN skyv desse prefiksa til kvar klient som koplar til. Når begge sider meiner dei eig 172.18.0.0/16, held éin rutingtabell to motstridande krav.

Prefikslengda avgjer vinnaren, ikkje rekkjefølgja rutene står i. Ein tunnel som skyv 10.0.0.0/8, slår ikkje ei bru-rute på 172.18.0.0/16, fordi /8 er mindre spesifikk. Ein tunnel som skyv 172.18.0.0/16, eller 172.18.5.0/24 inni henne, gjer det. Derfor verkar éin laptop på kontornettet og feilar på hotell-Wi-Fi med same VPN: klienten mottar ulike prefiks.

Den same tabellen styrer den andre retninga. Ein container som treng ein intern vert på 10.8.4.20, sender pakken til bru-gatewayen sin, og verten ruter han deretter inn i tunnelen. Den vegen verkar vanlegvis fordi verten utfører NAT, men han feilar når bedriftssida berre godtar VPN-adressa til laptopen, eller når reversstifiltrering droppar det asymmetriske svaret.

Samanlikn dei tre reparasjonane

Det finst berre tre vegar ut, og dei skil seg i kven som må godkjenne dei og kva som ryker medan du brukar ein av dei.

RepairWho owns itWhat it costs
Renumber the container networkYouRecreates the network, restarts services, invalidates literal addresses in configs and scripts
Exclude your range from the tunnelNetwork teamChanges what every laptop sees, needs a change request and a client profile update
Reach the service through a published portYou and the clientOne port only, no direct container-to-container routing across the tunnel

Omnummerering er den einaste reparasjonen du kan fullføre utan ein sak, og derfor stoppar dei fleste skriveri der. Han er billeg på eit ungt prosjekt og dyr når eit migreringsverktøy eller ein lagra tilkoplingsstreng peikar på ei litterær adresse. Tel dei referansane før du redigerer YAML, ikkje etterpå.

Eit unntak frå tunnelen er det reinaste svaret når overlappen ligg i eit område bedrifta di faktisk eig. Det er òg det tregaste, og det er ubrukeleg for ein innleigd konsulent som ikkje kan endre klientprofilen. Ein publisert port eller ein liten revers-proxy unngår diskusjonen: klienten snakkar med ei adresse tunnelen allereie ruter rett, og berre den porten må vere tilgjengeleg.

Fest eit område med vilje

For eitt enkelt prosjekt, deklarer subnettet i compose-fila så prosjektet sluttar å hente frå den delte poolen:

networks:
  default:
    ipam:
      config:
        - subnet: 10.201.7.0/24

Ta det området frå eit register teamet ditt vedlikeheld, ikkje frå eit døme du fann medan du søkte. Sjekk det mot prefiksa VPN-en skyv, heimenettverka folk jobbar frå, og dei andre containernettverka på same vert. Planlegg så attopprettinga, fordi eit eksisterande nettverk held på det gamle subnettet: docker compose down, deretter up -d. docker network rm nektar medan endepunkt er tilkopla, og kvar ipv4_address-oppføring i fila må liggje innanfor det nye området.

For nettverk Docker opprettar sjølv, set ein daemon-pool i /etc/docker/daemon.json:

{
  "default-address-pools": [
    { "base": "10.201.0.0/16", "size": 24 },
    { "base": "10.202.0.0/16", "size": 24 }
  ]
}

Poolen gjeld nettverk som blir oppretta etter at daemonen startar på nytt, og bruer som allereie finst, held på adressene sine. Det er praktisk og lett å gløyme, så handsam eit gammalt prosjekt som framleis overlappande til nokon attopprettar nettverket. Dockers nettverksdokumentasjon for motoren skildrar tildelingsreglane viss du må forsvare poolen i ein gjennomgang.

Linux-brua og Docker Desktop feilar ulikt

På ein Linux-vert ligg containerane på bruer i namnerommet til verten. Éin tabell avgjer alt, så samanlikninga over er heile historia: les bru-ruta, les tunnelruta, og sjå kva som vinn for ei ekte containeradresse.

Docker Desktop plasserer containerar bak ein VM med sin eigen NAT. Verten har inga rute til containeradressa i det heile; han når tenesta gjennom ein publisert port, vanlegvis bunden til 127.0.0.1. Ein VPN-klient kan derfor bryte tenesta utan nokon subnett-overlapp, anten ved å installere ei rute for det interne området til VM-en eller ved å blokkere loopback-trafikk medan tunnelen er tilkopla. Viss ip route get på verten rapporterer inga rute for containeradressa, er det venta og ikkje feilen.

Den praktiske konsekvensen er kvar du ser først. På Linux, start med rutingtabellen. På Desktop, start med den publiserte porten og brannmurreglane til VPN-klienten, og sjekk deretter om det interne subnettet til VM-en kolliderer med noko tunnelen skyv.

Stadfest med tunnelen oppe

Kopla til VPN-en to gonger før du kallar det fiksa, fordi ein profil som skyv ruter ved tilkopling og trekkjer dei tilbake ved fråkopling kan sjå rett ut etter første forsøk. Køyr så kontrollane klienten faktisk køyrer:

  1. ip route get frå verten, med den verkelege adressa til containeren.
  2. Ein førespurnad frå ein annan container, for å prove at tenesta sjølv er frisk.
  3. curl -sv http://127.0.0.1:8080/ frå klienten med tunnelen oppe, deretter traceroute -n til containeradressa frå ein maskin på LAN-et.
  4. sysctl net.ipv4.conf.all.rp_filter viss førespurnaden når verten men svaret forsvinn.

Til slutt, skriv det valde området inn i same registeret som du brukte til å velje det, med dato og prosjektet som eig det. Den neste overlappen kjem frå eit prosjekt ingen dokumenterte, og det einaste forsvaret er at området vart reservert med vilje i staden for trekt tilfeldig.

Relaterte artiklar