CRI-O — container runtime, разработанный специально как runtime для Kubernetes. Реализует Kubernetes CRI (Container Runtime Interface) — стандартный API для взаимодействия kubelet с runtime. В отличие от Docker как runtime, CRI-O не имеет CLI, daemon с socket-ом для разработчиков или утилит сборки образов — только запуск контейнеров по запросу Kubernetes.
Как работает
Kubelet (агент Kubernetes на каждой ноде) общается с CRI-O через gRPC. CRI-O получает запрос запустить Pod, скачивает образ из Registry, создаёт OCI-бандл и передаёт его низкоуровневому runtime: runc (по умолчанию) или crun. runc создаёт контейнер через системные вызовы ядра (namespaces, cgroups).
Стек: kubelet → CRI-O → runc → Linux kernel. Docker использовал более длинную цепочку: kubelet → dockershim → Docker daemon → containerd → runc. Kubernetes 1.24 (2022) удалил dockershim, сделав прямую поддержку Docker устаревшей.
CRI-O автоматически подбирает версию образа, совместимую с версией Kubernetes. Поддерживает OCI Image Spec — образы Docker Hub работают без конвертации.
История
CRI-O анонсирован Red Hat в 2016 году под названием ocid (OCI Daemon). Переименован в CRI-O перед релизом 1.0 в 2017 году. В 2019 году передан CNCF как incubating-проект. Kubernetes 1.24 (май 2022) удалил встроенную поддержку Docker через dockershim — CRI-O и containerd стали основными runtime. В AlmaLinux/OpenShift используется CRI-O как runtime по умолчанию.
CRI-O: настройка и интеграция с Kubernetes
CRI-O настраивается через /etc/crio/crio.conf: параметры storage (overlay2 в большинстве случаев), network (CNI плагины в /opt/cni/bin), image pull policy, log level. Хранилище образов: /var/lib/containers/storage (Containers/Storage из проекта containers.org — общая библиотека для CRI-O, Podman, Buildah). Логи контейнеров: /var/log/pods/
Отличия CRI-O от containerd: CRI-O разработан специально для Kubernetes, не имеет API для прямого использования (только CRI). containerd — более универсальный runtime с nerdctl CLI. В Kubernetes 1.24+ оба runtime полностью поддерживаются. Red Hat OpenShift использует CRI-O как стандартный runtime. RHEL/CentOS/AlmaLinux: CRI-O устанавливается из пакетов cri-o, работает стабильно на этих дистрибутивах. Диагностика: crictl ps (список контейнеров), crictl logs
Жизненный цикл контейнера в CRI-O
Kubernetes kubelet взаимодействует с CRI-O через gRPC API (CRI spec). При создании Pod: kubelet отправляет RunPodSandbox → CRI-O создаёт network namespace и настраивает CNI → PullImage → CreateContainer → StartContainer. При удалении: StopContainer → RemoveContainer → StopPodSandbox → RemovePodSandbox. Sandbox — изолированная среда для Pod с собственным network namespace, shared между всеми контейнерами в Pod.
На что обращать внимание
CRI-O не имеет CLI для ручного управления контейнерами — вместо него используют crictl (единый CLI для всех CRI-совместимых runtime). Для разработки и локальной отладки Docker удобнее: docker exec, docker logs, docker build работают привычно. CRI-O vs containerd (от Docker): оба являются CRI-совместимыми runtime, containerd имеет более широкую экосистему (использует Docker Desktop), CRI-O минималистичнее и оптимизирован под Kubernetes.
CRI-O vs containerd
Kubernetes поддерживает несколько container runtimes через CRI: CRI-O и containerd — основные. Docker использовал dockershim (удалён в K8s 1.24). CRI-O — легковеснее containerd: меньше потребление памяти, фокус исключительно на CRI. containerd — более универсален, используется и вне K8s. На AlmaLinux и RHEL-совместимых дистрибутивах CRI-O поставляется через официальные репозитории. Podы управляются одинаково независимо от runtime. Docker registry совместим с CRI-O — образы хранятся в OCI-формате.