Learning Platform
Глоссарий Troubleshooting
Урок 03.02 · 18 мин
Начальный
dockerhistoryocirunccontainerd

Краткая история и OCI

Идея «изолировать процесс» в Unix-мире намного старше, чем Docker. Docker появился в 2013 году и стал популярен не потому, что изобрёл изоляцию, а потому что упаковал её в удобный CLI с понятным форматом образов. Чтобы понять текущую экосистему — где Docker, где containerd, где OCI, где Podman — нужно пройти по таймлайну.

Этот урок короче предыдущего, и в нём больше дат и имён. Цель — чтобы ты на собеседовании или в чате с коллегой понимал, о чём речь, когда слышишь «containerd», «runc», «OCI image spec» или «cri-o».


Таймлайн

История контейнеров — 45 лет от chroot до OCI
1979: chrootСистемный вызов в Unix V7. Меняет видимый корень файловой системы для процесса. Это не изоляция, это смена точки '/'. Используется до сих пор для legacy задач
2000: FreeBSD jailsСерьёзное усиление chroot. Изоляция PID, network, user. Прообраз контейнеров. До сих пор используется на FreeBSD
2004: Solaris ZonesSun сделала полноценную контейнеризацию для Solaris. Изолированные zones со своими сетями, FS, юзерами. Поддерживается в illumos
2006-2007: cgroups + namespacesGoogle добавляет cgroups в Linux kernel. Параллельно растёт инфраструктура namespaces. Это два кирпича, на которых стоит Docker
2008: LXCLinux Containers — первая полноценная контейнеризация на Linux. Использует namespaces + cgroups. Сложный в использовании, но рабочий
2013: DockerSolomon Hykes показал prototype на DockerCon. Изначально работал поверх LXC, потом переписан на свой runtime libcontainer. Главное — простой CLI и формат image
2015: OCIOpen Container Initiative. Стандарт на формат image и runtime. Создан совместно Docker, Red Hat, Google, CoreOS, чтобы не быть запертыми в одну реализацию
2017: containerd + CRI-Ocontainerd выделился из Docker как самостоятельный runtime для Kubernetes. CRI-O — альтернатива от Red Hat. Оба не зависят от docker daemon
2020+: Podman, OrbStackАльтернативные UI и daemonless подходы. Podman — rootless без daemon'а. OrbStack — быстрый Docker-совместимый рантайм для mac

chroot (1979) — старший родственник

chroot появился ещё в Unix V7. Это очень простая штука: процессу меняется видимый корень файловой системы.

Mount, /etc/fstab и mount namespaces Был /, стал /some/subdir. Теперь процесс физически не может выйти за пределы этой папки (через корень — может через другие лазейки, об этом ниже).

chroot до сих пор используется для:

  • Сборки пакетов в чистой среде.
  • Восстановления Linux-системы из live-CD.
  • Простых «sandbox» для устаревших приложений.

Что chroot не делает: ничего не изолирует, кроме видимости файловой системы. Процесс видит все PID, все сети, все IPC. На современном Linux простой chroot — это игрушка, а не изоляция.


FreeBSD jails (2000) и Solaris Zones (2004)

Эти два инструмента были первыми «настоящими» контейнерами в Unix-мире. Они изолировали не только корень FS, но и:

  • Сеть (свой стек или свой IP).
  • Процессы (свой list).
  • Пользователей.

FreeBSD jails до сих пор живёт и используется в FreeBSD-продакшенах. Solaris Zones живёт в illumos-дистрибутивах (SmartOS, OmniOS).

На Linux в это время ничего сопоставимого не было. Только хаки на chroot и редкие проекты вроде Linux-VServer и OpenVZ.


cgroups + namespaces (2006-2008) — два кирпича Docker

В 2006-2008 годах в Linux kernel добавили две вещи, без которых Docker был бы невозможен:

  • cgroups — изначально проект Google для управления ресурсами на их фермах (Borg).
  • namespaces — инкрементально добавлялись разные типы. Mount namespace (2002), UTS (2006), IPC (2006), PID (2008), Network (2008), User (2013), и т.д.

К 2011 году все базовые namespace типы были в mainline kernel. Это и есть тот момент, когда «можно делать контейнеры на Linux».


LXC (2008) — первый Linux container

LXC (Linux Containers) — это набор userspace утилит, которые используют cgroups + namespaces, чтобы запустить полную Linux-систему в контейнере. Не один процесс, а целый дистрибутив.

LXC рабочий, но сложный — конфиг тяжёлый, нет красивого CLI, нет образов в том смысле, в каком они появились в Docker. До сих пор используется в LXD (Canonical), и для системных контейнеров (где нужен полноценный init и набор сервисов).


Docker (2013) — то, что взлетело

Solomon Hykes показал прототип Docker на PyCon 2013. Изначально Docker использовал LXC под капотом, но скоро переписал свой runtime (libcontainer, позже выделенный в runc).

Что сделало Docker популярным:

  1. Image формат. Слои, кеширование, тэги. До этого «образ» — это просто tarball. Docker сделал слоистый формат, который позволяет переиспользовать общие куски.
  2. Docker Hub. Публичный registry, где docker pull nginx работало за пять секунд, и тебе не надо было ничего настраивать. Это был сетевой эффект — все начали публиковать образы.
  3. Простой CLI. docker run, docker build, docker push. Одна команда — один результат.
  4. Dockerfile. Декларативный формат для сборки образа. Намного проще, чем bash-скрипты сборки.

К 2015 году Docker стал стандартом де-факто для контейнеризации.


OCI (2015) — стандарт, чтобы не быть запертыми

К 2015 году стало понятно: Docker — компания, она может развернуться куда угодно. Индустрии нужен открытый стандарт, чтобы не быть зависимыми от одной реализации. Так появился Open Container Initiative (OCI) — консорциум под крылом Linux Foundation.

OCI стандартизировал две вещи:

  • OCI Image Format — формат, в котором лежит образ (манифест, слои, конфиг).
  • OCI Runtime Spec — как должен выглядеть runtime, который запускает контейнер из распакованного образа.

Docker отдал свой runtime (runc) и формат image в OCI. Теперь любая реализация может быть OCI-совместимой: containerd, CRI-O, Podman, gVisor, Kata Containers.


Что такое syscall — физический переход из userspace в kernel

Картина после 2017: «докер» больше не одно

Современный стек: docker CLI -> containerd -> runc -> kernel
docker CLIТо, что ты печатаешь в терминале. Просто HTTP-клиент к Docker daemon
HTTP
dockerdDocker Engine daemon. Управляет образами, сетями, томами. Дальше делегирует containerd
containerdВысокоуровневый runtime. Скачивает образы, распаковывает, управляет жизненным циклом контейнеров. Используется и в Docker, и в Kubernetes
gRPC
runcНизкоуровневый runtime. Делает clone() с флагами namespace, монтирует rootfs, применяет cgroups. Это OCI runtime reference implementation
kernelLinux kernel namespaces + cgroups. Финальная стадия

Когда ты пишешь docker run nginx, на самом деле работает целая цепочка:

  1. docker (CLI) шлёт HTTP-запрос на /var/run/docker.sock к dockerd.
  2. dockerd просит containerd создать контейнер.
  3. containerd через containerd-shim запускает runc.
  4. runc делает clone() с правильными флагами, монтирует rootfs, применяет cgroups, и exec()-ит главный процесс.

Kubernetes пропускает первые два шага — он работает напрямую с containerd (через CRI — Container Runtime Interface). Поэтому в k8s-кластере docker daemon не нужен, нужен только containerd или CRI-O.


Альтернативы Docker сегодня (2026)

  • Podman (Red Hat) — daemonless, rootless по умолчанию. Не нужен root для запуска контейнеров. Совместим с Docker CLI: alias docker=podman часто работает.
  • containerd + nerdctl — то же containerd, что внутри Docker, но с прямым CLI.
  • OrbStack (mac only) — Docker-совместимый рантайм для macOS, который стартует за секунды и потребляет меньше памяти.
  • Rancher Desktop — Docker + k3s в одном пакете, open source.
  • Colima — CLI-only альтернатива Docker Desktop для mac на базе lima (Linux VM).

Все они OCI-совместимы. Образ, собранный через docker build, можно запустить через podman run или nerdctl run — это и есть смысл стандартизации.


Попробуй сам

Если у тебя установлен Docker, посмотри на цепочку процессов:

docker run -d --name demo nginx
ps -ef | grep -E '(dockerd|containerd|runc)' | grep -v grep

Ты увидишь dockerd, containerd, и containerd-shim-runc-v2. Это и есть многослойный стек. Сам процесс nginx будет дочерним от shim’а.

Останови контейнер:

docker rm -f demo

На macOS с OrbStack или Docker Desktop вся эта цепочка крутится в Linux-VM, поэтому ps -ef на хосте покажет только сам клиент. Но внутри VM (доступ через docker run --rm --privileged -it alpine sh + ps) — стек тот же.


Проверка знанийKnowledge check
Что такое OCI и почему его появление в 2015 году важно?
ОтветAnswer
OCI (Open Container Initiative) — это консорциум под крылом Linux Foundation, созданный в 2015 году совместно Docker, Red Hat, Google и CoreOS. Он стандартизировал две вещи: формат container image (OCI Image Format) и интерфейс runtime, который из этого образа запускает контейнер (OCI Runtime Spec). До OCI Docker был де-факто стандартом, но это была одна реализация одной компании — индустрия была заперта в одну экосистему. После OCI любая реализация может быть совместимой: containerd, CRI-O, Podman, gVisor, Kata Containers. Docker отдал свой runc и формат image в OCI как reference implementation. Благодаря этому образ, собранный через docker build, можно запустить через podman run или nerdctl run — это и обеспечивает индустриальную совместимость.

Проверьте понимание

Результат: 0 из 0
Концептуальный
Вопрос 1 из 5. Когда появились cgroups и namespaces в Linux kernel?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 5