Прим. перев.: Мы написали уже не одну публикацию (см. ссылки в конце статьи) об исполняемых средах контейнеров (container runtimes) — речь в них, как правило, идёт в контексте Kubernetes. Однако зачастую эти материалы вызывали у читателей вопросы, свидетельствующие о недостаточном понимании, откуда взялся очередной проект, как он связан с другими и что вообще происходит во всём этом контейнерном «зоопарке».
Недавняя статья от технического директора подразделения IBM Watson & Cloud Platform по стратегии в области контейнеров и архитектуры Linux — Phil Estes — предлагает отличную ретроспективу и помогает сориентироваться, получить более обширное понимание тем, кто потерял (или так и не уловил) нить событий. Будучи одним из мейнтейнеров проекта Moby и containerd, членом технических комитетов Open Container Initiative (OCI) и Moby, а также обладая статусом Docker Captain, автор пишет о прошлом, настоящем и будущем нового дивного мира container runtimes. И для самых ленивых материал начинается с компактного TL;DR по теме…
В мире операционной системы Linux уже довольно долго существовала технология контейнеризации — первые идеи о раздельных пространствах имён для файловых систем и процессов появились уже более десятилетия назад. А в относительно недавнем прошлом появился LXC и стал стандартным для пользователей Linux способом взаимодействовать с мощной технологией изоляции, спрятанной в ядре Linux.
Однако, даже несмотря на попытки LXC спрятать сложность объединения различных технологических «внутренностей» того, что мы сегодня обычно называем контейнером, контейнеры оставались некой магией и укрепились лишь в мире особо сведущих, так и не получив широкого распространения в массах.
Всё изменилось в 2014 году с Docker, когда появилась новая, дружелюбная к разработчикам, обёртка той же самой технологии ядра Linux, что была на вооружении у LXC — ведь на самом деле ранние версии Docker «за кулисами» использовали LXC, — и контейнеры стали по-настоящему массовым явлением, поскольку разработчики прониклись простотой и возможностями повторного использования образов Docker-контейнеров и простыми командами для работы с ними.
Конечно, Docker не был единственным, кто хотел заполучить долю на рынке контейнеров, когда сопровождающая их шумиха и не думала затихать после первого взрывного интереса в 2014 году. За прошедшие годы появились разнообразные альтернативные идеи для исполняемых сред контейнеров от CoreOS (rkt), Intel Clear Containers, hyper.sh (легковесная виртуализация на базе контейнеров), а также Singularity и shifter в мире научных исследований в области высокопроизводительных вычислений (HPC).
Рынок продолжал расти и взрослеть, и с Open Container Initiative (OCI) пришли попытки стандартизации изначальных идей, продвигаемых Docker. На сегодняшний день многие исполняемые среды контейнеров или уже совместимы с OCI, или на пути к этому, предлагая производителям равные условия по продвижению их фич и возможностей, ориентированных на особое применение.
Следующим этапом эволюции контейнеров было объединение с контейнерами распределённых вычислений а-ля микросервисы — и всё это в новом мире быстрой разработки и итераций деплоя (можем сказать, что DevOps), который активно набирал обороты вместе с популярностью Docker.
Хотя до получения Kubernetes'ом доминирующей позиции существовал и Apache Mesos, и другие платформы для оркестровки программного обеспечения, стремительный взлёт провёл K8s от небольшого Open Source-проекта из Google до главного проекта организации Cloud Native Computing Foundation (CNCF).
Прим. перев.: Знаете ли вы, что CNCF появилась в 2015 году по случаю релиза Kubernetes 1.0? В этот же момент проект был передан компанией Google в новую независимую организацию, ставшую частью The Linux Foundation.
Мероприятие по случаю выпуска K8s 1.0, которое, в числе прочих, спонсировали Mesosphere, CoreOS, Mirantis, OpenStack, Bitnami
Из новости про релиз Kubernetes 1.0 на ZDNet
Даже после того, как Docker выпустил конкурирующую платформу для оркестровки — Swarm, — встроенную в Docker и обладающую простотой в стиле Docker и фокусом на безопасной по умолчанию конфигурации кластера, этого уже не было достаточно для того, чтобы остановить растущий интерес к Kubernetes.
Однако многие заинтересованные стороны вне набравших быструю популярность облачных (cloud native) сообществ были сбиты с толку. Рядовой наблюдатель не мог разобраться, что же происходит: борьба Kubernetes с Docker или их сотрудничество? Поскольку Kubernetes был лишь платформой для оркестровки, требовалась исполняемая среда контейнеров, которая бы выполняла непосредственный запуск контейнеров, оркестрируемых в Kubernetes. С самого начала Kubernetes использовал движок Docker и, даже несмотря на конкурентную напряженность между Swarm и Kubernetes, Docker всё ещё оставался runtime'ом по умолчанию и требовался для функционирования кластера Kubernetes.
С небольшим числом исполняемых сред контейнеров, отличных от Docker, казалось ясным, что сопряжение runtime'а с Kubernetes потребует специально написанного интерфейса — shim — для каждой из исполняемых сред. Отсутствие понятного интерфейса для реализации исполняемых сред контейнеров очень усложняло добавление поддержки новых runtime'ов в Kubernetes.
Чтобы решить проблему растущей сложности внедрения runtime'ов в Kubernetes, сообщество определило интерфейс — конкретные функции, которые исполняемая среда контейнеров должна реализовывать в рамках Kubernetes, — назвав его Container Runtime Interface (CRI) (он появился в Kubernetes 1.5 — прим. перев.). Это событие не только помогло проблеме разрастающегося числа фрагментов кодовой базы Kubernetes, затрагивающих применение исполняемых сред контейнеров, но и способствовало пониманию, какие именно функции должны поддерживаться потенциальными runtime'ами, если они хотят соответствовать CRI.
Как легко догадаться, CRI ожидает от исполняемой среды весьма простых вещей. Такая среда должна быть способна запускать и останавливать поды, обрабатывать все операции с контейнерами в контексте подов (запуск, остановка, пауза, kill, удаление), а также поддерживать управление образами контейнеров с помощью реестра. Предусмотрены также вспомогательные функции для сбора логов, метрик и т.п.
Когда новые фичи появляются в Kubernetes, если они зависят от прослойки исполняемой среды контейнеров, то такие изменения вносятся в версионный CRI API. Это в свою очередь создаёт новую функциональную зависимость от Kubernetes и требует выпуска очередных версий runtime'ов, поддерживающих новые возможности (один из недавних примеров — user namespaces).
По состоянию на 2018 год существует несколько опций для использования в качестве исполняемых сред контейнеров в Kubernetes. Как показано на иллюстрации ниже, одним из реальных вариантов по-прежнему остаётся Docker с его dockershim, реализующим CRI API. И на самом деле в большинстве сегодняшних инсталляций Kubernetes именно он, Docker, остаётся исполняемой средой по умолчанию.
Одним из интересных следствий напряжённости между стратегией Docker по оркестровке со Swarm и сообществом Kubernetes стал совместный проект, взявший из Docker основу runtime'а и собравший из неё новый, разрабатываемый совместно, Open Source-проект — containerd. Со временем containerd был передан в CNCF — ту же самую организацию, что управляет и владеет проектом Kubernetes. (Прим. перев.: Более подробно появление containerd мы описывали в отдельной статье.)
Из анонса containerd в блоге Docker
Containerd, будучи простой, базовой и независимой от взглядов конкретной компании (un-opinionated) реализацией runtime'а и для Docker, и для Kubernetes (через CRI), стал набирать популярность как потенциальная замена для Docker во множестве инсталляций Kubernetes. На сегодняшний день у IBM Cloud и Google Cloud кластеры на базе containerd находятся в раннем доступе/бета-режиме. В Microsoft Azure тоже пообещали перейти на containerd в будущем, а Amazon всё ещё рассматривает различные варианты runtime'ов для своих контейнерных решений (ECS и EKS), пока что продолжая использовать Docker.
Red Hat пришла в пространство исполняемых сред контейнеров, создав простую реализацию CRI, названную cri-o, на базе эталонной реализации OCI — runc. Docker и containerd тоже основаны на runc, однако создатели cri-o утверждают, что их runtime'а «просто достаточно» для Kubernetes и большего не требуется — они лишь добавили самые необходимые для реализации Kubernetes CRI функции поверх базового бинарника runc. (Прим. перев.: Подробнее о проекте CRI-O мы писали в этой статье, а про его дальнейшее развитие в виде podman — здесь.)
Проекты легковесной виртуализации: Intel Clear Containers и hyper.sh — появились в дебрях OpenStack Foundation, контейнерах Kata, и предлагают своё видение виртуализированных контейнеров для дополнительной изоляции, используя реализацию CRI под названием frakti. И cri-o, и containerd тоже работают с контейнерами Kata, так что их совместимый с OCI runtime может быть выбран в качестве подключаемой опции.
Говорить, что знаешь будущее, обычно не очень-то и мудро, но мы можем хотя бы зафиксировать некоторые появляющиеся тренды по мере того, как экосистема контейнеров движется от повального восторга и хайпа к более зрелому этапу своего существования.
Были ранние опасения насчёт того, что экосистема контейнеров сформирует раздробленную среду, разные участники которой придут к отличающимся и несовместимым идеям о том, что же такое контейнер. Благодаря работе OCI и ответственным действиям главных вендоров и участников, мы увидели здоровую обстановку в индустрии среди предложений в области программного обеспечения, отдающих предпочтение совместимости с OCI.
Даже в более новых окружениях, где стандарт использования Docker встретил меньше сопротивления из-за существующих ограничений — например, в HPC, — все попытки создать исполняемые среды контейнеров не на базе Docker тоже обратили внимание на OCI. Ведутся дискуссии и о том, может ли OCI быть жизнеспособным решением для специфичных нужд сообществ учёных и исследователей.
Добавив к этому стандартизацию подключаемых исполняемых сред контейнеров в Kubernetes с помощью CRI, мы можем представить мир, в котором разработчики и администраторы могут выбирать подходящие для своих задач инструменты и стеки ПО, ожидая и наблюдая интероперабельность во всей экосистеме контейнеров.
Рассмотрим конкретный пример, чтобы лучше понять этот мир:
Весь описанный сценарий прекрасно работает благодаря совместимости по спецификации OCI для исполняемых сред и образов и тому факту, что CRI предоставляет гибкость в выборе runtime'а.
Эта возможная гибкость и право выбора делает экосистему контейнеров по-настоящему замечательной, а также является очень важным условием для зрелости индустрии, которая так стремительно выросла с 2014 года. На пороге 2019 года и следующих лет я вижу светлое будущее с продолжающимися инновациями и гибкостью для тех, кто использует и создаёт платформы на базе контейнеров.
Дополнительную информацию по этой теме можно найти в недавнем выступлении Phil Estes на QCon NY: «CRI Runtimes Deep Dive: Who's Running My Kubernetes Pod!?»
Читайте также в нашем блоге:
Недавняя статья от технического директора подразделения IBM Watson & Cloud Platform по стратегии в области контейнеров и архитектуры Linux — Phil Estes — предлагает отличную ретроспективу и помогает сориентироваться, получить более обширное понимание тем, кто потерял (или так и не уловил) нить событий. Будучи одним из мейнтейнеров проекта Moby и containerd, членом технических комитетов Open Container Initiative (OCI) и Moby, а также обладая статусом Docker Captain, автор пишет о прошлом, настоящем и будущем нового дивного мира container runtimes. И для самых ленивых материал начинается с компактного TL;DR по теме…
Основные выводы
- С течением времени выбор среди исполняемых сред контейнеров рос, предоставляя всё больше вариантов, чем популярный движок Docker.
- Инициатива Open Container Initiative (OCI) успешно стандартизовала концепцию контейнера и контейнерного образа с тем, чтобы гарантировать интероперабельность («способность к взаимодействию» — прим. перев.) между исполняемыми средами.
- В Kubernetes добавили интерфейс Container Runtime Interface (CRI), позволяющий подключаться исполняемым средам контейнером к нижележащей прослойке оркестровки в K8s.
- Инновации в этой области позволяют контейнерам использовать легковесную виртуализацию и другие уникальные техники изоляции для растущих требований к безопасности.
- С OCI и CRI интероперабельность и выбор стали реальностью в экосистеме исполняемых сред контейнеров и оркестровки.
В мире операционной системы Linux уже довольно долго существовала технология контейнеризации — первые идеи о раздельных пространствах имён для файловых систем и процессов появились уже более десятилетия назад. А в относительно недавнем прошлом появился LXC и стал стандартным для пользователей Linux способом взаимодействовать с мощной технологией изоляции, спрятанной в ядре Linux.
Однако, даже несмотря на попытки LXC спрятать сложность объединения различных технологических «внутренностей» того, что мы сегодня обычно называем контейнером, контейнеры оставались некой магией и укрепились лишь в мире особо сведущих, так и не получив широкого распространения в массах.
Всё изменилось в 2014 году с Docker, когда появилась новая, дружелюбная к разработчикам, обёртка той же самой технологии ядра Linux, что была на вооружении у LXC — ведь на самом деле ранние версии Docker «за кулисами» использовали LXC, — и контейнеры стали по-настоящему массовым явлением, поскольку разработчики прониклись простотой и возможностями повторного использования образов Docker-контейнеров и простыми командами для работы с ними.
Конечно, Docker не был единственным, кто хотел заполучить долю на рынке контейнеров, когда сопровождающая их шумиха и не думала затихать после первого взрывного интереса в 2014 году. За прошедшие годы появились разнообразные альтернативные идеи для исполняемых сред контейнеров от CoreOS (rkt), Intel Clear Containers, hyper.sh (легковесная виртуализация на базе контейнеров), а также Singularity и shifter в мире научных исследований в области высокопроизводительных вычислений (HPC).
Рынок продолжал расти и взрослеть, и с Open Container Initiative (OCI) пришли попытки стандартизации изначальных идей, продвигаемых Docker. На сегодняшний день многие исполняемые среды контейнеров или уже совместимы с OCI, или на пути к этому, предлагая производителям равные условия по продвижению их фич и возможностей, ориентированных на особое применение.
Популярность Kubernetes
Следующим этапом эволюции контейнеров было объединение с контейнерами распределённых вычислений а-ля микросервисы — и всё это в новом мире быстрой разработки и итераций деплоя (можем сказать, что DevOps), который активно набирал обороты вместе с популярностью Docker.
Хотя до получения Kubernetes'ом доминирующей позиции существовал и Apache Mesos, и другие платформы для оркестровки программного обеспечения, стремительный взлёт провёл K8s от небольшого Open Source-проекта из Google до главного проекта организации Cloud Native Computing Foundation (CNCF).
Прим. перев.: Знаете ли вы, что CNCF появилась в 2015 году по случаю релиза Kubernetes 1.0? В этот же момент проект был передан компанией Google в новую независимую организацию, ставшую частью The Linux Foundation.
Мероприятие по случаю выпуска K8s 1.0, которое, в числе прочих, спонсировали Mesosphere, CoreOS, Mirantis, OpenStack, Bitnami
Из новости про релиз Kubernetes 1.0 на ZDNet
Даже после того, как Docker выпустил конкурирующую платформу для оркестровки — Swarm, — встроенную в Docker и обладающую простотой в стиле Docker и фокусом на безопасной по умолчанию конфигурации кластера, этого уже не было достаточно для того, чтобы остановить растущий интерес к Kubernetes.
Однако многие заинтересованные стороны вне набравших быструю популярность облачных (cloud native) сообществ были сбиты с толку. Рядовой наблюдатель не мог разобраться, что же происходит: борьба Kubernetes с Docker или их сотрудничество? Поскольку Kubernetes был лишь платформой для оркестровки, требовалась исполняемая среда контейнеров, которая бы выполняла непосредственный запуск контейнеров, оркестрируемых в Kubernetes. С самого начала Kubernetes использовал движок Docker и, даже несмотря на конкурентную напряженность между Swarm и Kubernetes, Docker всё ещё оставался runtime'ом по умолчанию и требовался для функционирования кластера Kubernetes.
С небольшим числом исполняемых сред контейнеров, отличных от Docker, казалось ясным, что сопряжение runtime'а с Kubernetes потребует специально написанного интерфейса — shim — для каждой из исполняемых сред. Отсутствие понятного интерфейса для реализации исполняемых сред контейнеров очень усложняло добавление поддержки новых runtime'ов в Kubernetes.
Container Runtime Interface (CRI)
Чтобы решить проблему растущей сложности внедрения runtime'ов в Kubernetes, сообщество определило интерфейс — конкретные функции, которые исполняемая среда контейнеров должна реализовывать в рамках Kubernetes, — назвав его Container Runtime Interface (CRI) (он появился в Kubernetes 1.5 — прим. перев.). Это событие не только помогло проблеме разрастающегося числа фрагментов кодовой базы Kubernetes, затрагивающих применение исполняемых сред контейнеров, но и способствовало пониманию, какие именно функции должны поддерживаться потенциальными runtime'ами, если они хотят соответствовать CRI.
Как легко догадаться, CRI ожидает от исполняемой среды весьма простых вещей. Такая среда должна быть способна запускать и останавливать поды, обрабатывать все операции с контейнерами в контексте подов (запуск, остановка, пауза, kill, удаление), а также поддерживать управление образами контейнеров с помощью реестра. Предусмотрены также вспомогательные функции для сбора логов, метрик и т.п.
Когда новые фичи появляются в Kubernetes, если они зависят от прослойки исполняемой среды контейнеров, то такие изменения вносятся в версионный CRI API. Это в свою очередь создаёт новую функциональную зависимость от Kubernetes и требует выпуска очередных версий runtime'ов, поддерживающих новые возможности (один из недавних примеров — user namespaces).
Нынешний ландшафт CRI
По состоянию на 2018 год существует несколько опций для использования в качестве исполняемых сред контейнеров в Kubernetes. Как показано на иллюстрации ниже, одним из реальных вариантов по-прежнему остаётся Docker с его dockershim, реализующим CRI API. И на самом деле в большинстве сегодняшних инсталляций Kubernetes именно он, Docker, остаётся исполняемой средой по умолчанию.
Одним из интересных следствий напряжённости между стратегией Docker по оркестровке со Swarm и сообществом Kubernetes стал совместный проект, взявший из Docker основу runtime'а и собравший из неё новый, разрабатываемый совместно, Open Source-проект — containerd. Со временем containerd был передан в CNCF — ту же самую организацию, что управляет и владеет проектом Kubernetes. (Прим. перев.: Более подробно появление containerd мы описывали в отдельной статье.)
Из анонса containerd в блоге Docker
Containerd, будучи простой, базовой и независимой от взглядов конкретной компании (un-opinionated) реализацией runtime'а и для Docker, и для Kubernetes (через CRI), стал набирать популярность как потенциальная замена для Docker во множестве инсталляций Kubernetes. На сегодняшний день у IBM Cloud и Google Cloud кластеры на базе containerd находятся в раннем доступе/бета-режиме. В Microsoft Azure тоже пообещали перейти на containerd в будущем, а Amazon всё ещё рассматривает различные варианты runtime'ов для своих контейнерных решений (ECS и EKS), пока что продолжая использовать Docker.
Red Hat пришла в пространство исполняемых сред контейнеров, создав простую реализацию CRI, названную cri-o, на базе эталонной реализации OCI — runc. Docker и containerd тоже основаны на runc, однако создатели cri-o утверждают, что их runtime'а «просто достаточно» для Kubernetes и большего не требуется — они лишь добавили самые необходимые для реализации Kubernetes CRI функции поверх базового бинарника runc. (Прим. перев.: Подробнее о проекте CRI-O мы писали в этой статье, а про его дальнейшее развитие в виде podman — здесь.)
Проекты легковесной виртуализации: Intel Clear Containers и hyper.sh — появились в дебрях OpenStack Foundation, контейнерах Kata, и предлагают своё видение виртуализированных контейнеров для дополнительной изоляции, используя реализацию CRI под названием frakti. И cri-o, и containerd тоже работают с контейнерами Kata, так что их совместимый с OCI runtime может быть выбран в качестве подключаемой опции.
Предсказывая будущее
Говорить, что знаешь будущее, обычно не очень-то и мудро, но мы можем хотя бы зафиксировать некоторые появляющиеся тренды по мере того, как экосистема контейнеров движется от повального восторга и хайпа к более зрелому этапу своего существования.
Были ранние опасения насчёт того, что экосистема контейнеров сформирует раздробленную среду, разные участники которой придут к отличающимся и несовместимым идеям о том, что же такое контейнер. Благодаря работе OCI и ответственным действиям главных вендоров и участников, мы увидели здоровую обстановку в индустрии среди предложений в области программного обеспечения, отдающих предпочтение совместимости с OCI.
Даже в более новых окружениях, где стандарт использования Docker встретил меньше сопротивления из-за существующих ограничений — например, в HPC, — все попытки создать исполняемые среды контейнеров не на базе Docker тоже обратили внимание на OCI. Ведутся дискуссии и о том, может ли OCI быть жизнеспособным решением для специфичных нужд сообществ учёных и исследователей.
Добавив к этому стандартизацию подключаемых исполняемых сред контейнеров в Kubernetes с помощью CRI, мы можем представить мир, в котором разработчики и администраторы могут выбирать подходящие для своих задач инструменты и стеки ПО, ожидая и наблюдая интероперабельность во всей экосистеме контейнеров.
Рассмотрим конкретный пример, чтобы лучше понять этот мир:
- Разработчик с MacBook использует Docker for Mac для разработки своего приложения и даже пользуется встроенной поддержкой Kubernetes (Docker здесь работает как CRI runtime), чтобы попробовать деплой нового приложения на подах K8s.
- Приложение проходит через CI/CD в софте вендора, который использует runc и специальный (написанный вендором) код для упаковки OCI-образа и загрузки его в корпоративный реестр контейнеров для тестирования.
- Собственная (on-premises) инсталляция кластера Kubernetes, работающая с containerd в качестве CRI runtime, запускает набор тестов для приложения.
- Эта компания по каким-то причинам выбрала контейнеры Kata для определённых рабочих нагрузок в production, поэтому при деплое приложения оно запускается в подах с containerd, настроенных на использование контейнеров Kata в качестве runtime вместо runc.
Весь описанный сценарий прекрасно работает благодаря совместимости по спецификации OCI для исполняемых сред и образов и тому факту, что CRI предоставляет гибкость в выборе runtime'а.
Эта возможная гибкость и право выбора делает экосистему контейнеров по-настоящему замечательной, а также является очень важным условием для зрелости индустрии, которая так стремительно выросла с 2014 года. На пороге 2019 года и следующих лет я вижу светлое будущее с продолжающимися инновациями и гибкостью для тех, кто использует и создаёт платформы на базе контейнеров.
Дополнительную информацию по этой теме можно найти в недавнем выступлении Phil Estes на QCon NY: «CRI Runtimes Deep Dive: Who's Running My Kubernetes Pod!?»
P.S. от переводчика
Читайте также в нашем блоге: