Windows контейнери и VPN: защо локалната мрежа се чупи
Контейнерът Windows използва таблицата за маршрутизиране на хоста, затова VPN, който блокира локалната подмрежа, отнася със себе си и префикса на контейнера. Режимът Linux поема по друг път.
На един лаптоп, с един свързан VPN клиент, Linux контейнерите продължават да говорят помежду си, а Windows контейнерите спират. Променливата не е образът, а пътят, по който пакетите влизат в хоста. Windows контейнерите в мрежата по подразбиране заемат таблицата за маршрутизиране и транслацията на хоста, затова политика, която променя маршрутизирането на хоста, променя и тях. Потвърдете това с търсене на маршрут, преди да преинсталирате каквото и да е.
Къде пакетите на Windows контейнер влизат в хоста
Контейнер в мрежата по подразбиране nat получава адрес от префикс на Host Networking Service, обикновено някъде в 172.16.0.0/12, и достига до хоста през виртуален адаптер. Хостът притежава маршрута за този префикс и транслеира трафика към адаптера, който е активен в момента. По средата на този път няма отделна виртуална машина.
Точно този дизайн прави отказа механичен. Когато контейнерът изпрати пакет, хостът прави търсене на маршрут за префикса на контейнера. Който маршрут победи, там отива пакетът, и контейнерът няма мнение по въпроса.
Какво променя VPN клиентът по този път
Корпоративният клиент често инсталира широк набор от маршрути и филтър, който забранява достъпа до локалната подмрежа, докато тунелът е активен. Намерението е защитно: компрометирана локална мрежа не бива да достига до защитена машина. Страничният ефект е, че маршрутът на хоста към префикса на контейнера вече не е локалната NAT мрежа.
Вместо това търсенето съвпада с тунела и пакетът се предава на шлюза, който никога не е чувал за този адрес на контейнер. Ping се проваля, приложението изтича по време, и контейнерът изглежда счупен, докато иконата на VPN свети. Погледнете таблицата на хоста, докато сте свързани, и конкурентният маршрут се вижда.
| Container mode | Outbound path | Typical result behind the VPN |
|---|---|---|
| Windows, default nat | Host routes and translates container traffic | Container prefix follows the tunnel and fails |
| Windows, transparent | Container sits on the physical link | Depends on the local subnet being allowed |
| Linux engine on Docker Desktop | VM egress proxied by a host process | Often keeps working |
Защо Linux контейнерите се държат различно
Linux машината пуска контейнерите в лека виртуална машина, а изходящите връзки от нея се отварят от прокси от страна на хоста от името на контейнера. Хостът инициира сокета, затова правилото на VPN за префикса на контейнера не се прилага по същия начин, и натоварването продължава да достига мрежата.
Тази разлика обяснява и защо Linux рецептите не се пренасят. Linux контейнер, който има нужда от собствен тунел, получава устройство TUN плюс възможността NET_ADMIN. Windows контейнерите не излагат интерфейс като устройство, затова този модел няма еквивалент от онази страна.
Докажете маршрута, после изберете дизайн
Събирайте доказателства от хоста, не от контейнера, защото хостът прави търсенето:
docker network inspect nat --format "{{range .IPAM.Config}}{{.Subnet}}{{end}}"
route print -4
Get-NetRoute -AddressFamily IPv4 | Where-Object DestinationPrefix -like "172.16.*"
Изпълнете изхода от маршрутите веднъж преди свързването на VPN и веднъж след това. Ако във втория изход префиксът на контейнера сочи към адаптера на тунела, диагнозата е завършена и рестартирането на контейнерите няма да помогне.
Първата опция е решение за политика: попитайте собственика на мрежата дали локалният LAN достъп може да бъде разрешен за това устройство. Няколко корпоративни клиента го предлагат като настройка, но това отслабва умишлена граница. Поискайте го като документирано изключение със собственик и дата за преглед. Превключвател за отделно устройство, към който никой не се връща, е начинът, по който защитна политика тихо изчезва.
Там, където политиката трябва да остане, преместете натоварването вместо да се борите с маршрута. Прозрачна мрежа с ясна подмрежа и шлюз поставя контейнерите на локалната връзка, Linux натоварване работи зад проксито на виртуалната машина, и отделна виртуална машина със свой клиент запазва собствената си политика. Изберете една съзнателно и я тествайте отвътре в контейнера, защото именно там възниква заявката на потребителя.