Многие привыкли воспринимать Docker как нечто цельное, но попытка написать собственный аналог контейнеризации позволяет взглянуть на технологию под другим углом. Выясняется, что «контейнеры» — это не отдельная функция ядра Linux, а комбинация из пяти разных механизмов, скрывающихся под одной оболочкой.
Как это устроено внутри
По своей сути контейнеры — это обычные процессы с наложенными ограничениями. Они не изолированы так, как виртуальные машины, и их можно обнаружить в системной директории /proc. Основные инструменты, которые обеспечивают работу Docker, включают:
- Namespaces: скрывают видимость ресурсов между хостом и контейнером.
- Cgroups: жестко ограничивают потребление системных ресурсов.
- Механизмы изоляции сети: позволяют контейнеру работать в своей среде.
Сами образы представляют собой обычные папки. При запуске Docker использует команды вроде chroot или pivot_root, превращая выбранную директорию в корневую файловую систему для процесса.
Сложности языка Go
Рантайм runc написан на языке Go, что создает определенные трудности. Go по своей природе многопоточен, тогда как многие системные вызовы Linux требуют однопоточной среды. Чтобы обойти это ограничение, разработчикам пришлось внедрить специальный модуль на языке C, который выполняется до инициализации среды Go.
Более того, в Go отсутствует полноценная поддержка fork, что критически важно для создания дочерних процессов с ограничениями. Чтобы имитировать это поведение, runc использует хитрый трюк: повторно запускает исполняемый файл через /proc/self/exe со специальными аргументами.
Безопасность и привилегии
Исторически Docker требовал прав суперпользователя для работы с API ядра Linux. Хотя ситуация улучшается, реализация «бесправных» (rootless) контейнеров остается сложной задачей. В частности, для обеспечения сетевой изоляции без прав root разработчикам приходится фактически переписывать весь сетевой стек в пространстве пользователя. Автор отмечает, что создание собственного инструмента — это лучший способ понять, насколько глубоко и причудливо устроены привычные технологии.
Источник: codeandcake.dev