🌌 Шість Вартових на брамах: що кожен бреше процесові — С.І.Д. обожнює цю тему й радо проведе тебе за руку: розберися, що саме кажуть процесові шість Вартових на брамах капсули — PID, мережа, файли, хостнейм, IPC, cgroup — і чому сьома брама, USER, за замовчуванням стоїть навстіж, тож root усередині капсули — це той самий root і зовні.
Простір імен (namespace) — це механізм ядра Linux, який обмежує видимість певного
класу глобальних системних ресурсів для групи процесів. Це не віртуалізація в сенсі
гіпервізора: процеси контейнера виконуються на тому самому ядрі, що й процеси хоста,
просто ядро підмінює їм «вид» на систему. Контейнер Docker технічно — звичайний процес
Linux, якому під час clone() або unshare() передали набір прапорців CLONE_NEW*.
Сучасне ядро підтримує вісім типів просторів імен, з яких Docker на сучасному хості (cgroups v2, напр. Ubuntu 24.04 чи Codespaces) вмикає шість базових за замовчуванням:
veth-пари й міст docker0.pivot_root, і не бачить монтувань хоста./sys/fs/cgroup хоста. Саме CGROUP, а не USER, доповнює
п'ятірку класичних просторів до шістки, яку Docker створює без додаткових прапорців.Ще два типи існують, але до цієї шістки за замовчуванням не входять:
--userns-remap, тобто root у контейнері за замовчуванням
відповідає root на хості. Це найважливіший для безпеки простір — і водночас єдиний із
«камер», що лишається ввімкненою: доки USER не задіяно, внутрішній root видно ззовні як
справжній root.docker run не активується.Ключова відмінність PID-простору від решти — ієрархічність: процес, що створив новий
PID namespace, бачить процеси й свого, і всіх вкладених просторів (з їхніми «зовнішніми»
PID), а процеси всередині — лише себе й таких самих «сусідів» у своєму просторі. Саме
тому ps aux на хості показує всі процеси контейнерів, а ps aux усередині контейнера —
лише свої.
Для дослідження просторів імен зручні дві утиліти: lsns виводить таблицю всіх активних
просторів у системі з їхніми NS-ідентифікаторами (це номери inode спеціальних
псевдофайлів), а /proc/<pid>/ns/ містить символьні посилання виду pid:[4026531836]
для кожного простору, у якому виконується процес. Якщо два процеси мають однакове число
в дужках — вони перебувають в одному й тому самому просторі імен, навіть якщо формально
належать різним контейнерам (це трапляється, коли контейнери запущені з --network container:<інший> — вони свідомо ділять NET-простір). Команда nsenter -t <pid> -n ...
дозволяє «увійти» в простір імен уже запущеного процесу з боку хоста — це основний
інструмент діагностики мережі контейнера ззовні.
Прочитати namespaces(7) (man-pages) і розділ Docker docs «Namespaces in Docker»; на своїй машині виконати lsns і порівняти список просторів імен хоста зі списком усередині docker run -it ubuntu:24.04 bash; додатково переглянути символьні посилання /proc/
Який з шести просторів імен відповідає за те, що echo $$ усередині контейнера повертає 1, а не реальний PID процесу на хості, і що покаже /proc/1/ns/pid зсередини контейнера й ззовні?
lsns — це inode, і роздає їх Диспетчер, не питаючи нікого. Але С.І.Д. присягається, що на списаній машині в класі PID-простір його найпершої капсули мав номер, який закінчувався на 3101, — і що Пиксель у той момент сидів на клавіатурі. «Збіг, ранере? Я перевіряв: 0xC1D збігом не буває».Кожна команда терміналу з цієї сторінки — одним реченням. Позначка нове — команда зустрічається в курсі вперше; далі вважаємо її знайомою.
docker rundocker run -it ubuntu:24.04 bash — інтерактивно з терміналом; -d — у фоні; --rm — видалити після виходу; -p 8080:80 — прокинути порт).dockerdocker <підкоманда> --help — довідка).lsnslsns -p <PID>) — показує, у яких «кімнатах» ядра він живе.docker inspect-f '{{.State.Pid}}' — витягнути одне поле.docker execdocker exec -it storage sh).sudounshareunshare --pid --fork --mount-proc bash).psps aux — усі процеси з користувачем, PID і командою (у контейнері видно лише його власні).💡 Прочитати README прямо в терміналі: cat README.md (виведе весь файл) або less README.md (посторінково; вихід — клавіша q).
Довідка з будь-якої команди: man curl (повний посібник, вихід — q) або коротко curl --help; для підкоманд — docker run --help, cargo build --help.