Docker Fundamentals: полный гайд по сетям и драйверам


Введение
В этой статье разберём все сетевые драйверы Docker, затронем плагины, чуть-чуть легаси-линки для старых серверов (ну те самые, которые используют старый Docker). Сразу ориентир, чтобы не потеряться в объёме: статья разбита на две части.
Часть 1 — то, что нужно знать почти всем: как контейнер видит сеть, default bridge и user-defined bridge (в реальной жизни там живёт большая часть контейнеров), host, none и базовые вещи про порты и DNS, которые касаются любой сети. Если вы новичок или просто хотите разобраться с сетью Docker для повседневной работы — этого достаточно, дальше можно не читать.
Часть 2 — для тех, кто уже освоился с базой и либо столкнулся с конкретной задачей, либо просто хочет разобраться глубже: тонкая настройка bridge, легаси-линки, overlay для Swarm, macvlan/ipvlan для bare metal, сетевые плагины и т. д. Каждый раздел там подписан, для какого сценария он актуален (если он вам сейчас не нужен, смело пропускайте и возвращайтесь, когда понадобится).
Статья будет актуальна для людей, которые изучают Docker и хотят разобраться с сетями, а также для тех, кто уже знает небольшую базу по Docker.
1. Что вообще видит контейнер
Контейнер понятия не имеет, в какой сети он находится и кто его соседи. Он видит только сетевой интерфейс с IP-адресом, gateway, routing table и DNS. Всё остальное можно назвать абстракцией, которую строит Docker снаружи.
Когда Docker Engine стартует на Linux первый раз, он создаёт встроенную сеть bridge (её ещё называют default bridge). Любой контейнер, запущенный без --network, автоматически подключается туда. У default bridge есть masquerading (это разновидность NAT (Network Address Translation), которую Docker использует, чтобы контейнеры могли выходить в интернет через IP хоста). Если у хоста есть доступ в интернет, у контейнера он тоже появится без всякой дополнительной настройки.
Работает из коробки. Но у default bridge есть проблема: контейнеры внутри неё видят друг друга только по IP-адресу, а не по имени. Отсюда user-defined сети — их создают именно для того, чтобы обойти это ограничение.
Таблица драйверов
Драйвер | Что делает |
|---|---|
| Дефолтный драйвер. Если не указали |
| Убирает изоляцию сети между контейнером и хостом |
| Полностью изолирует контейнер от сети |
| Связывает несколько Docker-демонов, нужен для Swarm |
| Полный контроль над IPv4/IPv6 адресацией, VLAN на уровне L2/L3 |
| Контейнер получает собственный MAC и выглядит как физическое устройство в сети |
Плюс сторонние сетевые плагины, но о них отдельно ниже.
Несколько сетей на один контейнер
Контейнер можно подключить сразу к нескольким сетям, точно так же как физический хост можно подключить к нескольким Ethernet-сетям одновременно. К примеру: фронтенд-контейнер сидит в bridge-сети с внешним доступом и в --internal сети для связи с бэкендом, у которого наружу выхода нет вообще.
Когда сетей несколько, Docker сам решает, какая из них default gateway, и это может поменяться при подключении новой сети. Если хотите зафиксировать конкретную сеть как шлюз по умолчанию, есть gw-priority:
docker run --network name=gwnet,gw-priority=1 --network anet1 --name myctr myimage
docker network connect anet2 myctr
Команда запускает контейнер
myctr, сразу подключая его к двум сетям —gwnetс приоритетом шлюза 1 (то есть именно она станет default gateway) и обычнойanet1, а затем второй командой довешивает ему ещё и третью сетьanet2уже на лету, без пересоздания контейнера.
2. Bridge: дефолтный драйвер
У bridge-сети есть IPv4-подсеть и, опционально, IPv6-подсеть. Каждый подключённый контейнер получает интерфейс с адресом из этой подсети. По умолчанию bridge:
разрешает контейнерам внутри сети общаться друг с другом без ограничений;
блокирует доступ снаружи хоста и из других сетей;
использует masquerading для внешнего доступа — снаружи видно только IP хоста;
поддерживает публикацию портов наружу.
Технически это программный мост (software bridge), плюс правила iptables / firewall, которые Docker сам добавляет на хост, чтобы контейнеры из разных bridge-сетей не видели друг друга напрямую, а только через опубликованные порты.
Чем user-defined отличается от default?
Что | Default bridge | User-defined bridge |
|---|---|---|
DNS-резолвинг по имени контейнера | Нет (нужен legacy | Да |
Изоляция от посторонних контейнеров | Нет, все в одной куче | Да, только те, кто в этой сети |
Подключение/отключение контейнера на лету | Нет, нужно пересоздавать контейнер | Да, |
Конфигурация | Общая на всех, меняется через | Своя у каждой сети, задаётся при |
Шаринг переменных окружения между контейнерами | Через legacy | Нет (но есть тома, compose, Swarm secrets — способы получше) |
Официальная рекомендация: используйте user-defined bridge, default bridge — легаси-деталь.
Про безопасность: изоляция user-defined bridge работает только между разными сетями, а не внутри одной. Все контейнеры в одной user-defined сети видят порты друг друга без ограничений — если в одной сети сидят веб-сервер и база, у веб-сервера будет полный доступ к базе. Для реальной микросегментации разводите сервисы по отдельным сетям и подключайте общие контейнеры туда, где это действительно нужно. Попробую объяснить ниже на примере: есть reverse-proxy, подключённый сразу к нескольким изолированным сетям, в каждой из которых сидит один бэкенд:
docker network create net-app1
docker network create net-app2
docker run -d --name app1 --network net-app1 app1-image
docker run -d --name app2 --network net-app2 app2-image
docker run -d --name proxy --network net-app1 nginx
docker network connect net-app2 proxy
Для начала, чё тут вообще происходит? Создаются две отдельные сети: net-app1 и net-app2, которые между собой никак не связаны. Затем запускаем app1 в первой сети, app2 — во второй. Они физически не могут друг друга увидеть, потому что сидят в разных изолированных сетях, запускаем proxy (обычный nginx) и сразу подключаем его к net-app1 — там, где лежит app1. И наконец, довешиваем proxy ещё и сеть net-app2 через docker network connect, не пересоздавая контейнер. Теперь proxy — единственный, кто состоит сразу в обеих сетях.
Что получили в результате? В результате app1 и app2 друг друга не видят и напрямую общаться не могут — весь трафик между ними, если он вообще нужен, идёт только через proxy, у которого есть доступ в обе сети. Именно ради такого сценария и нужны контейнеры, подключённые сразу к нескольким сетям (multi-homed), — не чтобы «было побольше сетей», а чтобы явно контролировать, кто с кем может говорить.
Создание и управление
docker network create my-net # создать новую сеть
docker network rm my-net # удалить сеть (только если к ней никто не подключён)
docker network connect my-net my-nginx # подключить уже работающий контейнер к сети
docker network disconnect my-net my-nginx # отключить контейнер от сети
Тот же результат можно получить сразу при создании контейнера, без отдельного docker network connect, просто указав сеть прямо в docker create/docker run:
docker create --name my-nginx \
--network my-net \
--publish 8080:80 \
nginx:latest
Что тут:
--network my-net— контейнер сразу попадёт в сетьmy-net(а не в default bridge).--publish 8080:80— порт 80 внутри контейнера (там слушает nginx) пробрасывается на порт 8080 хоста, чтобы к контейнеру можно было достучаться снаружи.
В итоге получаем nginx, который сидит в изолированной сети my-net вместе с остальными контейнерами этого проекта и при этом доступен снаружи по <IP-хоста>:8080.
3. Host: без изоляции сети
Если запустить контейнер с --network host, сетевой стек контейнера вообще не изолируется от хоста — контейнер использует сеть хоста напрямую и не получает собственного IP. Контейнер, который слушает порт 80, окажется доступен на порту 80 хоста.
Публикация портов при этом не работает вообще — флаги -p, --publish, -P игнорируются с предупреждением:
WARNING: Published ports are discarded when using host network mode
Когда это полезно? Если контейнеру нужно слушать большой диапазон портов и производительность т.к. нет NAT, proxy на каждый порт.)
На каких системах это вообще работает
Тут речь о том, что host-режим не универсальная штука, доступная одинаково везде, где установлен Docker. Работает он по-разному в зависимости от того, что у вас: обычный Docker Engine на Linux-сервере, или Docker Desktop на Mac/Windows/Linux (это отдельный продукт, о нём подробнее в разделе 14).
На Docker Engine для Linux host-режим работает “из коробки”, включать ничего не нужно — вы просто пишете --network host, и оно сразу работает, как в примерах ниже.
На Docker Desktop: сеть там идёт через отдельную виртуальную машину, а не напрямую через сеть хоста (host-режим вообще там появился с версии 4.34), и его нужно включить руками: Settings/Resources/Network/Enable host networking. Без этого шага --network host в Docker Desktop просто не будет работать так, как ожидается.
4. None: полная изоляция
Тут мне в основном нечего сказать. --network none полностью убирает контейнер из сети — остаётся только loopback:
docker run --rm --network none alpine:latest ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
Нюанс: IPv6-адрес для loopback не настраивается, только IPv4 127.0.0.1. Используют это для батч-задач, которым сеть не нужна вообще, или для дополнительной изоляции процессов с чувствительными данными. Кстати, по той же причине, что и с host, сеть типа none тоже можно создать только в одном экземпляре — все контейнеры без сети логически равнозначны, второй такой сети просто нечего было бы отличать от первой.
5. Кратко о публикации портов, DNS и /etc/hosts
Публикация портов
По умолчанию порты контейнеров на bridge-сетях доступны хосту и другим контейнерам той же сети, но не наружу и не другим сетям. Чтобы порт стал виден снаружи, нужен --publish/-p.
Есть ещё и другие моменты, но это уже категории траблшутинга, которые стоит изучать/решать в зависимости от сценария.
DNS
У user-defined сети есть встроенный DNS-сервер Docker на адресе 127.0.0.11. Он резолвит имена контейнеров и форвардит внешние запросы на DNS-серверы хоста. Контейнеры на default bridge вместо этого получают просто копию /etc/resolv.conf хоста.
Флаг | Что делает |
|---|---|
| IP DNS-сервера, который можно указывать несколько раз |
| Домен поиска для неполных (сокращённых) имён |
| Опция resolv.conf |
| Имя хоста контейнера (дефолт ID контейнера) |
Пример (если взять учебниковые): если у вас в компании свой DNS-сервер, а не публичный, контейнеру можно явно на него указать (будет, например, --dns 10.0.0.53). --dns-search пригодится, когда не хочется каждый раз писать имя сервиса полностью: если задать --dns-search corp.local, обращение к db внутри контейнера само попробует зарезолвиться как db.corp.local. А --hostname просто чтобы при заходе внутрь контейнера видеть в приглашении что-то осмысленное вроде db-primary, а не случайный ID вроде a3f9c21b4e10, который Docker присваивает по умолчанию.
/etc/hosts внутри контейнера
Контейнер получает свой /etc/hosts с записью собственного hostname, localhost и парой стандартных вещей. Но кастомные хосты, которые прописаны в /etc/hosts на самом хосте, контейнерам не наследуются автоматически (если нужны дополнительные записи, их передают при старте через --add-host.)
Часть 2. Продвинутый уровень
6. Bridge: продвинутые настройки и типичные вопросы
Если вы новичок и только начинаете с Docker — эту часть лучше пропустить и вернуться к ней, когда уже освоитесь с базовыми командами docker network из раздела 2. Тут поговорим про тонкую настройку и вопросы, которые обычно всплывают уже в процессе реальной работы.
Опции драйвера
При создании сети через docker network create можно передать дополнительные настройки флагом -o (или --opt), по одной паре ключ=значение на флаг — например docker network create -o com.docker.network.driver.mtu=1400 my-net. Вот основные ключи, которые можно так передать:
Опция | Дефолт | Что делает |
|---|---|---|
| — | Имя интерфейса моста в Linux |
|
| Включить masquerading |
|
| Разрешить контейнерам внутри сети общаться друг с другом |
|
| MTU для сети контейнеров |
| все адреса | Дефолтный IP при публикации портов |
|
| Не назначать мосту IPv4-адрес самому (для ручной настройки gateway) |
| — | Адрес, который используется для source NAT |
|
| Управляет внешней связностью сети |
|
| Префикс имени интерфейса внутри контейнера |
dockerd — это сам фоновый процесс (демон), который управляет Docker Engine на хосте: слушает API, поднимает контейнеры, настраивает сети и т.д. Демон — это программа, которая крутится в фоне без прямого участия пользователя, dockerd как раз такая. У части опций выше есть аналог не как параметр конкретной сети, а как флаг запуска самого демона: --ip-masq, --icc, --ip, --mtu.
Разница? Через --opt вы настраиваете одну конкретную user-defined сеть, а через флаги dockerd только глобальный default bridge, и правки требуют правки /etc/docker/daemon.json и рестарта демона.(не всегда кстати именно требуются правки /etc/docker/daemon.json )
Ещё у демона есть флаг --bridge, которым можно задать свой собственный docker0 (пригодится, если на одном хосте запускаете сразу несколько экземпляров dockerd).
Дефолтный адрес для публикации портов
Если в -p 80 или -p 8080:80 не указан конкретный IP, порт контейнера станет доступен на всех адресах хоста, и IPv4, и IPv6. Как же поменять? Поменять дефолт можно опцией com.docker.network.bridge.host_binding_ipv4 и несмотря на название, туда можно передать IPv6-адрес. Если выставить ::, порты будут доступны только по IPv6, а 0.0.0.0 — и по IPv4, и по IPv6 сразу. Чтобы жёстко ограничить публикацию только IPv4, адрес нужно указывать прямо в опциях контейнера: -p 0.0.0.0:8080:80.
Настройка default bridge через daemon.json
Новичок? Этот раздел можно пропустить и вернуться к нему, только если реально столкнётесь с конкретной задачей: например, подсеть Docker
172.17.0.0/16пересекается с вашей корпоративной VPN-сетью и надо её поменять, или нужен свой DNS для всех контейнеров сразу. В большинстве повседневных задач с контейнерами этот файл никогда не понадобится.
Раз конфигурация default bridge общая на все контейнеры, крутить её приходится через /etc/docker/daemon.json, а не через docker network create(у Docker этот файл по умолчанию не создаётся при установке, так что если его нет это норм/создаёте сами.)
Прежде чем лезть его создавать, стоит понять, зачем он вообще нужен и нужен ли он вам? По факту daemon.json — это конфиг самого демона Docker целиком, а не только сети: там же настраиваются storage driver, логирование, registry-зеркала и так далее. Сетевые опции из примера ниже — лишь малая часть того, что там можно менять, и трогают они конкретно default bridge, которым, как уже говорилось выше в статье, в продакшене многие этим не рекомендуют пользоваться т.к. вместо него советуют user-defined bridge, а там всё настраивается через docker network create -o без всякого daemon.json.
{
"bip": "192.168.1.1/24",
"fixed-cidr": "192.168.1.0/25",
"mtu": 1500,
"default-gateway": "192.168.1.254",
"dns": ["10.20.1.2", "10.20.1.3"]
}
bip задаёт и адрес самого моста, и подсеть сети (в примере это 192.168.1.1/24 и 192.168.1.0/24 соответственно), fixed-cidr сужает диапазон, из которого выдаются адреса контейнерам.
Для IPv6 у default bridge своя отдельная тройка опций (на user-defined сети они не влияют):
{
"ipv6": true,
"bip6": "2001:db8::1111/64",
"fixed-cidr-v6": "2001:db8::/64",
"default-gateway-v6": "2001:db8:abcd::89"
}
ipv6 обязателен, bip6 — адрес моста и подсеть, fixed-cidr-v6 — диапазон для контейнеров (обычно /64 или короче; для локальных экспериментов лучше ULA-префикс fd00::/8, а не link-local fe80::/10). После правок нужен рестарт демона, без него ничего не применится:
sudo systemctl restart docker
Ручное управление gateway-адресом на мосту
(По-моему, это совсем нишевый случай) нужен, только если сами вручную конфигурируете сетевое оборудование хоста.
Опция com.docker.network.bridge.inhibit_ipv4 не даёт Docker’у самому повесить gateway-адрес на мост — пригодится, если хотите настроить его руками (например, добавили к мосту физический интерфейс и хотите, чтобы gateway был именно на нём). Работает только на user-defined сетях (могу ошибаться, работал только с таким типом), и без ручной настройки gateway после этого весь трафик снаружи-внутрь перестанет работать.
IPv6 в bridge
Актуально, только если у вас в принципе есть задача с IPv6 — если нет, спокойно пропускайте.
docker network create --ipv6 --subnet 2001:db8:1234::/64 my-net
Без --subnet Docker сам выберет ULA-префикс. Можно сделать сеть чисто IPv6, без IPv4 вообще:
docker network create --ipv6 --ipv4=false v6net
Для default bridge так нельзя, IPv4 там отключить не получится.
Лимит по количеству контейнеров
Актуально только на масштабе в сотни контейнеров в одной сети — если у вас их пара десятков, можно не думать об этом вообще.
Из-за особенностей ядра Linux bridge-сети становятся нестабильными при подключении 1000+ контейнеров к одной сети — начинаются проблемы со связью между ними. Если у вас реально столько контейнеров в одной сети, стоит задуматься о делении на несколько сетей.
Host-режим в Swarm
Актуально, только если вы вообще используете Swarm — для одиночных контейнеров через
docker runэто неприменимо.
Host-режим можно использовать и для Swarm-сервиса — docker service create --network host. Но control-трафик (управление самим Swarm и сервисом) всё равно идёт через overlay-сеть, а данные сервиса — уже через хостовую сеть демона. Отсюда и ограничение: если task сервиса слушает порт 80, на одной ноде сможет крутиться только один такой task.
7. Legacy container links
Кому и зачем: если вы работаете с новыми проектами/docker — не нужно вообще, всё уже закрыто user-defined bridge из раздела 2. Актуально, только если поддерживаете старый проект, где
--linkуже используется, и нужно понимать, что там происходит.
Это то, что было до появления пользовательских сетей, и то, ради чего сделали user-defined bridge — чтобы про этот раздел можно было забыть.
--link работает только в default bridge и позволяет двум контейнерам обмениваться информацией друг о друге. Официально это устарело, но вдруг вы встретите это.
docker run -d --name db training/postgres
docker run -d -P --name web --link db:db training/webapp python app.py
Что при этом происходит:
Docker создаёт переменные окружения в контейнере
web;В
/etc/hostsконтейнераwebдобавляется запись с IP контейнераdb;Если
dbперезапустят, запись в/etc/hostsобновится автоматически, а вот переменные окружения — нет, они статичны с момента старта.
Безопасность: все Docker-переменные окружения из контейнера-источника становятся видны получателю, включая всё, что было передано через -e при старте source-контейнера. Если там лежали секреты — они утекут в линкованный контейнер.
8. Overlay: сеть между несколькими хостами
Кому и зачем: нужно, если у вас к примеру несколько Docker-хостов и контейнеры/сервисы на них должны общаться друг с другом, как правило это ещё в связке со Swarm. Для одного хоста overlay может быть избыточен, там достаточно обычного bridge.
Overlay сшивает несколько демонов вместе. Сама сеть «лежит поверх» сетей отдельных хостов, а маршрутизацию пакетов между ними Docker берёт на себя.
Обязательно хосты должны быть в одном Swarm — даже если вы просто хотите связать пару standalone-контейнеров без всяких сервисов. Порты, которые должны быть открыты между хостами:
Порт | Зачем |
|---|---|
| Control plane Swarm |
| Трафик overlay-сети |
| Коммуникация между нодами |
Создание
docker network create -d overlay --attachable my-attachable-overlay
Флаг --attachable — важная деталь. Без него к сети смогут подключаться только Swarm-сервисы. С ним — ещё и standalone-контейнеры.
Шифрование
docker network create \
--opt encrypted \
--driver overlay \
--attachable \
my-attachable-multi-host-network
Включает IPsec на уровне VXLAN. За это придётся заплатить производительностью, так что перед продакшеном стоит протестировать. И отдельно предупреждение: не подключайте Windows-контейнеры к зашифрованным overlay-сетям — Swarm ошибку не покажет, но у Windows-контейнеров в такой сети сломается связь с Linux-контейнерами, а трафик между Windows-контейнерами шифроваться не будет вообще.
Как работает
Когда поднимается Swarm, на каждой ноде появляется overlay-сеть ingress и bridge-сеть docker_gwbridge (она как раз связывает ingress с реальным сетевым интерфейсом хоста). Если создать сервис без явной сети, он подключится к ingress. Но рекомендация: отдельная overlay-сеть под каждое приложение или группу связанных приложений.
docker network create -d overlay nginx-net
docker service create \
--name my-nginx \
--publish target=80,published=80 \
--replicas=5 \
--network nginx-net \
nginx
Discovery работает так же, как и в user-defined bridge — по DNS-имени контейнера/сервиса, при условии уникальных имён. Публикация портов на overlay работает так же, как и везде, с поддержкой tcp/udp/sctp по отдельности или сразу:
Значение | Что делает |
|---|---|
| TCP 80 контейнера → TCP 8080 overlay-сети |
| То же самое, но UDP |
| Оба протокола сразу на одном порту |
И тот же лимит, что и у bridge: при 1000+ контейнерах на одном хосте overlay-сеть становится нестабильной — ограничение ядра Linux, а не самого Docker.
9. Macvlan и IPvlan: контейнер как устройство в физической сети
Кому и зачем: bare metal-сценарии — приложения, которым нужен MAC-адрес или прямое присутствие в физической сети, мониторинг трафика, интеграция с сетевым оборудованием. В облаке или на Docker Desktop почти наверняка не понадобится — большинство облачных провайдеров такой трафик просто блокируют, а Docker Desktop эти драйверы вообще может быть и не поддерживать.
Оба драйвера решают одну и ту же задачу: контейнер должен выглядеть в сети как отдельное устройство, а не прятаться за NAT хоста, как это происходит в bridge. Разница лишь в реализации.
macvlan выдаёт контейнеру собственный уникальный MAC-адрес — для физической сети контейнер выглядит так же, как обычный отдельный компьютер, подключённый к свитчу. А в ipvlan у нас так: MAC не меняется, все контейнеры используют MAC родительского интерфейса хоста, а разделение идёт только по IP.
Оба при этом убирают Linux bridge из уравнения — трафик идёт напрямую через физический интерфейс хоста, без port mapping для внешних сервисов.
Macvlan | IPvlan | |
|---|---|---|
MAC на контейнер | Свой уникальный | Общий с parent-интерфейсом |
Нужное ядро Linux | 3.9+ (лучше 4.0+) | 4.2+ |
Нагрузка на сетевое оборудование | Больше MAC = больше нагрузка на CAM-таблицы свитчей, плюс нужен promiscuous mode | Меньше MAC-адресов в сети, требований к оборудованию меньше |
Контейнер ↔ хост напрямую | Не работает — ограничение ядра, нужна ещё и bridge-сеть в довесок | В L2-режиме тоже не работает, фильтруется ядром намеренно |
Когда выбирать | Легаси-приложения, которым нужен именно физический MAC | Когда есть ограничение по количеству MAC на интерфейсе/порту |
Общие для обоих ограничения: работают только на Linux (недоступны на Docker Desktop для Mac/Windows и на Docker Engine для Windows), не поддерживаются в rootless-режиме, большинство облачных провайдеров такой трафик блокирует — нужен физический доступ к сетевому оборудованию.
Как создаются сети
Синтаксис у обоих похож — указываете драйвер, подсеть, gateway и родительский интерфейс хоста (parent), через который пойдёт трафик:
# macvlan
docker network create -d macvlan \
--subnet=172.16.86.0/24 --gateway=172.16.86.1 \
-o parent=eth0 pub_net
# ipvlan
docker network create -d ipvlan \
--subnet=192.168.1.0/24 --gateway=192.168.1.1 \
-o ipvlan_mode=l2 -o parent=eth0 db_net
Если указать parent с точкой (например, eth0.50), Docker сам создаст VLAN-суб-интерфейс — это называется 802.1Q trunk mode, удобно, когда сетевой инженер уже выдал вам конкретный VLAN ID и подсеть под него.
Режимы работы
Драйвер | Режим | Что означает |
|---|---|---|
macvlan |
| Трафик идёт через физический интерфейс хоста напрямую |
macvlan |
| Более специфичные режимы для конкретного сетевого оборудования, встречаются редко |
ipvlan |
| Контейнеры на одном parent видят друг друга и резолвятся по имени, но не пингуют сам хост; разные подсети на одном parent не видят друг друга без роутера с proxy-arp |
ipvlan |
| Дропает broadcast/multicast, нет привычного gateway — Docker-хост по сути работает как маленький роутер, зато разные подсети на одном parent общаются между собой без внешнего роутера |
ipvlan |
| То же самое, что |
10. Сетевые плагины
Кому и зачем: если инфраструктура завязана на конкретный сетевой стек, которого нет среди встроенных драйверов. Для большинства проектов встроенных драйверов достаточно, плагины это очень редкий и специфический случай.
Если встроенных драйверов не хватает (например, нужен крутой VXLAN в стороннем виде или интеграция со специфическим сетевым стеком), можно поставить плагин от третьей стороны через LibNetwork. С точки зрения использования плагин ничем не отличается от встроенного драйвера:
docker network create --driver weave mynet
docker run --network=mynet busybox top
Все команды к сети mynet дальше уходят плагину weave.
Заключение
Во многих моментах, думаю, что в 95% случаев вам хватит user-defined bridge, и на этом можно закрыть статью и не грузить себе голову остальным. Host берём, когда нужна производительность или большой диапазон портов, none — когда контейнеру сеть вообще не должна быть нужна, overlay — если у вас несколько хостов и они завязаны на Swarm, а macvlan/ipvlan — это уже не только история про bare metal (да и вообще не только про него), а вариант, который выбирается в зависимости от потребностей, когда контейнеру важно быть видимым в сети как отдельное устройство.
В остальном вторая часть — это уже спецификация уровня «упёрся в задачу» (собственно, поэтому и пишу, кому и зачем, чтобы можно было находить нужное сразу, а не перечитывать всю статью заново и читать только то, что действительно потребуется).
KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.