Це чудова тема! Вона дозволяє зазирнути під капот "магії", яку ми використовуємо щодня.
Ось урок, написаний у стилі CS50: енергійно, доступно та з фокусом на розумінні суті.
🎓 Урок: Docker та Linux — Анатомія взаємодії
Привіт, друзі! Радий бачити вас на занятті.
Сьогодні ми розберемо одну з найпопулярніших технологій у світі розробки — Docker. Але ми не будемо просто заучувати команди. Ми підемо глибше. Ми запитаємо себе: "А як це взагалі працює?"
Чому Docker такий швидкий? Чому він легший за віртуальні машини? І до чого тут взагалі Linux, якщо ви, можливо, сидите зараз на MacBook або Windows?
Поїхали! 🚀
1. 🔥 Вступ: "У мене на комп'ютері працює!"
Уявіть ситуацію. Ви написали геніальний код на Python. Використали конкретну бібліотеку версії 3.2. На вашому ноутбуці все літає. Ви відправляєте код колезі (або на сервер), а там... помилка.
Чому? * У колеги інша версія Python. * У нього Windows, а у вас MacOS. * У нього встановлені інші системні бібліотеки.
Це класична проблема "Dependency Hell" (Пекло залежностей).
Раніше ми вирішували це Віртуальними Машинами (VM). Уявіть, що ваш застосунок — це меблі. Щоб перевезти меблі до друга і гарантувати, що вони стоятимуть так само, ви купуєте... цілий новий будинок, ставите туди меблі і перевозите весь будинок. Це надійно? Так. Це ефективно? Ні! Це дорого, важко і довго.
Docker пропонує інший підхід. Замість того, щоб возити будинки (цілі операційні системи), ми використовуємо контейнери.
Риторичне запитання:
Якби ви могли взяти свій код, запакувати його в легку коробку разом з усім необхідним і бути впевненим на 100%, що ця коробка відкриється однаково на будь-якому комп'ютері світу — ви б це зробили?
Звісно. І саме тут на сцену виходить Linux.
2. 🧠 Теоретична база: Магія Ядра
Щоб зрозуміти Docker, треба зрозуміти одну річ про Linux.
У Linux є Ядро (Kernel). Це "бос", який керує "залізом" (пам'яттю, процесором, диском).
У чому різниця між VM та Docker?
- Віртуальна машина (VM): Кожна VM має своє власне ядро. Це як окремі будинки. Якщо у вас 3 VM, у вас 3 ядра, які працюють одночасно, з'їдаючи ресурси.
- Docker (Контейнер): Всі контейнери використовують ОДНЕ спільне ядро (ядро хоста). Це як готель. У кожного гостя своя кімната (ізоляція), свій ключ, свій душ, але фундамент, водопровід і електрика — спільні для всієї будівлі.
Як це працює "під капотом"?
Docker — це не магія. Це просто зручний інтерфейс для двох крутих фішок Linux ядра:
-
Namespaces (Простори імен) — це "Стіни кімнати". Це те, що дає ізоляцію. Завдяки Namespaces, процес у контейнері думає: "Я тут один! Я головний!". Він не бачить процесів сусіднього контейнера, не бачить всієї файлової системи хоста.
- Інтуїтивно: Це як шори на очах коня. Кінь бачить тільки свою дорогу.
-
Cgroups (Control Groups) — це "Лічильники". Це обмеження ресурсів. Ви можете сказати: "Цей контейнер не може їсти більше 512 Мб пам'яті". Без Cgroups один "ненажерливий" контейнер міг би покласти весь сервер.
- Інтуїтивно: Це батьківський контроль на банківській картці. Ти можеш витрачати гроші, але не більше ліміту.
❗️ Запам'ятайте головне: Docker-контейнер — це звичайний процес Linux, просто він "обманутий" (ізольований) так, що думає, ніби він окремий комп'ютер.
3. 🧪 Приклади: Від ілюзії до реальності
Давайте подивимось, як ця "брехня на благо" виглядає на практиці.
Приклад 1: Ілюзія самотності (PID Namespace)
Коли ви запускаєте Linux, у вас сотні процесів. PID 1 — це система ініціалізації (зазвичай systemd).
Чого ми очікуємо: Якщо ми запустимо Ubuntu в Docker, чи побачить вона процеси мого основного комп'ютера?
Давайте перевіримо:
# Запускаємо контейнер і просимо показати список процесів (ps aux)
docker run --rm ubuntu ps aux
Результат:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 2340 584 ? Rs 12:00 0:00 ps aux
Пояснення:
Бачите? Процес ps aux має PID 1.
Для контейнера він — єдиний процес у Всесвіті. Але насправді, для вашого комп'ютера (хоста), цей процес може мати PID 45678. Це і є робота Namespaces. Docker створив "паралельну реальність" для цього процесу.
Приклад 2: Різні світи (Файлова система)
У мене на комп'ютері стоїть, наприклад, Fedora Linux. А я хочу запустити застосунок, якому потрібен Debian.
Питання: Чи не посваряться вони?
# Перевіримо версію OS всередині контейнера
docker run --rm debian cat /etc/os-release
Результат: Ви побачите PRETTY_NAME="Debian GNU/Linux...".
Незважаючи на те, що ядро спільне, файлова система у кожного своя. Docker підміняє кореневу папку / для контейнера.
4. 🛠 Практична частина
Тепер ваша черга! Відкрийте термінал. (Якщо у вас Windows/Mac, переконайтеся, що Docker Desktop запущено — він створить мікро-Linux віртуалку, щоб все це працювало).
Завдання 1: "Матрьошка"
Запустіть контейнер alpine (це супер-легкий Linux) і "заійдіть" всередину нього.
docker run -it alpine sh
- Виконайте
ls /. Це файли вашого комп'ютера чи контейнера? - Вийдіть командою
exit.
Завдання 2: "Тюремник" (Cgroups)
Спробуємо обмежити контейнер.
docker run -it --memory="10m" alpine sh
- Ми дали йому всього 10 Мб RAM. Спробуйте всередині виконати команду, яка їсть пам'ять (або просто уявіть це). Якщо процес перевищить ліміт, ядро Linux (через механізм OOM Killer) безжально вб'є його. Це захищає решту системи.
Завдання 3: "Портал у реальний світ" (Volumes)
Контейнери ефемерні (тимчасові). Якщо ви створите файл у контейнері і видалите контейнер — файл зникне.
Завдання: Зробити так, щоб файл залишився.
1. Створіть папку data на робочому столі.
2. Запустіть:
bash
docker run -v $(pwd)/data:/app alpine touch /app/hello.txt
3. Перевірте папку data на вашому реальному комп'ютері. З'явився файл? Чому?
Завдання 4: Міні-кейс "А що, якщо..."
- Питання: Якщо я видалю Docker, чи зникнуть мої Images (образи)?
- Питання: Чи може процес із контейнера "зламати" мій хост-комп'ютер? (Підказка: за замовчуванням
rootу контейнері — це часто і єrootна хості, просто обмежений namespaces. Це ризик!)
5. 💡 Мислення як у розробника
Як відрізнити новачка від профі в роботі з Docker?
❌ Помилка новачка:
Сприймати контейнер як "легку віртуалку".
Новачки часто заходять у контейнер через термінал, встановлюють там вручну програми (apt-get install), редагують конфіги... і потім дивуються, що після перезапуску все зникло.
Docker-контейнери — це "худоба", а не "домашні улюбленці". Ми їх не лікуємо, ми їх замінюємо на нові.
✅ Як думає профі:
- Immutability (Незмінність): Все має бути прописано в
Dockerfile. Я повинен мати можливість видалити всі контейнери, запустити одну команду, і все відновиться за секунди. - Один процес — один контейнер: Не пхайте в один контейнер базу даних, веб-сервер і бекенд. Розділяйте. Це дозволяє легко оновлювати частини системи окремо.
- Безпека: Профі знає, що Docker використовує ядро хоста. Тому він ніколи не запускає сумнівні образи з правами
rootбез потреби.
6. 🧩 Підсумок
Сьогодні ми розібрали фундамент:
- Docker — це не віртуалізація заліза. Це ізоляція процесів.
- Він використовує функції ядра Linux: Namespaces (щоб сховати процеси) та Cgroups (щоб обмежити ресурси).
- Контейнер ділить ядро з хостом, але має власну файлову систему.
Що ви тепер вмієте?
Ви розумієте різницю між VM та Контейнером не просто як "важкий/легкий", а на рівні архітектури. Ви знаєте, що коли ви пишете docker run, ви насправді звертаєтесь до Linux-ядра з проханням "виділити окрему пісочницю".
🔜 Тизер наступного уроку: Ми вміємо запускати чужі контейнери. Але як створити свій? На наступному занятті ми станемо архітекторами: ми напишемо свій перший Dockerfile, і я покажу вам, як створити свій власний "всесвіт" з нуля.
Бережіть себе, і до зустрічі на наступному уроці! 👋