A konténerek válaszolnak az irodai LAN-on, majd abban a pillanatban abbahagyják a válaszadást, amikor a vállalati VPN csatlakozik. A konténerben semmi sem változott: nincs újraindítás, nincs image-frissítés, nincs konfigurációmódosítás. Ami változott, az a gazdagép útválasztási táblája, ahol az alagút által hozzáadott útvonal most lefedi a Docker által kiosztott címet. Mielőtt alhálózatot szerkeszt vagy VPN-kivételt kér, tegye egymás mellé a két címtervet, mert a javítások nagyon eltérő időráfordítással járnak.

Olvassa el az útvonalat, mielőtt módosítja a konfigurációt

Kezdje azzal a hálózattal, amelyet a Docker valóban felépített. Az IPAM-blokk a címterv, az alhálózat pedig az a sor, amely számít:

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

A Compose alapértelmezés szerint /16-ot oszt minden új projekthez, így két szolgáltatás is elfér egy 65,536 címes tartományban. Éppen ez a szélesség teszi gyakorivá az átfedéseket: egy véletlenszerűen választott /16 elég nagy ahhoz, hogy elnyeljen egy oldalt, amelyet az alagúton keresztül ér el, és senki sem veszi észre, amíg az alagút fel nem jön.

Ezután hasonlítsa össze az útvonalválasztást egy konténer-címre, egyszer leengedett, egyszer felemelt alagúttal:

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

A válasz két formája különböző helyekre vezet. Ha a kimenet tun0, wg0 vagy más alagúteszközt nevez meg, a VPN-előtag legalább olyan specifikus, mint a híd útvonala, és a csomag soha nem érkezik meg a konténerbe. Ha továbbra is a hidat nevezi meg, a gazdagép eléri a konténert, és a hibája a szűrés, a DNS vagy egy visszaút, amely csak egy irányban sikertelen.

Miért könnyű /16-os ütközést elérni

A Docker a hídhálózatokat a privát készletekből meríti, az alapértelmezett készlet pedig a 172.16.0.0/12 blokkból jön /16-os szeletekben. A vállalati hálózatok gyakran ugyanazt a privát teret használják, és a távoli elérésű VPN ezeket az előtagokat minden csatlakozó klienshez eltolja. Amikor mindkét fél azt hiszi, hogy birtokolja a 172.18.0.0/16 címet, egy útválasztási tábla két ellentmondó állítást tart.

A győztest az előtag hossza dönti el, nem az útvonalak megjelenési sorrendje. Egy alagút, amely 10.0.0.0/8 nyom, nem győzi le a híd útvonalát 172.18.0.0/16, mert a /8 kevésbé specifikus. Egy alagút, amely 172.18.0.0/16, vagy 172.18.5.0/24 belsejét nyomja, igen. Ezért működik egy laptop az irodai hálózaton, és bukik el a hotel Wi-Fi-jén ugyanazzal a VPN-nel: a kliens különböző előtagokat kap.

Ugyanaz a tábla irányítja az ellenkező irányt is. Egy konténer, amelynek belső gazdagépre van szüksége a 10.8.4.20 címen, a csomagot a híd átjárójára küldi, a gazdagép pedig az alagútba irányítja. Ez az útvonal általában működik, mert a gazdagép végzi a NAT-ot, de akkor bukik el, amikor a vállalati oldal csak a laptop VPN-címét fogadja el, vagy amikor a fordított útvonal szűrése eldobja az aszimmetrikus választ.

Hasonlítsa össze a három javítást

Csak három kiút van, és abban különböznek, hogy kinek kell jóváhagynia őket, és mi törik el, miközben az egyiket alkalmazza.

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

Az újraszámozás az egyetlen javítás, amelyet ticket nélkül befejezhet, ezért a legtöbb írás ott megáll. Fiatal projektben olcsó, és drága, amikor egy migrációs eszköz vagy egy tárolt kapcsolati karakterlánc szó szerinti címre mutat. Számolja meg ezeket a hivatkozásokat a YAML szerkesztése előtt, nem utána.

Az alagútból való kivétel a legtisztább válasz, ha az átfedés olyan tartományban van, amelyet a cége valóban birtokol. Ez a leglassabb is, és haszontalan olyan alvállalkozónak, aki nem tudja módosítani a kliensprofilt. Egy közzétett port vagy egy kis fordított proxy elkerüli a vitát: a kliens olyan címmel beszél, amelyet az alagút már helyesen irányít, és csak annak a portnak kell elérhetőnek lennie.

Rögzítsen egy tartományt szándékosan

Egyetlen projektnél deklarálja az alhálózatot a compose fájlban, hogy a projekt ne merítsen a megosztott készletből:

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

Ezt a tartományt abból a nyilvántartásból vegye, amelyet a csapata vezet, ne egy keresés közben talált példából. Ellenőrizze a VPN által nyomott előtagokkal, a házi LAN-okkal, ahonnan az emberek dolgoznak, és az ugyanazon a gazdagépen lévő többi konténerhálózattal. Ezután tervezze meg az újralétrehozást, mert egy meglévő hálózat megtartja a régi alhálózatát: docker compose down, majd up -d. docker network rm elutasítja, amíg végpontok vannak csatlakoztatva, és a fájl minden ipv4_address bejegyzésének az új tartományba kell esnie.

Azokhoz a hálózatokhoz, amelyeket a Docker maga hoz létre, állítson be egy daemon-készletet a /etc/docker/daemon.json fájlban:

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

A készlet a daemon újraindítása után létrehozott hálózatokra vonatkozik, a már létező hidak pedig megtartják a címeiket. Ez kényelmes és könnyű elfelejteni, ezért tekintsen egy régi projektet továbbra is átfedőnek, amíg valaki újra nem hozza létre a hálózatát. A Docker motorhálózati dokumentációja leírja a kiosztási szabályokat, ha meg kell védenie a készletet egy felülvizsgálaton.

A Linux-híd és a Docker Desktop másképp bukik el

Linux gazdagépen a konténerek a gazdagép névterében lévő hidakon ülnek. Egy tábla dönt mindenről, ezért a fenti összehasonlítás a teljes történet: olvassa el a híd útvonalát, olvassa el az alagút útvonalát, és nézze meg, melyik nyer egy valódi konténer-címre.

A Docker Desktop a konténereket egy saját NAT-tal rendelkező VM mögé helyezi. A gazdagépnek egyáltalán nincs útvonala a konténer címéhez; a szolgáltatást egy közzétett porton keresztül éri el, amely általában a 127.0.0.1 címhez van kötve. Egy VPN-kliens ezért minden alhálózati átfedés nélkül is elronthatja a szolgáltatást, akár útvonalat telepít a VM belső tartományához, akár blokkolja a loopback-forgalmat, amíg az alagút csatlakoztatva van. Ha a gazdagépen a ip route get azt jelenti, hogy nincs útvonal a konténer címéhez, az várható, és nem a hiba.

A gyakorlati következmény az, hogy hova néz először. Linuxon kezdje az útválasztási táblánál. Desktopon kezdje a közzétett portnál és a VPN-kliens tűzfalszabályainál, majd ellenőrizze, hogy a VM belső alhálózata ütközik-e valamivel, amit az alagút nyom.

Ellenőrizze felemelt alagúttal

Csatlakoztassa újra a VPN-t kétszer, mielőtt javítottnak nevezné, mert egy profil, amely csatlakozáskor útvonalakat nyom, leválasztáskor pedig visszahúzza őket, az első kísérlet után helyesnek tűnhet. Ezután futtassa azokat az ellenőrzéseket, amelyeket a kliens valóban futtat:

  1. ip route get a gazdagépről, a konténer valódi címével.
  2. Kérés egy másik konténerből, hogy bizonyítsa, maga a szolgáltatás egészséges.
  3. curl -sv http://127.0.0.1:8080/ a klienstől felemelt alagúttal, majd traceroute -n a konténer címére a LAN egyik gépéről.
  4. sysctl net.ipv4.conf.all.rp_filter ha a kérés eléri a gazdagépet, de a válasz eltűnik.

Végül írja be a kiválasztott tartományt ugyanabba a nyilvántartásba, amelyből választotta, a dátummal és azzal a projekttel, amely birtokolja. A következő átfedés egy olyan projektből jön, amelyet senki sem dokumentált, és az egyetlen védelem az, hogy a tartományt szándékosan foglalták le, nem véletlenszerűen húzták.

Kapcsolódó cikkek