Оглавление:
Карта сайта:
Оглавление:
Карта сайта:
Это старая версия документа!
Страница: 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/16 — status_app-network
Если подсеть Docker пересекается с корпоративной (часто диапазон 172.16.0.0/12, в IEP — 172.22.0.0/16), Linux направляет пакеты в Docker-bridge, а не в VPN.
Это не проблема DNS и не resolv.conf. Имя резолвится верно; ломается маршрутизация на уровне ядра.
Типичная ловушка: DNS и маршрут говорят разное про один хост. Кажется, что «имя резолвится — значит всё ок», а curl и браузер URL не открывают.
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 hosts → 172.22.224.153 change-pass.iep.loc | DNS/hosts работает | Имя → IP верно. resolv.conf тут ни при чём | ip route get → dev 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.
| Проверка | Норма | Конфликт с 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
HOST=change-pass.iep.loc
getent hosts «$HOST»
IP получен — резолв в порядке (DNS или /etc/hosts).
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
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.loc → 172.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 стоит сразу после «Суть проблемы», перед пошаговыми командами — логика «сначала понять ловушку, потом чинить».