Kontit vastaavat toimiston LAN-verkossa ja lopettavat vastaamisen heti, kun yrityksen VPN yhdistää. Kontissa ei muuttunut mikään: ei uudelleenkäynnistystä, ei imagen päivitystä, ei asetusmuutosta. Muuttui isäntäkoneen reititystaulu, jossa tunnelin lisäämä reitti kattaa nyt Dockerin jakaman osoitteen. Ennen kuin muokkaat aliverkkoa tai pyydät VPN-poikkeusta, laita molemmat osoitesuunnitelmat vierekkäin, sillä korjaukset maksavat hyvin erilaisia määriä aikaa.

Lue reitti ennen kuin muutat asetuksia

Aloita verkosta, jonka Docker todella rakensi. IPAM-lohko on osoitesuunnitelma ja aliverkko on se rivi, jolla on merkitystä:

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

Compose varaa oletuksena /16:n jokaiselle uudelle projektille, joten kaksi palvelua mahtuu 65,536 osoitteen alueelle. Juuri tämä leveys tekee päällekkäisyyksistä yleisiä: satunnaisesti valittu /16 on tarpeeksi suuri nielaisemaan sivuston, johon pääset tunnelin kautta, eikä kukaan huomaa sitä ennen kuin tunneli nousee.

Vertaa sitten reitin valintaa yhdelle kontin osoitteelle, kerran tunneli alhaalla ja kerran ylhäällä:

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

Kaksi vastauksen muotoa johtavat eri paikkoihin. Jos tuloste nimeää tun0, wg0 tai toisen tunnelilaitteen, VPN-etuliite on vähintään yhtä tarkka kuin sillan reitti ja paketti ei koskaan saavuta konttia. Jos se nimeää edelleen sillan, isäntä voi tavoittaa kontin ja vikasi on suodatus, DNS tai paluupolku, joka epäonnistuu vain yhteen suuntaan.

Miksi /16-törmäys on helppo osua

Docker ottaa siltäverkot yksityisistä altaista ja oletusalta tulee lohkosta 172.16.0.0/12 /16:n siivuina. Yritysverkot käyttävät usein samaa yksityistä tilaa ja etäkäyttö-VPN työntää nämä etuliitteet jokaiselle yhdistävälle asiakkaalle. Kun molemmat osapuolet uskovat omistavansa 172.18.0.0/16, yksi reititystaulu pitää kahta ristiriitaista väitettä.

Voittajan ratkaisee etuliitteen pituus, ei reittien ilmestymisjärjestys. Tunneli, joka työntää 10.0.0.0/8 ei voita sillan reittiä 172.18.0.0/16, koska /8 on vähemmän tarkka. Tunneli, joka työntää 172.18.0.0/16, tai 172.18.5.0/24 sen sisällä, voittaa. Siksi yksi kannettava toimii toimiston verkossa ja epäonnistuu hotellin Wi-Fi-verkossa samalla VPN:llä: asiakas saa eri etuliitteet.

Sama taulu hallitsee toista suuntaa. Kontti, joka tarvitsee sisäisen isännän osoitteessa 10.8.4.20 lähettää paketin siltayhdyskäytävälleen ja isäntä reitittää sen sitten tunneliin. Tämä polku toimii yleensä siksi, että isäntä tekee NAT:in, mutta se epäonnistuu, kun yrityksen puoli hyväksyy vain kannettavan VPN-osoitteen tai kun käänteisen polun suodatus pudottaa epäsymmetrisen vastauksen.

Vertaa kolmea korjausta

Ulos on vain kolme tietä, ja ne eroavat siinä, kenen on hyväksyttävä ne ja mikä menee rikki, kun sellaista käytät.

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

Uudelleennumerointi on ainoa korjaus, jonka voi saada valmiiksi ilman tikettiä, ja siksi useimmat kirjoitukset pysähtyvät siihen. Se on halpa nuoressa projektissa ja kallis, kun migraatiotyökalu tai tallennettu yhteysmerkkijono osoittaa kirjaimelliseen osoitteeseen. Laske ne viittaukset ennen YAML:n muokkausta, ei sen jälkeen.

Poikkeus tunnelista on puhtain vastaus, kun päällekkäisyys on alueella, jonka yrityksesi todella omistaa. Se on myös hitain, ja se on hyödytön urakoitsijalle, joka ei voi muuttaa asiakasprofiilia. Julkaistu portti tai pieni käänteinen välityspalvelin välttää väittelyn: asiakas puhuu osoitteelle, jonka tunneli jo reitittää oikein, ja vain sen portin on oltava tavoitettavissa.

Kiinnitä alue tarkoituksella

Yhdelle projektille ilmoita aliverkko compose-tiedostossa, jotta projekti lakkaa ottamasta jaetusta altaasta:

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

Ota tämä alue rekisteristä, jota tiimisi pitää, älä esimerkistä jonka löysit hakemalla. Tarkista se VPN:n työntämiä etuliitteitä, kodin LAN-verkkoja joista ihmiset työskentelevät ja saman isännän muita konttiverkkoja vastaan. Suunnittele sitten uudelleenluonti, koska olemassa oleva verkko säilyttää vanhan aliverkkonsa: docker compose down, sitten up -d. docker network rm kieltäytyy, kun päätepisteitä on kiinnitetty, ja jokaisen tiedoston ipv4_address merkinnän on osuttava uudelle alueelle.

Verkkoihin, jotka Docker luo itse, aseta daemon-altaan tiedostossa /etc/docker/daemon.json:

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

Allas koskee verkkoja, jotka luodaan daemonin uudelleenkäynnistyksen jälkeen, ja jo olemassa olevat sillat säilyttävät osoitteensa. Se on kätevää ja helppo unohtaa, joten käsittele vanhaa projektia edelleen päällekkäisenä, kunnes joku luo sen verkon uudelleen. Dockerin moottorin verkkodokumentaatio kuvaa jakosäännöt, jos sinun on puolustettava allasta katselmoinnissa.

Linux-silta ja Docker Desktop epäonnistuvat eri tavalla

Linux-isännässä kontit istuvat silloilla isännän nimiavaruudessa. Yksi taulu päättää kaiken, joten yllä oleva vertailu on koko tarina: lue sillan reitti, lue tunnelin reitti ja katso kumpi voittaa todelliselle kontin osoitteelle.

Docker Desktop laittaa kontit VM:n taakse, jolla on oma NAT. Isännällä ei ole lainkaan reittiä kontin osoitteeseen; se saavuttaa palvelun julkaistun portin kautta, yleensä sidottuna 127.0.0.1. VPN-asiakas voi siis rikkoa palvelun ilman mitään aliverkon päällekkäisyyttä, joko asentamalla reitin VM:n sisäiselle alueelle tai estämällä loopback-liikenteen, kun tunneli on yhdistetty. Jos ip route get isännässä ilmoittaa, ettei kontin osoitteelle ole reittiä, se on odotettua eikä vika.

Käytännön seuraus on, mihin katsot ensin. Linuxissa aloita reititystaulusta. Desktopissa aloita julkaistusta portista ja VPN-asiakkaan palomuurisäännöistä ja tarkista sitten, törmääkö VM:n sisäinen aliverkko johonkin, mitä tunneli työntää.

Varmista tunneli ylhäällä

Yhdistä VPN uudelleen kahdesti ennen kuin sanot sen korjatuksi, koska profiili, joka työntää reitit yhdistettäessä ja vetää ne takaisin katkaistaessa, voi näyttää oikealta ensimmäisen yrityksen jälkeen. Aja sitten tarkistukset, jotka asiakas todella ajaa:

  1. ip route get isännästä, kontin todellista osoitetta käyttäen.
  2. Pyyntö toisesta kontista, jotta todistat palvelun itsensä olevan kunnossa.
  3. curl -sv http://127.0.0.1:8080/ asiakkaasta tunnelin ollessa ylhäällä, sitten traceroute -n kontin osoitteeseen LAN-verkossa olevalta koneelta.
  4. sysctl net.ipv4.conf.all.rp_filter jos pyyntö saavuttaa isännän mutta vastaus katoaa.

Kirjoita lopuksi valittu alue samaan rekisteriin, josta otit sen, päivämäärän ja sitä omistavan projektin kanssa. Seuraava päällekkäisyys tulee projektista, jota kukaan ei dokumentoinut, ja ainoa puolustus on, että alue varattiin tarkoituksella eikä vedetty sattumalta.

Aiheeseen liittyvät artikkelit