- Понимание технологии контейнеров
- Технология контейнеров Docker
- Процессы внутри контейнера
- Механизм Namespace
- Технология пространств имён (Namespaces) в Linux
- Работа нескольких пространств имён
- Принцип реализации контейнеров Docker
- Сравнение контейнеров и виртуальных машин
- Лёгкая виртуализация Docker
- Заключение
Понимание технологии контейнеров
Контейнеры — это разновидность технологии песочницы. Как следует из названия, песочница — это технология, которая может «упаковывать» приложения, как контейнер, гарантируя, что приложения не будут мешать друг другу из-за установленных границ. Более того, приложения, помещённые в такие «контейнеры», могут быть перенесены и запущены в разных системных средах.
Прежде чем углубляться в принципы работы контейнерной технологии, важно понять концепцию процессов. Статическое представление процесса — это программа, которая обычно спокойно хранится на диске. Когда она запускается, она превращается в совокупность данных и состояний внутри компьютера — её динамическое представление. Основная функциональность контейнерной технологии заключается в создании «границы» для процессов путём ограничения и изменения их динамического поведения.
Технология контейнеров Docker
Для большинства контейнеров Linux, включая Docker, технология Cgroups primarily используется для наложения ограничений, а технология Namespace является основным методом изменения представления процесса.
Представьте, что у вас есть проект Docker, работающий в операционной системе Linux, скажем, Ubuntu 22.04. Давайте создадим контейнер для эксперимента:
$ docker run -it busybox /bin/sh
Эта команда Docker запускает контейнер на основе образа busybox и запускает в нём интерактивную сессию оболочки.
docker run: Создаёт и запускает новый экземпляр контейнера.-i: Оставляет STDIN открытым, даже если терминал не подключён, что позволяет взаимодействовать с контейнером.-t: Назначает псевдотерминал или терминал, создавая интерактивную среду оболочки./bin/sh: Указывает команду, которая будет выполнена при запуске контейнера; в данном случае это запуск сессии оболочки внутри контейнера.
Процессы внутри контейнера
Таким образом, машина с Ubuntu становится хостом, а контейнер, запускающий /bin/sh, работает внутри неё. Этот пример и его основополагающий принцип должны быть знакомы опытным пользователям Docker. Если вы выполните команду ps внутри контейнера, вы заметите кое-что интересное:
/ # ps
PID USER TIME COMMAND
1 root 0:00 /bin/sh
10 root 0:00 ps
Здесь первоначальный /bin/sh, запущенный внутри Docker, является процессом номер 1 (PID=1) внутри контейнера, и работают только два процесса. Это означает, что /bin/sh и команда ps, которую мы только что выполнили, изолированы в отдельной среде от хоста.
Механизм Namespace
Как это достигается? Обычно, когда программа /bin/sh запускается на хосте, операционная система присваивает ей идентификатор процесса, например PID=100, который уникально её идентифицирует. При запуске этой программы внутри контейнера Docker применяется «иллюзия», благодаря которой процесс, фактически имеющий PID=100, считает себя первым процессом (PID=1). Этот механизм манипулирует пространством процессов изолированных приложений, позволяя им видеть пересчитанные идентификаторы процессов.
Технология пространств имён (Namespaces) в Linux
Использование пространств имён довольно интересно: это всего лишь необязательный параметр для создания новых процессов в Linux. Системный вызов для создания процессов в Linux — clone():
int pid = clone(main_function, stack_size, SIGCHLD, NULL);
Этот вызов создаёт новый процесс и возвращает его идентификатор pid. При использовании системного вызова clone() для создания нового процесса можно указать аргумент CLONE_NEWPID:
int pid = clone(main_function, stack_size, CLONE_NEWPID | SIGCHLD, NULL);
После этого вновь созданный процесс «увидит» новое пространство процессов, где его PID равен 1. Эта «иллюзия» не изменяет фактический PID в пространстве процессов хоста, который остаётся реальным значением, например 100.
Работа нескольких пространств имён
Многократное выполнение описанного вызова clone() создаст несколько пространств имён PID. Процессы приложений в каждом пространстве имён считают себя первыми процессами в своих контейнерах, не зная о фактическом пространстве процессов хоста или о других пространствах имён PID. Помимо пространства имён PID, Linux предлагает пространства имён Mount, UTS, IPC, Network и User, чтобы «скрывать» различные контексты процессов.
Mount Namespace
- Mount Namespace: позволяет изолированным процессам видеть только те точки монтирования, которые относятся к текущему пространству имён, то есть процессы внутри контейнера не знают о других точках монтирования на хосте.
Network Namespace
- Network Namespace: предоставляет изолированным процессам представление о сетевых устройствах и конфигурации, специфичной для текущего пространства имён. Каждое сетевое пространство имён имеет свои сетевые устройства, IP-адреса, таблицы маршрутизации и номера портов, отдельные от хоста и других пространств имён.
Другие пространства имён
- UTS Namespace: изолирует имя узла (hostname) и сетевое имя хоста.
- IPC Namespace: разделяет ресурсы для межпроцессного взаимодействия, такие как очереди сообщений и семафоры.
- User Namespace: изолирует идентификаторы пользователей и групп, позволяя сопоставлять идентификаторы пользователей внутри контейнера с другими идентификаторами на хосте для повышения безопасности.
Принцип реализации контейнеров Docker
Это основной принцип реализации контейнеров Linux. Таким образом, кажущаяся сложной концепция контейнеров Docker, по сути, заключается в указании набора параметров пространства имён при создании процесса контейнера. Следовательно, контейнер может «видеть» только те ресурсы, файлы, устройства, состояния или конфигурации, которые ограничены текущим пространством имён, и полностью не осознаёт хост и посторонние программы.
Сравнение контейнеров и виртуальных машин
Контейнеры, таким образом, являются особым видом процессов. При рассмотрении идеи выделения независимого пространства для процессов на ум приходят виртуальные машины. Они эмулируют оборудование с помощью программного обеспечения Hypervisor, запуская полноценную гостевую операционную систему для достижения изоляции приложений. В отличие от них, контейнеры Docker достигают изоляции с помощью пространств имён и технологии Cgroups, разделяя ядро операционной системы хоста.
Лёгкая виртуализация Docker
Docker часто называют технологией «лёгкой» виртуализации, поскольку он напрямую использует ресурсы хоста без необходимости эмуляции оборудования или запуска дополнительной операционной системы. Это даёт значительные преимущества по сравнению с традиционными виртуальными машинами в скорости запуска, использовании ресурсов и производительности.
Заключение
Технология контейнеров Docker предоставляет изолированную, но лёгкую среду для процессов приложений с помощью пространств имён и технологии Cgroups. Эта технология позволяет контейнерам быстро запускаться, эффективно работать и сохранять изоляцию от хоста и других контейнеров, что делает её незаменимой технологией в современных облачных вычислениях и микросервисных архитектурах.
Novita AI* — единая платформа для безграничного творчества, предоставляющая доступ к более чем 100 API. От генерации изображений и обработки языка до улучшения аудио и манипуляции видео, недорогая модель оплаты по мере использования освобождает вас от забот о сопровождении GPU при создании собственных продуктов. Попробуйте бесплатно. *
