Курс СРС SRS05
до ЛР3 рівень 2 → «4»↔ Лабораторна 3↔ Лекція 3⌨️ команди 5
Самостійна робота · ~2.5 год

Мережі Docker (bridge/none/host) і службове DNS між контейнерами

🌌 Листоноша приватного кварталу — С.І.Д. душі не чує у своєму Листоноші: розберися, чому в приватному кварталі (user-defined мережа) той доносить лист за іменем контейнера, навіть коли адреси міняються щоночі, а на загальному майдані (дефолтний bridge) той самий лист повертається з поміткою «адресата не знайдено».

📚 ТЕОРЕТИЧНІ ВІДОМОСТІ

Три базові драйвери мережі

Docker пропонує кілька мережевих драйверів, з яких три ключові для однієї машини: bridge (за замовчуванням) — створює віртуальний комутатор (Linux bridge) на хості, до якого кожен контейнер підключається через пару veth (одна «нога» в мережевому просторі імен контейнера, інша — на боці бриджа); host — контейнер повністю ділить мережевий простір імен хоста (немає ізоляції NET, немає накладних витрат NAT, але й немає прихованості портів); none — контейнер отримує лише loopback-інтерфейс і жодного зовнішнього зв'язку, що корисно для максимально ізольованих обчислень без мережевого вводу-виводу взагалі.

Ключова відмінність, яку часто пропускають: дефолтна bridge-мережа (та, що створюється автоматично й називається bridge, з інтерфейсом docker0 на хості) і user-defined bridge-мережа (та, що явно створена командою docker network create mynet) поводяться по-різному щодо DNS. У дефолтній мережі контейнери можуть спілкуватися між собою лише за IP-адресою (яка до того ж не гарантовано стабільна між перезапусками) — вбудований DNS-сервер Docker (на адресі 127.0.0.11 усередині кожного контейнера) там не резолвить імена інших контейнерів. У user-defined мережі ж кожен контейнер автоматично реєструється в цьому вбудованому DNS під своїм --name (і будь-якими мережевими алісами), тож ping storage чи звернення до http://storage:5432 з іншого контейнера в тій самій мережі просто працює — без ручного керування /etc/hosts чи фіксованих IP.

Ізоляція на рівні мережі — не лише зручність, а й безпековий кордон: контейнери в різних user-defined мережах не бачать одне одного за замовчуванням, навіть якщо обидва працюють на тому самому хості. Це дозволяє архітектурний патерн «сховище видно лише застосунку, застосунок видно лише проксі» — кожна пара сервісів, яким потрібно спілкуватися, підключається до спільної мережі, а решта лишається відрізаною. Один контейнер можна підключити одразу до кількох мереж (docker network connect), що дає гнучкість топології без відкриття портів назовні на хості.

Проброс порту на хост (-p host:container) і мережева видимість між контейнерами — це два незалежні механізми. Контейнери в одній user-defined мережі бачать порти один одного напряму (через внутрішню IP-адресу чи ім'я, на будь-якому порту, який слухає сервіс), без жодного -p; прапорець -p потрібен лише тоді, коли доступ повинен мати хост (чи зовнішній світ) — а не інший контейнер. Саме тому «закритий канал» між капсулою й сховищем не вимагає жодного проброшеного порту назовні: досить спільної ізольованої мережі, а порти на хост можна взагалі не відкривати.

📖 ОПРАЦЮВАТИ

Прочитати Docker docs «Networking overview» і «Use bridge networks»; створити user-defined bridge мережу (docker network create) і перевірити, що контейнери резолвлять один одного за іменем через вбудований DNS-сервер Docker.

🖥️ ТЕРМІНАЛ — СПРОБУЙ САМ
🎯 ЗАВДАННЯ
  1. Створити user-defined bridge мережу docker network create dark-channel і підключити до неї два контейнери (--network dark-channel --name storage і --name capsule); з capsule виконати ping storage і переконатися, що ім'я резолвиться.
  2. Запустити ті самі два контейнери в дефолтній bridge-мережі (без --network) і показати, що ping storage за іменем не працює, а працює лише за IP-адресою (яку доведеться дізнатися окремо через docker inspect).
  3. Підняти простий сервіс (наприклад, Redis або HTTP-сервер) у storage без жодного -p на хост і звернутися до нього з capsule за адресою storage:<порт>; переконатися, що з хоста цей порт водночас недоступний.
  4. Створити третій контейнер outsider у зовсім іншій user-defined мережі й показати, що з нього ping storage не проходить навіть за іменем, навіть за IP — довести мережеву ізоляцію між різними user-defined мережами.
  5. Використати docker network connect, щоб підключити outsider додатково до dark-channel, і показати, що після цього зв'язок зі storage з'являється — контейнер може одночасно перебувати у двох мережах.
❓ КОНТРОЛЬНІ ПИТАННЯ
  1. Чим дефолтна bridge-мережа docker0 відрізняється від user-defined bridge-мережі щодо DNS-резолвінгу за іменем контейнера?
  2. На якій IP-адресі всередині контейнера доступний вбудований DNS-сервер Docker?
  3. Чому контейнерам в одній user-defined мережі не потрібен прапорець -p, щоб звертатися один до одного?
  4. Що відбувається з мережевою ізоляцією, якщо контейнер підключений одночасно до двох різних user-defined мереж?
  5. Чим мережевий драйвер host відрізняється від bridge з погляду ізоляції та накладних витрат?
  6. Що бачить контейнер, запущений із мережевим драйвером none?
  7. Як реалізовано фізичне з'єднання контейнера з мостом docker0 на рівні мережевого стека Linux?
✅ САМОПЕРЕВІРКА

Чим user-defined bridge мережа відрізняється від дефолтної bridge мережі docker0 щодо DNS-резолвінгу між контейнерами?

🥚 ПАСХАЛКА
Листоноша носить листи за іменами, але порти йому байдужі — тому С.І.Д. тримає у своєму кварталі ще одні двері: порт 3101, на якому він слухає ефір «Нічної Хвилі», відколи сидів на списаній машині. storage:3101 резолвиться так само, як storage:80; що всередині конверта — Листоноша не питає. І, як зазначає С.І.Д., «ТехНова» цей порт ніколи не сканує: у їхніх таблицях його немає.
⌨️ КОМАНДИ НА ЦІЙ СТОРІНЦІ 5

Кожна команда терміналу з цієї сторінки — одним реченням. Позначка нове — команда зустрічається в курсі вперше; далі вважаємо її знайомою.

docker network
Керує мережами: docker network create net — своя мережа, де контейнери бачать один одного за іменами.
docker
Клієнт Docker: усі дії з образами й контейнерами — через його підкоманди (docker <підкоманда> --help — довідка).
docker run
Створює й запускає контейнер з образу (docker run -it ubuntu:24.04 bash — інтерактивно з терміналом; -d — у фоні; --rm — видалити після виходу; -p 8080:80 — прокинути порт).
echo
Друкує рядок або значення змінної (наприклад echo $$ — PID поточної оболонки).
ping
Перевіряє, чи досяжний хост у мережі, надсилаючи ICMP-пакети (ping storage).

💡 Прочитати README прямо в терміналі: cat README.md (виведе весь файл) або less README.md (посторінково; вихід — клавіша q).
Довідка з будь-якої команди: man curl (повний посібник, вихід — q) або коротко curl --help; для підкоманд — docker run --help, cargo build --help.

← SRS04усі темиSRS06 →