CRI-O — альтернатива Docker для запуска контейнеров в Kubernetes



    Многие DevOps-инженеры и системные администраторы, особенно успевшие поработать с Kubernetes, уже слышали про проект CRI-O, озаглавленный как «легковесная исполняемая среда для контейнеров в Kubernetes». Однако зачастую представления о его назначении, возможностях и статусе весьма размыты — из-за молодости проекта, отсутствия опыта практического применения и растущего числа изменений в области стандартов для контейнеров. Эта статья — ликбез о CRI-O, рассказывающая о появлении проекта, его особенностях и актуальном статусе.

    История появления


    Следуя за растущей популярностью применения Linux-контейнеров, в середине 2015 года некоммерческая организация The Linux Foundation при содействии CoreOS, Docker, Red Hat и ряда других компаний представила проект Open Container Project, который ныне известен как Open Container Initiative (OCI). Его цель — «создание открытых индустриальных стандартов для форматов и исполняемой среды контейнеров».



    Предполагалось, что проект объединит базу конкурирующих продуктов для контейнеров, таких как runc от Docker и appc от CoreOS, в единые стандарты. Актуальным же итогом деятельности OCI стал выпуск минувшим летом версии 1.0 для двух стандартов:

    • для исполняемой среды контейнеров (Runtime Specification, runtime-spec) — определяет, как запускается «комплект файловой системы» (filesystem bundle) с содержимым контейнера (эталонная реализация — тот самый runc);
    • для формата образов контейнеров (Image Specification, image-spec) — определяет формат, из которого образ контейнера будет распакован в filesystem bundle (для дальнейшего запуска).

    В то же самое время и независимо от Open Container Initiative, но «с акцентом на продвижение стандартов для контейнеров через OCI», компания Red Hat занялась созданием OCID (Open Container Initiative Daemon), поместив его в инкубатор проекта Kubernetes и анонсировав в сентябре 2016 года.

    В рамках OCID инженеры Red Hat собирались развивать инновации в области контейнеров: исполняемой среды, распространения образов, хранилища, их подписи и т.п. При этом проект позиционировался как «не конкурирующий с Docker», потому что «в действительности он использует ту же исполняемую среду OCI runc, что применяется в Docker Engine, тот же формат образов и позволяет использовать docker build и относящиеся к нему инструменты».

    Уже тогда OCID назывался «реализацией стандартного интерфейса для исполняемой среды для контейнеров в Kubernetes», в котором следуют философии UNIX, когда одна утилита выполняет одну задачу. Поэтому функциональность OCID была сразу разбита по следующим компонентам:

    • OCI Container Runtime Environment (runc);
    • OCI Runtime Tools (развиваемый в OCI набор утилит для работы с runtime-spec);
    • containers/image (набор библиотек на языке Go для работы с образами контейнеров и реестрами — эти возможности также доступны через консольную утилиту skopeo, созданную в Red Hat для Project Atomic);
    • containers/storage (библиотека на Go, предоставляющая методы для хранения слоёв файловой системы, образов контейнеров и самих контейнеров; включает в себя обёртку с консольным интерфейсом);
    • CNI (Container Network Interface) (спецификация и библиотеки для управления сетевыми интерфейсами в контейнерах — подробнее о CNI мы писали в этой статье).

    Однако название «OCID», напрямую ссылающееся на инициативу OCI, не получило одобрения в самой Open Container Initiative, поскольку к списку официальных проектов OCID не относился. И уже вскоре после первого анонса, по требованию OCI, проект получил новое название — CRI-O («CRI» расшифровывается как «Container Runtime Interface»).

    По существу можно сделать вывод, что OCI стала необходимой предтечей для CRI-O, а в Red Hat воспользовались трендом стандартизации, способствуя ему с одной стороны и преследуя свои цели (низкоуровневый стек для Project Atomic и OpenShift) — с другой. Сообщество Linux и Open Source от этого скорее только выиграло, получив конкуренцию и разнообразие среди свободных продуктов, да и в OCI подчеркнули, что их недовольство было связано исключительно с названием проекта, но не самим его назначением:

    «Open Container Initiative (OCI) сосредоточена на создании формальной спецификации для исполняемой среды и формата образов контейнеров, поскольку стандартизация в этих областях будет способствовать и другим инновациям. Любые другие проекты на данный момент выходят за рамки OCI, однако мы поощряем своих участников, продолжающих работу над спецификацией для исполняемой среды и формата образов, поскольку это полезно для всей индустрии. Инновации быстро происходят на уровне реализации, и мы намерены интегрировать все уместные улучшения в спецификации. Наша цель — поддерживать эффективный рост и здоровье технологии контейнеров и всего сообщества Open Source».

    По сей день Red Hat продолжает продвигать CRI-O в мире ИТ-специалистов, примером чему может служить недавняя (июнь 2017 г.) публикация «6 причин, почему CRI-O — лучшая исполняемая среда для Kubernetes» в блоге Project Atomic. В качестве таких причин авторы называют:

    1. Открытая схема управления проектом и его развитие в рамках сообщества «родительского» Kubernetes.
    2. «По-настоящему открытый проект», что подтверждается приятным комментарием от инженера из Intel:

      … а также активностью контрибьюторов, переносом некоторых улучшений в кодовую базу самого Kubernetes.
    3. Минимальная кодовая база (доступная для простого аудита и достаточно надёжная), остальные компоненты к которой подключаются от других проектов.
    4. Стабильность, достигаемая благодаря полной ориентированности на Kubernetes, использованию upstream-тестов из K8s (node-e2e и e2e) перед принятием патчей (если релиз CRI-O ломает что-то в K8s, он блокируется), а также своих интеграционных тестов.
    5. Безопасность, т.к. в нём доступны все необходимые для Kubernetes функции вроде SELinux, Apparmor, seccomp, capabilities.
    6. Использование стандартизированных компонентов, т.к. проект следует спецификациям OCI.

    Другой пример технологического евангелизма в этом направлении — совсем свежий (сентябрь 2017 г.) доклад «Понимая стандарты для контейнеров» (видео, слайды) в исполнении Scott McCarty из Red Hat:



    Но вернёмся к технологической составляющей CRI-O. Как же устроен этот проект?

    Архитектура и особенности CRI-O


    На сегодня, благодаря усилиям Red Hat, Intel, SUSE, Hyper и IBM (все они числятся среди основных компаний-разработчиков CRI-O), мы получили альтернативу Docker для Kubernetes, позволяющую запускать поды с использованием любой исполняемой среды для контейнеров, совместимой со спецификацией OCI. Официально при этом поддерживаются всем известная runc, а также Clear Containers от Intel (являются частью более глобального проекта Clear Linux; в прошлом месяце выпустили их версию 3.0, переписанную на Go).

    Компоненты CRI-O практически не изменились со времён анонса OCID: помимо исполняемой среды (совместимой с OCI) это прежние OCI Runtime Tools, containers/storage, containers/image, CNI, а также новая небольшая утилита conmon, предназначенная для мониторинга контейнеров (включая обнаружение ошибок нехватки памяти — OOM) и обработки журналирования из процесса контейнера.

    Общая же архитектура CRI-O и его место в Kubernetes представляется следующим образом:



    Принцип функционирования Kubernetes в связке с CRI-O сводится к следующей схеме:

    • Kubernetes обращается к kubelet для запуска пода, а kubelet перенаправляет этот запрос к демону CRI-O через интерфейс Kubernetes CRI.
    • CRI-O с помощью библиотеки containers/image забирает образ из реестра.
    • CRI-O с помощью библиотеки containers/storage распаковывает загруженный образ в корневую файловую систему контейнера (хранимую в COW).
    • Создав rootfs для контейнера, CRI-O с помощью утилиты generate из OCI Runtime Tools готовит JSON-файл, соответствующий спецификации OCI runtime и содержащий описание, как запустить контейнер.
    • CRI-O запускает исполняемую среду (например, runc) с использованием созданной спецификации.
    • Контейнер попадает в поле зрения мониторинга, осуществляемого с помощью утилиты conmon (отдельный процесс в системе), которая также обслуживает логирование для контейнера и записывает код завершения процесса контейнера.
    • Сеть для пода настраивается с помощью любого из плагинов CNI.

    Статус


    Последний публичный релиз CRI-O — 1.0.0-rc3, выпущенный на прошлой неделе. Среди его изменений выделяются поддержка Minikube (для запуска CRI-O с локальным кластером Kubernetes), лимиты для размера лога контейнера, поддержка квоты для overlay, возможность запуска на файловых системах на базе tmpfs. Его анонс завершается фразой, что «теперь мы близки к выпуску 1.0, как только количество багов уменьшится». Обновлено: 16 октября, через 3 дня после публикации этой статьи, состоялся релиз CRI-O v1.0.0, который официально предназначен для работы с Kubernetes 1.7, а в скором времени ожидается обновление (RC1 следующей версии) для K8s 1.8.

    Релиз Kubernetes 1.8, который состоялся в конце сентября, «повысил» статус поддержки CRI-O до стабильного, поскольку были пройдены все тесты e2e.

    Для перевода вашей инсталляции Kubernetes с Docker на CRI-O потребуется:

    1. Установить и настроить CRI-O (/etc/crio/crio.conf, /etc/containers/policy.json и т.п.; сам сервис запускается как системная служба — рекомендуется в связке с systemd) на каждом узле, где осуществляется миграция.
    2. Исправить требования службы kubelet в systemd (/etc/systemd/system/kubelet.service) и настроить её параметры (/etc/kubernetes/kubelet.env).
    3. Подготовить плагин CNI.
    4. Запустить сервис crio и перезапустить kubelet.

    Более подробную инструкцию можно найти здесь.

    cri-containerd


    Напоследок, полезно будет упомянуть и параллельную активность со стороны компании Docker под названием cri-containerd. Это ещё одна Open Source-реализация уже упомянутого интерфейса Kubernetes CRI для тех, кто выбрал containerd в качестве единственной исполняемой среды для контейнеров (вместе с теми же runc и CNI для решения соответствующих задач). Имея статус альфа-версии, cri-containerd поддерживает Kubernetes 1.7+, прошёл все тесты на валидацию с CRI и все тесты node e2e.

    На недавнем выступлении Liu Lantao (Google) и Abhinandan Prativadi (Docker) было объявлено, что бета-версию этого решения ожидают к концу года (слайды доклада):



    P.S.


    А в завершении такой статьи не могу не привести замечательную цитату Kelsey Hightower‏, хорошо известного в DevOps-сообществе как минимум благодаря «Kubernetes The Hard Way»:

    cri-o, containerd, rkt или docker? С нетерпением жду дня, когда ответом будет: «Всё равно».

    Читайте также в нашем блоге:

    Флант 244,31
    Специалисты по DevOps и высоким нагрузкам в вебе
    Поделиться публикацией
    Комментарии 10
    • +3
      Так и не смог понять какие преимущества дают cri-o и cri-containerd перед уже существующей реализацией. Просто стандартизация и нативная интеграция с kubernetes?
      • +1
        Насколько я понимаю, люди просто хотят выкинуть докер, т.к. он тащит своё полиси и это мешает альтернативной оркестрации.
        • 0

          Все лучше — модульность, надежность, стабильность, разработчики, поддержка крупных компаний.
          В принципе, те работал с докером на крупных инсталляциях не задают вопрос зачем, а спрашивают когда?

          • 0
            Это не аргументы, а маркетинговый булшит.
        • +1
          to: fear86
          С точки зрения Kubernetes — Docker по умолчанию несет в себе много ненужного, например встроенный инструментарий swarm или автоматическое конфигурирование правил iptables.
          Когда выходит новая версия docker, совершенно не факт что Kubernetes будет нормально с ней работать.

          В случае же с CRI-O это будет отдельный компонент, отвечающий только за контейнирезацию. Больше не нужно будет думать что разработчики Docker изменят в следующем релизе, что поломает текущее взаимодействие с Kubernetes.
          • 0
            Ну мне и раньше не нужно было думать о «что разработчики Docker изменят в следующем релизе», это проблемы kubernetes девелоперов. В общем они хотят облегчить себе жизнь и избавится от 3rd party софта. В этом конечно есть смысл.
            • 0
              Я имел ввиду девелоперы Kubernetes вынуждены говорить вам при установке: «вы должны использовать Docker не старше такой-то версии»
              А вы в свою очередь имеете шанс столкнуться с некоторыми проблемами если не запретите Docker рулить iptables, т.к. этим уже занимается Kubernetes.
              • 0
                Это все должно было быть в статье, что бы не приходилось вытягивать все клещами.
                • 0
                  Всё это по сути проистекает из фактического vendor lock-in в случае Docker (пусть оно даже при этом и Open Source…), который устраняется переходом на проект с открытой политикой управления (open governance) и модульностью by design, о чём в статье написано.
          • 0
            Вышел CRI-O v1.0.0 (обновил в тексте статьи).

            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

            Самое читаемое