Инструменты пользователя

Инструменты сайта


linux:docker_network_conflict

Это старая версия документа!


Конфликт сети Docker с корпоративной / VPN-сетью

Страница: dev:docker_network_conflict Когда смотреть: внутренний сервис не открывается, DNS «в порядке», VPN подключён, недавно поднимали Docker.

Симптомы

Не открывается внутренний сервис (Jira, LDAP, change-pass.iep.loc, git и т.п.) — ни в браузере, ни в curl Ошибка: Connection refused или Failed to connect на портах 80/443 getent hosts hostname возвращает ожидаемый IP Проблема часто появляется после docker compose up или когда на машине много compose-проектов VPN подключён (tun0 / tun1 есть), но сервис недоступен

Суть проблемы

Docker создаёт bridge-интерфейсы (br-xxxxxxxxxxxx) с собственными подсетями:

172.17.0.0/16 — default bridge 172.22.0.0/16 — сеть проекта rpcserver_default 172.18.0.0/16status_app-network Если подсеть Docker пересекается с корпоративной (часто диапазон 172.16.0.0/12, в IEP — 172.22.0.0/16), Linux направляет пакеты в Docker-bridge, а не в VPN.

Это не проблема DNS и не resolv.conf. Имя резолвится верно; ломается маршрутизация на уровне ядра.

Один IP — два разных случая

Типичная ловушка: DNS и маршрут говорят разное про один хост. Кажется, что «имя резолвится — значит всё ок», а curl и браузер URL не открывают.

Пример: change-pass.iep.loc

grep -n change-pass /etc/hosts /etc/resolv.conf 2>/dev/null getent hosts change-pass.iep.loc ip route get 172.22.224.153 При конфликте с Docker вывод такой:

172.22.224.153 change-pass.iep.loc 172.22.224.153 dev br-355c08cd95dd src 172.22.0.1 uid 1891243316

  cache

Разбор:

Строка / команда Что кажется Что на самом деле getent hosts172.22.224.153 change-pass.iep.loc DNS/hosts работает Имя → IP верно. resolv.conf тут ни при чём ip route getdev br-355c08cd95dd src 172.22.0.1 Пакеты уходят в Docker-bridge, не в VPN/IEP grep … /etc/hosts — пусто Имя резолвится через DNS, без записи в /etc/hosts

Одна подсеть 172.22.0.0/16 — два назначения:

Корпоративная IEP — сервер change-pass.iep.loc (172.22.224.153), доступ через VPN (tun0) Docker rpcserver_default — bridge br-355c08cd95dd, адрес 172.22.0.1/16 Ядро не различает «корпоративный и «docker 172.22.x.x. Срабатывает маршрут 172.22.0.0/16 dev br-… → трафик не доходит до IEP → Connection refused.

DNS vs маршрут — сводка

Проверка Норма Конфликт с Docker getent hosts HOST IP из корпсети То же — IP верный ip route get IP via 10.x.x.x dev tun0 dev br-… src 172.22.0.1 curl https://HOST/ HTTP 200 Connection refused

Если getent «работает», а curl — нет, сначала ip route get, не resolv.conf. После устранения конфликта тот же IP, другой маршрут:

172.22.224.153 via 10.5.192.1 dev tun0 src 10.5.193.211

  cache

Быстрая диагностика

1. DNS

HOST=change-pass.iep.loc getent hosts «$HOST» IP получен — резолв в порядке (DNS или /etc/hosts).

2. Маршрут (главная проверка)

ip route get $(getent hosts «$HOST» | awk '{print $1; exit}') Плохо:

172.22.224.153 dev br-355c08cd95dd src 172.22.0.1 Хорошо:

172.22.224.153 via 10.5.192.1 dev tun0 src 10.5.193.211

3. Порты и HTTP

IP=$(getent hosts «$HOST» | awk '{print $1; exit}') nc -vz «$IP» 80 nc -vz «$IP» 443 curl -vk –connect-timeout 5 «https:$HOST/» При конфликте с Docker — Connection refused до VPN, даже если tun0 поднят. ==== 4. Конфликтующая Docker-сеть ==== ip route | grep 172.22 docker network ls docker network inspect $(docker network ls -q) | grep -E '«Name»|Subnet|Gateway' Ищите Subnet, совпадающий с корпоративным диапазоном. Кейс 2026-08-13: Сеть: rpcserver_default Subnet: 172.22.0.0/16 Bridge: br-355c08cd95dd Конфликт с: change-pass.iep.loc (172.22.224.153) ===== Скрипт проверки ===== #!/usr/bin/env bash set -u HOST=«${1:-change-pass.iep.loc}» echo «=== DNS ===» getent hosts «$HOST» || { echo «DNS fail»; exit 1; } IP=$(getent hosts «$HOST» | awk '{print $1; exit}') echo «IP=$IP» echo echo «=== Route ===» ip route get «$IP» echo echo «=== TCP 80/443 ===» nc -vz «$IP» 80 2>&1 || true nc -vz «$IP» 443 2>&1 || true echo echo «=== Docker routes (172.16/12) ===» ip route | grep -E '172.(1[6-9]|2[0-9]|3[0-1]).' || echo «(none)» echo echo «=== Docker networks ===» docker network inspect $(docker network ls -q) 2>/dev/null | grep -E '«Name»|Subnet|Gateway' || echo «docker not available» chmod +x check-docker-network-conflict.sh ./check-docker-network-conflict.sh change-pass.iep.loc ===== Решение ===== ==== Сразу восстановить доступ ==== cd ~/projects/rpc.server docker compose down Проверка: ip route get 172.22.224.153 curl -vk https://change-pass.iep.loc/ Маршрут — через tun0, не br-…. curl — HTTP 200. ==== Навсегда: другой subnet в compose ==== networks: default: ipam: config: - subnet: 192.168.220.0/24 Берите диапазоны вне 172.16.0.0/12, если VPN/IEP использует 172.18–172.31. Примеры: 192.168.200.0/24, 192.168.220.0/24. ==== Глобально: пулы для новых сетей Docker ==== /etc/docker/daemon.json: { «default-address-pools»: [ { «base»: «192.168.200.0/16», «size»: 24 } ] } sudo systemctl restart docker После смены пулов пересоздайте compose-проекты (docker compose down && docker compose up -d). Старые сети с 172.22.0.0/16 останутся, пока их не удалите. ===== Таблица: что проверять ===== ^ Симптом ^ Причина ^ Действие ^ | DNS не резолвит | resolv.conf, VPN DNS, /etc/hosts | getent hosts | | DNS OK, route через br-… | Конфликт subnet Docker | ip route get, docker network inspect | | Route через tun0, timeout | VPN без маршрута в сеть | ip route, админы VPN | | Route OK, Connection refused | Сервис не слушает порт | nc -vz на сервере | | TLS verify error | Корпоративный CA | curl -k / установка CA | ===== Профилактика ===== Не использовать 172.16.0.0/12 для Docker при работе с IEP/RTLabs VPN Перед docker compose up: docker network inspect … | grep Subnet После смены VPN/машины: ip route get <корп-хост> Subnet compose-проектов — в README ===== Полезные команды ===== ip route | grep '^172\.' docker network ls docker network inspect rpcserver_default docker network rm rpcserver_default # если compose уже down ===== История кейса ===== Дата: 2026-08-13 Хост: change-pass.iep.loc172.22.224.153 Причина: rpcserver_default (172.22.0.0/16) перехватывала маршрут Решение: docker compose down + subnet 192.168.220.0/24 в compose Результат: route via tun0, curl → HTTP 200 Структура: симптомы → суть → пример с двумя случаями → пошаговая диагностика → скрипт → решение → таблица → профилактика → кейс. Блок про getent vs ip route get стоит сразу после «Суть проблемы», перед пошаговыми командами — логика «сначала понять ловушку, потом чинить».

linux/docker_network_conflict.1786608127.txt.gz · Последние изменения: 2026/08/13 08:02 — werwolf