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