Поясніть роботу Docker networking. Які є типи мереж?
Docker networking це шар, що вирішує, як container дістають один одного і зовнішній світ. Шість вбудованих драйверів, але більшість прод-сетапів використовує лише два: user-defined bridge для single host, overlay для multi-host.
Теорія
TL;DR
- Docker створює віртуальні мережі; container приєднуються і отримують внутрішній IP.
- Шість вбудованих драйверів покривають кожен поширений кейс. Обирай за топологією, не за вподобанням.
bridge(дефолт): ізольована віртуальна мережа на одному host. Дефолт дляdocker run, якщо не задаєш.- User-defined bridge як дефолтний bridge, але з DNS-резолюцією по імені container, майже завжди кращий вибір.
host: container ділить network stack host (без ізоляції, найшвидше).none: жодної мережі (рідко, для дуже locked-down навантажень).overlay: охоплює кілька Docker host через VXLAN. Потрібен для Swarm-сервісів.macvlan/ipvlan: container з'являється як реальний пристрій на фізичному LAN (рідко, для legacy або специфічних маршрутизаційних потреб).
Швидкий приклад
# Перелік мереж, що Docker створює за замовчуванням
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
4f06b3e2c0c1 bridge bridge local
8a3f2d1c9b8e host host local
1234567890ab none null local
# Створимо user-defined bridge (правильний дефолт для app-стеків)
$ docker network create mynet
# Запустимо два container; вони можуть ping'ати одне одного по імені
$ docker run -d --name api --network mynet myapp
$ docker run -d --name db --network mynet postgres:16
$ docker exec api ping -c 1 db
# Резолвить db → 172.18.0.2 через embedded DNS Docker, ICMP працює.User-defined bridge дають name-based DNS автоматично, дефолтний bridge ні. Це сама причина брати їх.
Драйвери детально
bridge (дефолт) — single host
Віртуальний L2-bridge на host. Container, приєднані до нього, отримують IP на приватному підмережі (наприклад, 172.17.0.0/16 для дефолтного bridge).
- Дефолтна
bridge-мережа (створена Docker при інсталі): без DNS по імені, лише через--link(deprecated). Уникай. - User-defined bridge (
docker network create mynet): container резолвлять одне одного по імені container. Завжди краще.
Iptables NAT-правила форвардять опубліковані порти (-p) з host на IP container.
host — без ізоляції
docker run --network host nginx
# nginx слухає host-порт 80 напряму. -p не треба.Container ділить network namespace host. Без NAT, без port mapping, без окремого IP. По продуктивності найшвидше (без overhead). По безпеці найслабше (container бачить кожен host-інтерфейс).
Бери, коли треба сирий мережевий performance або bind на конкретні host-інтерфейси. Уникай у shared / multi-tenant сетапах.
none — ізольовано
docker run --network none alpine ip a
# Лише loopback (lo). Жодної зовнішньої мережі.Container має свій network namespace, але немає інтерфейсів крім lo. Бери для batch-job, що не повинні чіпати мережу, або для ручного налаштування мережі post-factum.
overlay — multi-host (Swarm)
Охоплює Docker-host у Swarm-кластері через VXLAN-енкапсуляцію. Container на host A і host B можуть говорити, ніби на тому самому LAN.
# На Swarm-менеджері
$ docker network create --driver overlay --attachable myoverlayВикористовується для Swarm-сервісів. Без Swarm майже ніколи не тягнешся за overlay. Kubernetes має свій еквівалент (CNI-плагіни) і не використовує Docker overlay.
macvlan — container як реальний пристрій на LAN
Container отримує свою MAC-адресу на фізичній мережі. Виглядає як окремий пристрій для роутера, DHCP-сервера тощо.
$ docker network create --driver macvlan \
--subnet=192.168.1.0/24 \
--gateway=192.168.1.1 \
-o parent=eth0 \
pubnet
$ docker run --network pubnet --ip 192.168.1.50 myappБери, коли legacy-софт очікує bind на реальний LAN-інтерфейс, або коли треба, щоб кожен container був на тій самій підмережі, що й офісна. Caveat: більшість cloud-провайдерів (AWS, GCP, Azure) блокують MAC, які не присвоїли, macvlan чисто не працює у хмарі.
ipvlan — схоже на macvlan, IP-рівень
Як macvlan, але container ділять MAC host. Краще для середовищ, де MAC обмежені (хмара, switch port-security). Менш поширений, ніж macvlan.
Як працює DNS container
User-defined bridge і overlay-мережі включають embedded DNS-сервер Docker на 127.0.0.11. З container:
# Container 'api' на 'mynet' резолвить сусіда 'db'
$ docker exec api cat /etc/resolv.conf
nameserver 127.0.0.11
$ docker exec api nslookup db
Server: 127.0.0.11
Name: db
Address 1: 172.18.0.2DNS знає про усі container на тій самій мережі. Імена резолвляться у поточні IP (IP container можуть мінятися на рестарті, DNS встигає).
Команди управління мережею
docker network ls # перелік
docker network inspect <name> # повні деталі (subnet, приєднані container)
docker network create [opts] <name> # створити
docker network rm <name> # видалити (має бути порожнім)
docker network connect <net> <container> # приєднати running container
docker network disconnect <net> <container> # відключити
docker network prune # видалити невикористаніТипові помилки
Використання дефолтного bridge і дивуватися, чому DNS падає
# НЕПРАВИЛЬНО: container на дефолтному bridge не резолвлять одне одного по імені
$ docker run -d --name db postgres:16
$ docker run -d --name api myapp # обидва на дефолтному bridge
$ docker exec api ping db # name resolution падаєФікс: створи user-defined bridge.
$ docker network create mynet
$ docker run -d --name db --network mynet postgres:16
$ docker run -d --name api --network mynet myapp
$ docker exec api ping db # працюєCompose створює user-defined bridge per project автоматично, тому DNS «просто працює» у Compose.
Публікація портів на host-мережі
# НЕПРАВИЛЬНО: -p ігнорується на host-мережі
$ docker run --network host -p 8080:80 nginx
# nginx все одно слухає host:80 (його реальний порт), -p нічого не робитьhost-режим і -p взаємно виключні. Обирай одне.
Використання localhost для з'єднання з іншими container
Класична помилка. localhost всередині container це сам container. Бери service-ім'я (на user-defined bridge або Compose-проекті) або IP container (крихко, IP міняються).
Overlay без Swarm
$ docker network create --driver overlay test
Error response from daemon: This node is not a swarm manager.Overlay потребує Swarm-кластер (docker swarm init спочатку). Поза Swarm бери bridge.
Реальне застосування
- Локальний dev з Compose: кожен project автоматично отримує свій user-defined bridge. Service-name DNS працює з коробки.
- Single-host production: явний user-defined bridge на app-стек. Внутрішні сервіси без публікації, web/proxy опубліковано.
- Swarm-кластери: overlay-мережі для service-to-service трафіку між node. Шифровано за замовчуванням у сучасному Swarm.
- Performance-критичні навантаження на bare metal:
--network host, щоб скіпнути bridge і NAT-overhead. - Спеціальна LAN-інтеграція (legacy, IoT, домашні лаби): macvlan, щоб container були «на LAN» зі своїм IP/MAC.
Питання для поглиблення
Q: Чому container на user-defined bridge мають DNS, а на дефолтному bridge ні?
A: Історично. Дефолтна bridge-мережа це оригінальна реалізація Docker; user-defined bridge прийшли пізніше з DNS-by-name з коробки. Дефолтний bridge зберегли для backward-compatibility, але по суті deprecated для нових use case.
Q: Чи може container належати кільком мережам?
A: Так. docker run --network net1 ... && docker network connect net2 container. Корисно для розділення відповідальностей: web container на frontend і backend, db лише на backend.
Q: Яка різниця між bridge і --network=host?
A: bridge дає container свій network namespace і IP, з NAT, що транслює до/від host. host робить, щоб container ділив network namespace host, той самий IP, ті самі інтерфейси, без NAT.
Q: Як Kubernetes networking співвідноситься з Docker?
A: Kubernetes не використовує Docker networking. K8s має CNI (Container Network Interface) plugin-модель, кожен pod отримує свій network namespace, але connectivity забезпечує CNI-плагін (Calico, Flannel, Cilium тощо), не Docker. Під капотом runtime (containerd) все ще створює namespace; Kubernetes дає IP і routing.
Q: (Senior) Коли б ти обрав macvlan замість bridge з -p?
A: Коли трафік container має походити з реальної LAN-адреси (legacy-сервіси, що whitelist'ять по IP, license-сервери, прив'язані до MAC, мережеве обладнання). Bridge + -p завжди показує IP host ззовні; macvlan дає container свій IP. Уникай у хмарі, великі cloud-провайдери відхиляють незнайомі MAC на hypervisor.
Приклади
Ручне створення user-defined bridge для стеку
$ docker network create --driver bridge \
--subnet 172.20.0.0/24 \
--gateway 172.20.0.1 \
appnet
$ docker run -d --name db --network appnet \
-e POSTGRES_PASSWORD=devpass postgres:16
$ docker run -d --name api --network appnet \
-e DATABASE_URL=postgres://postgres:devpass@db:5432/app myapp
$ docker run -d --name web --network appnet -p 80:80 nginx
# web дістає api по імені; api дістає db по імені; лише web відкритий host.Production-shape патерн: явна мережа, сервіси без публікації крім entry point.
Inspecting мережі
$ docker network inspect appnet --format '{{json .Containers}}' | jq
{
"a3f9d2b8c1e4": {
"Name": "db",
"IPv4Address": "172.20.0.2/24"
},
"b7e1f4d6a2b8": {
"Name": "api",
"IPv4Address": "172.20.0.3/24"
},
...
}Хто на мережі і з яким IP. Корисно для дебагу проблем зі спілкуванням.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.
Коментарі
Ще немає коментарів