Итак, Docker - это несколько технологий по созданию, транспортировке, запуску и управлению контейнерами. Давай попробуем собрать это всё воедино.
Когда мы запускаем с помощью Docker CLI команду для создания контейнера
docker container run -it ubuntu
, то клиент Docker преобразует команду в запрос к restful API, который затем передает её демону dockerd.
Демон Docker, получив инструкцию, сначала проверяет, доступен ли предоставленный образ в локальной системе. Если это не так, образ загружается из docker-реджистри (по умолчанию Docker Hub).
Как только образ получен, будет вызван containerd, чтобы запустить контейнер. containerd отвечает за преобразование загруженного образа в специальный bundle. Это такой набор файлов, который соответствует спецификации OCI.
Затем он передает пакет в обёртку containerd-shim, которая, в свою очередь, вызывает среду runC, которая и запускает контейнер.
runC взаимодействует с механизмами namespaces и cgroups в ядре, и они производят изоляцию некоторой вычислительной части нашего хоста, которая и есть контейнер. Вот именно так создаётся контейнер, если мы используем для запуска Docker.