A Compose-szolgáltatásod időtúllépésbe fut egy API-val szemben, amelyet ugyanazon a gépen a böngésző panasz nélkül megnyit. Ez a különbség a nyom: a működő kérés egy VPN-alagúttal rendelkező hostról indul, a beragadó kérés pedig egy saját hálózati veremmel rendelkező konténerből. A konténeren belül semmi nem ismeri az alagút útvonalait, ezért a privát cél elérhetetlen marad, bárhogyan is írják a nevet. A megoldás egy szándékos ugrás a hoston keresztül, nem egy okosabb útvonaltábla.

Kezdd azzal, miért különbözik a két útvonal, aztán döntsd el, hol éljen az alagút.

Miért működik a host, és miért nem a konténer

Az alagút felállítása interfészt, útvonalakat és általában a VPN által adott feloldóbejegyzést ad a hostnak. A konténer ebből semmit nem örököl: egy interfésszel indul a motor hídján és egy alapértelmezett útvonallal, amely arra a hídra mutat. A hoston telepített útvonalak láthatatlanok minden számára, ami ezen a névtéren belül fut.

Ezért tűnnek a tünetek következetlennek, nem egyszerűen töröttnek. A host feloldja a privát nevet és csatlakozik, mert ott a név és az útvonal is létezik. A konténer a csomagját egy privát címre küldi, amelyet semmi nem ér el a híd útvonalán, és a kérés időtúllépésbe fut. A név hozzáadása a konténer hosts fájljához nem változtat semmit, mert maga a cím elérhetetlen onnan, ahol a konténer áll.

Érd el a hostot a konténer belsejéből

A konténerben futó folyamat, amely a localhost címet hívja, a konténert hívja. A Docker Desktop a host.docker.internal nevet teszi közzé, amely a motort futtató gépre mutat vissza; a Linux motorok definiálatlanul hagyják, hacsak a szolgáltatás nem kéri, és pontosan ezt teszi az alábbi leképezés. Ezzel az alkalmazás a privát cím helyett egy nevet és egy portot céloz.

services:
  app:
    extra_hosts:
      - "host.docker.internal:host-gateway"
    environment:
      INTERNAL_API_HOST: "host.docker.internal:8666"

Az alagút az ugrás host oldalán marad, és az abban a változóban szereplő port az, amelyen a proxy figyelni fog. Az alagutat elvesztő konténer most egyetlen ismert ugrásnál hibázik, ahelyett hogy olyan útvonalat próbálna, amellyel soha nem rendelkezett.

Válaszd ki, hol él az alagút

Egy privát API-t igénylő Compose-szolgáltatás számára három forma lehetséges, és abban különböznek, melyik folyamat birtokolja az alagutat. A VPN-kliens futhat a konténer image-en belül, ami az alagúteszköz feltárását és a vele járó hálózati adminisztrációs képesség megadását igényli. Az alkalmazás megoszthatja egy külön alagút-konténer hálózati névterét, így mindkét folyamat egy vermet és egy útvonaltáblát lát. Vagy az alagút a hoston maradhat, egy szűk továbbítóval a hostból a konténerbe.

Az első kettő profilfájlokat, újracsatlakozási viselkedést és feloldószabályt húz a projektbe, és a fájl minden szolgáltatását az alagút állapotától teszi függővé. Ez sok csatolás egyetlen API-híváshoz. Egy fejlesztői veremhez, amely egyetlen belső végpontot olvas, a host oldali továbbító a legkisebb változás, amely mégis ott tartja a hitelesítő adatokat, ahol a platformcsapat kezeli őket.

Tegyél közzé egyetlen szűk útvonalat a hoston

Kezdd azzal, amit a továbbító örököl: futtasd azzal a fiókkal, amely az alagutat birtokolja, és a kimenő socketjei átveszik a host útvonalait és a host feloldóját. Egy nginx location blokk egy útvonalat fed le.

server {
    listen 8666;
    location /search/ {
        proxy_pass http://10.20.30.40:8090/;
        proxy_set_header Host internal-api.example;
        proxy_read_timeout 60s;
    }
}

Kezeld a címet és a portot helyőrzőként, és tedd be azt a párt, amelyen az API valójában figyel. Minden további upstream saját location blokkot érdemel, és minden blokk csak azokat az útvonalakat engedje be, amelyeket ez a szolgáltatás hív, hogy a proxy ne váljon a privát hálózat általános ajtajává. A figyelőt a híd címéhez kösd a host-gatewayen érkező klienseknél, loopbackhez csak akkor, ha a kliens osztozik a host hálózati névterén, és soha ne 0.0.0.0-hoz. Olyan portot is válassz, amely még szabad: egy már foglalt szám figyelés nélkül hagyja a proxyt, miközben a konténer tovább fut időtúllépésbe, ami nem különböztethető meg attól a hálózati hibától, amellyel kezdted.

Portok, nevek és a TLS-döntés

A névfeloldás ugyanúgy válik szét, mint az útválasztás. A konténer nyilvános lekérdezései a motor feloldóján mennek át, ezért egy privát név, amely a hoston feloldódik, a konténeren belül nem fog feloldódni. A proxy az az összetevő, amely a privát nevet feloldja, mert örökli a host feloldóját.

A TLS az a döntés, amelyet elhalasztanak, majd megmagyarázza a következő hibát. Ha a proxy érintetlenül továbbítja a bájtokat, a konténer az API saját tanúsítványát látja, és szüksége van a belső CA-ra a bizalmi tárolójában. Ha a proxy lezárja a TLS-t, az a bizalom a hostra kerül, és az alkalmazás a kapott host fejlécből kezd hivatkozásokat építeni. Válassz egy elrendezést, és alkalmazd minden erőforrásra, mert a másik által kiadott átirányítás olyan hostnévre mutat, amelyet a konténer nem tud feloldani.

Ellenőrizd a szolgáltatás belsejéből

A kérést a konténerből küldd, ne a hostról: egy egyszerű curl a proxy útvonalára, majd az alkalmazás saját állapotellenőrzése. Amikor a proxy válaszol, de az alkalmazás továbbra is hibázik, hasonlíts össze három dolgot: az általa épített alap URL-t, a környezetében lévő bármely proxyváltozót és a CA-t, amelyben megbízik. Mindegyik a konténer környezetében és naplóiban van, és bármelyik javítása békén hagyja a VPN-t.

Írd be a választott elrendezést a projekt README-jébe, amíg friss. Különben a következő ember, aki ebbe az időtúllépésbe fut, ugyanazt a délutánt tölti azzal, hogy újra felfedezze: az alagút a hoston él.

Kapcsolódó cikkek