На одном ноутбуке, с одним подключённым клиентом 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 работает за прокси виртуальной машины, и отдельная виртуальная машина со своим клиентом сохраняет собственную политику. Выберите одну осознанно и проверьте её изнутри контейнера, потому что именно там возникает запрос пользователя.

Похожие статьи