Ваш контејнер и даље одговара на свом контролном мосту, али сваки одлазни пакет излази преко канцеларијског macvlan-а. Ништа није отказало. Два прикључка дају по један гејтвеј, а једина подразумевана рута отишла је ка мрежи коју нисте имали на уму, па услуга наставља да ради док њен саобраћај иде дужим путем. Када неко то примети, доказ је табела рутирања, а не порука о грешци.

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

Зашто подразумевана рута слеће на погрешну мрежу

Свака мрежа којој се услуга придружи може да понуди свој гејтвеј, а контејнер ипак заврши са тачно једном подразумеваном рутом. Пре Compose 2.33.1 нерешено се решавало сортирањем имена мрежа, па је ознака попут control, која долази пре office, одређивала куда саобраћај иде. Ништа унутар контејнера не бележи да је одлука била произвољна, и зато она пролази кроз преглед кода и касније се појави као чудна путања. Стављање политике у compose датотеку једини је начин да избор буде проверљив.

Која мрежа побеђује, заиста мењају две ствари: вредности gw_priority које доделите и то које су мреже уопште повезане. Додајте трећу мрежу и скуп кандидата расте; уклоните macvlan и нема више ничега да се такмичи са мостом. Ниједан од тих потеза не појављује се у евиденцији апликације, јер погрешна подразумевана рута ретко прекида везу потпуно. Она само чини да одговори стижу са адресе коју друга страна можда не очекује.

Закуцајте гејтвеј уз gw_priority

Compose излаже gw_priority на сваком прикључку услуге на мрежу од верзије 2.33.1, а побеђује највећи број. Не постоји кључ гејтвеја по услузи, па вредност припада блоку networks те услуге. Пример испод даје подразумевану руту контроли, док office остаје доступан за свој директно повезани LAN.

services:
  vpn:
    networks:
      control:
        gw_priority: 1
      office:
        gw_priority: 0

networks:
  control:
    driver: bridge
    ipam:
      config:
        - subnet: 172.30.50.0/24
  office:
    driver: macvlan
    driver_opts:
      parent: eno1.120
      macvlan_mode: bridge
    ipam:
      config:
        - subnet: 192.168.120.0/24
          ip_range: 192.168.120.192/27
          gateway: 192.168.120.1

Читајте блок као две одвојене контроле: gw_priority одлучује о подразумеваној рути, а део ipam одлучује о адресирању. Промена само subnet-а оставља избор излаза нетакнут, и то је најчешћи начин да ова поправка буде примењена на пола. Држите приоритете поред мреже којом управљају, да следећи читалац не би морао да тражи одлуку.

Не мешајте gw_priority са обичним својством priority поред њега. Оно уређује стварање веза и ништа не говори о рутирању, па не може да изабере подразумевани гејтвеј и не поправља имена интерфејса. Ако неко препоручи да подигнете priority да бисте усмерили саобраћај, препорука је погрешна чак и када резултујући редослед случајно изгледа тачно.

Проверите која мрежа заиста носи подразумевану руту

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

docker compose config --quiet
docker exec vpn ip -4 route show default
docker exec vpn cat /proc/net/route

Тачан резултат наводи мостовни уређај и 172.30.50.1; погрешан наводи 192.168.120.1 и уређај macvlan. Ако слика не садржи пакет iproute2, датотека /proc ипак пријављује подразумевану руту, са одредиштем 00000000 и бајтовима гејтвеја обрнутим. Упоредите колону интерфејса са docker inspect када имена уређаја нису јасна.

Macvlan је физички порт, а не клон моста

Macvlan даје контејнеру други идентитет на каблу и управо то омогућава приступ локалним уређајима. То такође значи да порт прекидача и хипервизор морају да прихвате додатну MAC адресу, а многе облачне мреже то тихо одбијају. Тестирајте један контејнер пре него што испланирате флоту, јер одбијена MAC обично изгледа као веза која је подигнута и ништа не пропушта.

Подешавање macvlan_mode: bridge је режим драјвера macvlan, а не софтверски мост Docker-а, а passthru је посебан специјализован режим, а не подразумевани. Linux такође спречава macvlan контејнер да стигне до сопственог домаћина преко истог родитеља, и зато се контролни мост задржава уместо да се очекује да један прикључак обави оба посла.

Именујте родитеља VLAN-а пре него што га Compose види

Docker третира родитеља са тачком као eno1.120 као подинтерфејс 802.1Q и сам ствара уређај VLAN. Та погодност има границе: изведено име зависи од имена физичког интерфејса, а дугачка имена могу да гурну резултат изван онога што околни алати очекују. Стварање именованог VLAN интерфејса у мрежној конфигурацији домаћина и усмеравање parent-а ка њему чини оба краја предвидљивим.

Запамтите да је кључ под networks име Compose-а, а не Linux уређај. Тражење интерфејса названог office на домаћину неће успети, јер језгро види само родитељски интерфејс и пар veth иза контејнера.

Направите места за VPN одозго

VPN клијент се повезује пошто ове мреже постоје, па може да дода прецизније руте, правила политике и филтере независно од gw_priority. Планирајте удаљене префиксе према обе локалне подсетке, укључујући одговоре који су потребни контролној путањи. Када се удаљени префикс преклапа са канцеларијским LAN-ом, исправите план адреса уместо да ишчупате цео приватни опсег из тунела.

Поново проверите адресе, руте и путању услуге пошто VPN крене и још једном пошто се поново повеже, јер се управо при поновном повезивању губи ручно додата рута. Запишите очекивану табелу пре првог теста да би касније поређење било diff, а не вежба памћења. Задржите трајно власништво над мрежом у Compose-у и пустите VPN конфигурацији да поседује само сопствену политику.

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