Разбираемся, как объединить в сеть контейнеры Docker на одном хосте. В статье — создание и настройка пользовательских bridge-сетей и подключение к ним контейнеров для вашего сервера или VPS.
Введение
Bridge-сеть (сетевой мост) в Docker работает как виртуальный маршрутизатор, соединяющий контейнеры на одном хосте, обеспечивая их связь друг с другом и с внешними сетями через NAT. Однако стандартная bridge-сеть имеет существенные недостатки, из-за чего использовать её сложно и не рекомендуется в продакшене.
Альтернативой является пользовательская bridge-сеть, не имеющая недостатков дефолтной, — рассказываем как создать её и подключить к ней контейнеры на Ubuntu 24.04.
Сеть в Docker
Сетевая подсистема Docker имеет несколько драйверов, основные из них:
- bridge — создаёт изолированный сетевой мост на хосте. Контейнеры подключаются к этому мосту и могут взаимодействовать между собой и с внешним миром через NAT. Это дефолтный драйвер.
- host — удаляет сетевую изоляцию между контейнером и хостом. Контейнер использует сетевой стек хоста напрямую, без какой-либо изоляции namespace.
- none — полностью отключает сеть для контейнера: он не будет иметь доступа к внешним сетям и loopback-интерфейсу.
- overlay — позволяет создавать распределённые сети между несколькими Docker-хостами, что необходимо для кластерных решений и Docker Swarm.
При установке Docker автоматически создается bridge-сеть с именем bridge, которая назначается контейнерам по умолчанию. Использование стандартного сетевого моста в Docker имеет ряд недостатков, особенно для продакшен-среды. Основные проблемы — отсутствие встроенного DNS, неудобство управления и отсутствие изоляции между контейнерами. Все службы, подключённые к сети по умолчанию, могут свободно взаимодействовать друг с другом, что создаёт потенциальные уязвимости. Кроме того, организация обнаружения сервисов требует применения устаревшего механизма --link или ручного назначения статических IP-адресов, а каждый сервис нуждается в ручном пробросе портов для обеспечения внешнего доступа.
В отличие от дефолтной сети, пользовательская bridge-сеть предоставляет полный контроль над сетевым взаимодействием контейнеров, обеспечивая автоматическое разрешение имён и изоляцию трафика.
Создание и настройка пользовательского сетевого моста
Создание пользовательского сетевого моста
Команда для создания пользовательской bridge-сети:
docker network create my_bridge
Такая команда создаст bridge-сеть с настройками по умолчанию: автоматической выдачей IP-адресов из диапазона 172.18.0.0/16 и шлюзом 172.18.0.1.
Но для продакшен-среды лучше явно указывать параметры сети:
docker network create \
--driver bridge \
--subnet 172.28.0.0/16 \
--gateway 172.28.0.1 \
--ip-range 172.28.5.0/24 \
my_custom_bridge
Здесь:
- --subnet определяет общий диапазон адресов сети;
- --gateway задает IP-адрес шлюза;
- --ip-range ограничивает пул адресов для автоматической выдачи.
Настройка статических IP-адресов
Для сервисов, требующих постоянных адресов, нужно явно назначить IP:
docker run -d \
--name database \
--network my_custom_bridge \
--ip 172.28.5.10 \
postgres:15
docker run -d \
--name backend \
--network my_custom_bridge \
--ip 172.28.5.20 \
--env DB_HOST=172.28.5.10 \
my_backend:latest
Проверка соединения и DNS
Пользовательские сети обеспечивают автоматическое разрешение имён через встроенный DNS-сервер. Проверка связи по имени:
docker run --rm \
--network my_custom_bridge \
alpine ping -c 4 database
Тестирование DNS-резолвинга:
docker run --rm \
--network my_custom_bridge \
alpine nslookup database
Валидация конфигурации
Проверка настроек сети:
docker network inspect my_custom_bridge
docker inspect database --format '{{ .NetworkSettings.Networks }}'
Мониторинг сетевой статистики:
docker network ls
docker network stats my_custom_bridge
Подключение контейнеров
После создания пользовательской bridge-сети, к ней нужно подключить контейнеры. Это можно сделать двумя способами.
Создание нового контейнера с подключением:
docker run -d \
--name my_container \
--network my_custom_bridge \
nginx:alpine
Подключение существующего контейнера:
docker network connect my_custom_bridge existing_container
Подключение к нескольким сетям одновременно, контейнер при этом будет доступен во всех подключённых сетях:
docker network connect net01 app01
docker network connect net02 app01
Отключение:
docker network disconnect my_custom_bridge container_name
Просмотр сетей, к которым подключён контейнер:
docker inspect container_name --format '{{json .NetworkSettings.Networks}}' | jq
Важно:
- Контейнер может быть подключён к нескольким сетям одновременно.
- DNS-имя контейнера разрешается во всех подключённых сетях.
- В каждой сети у контейнера будет новый IP.
- Отключение от сети не останавливает контейнер.
Пример для многоуровневой архитектуры
Создание сетей для разных уровней приложения.
- для фронтенда:
docker network create \
--subnet 172.30.1.0/24 \
frontendnet
- для бэкенда:
docker network create \
--subnet 172.30.2.0/24 \
backendnet
Подключение контейнеров:
docker run -d \
--name frontend \
--network frontendnet \
nginx:alpine
docker run -d \
--name backend \
--network backendnet \
--network frontendnet \
node:18
Диагностика и мониторинг сетевого трафика
Проверка связи между контейнерами
Проверка доступности по DNS-имени:
docker exec -it app01 ping -c 4 app02
Тестирование DNS-резолвинга:
docker exec -it app01 nslookup app02
docker exec -it app01 dig app02
Проверка доступности конкретного порта:
docker exec -it app01 nc -zv app02 5432
docker exec -it app01 telnet app02 80
Мониторинг сетевой статистики
Docker имеет собственные инструменты для мониторинга сетевой активности. Общая статистика по сетям:
docker network ls
docker network inspect my_bridge --format '{{json .Containers}}' | jq
Статистика использования сети конкретным контейнером:
docker stats app01 --format "table {{.NetIO}}"
Детальные данные о сетевых интерфейсах конкретного контейнера:
docker inspect app01 --format '{{json .NetworkSettings.Networks}}' | jq
Анализ сетевого трафика
Для анализа пакетов внутри контейнеров используется tcpdump. Установка tcpdump в контейнер и захват трафика:
docker exec -it app01 sh -c "apk add tcpdump && tcpdump -i eth0 -n -w /tmp/capture.pcap"
Анализ трафика на хосте:
docker cp app01:/tmp/capture.pcap ./capture.pcap
tcpdump -r capture.pcap -n
Захват трафика в реальном времени с фильтрацией:
docker exec -it app01 tcpdump -i eth0 -n tcp port 80
Читайте в блоге:
- Установка и настройка Node.js на Ubuntu 24.04: пошагово для начинающих
- Управление версиями Node.js через nvm на Ubuntu 24.04
- Как установить и настроить Mattermost на Ubuntu