Сети в Docker

🕒 3 мин.

Из статьи вы узнаете, как устроены сети в Docker, зачем нужны пользовательские сети и как с их помощью изолировать и связывать контейнеры.

Основы

По умолчанию docker имеет 3 сети:

$ docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
9b3a83f7ee29   bridge    bridge    local
b0e4b775235f   host      host      local
3421a5ef3f9a   none      null      local
  • bridge — это сеть по умолчанию, то есть когда мы при создании контейнера не указываем никакую другую сеть, контейнер создаётся в этой сети. Здесь контейнеры могут пинговать друг друга по ip-адресу, но с хоста контейнеры недоступны. Это самый часто используемый вариант для запуска одиночных контейнеров.
  • host — если контейнер находится в этой сети, то он использует сеть хоста. Например, если на хосте запущен nginx, то из контейнера можно выполнить curl http://localhost.
  • none — если контейнер находится в этой сети, то он полностью изолирован. У него как бы и нет сети.

Эти сети создаются Docker автоматически и доступны сразу после установки.

Docker позволяет создать пользовательскую сеть — по сути, это как bridge, но с некоторыми преимуществами:

  • Контейнеры в одной пользовательской сети могут обращаться друг к другу не только по ip-адресу, но и по имени.
  • Разные пользовательские сети изолированы друг от друга и от сети bridge.

На практике пользовательские сети чаще всего используют в Docker Compose и микросервисных приложениях.

Создание пользовательской сети

Создадим пользовательскую сеть:

$ docker network create mynet

Посмотрим список сетей:

$ docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
9b3a83f7ee29   bridge    bridge    local
b0e4b775235f   host      host      local
930c0d070d89   mynet     bridge    local
3421a5ef3f9a   none      null      local

Получим информацию о созданной нами сети:

$ docker network inspect mynet 
[
    {
        "Name": "mynet",
        "Id": "930c0d070d89869941fcd096cf2a9cd91e0673b9d51c99a92526f521b791c099",
        "Created": "2025-10-23T16:32:10.120275792+03:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.22.0.0/16",
                    "Gateway": "172.22.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]
  • Здесь можно увидеть диапазон IP-адресов, шлюз и список подключённых контейнеров.

Запустим два контейнера в одной сети:

$ docker run -d --name my_nginx --network mynet nginx
$ docker run --rm -it --network mynet alpine sh
  • Мы подключились сразу ко второму контейнеру.

Из второго контейнера пропингуем первый (по имени) и выйдем:

# ping -c 1 my_nginx
PING my_nginx (172.22.0.2): 56 data bytes
64 bytes from 172.22.0.2: seq=0 ttl=64 time=0.104 ms

--- my_nginx ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.104/0.104/0.104 ms

# exit

Nginx работает внутри пользовательской сети mynet, там же работает alpine. Они могут обращаться друг к другу по имени. Docker сам настраивает DNS внутри пользовательской сети. А с хоста они недоступны, так как не проброшены порты.

Выключим контейнер и удалим его:

$ docker stop my_nginx
$ docker rm my_nginx

Изоляция пользовательских сетей

Каждая пользовательская сеть изолирована от других, но контейнер можно добавлять в разные сети. Изоляция сетей позволяет разделять сервисы и ограничивать их взаимодействие между собой.

Создадим другую сеть:

$ docker network create isolated-net

Запустим контейнер nginx в сети mynet, а контейнер alpine в isolated-net.

$ docker run -d --name my_nginx --network mynet nginx
$ docker run --rm -d --name myalp --network isolated-net alpine sleep 3600
  • sleep 3600 — чтобы контейнер не завершился сразу после старта.

Подключимся к контейнеру myalp и попробуем пропинговать my_nginx:

$ docker exec -it myalp sh

# ping my_nginx
ping: bad address 'my_nginx'

# exit
  • Не пингуется.

Добавим этот контейнер в сеть mynet, именно там находится my_nginx:

$ docker network connect mynet myalp
  • Контейнер при этом получает дополнительный сетевой интерфейс.

Попробуем пропинговать ещё раз:

$ docker exec -it myalp sh

/ # ping -c 1 my_nginx
PING my_nginx (172.22.0.2): 56 data bytes
64 bytes from 172.22.0.2: seq=0 ttl=64 time=0.079 ms

--- my_nginx ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.079/0.079/0.079 ms

# exit
  • Теперь пингуется.

Выключим контейнер и удалим его, чтобы не захламлять систему тестовыми контейнерами:

$ docker stop my_nginx
$ docker rm my_nginx

Полезные команды

Эти команды полезны при отладке сетевых проблем и изучении взаимодействия контейнеров.

  • docker network create <name> — создать bridge-сеть
  • docker network ls — посмотреть все сети
  • docker network inspect <name> — детали сети (контейнеры, IP, DNS)
  • docker network connect <net> <container> — подключить контейнер к сети
  • docker network disconnect <net> <container> — отключить
  • docker network rm <name> — удалить сеть (только если пустая)

Если понравилась статья, подпишись на мой канал в VK или Telegram.

Мы используем cookie-файлы для наилучшего представления нашего сайта. Продолжая использовать этот сайт, вы соглашаетесь с использованием cookie-файлов.
Принять
Отказаться
Политика конфиденциальности