Ваша Compose услуга улази у истек времена према API-ју који прегледач на истој машини отвара без икакве жалбе. Та разлика је траг: захтев који ради излази са хоста са VPN тунелом, а захтев који виси излази из контејнера са сопственим мрежним стеком. Ништа унутар контејнера не зна руте тунела, па приватно одредиште остаје недоступно како год се име напише. Решење је намерни скок кроз хост, а не паметнија табела рутирања.

Почните од тога зашто се два пута разликују, а затим одлучите где тунел треба да живи.

Зашто хост ради, а контејнер не

Подизање тунела даје хосту интерфејс, скуп рута и обично запис у резолверу који обезбеђује VPN. Контејнер ништа од тога не наслеђује: почиње са једним интерфејсом на мосту погона и подразумеваном рутом која показује на тај мост. Руте инсталиране на хосту невидљиве су свему што ради у том простору имена.

Зато симптоми изгледају неконзистентно, а не само покварено. Хост разрешава приватно име и повезује се, јер тамо постоје и име и рута. Контејнер шаље свој пакет на приватну адресу до које ништа на путу преко моста не може да стигне, и захтев истиче. Додавање имена у hosts датотеку контејнера не мења ништа, јер је сама адреса недоступна са места где контејнер стоји.

Стигните до хоста из унутрашњости контејнера

Процес у контејнеру који зове localhost зове контејнер. Docker Desktop објављује host.docker.internal као име које показује назад на машину која покреће погон; Linux погони га остављају недефинисаним осим ако услуга то затражи, а управо то чини мапирање испод. С тим апликација циља име и порт уместо приватне адресе.

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

Тунел остаје на страни хоста овог скока, а порт у тој променљивој је онај на ком ће прокси слушати. Контејнер који изгуби тунел сада пада на једном познатом скоку уместо да покушава руту коју никада није имао.

Изаберите где тунел живи

За Compose услугу којој треба приватни API могућа су три облика, и разликују се по томе који процес поседује тунел. VPN клијент може да ради унутар слике контејнера, што захтева излагање уређаја тунела и давање могућности администрације мреже која иде с тим. Апликација може да дели мрежни простор имена посебног контејнера тунела, тако да оба процеса виде један стек и једну табелу рутирања. Или тунел може да остане на хосту, са уским прослеђивачем са хоста у контејнер.

Прва два увлаче профилске датотеке, понашање поновног повезивања и политику резолвера у пројекат и чине сваку услугу у датотеци зависном од здравља тунела. То је превише повезаности за један позив API-ја. За развојни стек који чита једну интерну крајњу тачку, прослеђивач на страни хоста је најмања промена која ипак чува акредитиве тамо где их тим платформе управља.

Објавите једну уску путању на хосту

Почните од онога што прослеђивач наслеђује: покрените га под налогом који поседује тунел, и његови излазни сокети преузимају руте хоста и резолвер хоста. Један nginx location блок покрива једну путању.

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

Третирајте адресу и порт као замене и убаците пар на ком API заиста слуша. Сваки даљи upstream заслужује свој location блок, и сваки блок треба да пропушта само путање које ова услуга позива, да прокси не би постао општа врата у приватну мрежу. Вежите слушаоца за адресу моста за клијенте који долазе преко host-gateway, за loopback само када клијент дели мрежни простор имена хоста, и никада за 0.0.0.0. Изаберите и порт који је још слободан: већ заузет број оставља прокси да не слуша док контејнер наставља да истиче, што се не може разликовати од мрежне неисправности са којом сте почели.

Портови, имена и одлука о TLS-у

Разрешавање имена се дели исто као рутирање. Јавне претраге контејнера иду кроз резолвер погона, па се приватно име које се разрешава на хосту неће разрешити унутар контејнера. Прокси је компонента која разрешава приватно име, јер наслеђује резолвер хоста.

TLS је одлука која се одлаже и затим објашњава следећу неисправност. Ако прокси прослеђује бајтове нетакнуте, контејнер види сопствени сертификат API-ја и потребан му је интерни CA у његовом складишту поверења. Ако прокси завршава TLS, то поверење се премешта на хост и апликација почиње да гради везе из примљеног host заглавља. Изаберите један распоред и примените га на сваки ресурс, јер преусмерење које изда други указује на име хоста које контејнер не може да разреши.

Проверите из унутрашњости услуге

Пошаљите захтев из контејнера, не са хоста: обичан curl на путању проксија, затим сопствена провера здравља апликације. Када прокси одговори али апликација и даље не успева, упоредите три ствари: основни URL који гради, било коју прокси променљиву у његовом окружењу и CA ком верује. Све се налази у окружењу и дневницима контејнера, и поправка било које од њих оставља VPN на миру.

Запишите изабрани распоред у README пројекта док је још свеж. Иначе ће следећа особа која наиђе на овај истек времена провести исто поподне поново откривајући да тунел живи на хосту.

Повезани чланци