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