linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
  • Введение
  • Уроки
  • How it works
  • Симулятор
  • База знаний
  • Собеседование
Index
Categories
All entries
Footer
linuxlab-УчебникиЦеныО платформеКонфиденциальность и куки
Copyright © 2026 LinuxLab. Все права защищены.
home/linux/kb/Контейнеры (бонус)/runc-and-runsc

kb/containers ── Контейнеры (бонус) ── advanced

runc, runsc, kata - container runtimes

runc - стандартный OCI-runtime, namespaces+cgroups+seccomp. runsc/gVisor - userspace-ядро для дополнительной изоляции. kata - облегчённая VM на контейнер. Performance ↔ isolation trade-off.

view as markdownaka: runc, runsc, kata, gvisor, container-runtime, low-level-runtime

Что есть OCI Runtime

Подсистема которая берёт OCI bundle ([[oci-spec|spec]]: config.json + rootfs/) и запускает контейнер. Что именно делает, её решение, главное чтобы соответствовало OCI runtime spec.

Три популярных варианта в 2026:

RuntimeПодходTrade-off
runcnamespaces + cgroups + seccomp в host kernelмаксимум performance, минимум изоляции
runsc (gVisor)userspace-kernel перехватывает syscall'ы~30% slower, гораздо больше isolation
kata-containersкаждый контейнер в lightweight VM~5% overhead, VM-grade isolation
crunальтернатива runc на C, faster startupкак runc по isolation
youkirunc-compatible на Rustкак runc

runc, референс

Создан Docker/OCI как минимальный эталон. Открытый код, в каждом дистро. Под капотом всех общих контейнерных стеков (Docker, containerd, CRI-O, podman), runc или его replacement (crun).

Что делает runc при runc run myctr:

  1. Читает config.json
  2. Создаёт [[namespaces|namespaces]] (PID, NET, MNT, IPC, UTS, USER)
  3. Настраивает [[cgroups|cgroups]] (memory, cpu)
  4. Применяет capabilities dropping (CAP_DROP)
  5. Применяет seccomp profile
  6. Применяет AppArmor/SELinux profile если задан
  7. chroot в rootfs
  8. exec указанной в config команды

Всё это, в host kernel. Контейнер видит host'овое ядро, использует тот же VFS, тот же scheduler. Изоляция, namespaces.

Прямой запуск без Docker:

bash
# Подготовить bundle
mkdir -p mycontainer/rootfs
cd mycontainer
docker export $(docker create alpine) | tar -C rootfs -xf -
runc spec                                  # создаст config.json
# отредактировать config.json под нужды
# Запустить
sudo runc run mycontainer-id
# Управление
runc list
runc kill mycontainer-id KILL
runc delete mycontainer-id

Это уровень "ниже Docker". Используют когда нужно понять, что именно происходит, или для embedded-сценариев.

runc, где он в Docker stack'е

docker / podman
      │
      ▼
containerd (или CRI-O)
      │
      ▼
containerd-shim (один на контейнер, переживает рестарт containerd)
      │
      ▼
runc (запускает init-процесс, потом exit'ит)
      │
      ▼
init процесс контейнера (PID 1 в pid-namespace)

shim нужен чтобы переживать рестарт higher-level менеджеров. runc, короткоживущий, отрабатывает и умирает.

crun, альтернатива на C

Тот же контракт, что runc, но:

  • Написан на C (runc, Go), startup faster
  • Меньше memory footprint
  • Default в podman / RHEL 8+

Полностью drop-in replacement: containerd конфигом можно переключить с runc на crun, всё работает.

Используй когда стартуете много короткоживущих контейнеров (CI, k8s job's, function-as-a-service).

runsc / gVisor, userspace kernel

Концепция: между application syscall и host kernel поставить userspace-kernel (gVisor's "Sentry"), который перехватывает большинство syscall'ов и реализует их сам.

app (внутри контейнера)
      │ syscall
      ▼
Sentry (gVisor userspace-kernel)
      │ ограниченное подмножество host-syscall'ов
      ▼
host kernel

Плюсы:

  • Не привязан к host kernel для большинства syscall'ов эксплойт kernel CVE сложнее
  • Меньше attack surface: ~50 host syscalls вместо ~400
  • Без VM, startup быстрый (доли секунды)

Минусы:

  • Performance hit, 10-50% в зависимости от нагрузки
  • Не все syscalls работают, пограничные сетевые/file features могут не поддерживаться (io_uring, например, частично)
  • Не все workload подходят, БД с iouring или AIO будут страдать

Запуск:

bash
# Установка
curl -fsSL https://gvisor.dev/archive.key | sudo gpg --dearmor ...
apt install runsc
# Регистрация в Docker
cat /etc/docker/daemon.json
{
  "runtimes": {
    "runsc": { "path": "/usr/bin/runsc" }
  }
}
systemctl restart docker
# Использовать
docker run --runtime=runsc -it alpine

Где применяется:

  • Google App Engine / Cloud Run, внутри
  • Untrusted code execution (online code playgrounds)
  • Multi-tenant CI, где шаренный кластер запускает чужой код

kata-containers, VM-based

Каждый контейнер запускается в lightweight VM (через qemu/cloud-hypervisor/firecracker). Плюс:

  • Hardware-grade isolation, VM boundary, не namespace boundary
  • Совместимость почти 100%, внутри VM настоящее Linux-ядро
  • Поддержка GPU passthrough, custom kernels

Минус:

  • Overhead в RAM (~50-200 MB на контейнер для VM)
  • Startup slower, 1-2 сек вместо < 100ms
  • Nested virtualization в облаках бывает запрещена
bash
# k8s через crio, runtimeClass
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
  name: kata
handler: kata
---
apiVersion: v1
kind: Pod
metadata:
  name: secure-pod
spec:
  runtimeClassName: kata
  containers:
  - name: app
    image: myapp:v1

Используется в:

  • AWS Lambda + Firecracker, не Kata, но ту же идею
  • Kata on AKS / Azure Container Instances
  • Confidential containers (CoCo), Kata + AMD SEV / Intel TDX для unencrypted-memory-protection

Сравнение

Признакruncrunsc / gVisorkata-containers
Изоляцияnamespacesuserspace kernelVM
Performance100% (baseline)~70-90%~95%
Memory overhead~few MB~30 MB на Sentry~50-200 MB на VM
Startup~100 ms~150 ms~1-2 sec
Compatibility100%~85%~99%
Use casedefault everywhereuntrusted codemulti-tenant secure
Где defaultDocker, containerd, CRI-O, k8sGoogle Cloud RunOCI confidential

RuntimeClass в k8s

k8s allows multiple runtimes side-by-side:

yaml
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
  name: gvisor
handler: runsc
---
apiVersion: v1
kind: Pod
spec:
  runtimeClassName: gvisor             # этот pod через gVisor
  containers: [...]

Default, пусто (== runc). Опционально можно отдельные namespaces / labels форсить на untrusted-runtime.

Когда что-то пошло не так

  • exec format error, multi-arch image, runtime запускает binary не своей архитектуры. Pull правильный platform.
  • OCI runtime exec failed: exec failed, entrypoint не существует или не executable в rootfs. chmod +x или проверь путь.
  • runsc workload падает с unsupported syscall, runsc --strace или dmesg от gVisor покажет какой; иногда --platform=ptrace fallback (медленнее, шире совместимость).
  • Kata медленно стартует, обычно cold-start cloud-hypervisor. enable_template = true в configuration.toml для prebooted-VM.
  • runc-update не работает на cgroup'ы, на cgroupv1 vs v2 разные пути. Современные runc оба умеют, но containerd может не передавать новый формат.
  • Unknown runtime в Docker, не зарегистрирован в /etc/docker/daemon.json либо systemctl restart docker не сделан.

Альтернативы и связанные

  • firecracker, VMM, не runtime, но Kata может его использовать
  • bubblewrap (bwrap), как runc для Flatpak; не OCI-compatible
  • lxc/lxd, старая, не OCI; больше "system contains" вместо "application contains"
  • systemd-nspawn, встроенная контейнеризация systemd; тоже не OCI

§ команды

bash
runc spec

Сгенерить дефолтный config.json для bundle - точка старта

bash
sudo runc run mycontainer

Запустить из текущей директории (где config.json + rootfs/)

bash
runc list

Все запущенные runc-контейнеры на хосте - debug-tool

bash
docker run --runtime=runsc -it alpine

Запустить через gVisor - изоляция выше, но не все syscalls работают

bash
kubectl describe pod mypod | grep -i runtime

Какой RuntimeClass используется для pod'а в k8s

bash
ctr run --runtime=io.containerd.runsc.v1 docker.io/alpine alpine sh

Прямой запуск в containerd с указанием runtime

bash
runsc --platform=ptrace run mycontainer

Force ptrace-platform - fallback при unsupported KVM или kvm-unfriendly host

§ см. также

  • oci-specOCI spec - стандарт контейнеровOCI - три спеки: Image (слои + manifest), Runtime (config.json + rootfs для runc), Distribution (registry API). Стандарт после Docker'а; runc, podman, containerd, CRI-O - всё OCI-compatible.
  • namespacesLinux namespacesNamespaces - механизм ядра, который даёт процессу собственный изолированный view на ресурс (сеть, mount-points, PID, UID, IPC, hostname, time). На них построены все контейнеры.
  • cgroupscgroups (v2)cgroups v2 - иерархическая виртуальная FS под `/sys/fs/cgroup` через которую ядро лимитирует CPU/память/I/O процессов. Docker/k8s/systemd пишут сюда.
  • seccompseccomp - фильтр системных вызововseccomp - kernel-level фильтр syscall'ов. Процесс декларирует «можно только эти», и kernel отсекает остальные. Основа sandbox'а Docker и Chrome.
  • kubernetes-pod-lifecycleKubernetes pod lifecycle - от Pending до TerminatedPod проходит фазы Pending → Running → Succeeded/Failed/Unknown. Init-containers выполняются последовательно до основных. Probes: startup → readiness/liveness. SIGTERM + grace period при удалении.
  • docker-storage-driversDocker storage drivers - overlay2, btrfs, zfsStorage driver - как Docker хранит image-layers и контейнер-changes на диске. overlay2 default (overlayfs над ext4/xfs), btrfs/zfs через subvolumes/snapshots, fuse-overlayfs для rootless.
  • kubelet-internalskubelet - архитектура агента ноды Kuberneteskubelet - демон на каждой ноде. Получает PodSpec через API, запускает контейнеры через CRI, монтирует volumes через CSI, следит за health. При pressure делает eviction. Image GC и cgroup-tree - тоже его.
Footer
linuxlab-
Copyright © 2026 LinuxLab. Все права защищены.
Учебники
Цены
О платформе
Конфиденциальность и куки