OCI Runtime Spec 1.0 и containerd 1.0 RC: стандарт есть, vendor lock-in уходит
OCI Runtime Spec 1.0 и Image Spec 1.0 финализированы. containerd 1.0 RC объявлен стабильным - смотрим что это меняет для production-кластеров без Docker-демона.
OCI Runtime Spec 1.0 и Image Spec 1.0 финализированы; containerd 1.0 RC объявлен стабильным CNCF-проектом
На прошлой неделе OCI (Open Container Initiative) официально выпустила Runtime Spec 1.0 и Image Spec 1.0. Примерно одновременно Docker объявил containerd 1.0 RC стабильным и передал проект в CNCF. Два события которые на первый взгляд кажутся бюрократическими формальностями, но на практике меняют кое-что важное.
Почему вопрос совместимости вообще стоял
До сегодняшнего дня ситуация с образами была такая: Docker-образы де-факто стандарт, но де-юре это формат Docker Inc. Другие runtime - rkt от CoreOS, clearcontainers от Intel - делали что-то своё или пытались быть совместимыми, но без гарантий. Образ собранный одним инструментом мог не запуститься другим, или запуститься но с отличиями в поведении.
OCI Image Spec 1.0 закрывает этот вопрос: теперь есть формальная спецификация формата образа, которая не принадлежит ни одному вендору. Runtime Spec 1.0 описывает как контейнер должен запускаться, что должны делать runc и аналоги. Обе спецификации заморожены - API v1 с обязательством обратной совместимости.
Практически это означает: образ собранный через docker build соответствует OCI Image Spec (Docker уже давно привёл свой формат к черновику спецификации), и его можно запустить через любой OCI-совместимый runtime. Или через containerd напрямую.
Что такое containerd и зачем это нам
containerd - это runtime-демон, который сидит под Docker с версии 1.11. Docker-демон делегирует ему реальную работу с контейнерами: создание, запуск, сеть, хранилище. До недавнего времени containerd был внутренним компонентом Docker-а - API нестабильный, документация для внешних потребителей отсутствовала.
С 1.0 RC containerd становится самостоятельным проектом с публичным gRPC API. Kubernetes теоретически может использовать его напрямую через CRI (Container Runtime Interface), минуя Docker-демон целиком.
Почему это интересно с практической точки зрения:
- Docker-демон делает много лишнего для Kubernetes. Swarm, build API, registry push/pull, volumes через плагины - всё это не нужно Kubernetes, но демон всё равно это тащит. containerd - только то что нужно для запуска контейнеров.
- Меньше компонентов в цепочке - меньше мест где что-то может сломаться. Docker-демон как прослойка между kubelet и containerd добавляет latency и ещё один процесс который нужно мониторить.
- Обновления Docker-демона на production-нодах - всегда небольшой риск и перезапуск. Если runtime меняется реже и имеет более узкий scope, обновления проще.
Где мы сейчас и куда смотрим
Пока что на managed-кластерах у нас везде Docker-демон - ничего не менялось. Переход на containerd напрямую сейчас выглядит как исследовательская задача, не как срочная миграция. CRI-плагин для containerd (cri-containerd) существует, но ещё в alpha. Это не то что хочется катить на production в пятницу.
Тем не менее направление понятно и осмысленное. Мы уже смотрели на это в контексте мultistage builds - там тоже разделение слоёв (build vs runtime) дало конкретный выигрыш. Здесь аналогичная логика: Docker хорош как инструмент разработчика с удобным CLI и богатой экосистемой, но в роли production runtime для Kubernetes он избыточен.
Что финализация спецификации меняет прямо сейчас
Даже без перехода на containerd сам факт стабильной спецификации меняет несколько вещей:
Инструменты сборки. Теперь можно писать инструмент который строит OCI-совместимый образ не вызывая Docker вообще - просто реализуя спецификацию. Это открывает путь к сборке образов без привилегированного демона, что актуально для CI-окружений где Docker-in-Docker это отдельная головная боль.
Выбор runtime без переписывания всего. Если сегодня образы собираются в OCI-формате, смена runtime - это операция на уровне конфигурации кластера, а не переделка пайплайна сборки. Это снимает vendor lock-in не гипотетически, а реально.
runc остаётся общей точкой. И Docker, и containerd используют runc как low-level runtime. Спецификация описывает именно то что делает runc - значит совместимость идёт через общий низкоуровневый слой.
Промежуточный итог
OCI 1.0 - это не революция, это завершение работы которая шла с 2015 года. Но завершение важное: рынок контейнерных runtime теперь соревнуется на стабильном поле, а не на черновике. containerd 1.0 RC с CNCF-статусом - следующий шаг в том же направлении.
Мы продолжаем следить за тем как CRI-интеграция containerd взрослеет - и когда cri-containerd перейдёт из alpha в что-то более твёрдое, посмотрим на пилот на тестовом кластере. Пока - стабилизируем то что есть, читаем спецификации и радуемся что хотя бы формат образа больше не вопрос.