Контейнеры дают скорость и плотность, но не отдельное ядро: все процессы на хосте делят один kernel. Для доверенных сервисов этого достаточно, для арендаторов, CI-задач и недоверенного кода — уже нет. Kata Containers закрывает этот разрыв: каждый под или контейнер запускается в лёгкой виртуальной машине со своим ядром, а снаружи остаётся обычным OCI-контейнером, который понимают Docker, containerd и Kubernetes.
Зачем контейнеру виртуальная машина
Граница безопасности у runc проходит по namespaces, seccomp, capabilities и AppArmor или SELinux. Это надёжный, но общий периметр: уязвимость ядра или ошибка в конфигурации одного пода может затронуть соседей. Kata меняет модель — гипервизор изолирует гостя аппаратно, и для выхода за пределы контейнера нужно пробить уже VMM, а не только syscall-фильтр.
Плата предсказуема: память на гостя, долгий холодный старт и меньшая плотность. Поэтому Kata не «лучше» runc вообще, а закрывает конкретный класс задач — мультитенантные платформы и выполнение чужого кода.
Как это работает
Runtime (kata-runtime на Go или runtime-rs на Rust) готовит OCI-спеку и запускает VMM. VMM — QEMU, Cloud Hypervisor, Firecracker или Dragonball — поднимает мини-ВМ с отдельным ядром. Гостевой агент внутри принимает команды по vsock. Обмен файлами идёт через virtio-fs, диски — через virtio-blk, служебные каналы — через virtio-serial.
В Kubernetes цепочка выглядит так: манифест с runtimeClassName, kubelet, CRI-плагин containerd, shim kata-containers, VMM. Приложению достаются те же образы, переменные окружения и тома. Что под действительно в ВМ, показывает версия ядра: снаружи и внутри она разная.
Нужны VT-x или AMD-V, доступ к /dev/kvm и права на него. На вложенных ВМ в облаках KVM часто отключён — проверяйте до установки.
Проверка окружения
Начните с железа и модулей ядра. Если счётчик ниже единицы или /dev/kvm отсутствует, дальнейшая установка бессмысленна.
egrep -c '(vmx|svm)' /proc/cpuinfo
ls -l /dev/kvm
sudo apt install cpu-checker && sudo kvm-ok
grep -E 'CONFIG_KVM=|CONFIG_VHOST=' /boot/config-$(uname -r)
kvm-ok входит в пакет cpu-checker для Debian и Ubuntu; в других дистрибутивах проверьте устройство и права группы kvm. Служба должна иметь доступ к /dev/kvm — иначе появится ошибка «could not access KVM kernel module».
Установка и containerd
Пакеты kata-containers в репозиториях отстают от релизов, поэтому для стенда берут официальный статический архив: внутри ядро, образ гостя и бинарники. Распакуйте его в /opt/kata и подключите конфигурацию.
sudo tar -xJf kata-static-*.tar.xz -C /
sudo mkdir -p /etc/kata-containers
sudo ln -sf /opt/kata/share/defaults/kata-containers/configuration-qemu.toml /etc/kata-containers/configuration.toml
sudo kata-runtime check
Дальше зарегистрируйте рантайм в containerd. Правка /etc/containerd/config.toml добавляет отдельный обработчик kata и не трогает runc по умолчанию: остальные контейнеры продолжат работать как раньше. У runtime-rs путь к конфигурации другой: подкаталог runtime-rs.
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.kata]
runtime_type = "io.containerd.kata.v2"
privileged_without_host_devices = true
pod_annotations = ["io.katacontainers.*"]
После перезапуска службы проверьте рантайм на одном образе. Ключ —runtime принимает имя обработчика, а —rm убирает контейнер после выхода.
sudo systemctl restart containerd
sudo ctr run --runtime io.containerd.kata.v2 --rm docker.io/library/alpine:latest kata-check uname -r
Kubernetes и RuntimeClass
В кластере ставят Helm-чарт kata-deploy: он раскладывает бинарники на узлы и создаёт RuntimeClass. В managed-кластерах проверьте права на привилегированные DaemonSet и /dev/kvm.
export VERSION=$(curl -sSL https://api.github.com/repos/kata-containers/kata-containers/releases/latest | jq -r .tag_name)
helm install kata-deploy oci://ghcr.io/kata-containers/kata-deploy-charts/kata-deploy --version "$VERSION" --namespace kube-system
kubectl -n kube-system rollout status ds/kata-deploy
kubectl get runtimeclass
Дальше достаточно указать класс в поде. Ниже — минимальный запуск и проверка того, что ядро внутри действительно гостевое.
kubectl run kata-test --image=alpine --restart=Never \
--overrides='{"spec":{"runtimeClassName":"kata-qemu"}}' -- sleep 3600
kubectl exec kata-test -- uname -r
uname -r
kubectl get pod kata-test -o jsonpath='{.spec.runtimeClassName}'
Если версии совпали, под ушёл в runc. Причина обычно одна: опечатка в имени класса или kubelet не увидел обновлённый конфиг. В логах kata-deploy видно, какие обработчики зарегистрированы.
Настройка виртуального окружения
Основные параметры лежат в configuration.toml. Для плотных нагрузок уменьшают память и число vCPU, для тяжёлых — наоборот. Значения по умолчанию рассчитаны на совместимость, а не на экономию.
[hypervisor.qemu]
default_vcpus = 2
default_memory = 1024
default_maxvcpus = 8
shared_fs = "virtio-fs"
block_device_driver = "virtio-blk"
Команда kata-runtime env печатает итоговую конфигурацию с путями — так видно, какой файл применился.
Проброс GPU или специфических устройств настраивается отдельно. Не рассчитывайте, что ускорение заработает «из коробки»: проверяйте на одном узле до раскатки.
Диагностика
Сбои выглядят одинаково: под висит в ContainerCreating или падает shim. Порядок разбора такой:
- journalctl -u containerd -f показывает, на каком этапе упал запуск: создание ВМ, монтирование rootfs или старт агента.
- kata-runtime check проверяет KVM, ядро, образ гостя и версии компонентов.
- kata-collect-data.sh собирает конфигурацию, логи и версии в один архив — с ним удобно идти в трекер.
- Ошибка «no space left on device» часто означает не диск, а нехватку места под образы ВМ и снапшоты.
Отдельная категория — несовпадение версий. Shim, runtime и гостевой агент должны быть из одного релиза; после обновления пакетов перезапустите containerd. Для отладки включайте debug на одном узле: логи растут быстро.
Когда оправдано, а когда нет
Kata выигрывает там, где нужно запускать чужой код: CI-раннеры, платформы функций, SaaS с арендаторами, песочницы для анализа файлов. Он уместен, когда аудит требует границы уровня ВМ.
Не стоит тащить его в плотный кластер из сотен мелких сервисов, в среды без KVM и туда, где критичен холодный старт. Альтернативы: gVisor с user-space ядром и усиленный runc с seccomp, user namespaces и read-only rootfs.
Итог
Kata Containers — это способ получить границу виртуальной машины, не меняя контейнерный workflow. Минимальный путь: проверить KVM, распаковать релиз, зарегистрировать обработчик в containerd, поставить RuntimeClass и убедиться, что версия ядра внутри пода отличается от хостовой.
Дальше настройте память и vCPU под свою плотность, включите сбор метрик и держите версии компонентов синхронными. Если /dev/kvm недоступен, решение не взлетит — это проверяют первым.