На одному ноутбуці, з одним підключеним клієнтом VPN, контейнери Linux продовжують спілкуватися між собою, а контейнери Windows зупиняються. Змінна не образ, а шлях, яким пакети потрапляють у хост. Контейнери Windows у типовій мережі позичають таблицю маршрутизації й трансляцію хоста, тому політика, що змінює маршрутизацію хоста, змінює й їх. Підтвердьте це пошуком маршруту, перш ніж будь-що перевстановлювати.

Куди пакети контейнера Windows потрапляють у хост

Контейнер у типовій мережі nat отримує адресу з префікса служби Host Networking Service, зазвичай десь усередині 172.16.0.0/12, і досягає хоста через віртуальний адаптер. Хост володіє маршрутом для цього префікса й транслює трафік до того адаптера, який зараз активний. Посередині цього шляху немає окремої віртуальної машини.

Саме ця схема робить збій механічним. Коли контейнер надсилає пакет, хост виконує пошук маршруту для префікса контейнера. Який маршрут переможе, туди пакет і піде, а контейнер тут нічого не вирішує.

Що клієнт VPN змінює на цьому шляху

Корпоративний клієнт часто встановлює широкий набір маршрутів і фільтр, який забороняє доступ до локальної підмережі, поки тунель активний. Намір захисний: скомпрометована локальна мережа не повинна досягати захищеної машини. Побічний ефект у тому, що маршрут хоста до префікса контейнера вже не є локальною мережею NAT.

Натомість пошук збігається з тунелем, і пакет передається шлюзу, який ніколи не чув про цю адресу контейнера. Ping не проходить, застосунок упирається в тайм-аут, і контейнер виглядає зламаним, поки значок VPN світиться. Подивіться на таблицю хоста під час підключення, і конкуруючий маршрут видно.

Container modeOutbound pathTypical result behind the VPN
Windows, default natHost routes and translates container trafficContainer prefix follows the tunnel and fails
Windows, transparentContainer sits on the physical linkDepends on the local subnet being allowed
Linux engine on Docker DesktopVM egress proxied by a host processOften 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 працює за проксі віртуальної машини, і окрема віртуальна машина з власним клієнтом зберігає власну політику. Виберіть одну свідомо й перевірте її зсередини контейнера, бо саме там виникає запит користувача.

Схожі статті