
Контейнеризация с использованием Docker или Podman предоставляет изолированные среды, но для организации взаимодействия между контейнерами необходимо продумать сетевую архитектуру. Наиболее прямолинейный способ – создание пользовательской bridge-сети, которая обеспечивает контейнерам внутреннюю маршрутизацию по DNS-именам и IP-адресам внутри одного хоста.
Для начала создаётся собственная сеть: docker network create mynet. Контейнеры, запущенные с флагом —network=mynet, получают доступ друг к другу по имени, указанному в параметре —name. Например, контейнер web может обращаться к контейнеру db через http://db:порт, не требуя настройки hosts-файла или явного указания IP-адресов.
При использовании docker-compose определение сети упрощается: в файле docker-compose.yml достаточно описать общую сеть в разделе networks и подключить к ней нужные сервисы. Это позволяет избежать ручного управления сетями и повышает читаемость конфигурации при масштабировании.
Для более сложных случаев – например, если контейнеры расположены на разных хостах – применяется overlay-сеть в связке с Docker Swarm. В этом случае контейнеры, запущенные в различных узлах кластера, могут взаимодействовать так же, как и на одной машине, но потребуется настройка TLS и менеджеров кластера.
Изоляция по умолчанию между контейнерами – мера безопасности. Подключая контейнеры к общей сети, необходимо ограничивать доступ к сервисам, которые не должны быть видны другим участникам. Использование фаерволов (например, iptables) и минимизация открытых портов внутри виртуальной сети – обязательная практика при развертывании в продакшене.
Настройка пользовательской сети Docker bridge

По умолчанию Docker создаёт сеть bridge с предопределённой конфигурацией, но для точного контроля соединений между контейнерами необходимо создать пользовательскую bridge-сеть.
Для создания сети с собственным подсетевым диапазоном и шлюзом:
docker network create \
--driver bridge \
--subnet 192.168.100.0/24 \
--gateway 192.168.100.1 \
custom-net
Созданная сеть custom-net позволяет запускать контейнеры с изолированной адресацией. Пример запуска двух контейнеров с привязкой к этой сети:
docker run -d --name container1 --network custom-net alpine sleep infinity
docker run -d --name container2 --network custom-net alpine sleep infinity
Проверка связи между контейнерами осуществляется командой:
docker exec container1 ping -c 3 container2
Контейнеры внутри одной пользовательской сети bridge могут обращаться друг к другу по именам, заданным через флаг --name. DNS-резолвинг обрабатывается встроенным DNS-сервером Docker.
Для просмотра настроек сети используйте:
docker network inspect custom-net
Чтобы ограничить доступ к хосту или внешним сетям, не публикуйте порты контейнеров и не подключайте их к другим сетям. Дополнительно можно использовать флаг --internal при создании сети, чтобы запретить выход в интернет:
docker network create \
--driver bridge \
--subnet 172.28.0.0/16 \
--gateway 172.28.0.1 \
--internal \
isolated-net
Это создаёт полностью замкнутую сеть, пригодную для безопасного взаимодействия контейнеров без внешнего доступа.
Создание двух контейнеров в одной пользовательской сети

Для взаимодействия контейнеров по именам хостов необходимо использовать пользовательскую сеть Docker. По умолчанию контейнеры в bridge-сети не разрешают DNS-имена друг друга.
- Создайте пользовательскую сеть:
docker network create --driver bridge my_custom_net
- Запустите первый контейнер в этой сети:
docker run -d --name container1 --network my_custom_net nginx
- Запустите второй контейнер с тем же параметром сети:
docker run -d --name container2 --network my_custom_net alpine sleep infinity
- Проверьте доступность container1 из container2:
docker exec -it container2 ping container1
Если ответ получен – сеть настроена корректно. Имена контейнеров в пределах пользовательской сети разрешаются автоматически через встроенный DNS-сервер Docker.
- Контейнеры можно перезапускать – их имена будут доступны до удаления из сети.
- Для доступа к конкретным портам не требуется публикация их на хосте, достаточно использовать внутренние порты.
- Сеть можно удалить командой
docker network rm my_custom_netтолько после остановки всех использующих её контейнеров.
Обмен данными между контейнерами через сетевые алиасы

Для взаимодействия контейнеров в одной сети Docker удобно использовать сетевые алиасы. Они позволяют обращаться к контейнерам по заданным именам, упрощая межконтейнерную коммуникацию без необходимости указывать IP-адреса.
Создайте пользовательскую сеть с помощью команды:
docker network create my_network
Запустите первый контейнер с присвоением ему алиаса:
docker run -d --name app --network my_network --network-alias backend nginx
Подключите второй контейнер к той же сети. Он сможет обращаться к первому по алиасу backend:
docker run -it --rm --network my_network alpine sh
Внутри второго контейнера проверьте доступность первого:
ping backend
Сетевой алиас не является DNS-именем контейнера, а выступает в роли дополнительного имени, которое можно использовать параллельно с основным. Это особенно полезно при обновлении контейнеров: новый экземпляр может получить тот же алиас и продолжить обслуживание запросов без изменения настроек клиентов.
Для динамического масштабирования используйте один алиас для нескольких контейнеров. Например, несколько экземпляров API могут регистрироваться с алиасом api, и другие сервисы смогут балансировать нагрузку между ними, используя стандартный DNS round-robin.
Сетевые алиасы работают только в пользовательских сетях. В bridge-сети по умолчанию DNS-резолвинг по алиасам невозможен. Всегда создавайте собственную сеть типа bridge или overlay для полноценного взаимодействия через алиасы.
Избегайте дублирования имен и алиасов в одной сети: это приведет к конфликтам и недоступности нужного контейнера по DNS.
Подключение контейнера к уже существующей сети

Для подключения контейнера Docker к существующей пользовательской сети, убедитесь, что сеть создана заранее с помощью команды:
docker network create --driver bridge my_custom_network
Чтобы подключить новый контейнер к этой сети при запуске, используйте опцию --network:
docker run -d --name my_container --network my_custom_network nginx
Если контейнер уже запущен, его можно подключить к сети динамически без остановки:
docker network connect my_custom_network my_container
Проверьте результат:
docker inspect my_container | grep -A 10 "Networks"
Для отключения от сети:
docker network disconnect my_custom_network my_container
Имейте в виду, что контейнеры в одной bridge-сети могут взаимодействовать по внутренним DNS-именам (по имени контейнера), что удобно при настройке связи между сервисами:
ping my_container
Если используется Compose, укажите нужную сеть в блоке networks:
services:
app:
image: alpine
networks:
- my_custom_network
networks:
my_custom_network:
external: true
Изменение сети контейнера, созданного без Compose, требует явного подключения вручную через docker network connect, поскольку параметры сети не могут быть изменены через docker update.
Проверка сетевого соединения между контейнерами

Для начала убедитесь, что оба контейнера подключены к одной пользовательской bridge-сети. Создать её можно командой docker network create --driver bridge my-net, а при запуске контейнеров указать параметр --network my-net.
Узнайте IP-адреса контейнеров с помощью docker inspect. Например: docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container_name. Полученные адреса будут использоваться для тестирования.
Для проверки сетевой доступности выполните внутри одного из контейнеров команду ping: docker exec -it container1 ping -c 4 172.18.0.3. Замените IP-адрес на тот, что принадлежит второму контейнеру. Ответ с временем отклика подтверждает успешную связность.
Для диагностики приложений используйте curl или nc. Например: docker exec -it container1 curl http://172.18.0.3:80 или docker exec -it container1 nc -zv 172.18.0.3 80. Первый способ подходит для HTTP, второй – для проверки открытых портов.
Если соединение не устанавливается, проверьте наличие iptables-правил, режим изоляции сети и настройки firewall хост-системы. Команда docker network inspect my-net покажет актуальные параметры и список подключённых контейнеров.
Передача портов между контейнерами с помощью socat

Для начала необходимо установить socat внутри обоих контейнеров или хотя бы в том, где будет инициироваться соединение. Команда для установки в Debian/Ubuntu:
apt-get update && apt-get install -y socat
Пример передачи TCP-порта 8080 из контейнера A в контейнер B:
В контейнере B запускается прослушивание локального порта, который будет принимать данные:
socat TCP-LISTEN:8080,reuseaddr,fork TCP:адрес_контейнера_A:8080
Здесь адрес_контейнера_A – IP контейнера A во внутренней сети Docker. Опция reuseaddr разрешает повторное использование порта, fork создает отдельный процесс для каждого соединения.
Если IP-адрес контейнера неизвестен, его можно получить командой docker inspect -f ‘{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}’ имя_контейнера.
Для обратной передачи или двунаправленной связи запускают два процесса socat с противоположными параметрами на каждом контейнере.
Для повышения безопасности рекомендуют ограничивать доступ по IP и использовать фильтрацию на уровне iptables, так как socat сам не шифрует трафик.
В случае, когда контейнеры работают на разных хостах, socat может работать в связке с SSH-туннелями для передачи портов через защищенное соединение.
Использование Docker Compose для автоматизации сетевого взаимодействия

Docker Compose позволяет легко настроить сеть между контейнерами, определяя сервисы и их параметры в едином YAML-файле. Для обеспечения взаимодействия достаточно задать общий пользовательский мостовой драйвер сети с помощью секции networks. Контейнеры, подключённые к одной сети, автоматически получают внутренние DNS-имена, что упрощает обмен данными по именам сервисов вместо IP-адресов.
Пример конфигурации для двух контейнеров:
version: "3.8"
services:
app1:
image: app1-image
networks:
- mynet
app2:
image: app2-image
networks:
- mynet
networks:
mynet:
driver: bridge
В данном случае оба контейнера подключены к сети mynet, что создаёт изолированное сетевое пространство с автоматическим разрешением имён. Для вызова сервиса app2 из app1 достаточно использовать адрес app2:порт.
Для настройки дополнительных параметров сети, таких как диапазон IP-адресов, можно использовать раздел ipam. Например, чтобы задать подсеть:
networks:
mynet:
driver: bridge
ipam:
config:
- subnet: 172.25.0.0/16
Это полезно для предотвращения конфликтов с другими сетями и контроля адресации внутри Docker-сети.
Docker Compose автоматически создаёт и удаляет сеть при запуске и остановке стека, что устраняет необходимость в ручном управлении сетевыми интерфейсами и гарантирует консистентность конфигурации.
Вопрос-ответ:
Какими способами можно организовать сетевое взаимодействие между двумя контейнерами в Linux?
Для связи двух контейнеров в Linux обычно используют сетевые мосты (bridge), которые создают виртуальную локальную сеть для контейнеров. Также можно настроить контейнеры на работу в одной пользовательской сети Docker, где они видят друг друга по именам. Еще один вариант — использовать сетевые плагины типа macvlan или host, чтобы контейнеры находились в одной подсети или на одном хосте. В зависимости от задачи и требуемой изоляции выбирают подходящий метод.
Как сделать так, чтобы контейнеры могли обмениваться данными через общую файловую систему?
Чтобы два контейнера могли работать с одними и теми же файлами, можно использовать общие тома (volumes). При создании контейнера нужно подключить один и тот же том к нужным директориям внутри каждого контейнера. Это позволяет им читать и записывать данные в общую папку, обеспечивая простой способ обмена информацией без необходимости передачи по сети.
Нужно ли открывать специальные порты для связи контейнеров, если они находятся на одном хосте?
Если контейнеры подключены к одной пользовательской сети Docker, открывать дополнительные порты не обязательно, так как они могут обращаться друг к другу по внутренним IP-адресам или по именам контейнеров. Однако если нужно сделать сервис доступным снаружи или между разными сетями, тогда потребуется проброс портов через параметр -p или настройка firewall.
Какие риски безопасности возникают при объединении двух контейнеров в одну сеть?
При объединении контейнеров в одну сеть повышается риск нежелательного доступа к сервисам друг друга, особенно если один из контейнеров скомпрометирован. В таком случае возможна перехват данных или атаки на другие контейнеры. Для защиты рекомендуют ограничивать права контейнеров, использовать сети с изоляцией и применять средства аутентификации и шифрования при передаче данных между контейнерами.
Можно ли объединить контейнеры, запущенные на разных физических машинах, чтобы они обменивались данными?
Да, для связи контейнеров на разных хостах используют сетевые оверлеи (overlay networks), которые позволяют создавать виртуальную сеть поверх нескольких физических машин. В Docker для этого применяется режим swarm или Kubernetes с сетевыми плагинами, обеспечивающими сквозное взаимодействие. Такой подход требует настройки маршрутизации и обеспечения безопасности, но позволяет контейнерам вести совместную работу, несмотря на физическое разделение.
