Когда в пятый раз у тебя появляется на работе падаван, которому надо все рассказать по нескольку раз, в какой-то момент приходит в голову светлая мысль все свои речи законспектировать, попутно хоть немного структурировав все это дело. Так что сия заметка о сontainerd для того, чтобы не повторяться в сотый раз. Возможно, кому-то еще это будет интересно, хотя тут все без рокет-сайнс. После скачивания архива из релиза containerd мы получаем набор бинарей: containerd containerd-shim containerd-shim-runc-v1 containerd-shim-runc-v2 crictl ctr Демон containerd по умолчанию использует файловую систему overlayfs для сборки конечного образа из "снапшотов". В терминологии containerd так называют "слои" докер/cri образов. Поэтому стоит проследить чтобы модуль overlay был включен в ядре (modprobe overlay) Дефолтный systemd-unit можно найти в репозитории. Пример конфига containerd, а также здесь есть более подробное описание всей структуры конфига. В частности, описано как настроить insecure registry Kubelet взаимодействует с containerd через сокет, расположение которого указывается через аргумент:  --container-runtime-endpoint=unix:///var/run/containerd/containerd.sock Сontainerd, получив спеки от кубелета, запускает контейнеры через прослойку - containerd-shim, который уже в свою очередь выполняет бинарь рантайма с нужными параметрами. Эталонной реализацией считается runc. В данный момент есть две версии api, которое использует containerd-shim. На данный момент актуальной является v2. (Прошу понять и простить за то, что примеры будут с v1). Подробнее описано здесь. Сontainerd-shim позволяет не привязывать процессы, запущенные в контейнере к демону containerd, что есть весьма хорошо, на случай если вы вдруг решили, например, добавить внезапно "insecure registry" или другой параметр в конфиге и, вследствие этого, понадобилось перезапустить демон containerd. Если посмотреть на список процессов, то можно увидеть что изолированные процессы являются дочерними по отношению к containerd-shim, который в свою очередь выглядит примерно следующим образом:  containerd-shim -namespace k8s.io -workdir /var/lib/containerd/io.containerd.runtime.v1.linux/k8s.io/2d538b1bdc00a5f6251c9f47babca6163794a065133bcd2a0a0264a37a533644 -address /run/containerd/containerd.sock -containerd-binary /usr/bin/containerd -namespace в данному случае - это не тот, немспейс, который в кубе. Это изолированный раздел в рамках самого containerd. Для kubelet'а по умолчанию создается немспейс k8s, но вы можете создать другой, если вдруг нашли оркестратор получше или запускаете что-то руками. -workdir определяет рабочую директорию для процесса, как ни странно. -address и -containerd-binary указывают на сокет и бинарь containerd (а точнее, containerd-shim стучится в аргумент "containerd publish"), для того, чтобы уведомлять о состоянии контейнера в основной демон. Именно из-за этого, в случае рестарта containerd, шимы оперативно сообщат о своем состоянии и вы сможете наблюдать актуальную картину запущенных контейнеров без запуска всего с нуля для приведения к тому состоянию, которое от него требует kubelet. Собственно, запуск контейнеров осуществляется не самим containerd, а через исполняемый файл рантайма, коих в наше время больше, чем кажется. Эталонным в наше время, как уже было отмечено, является runc, который и занимается, собственно, изоляцией или "контейнеризацией". Запускать контейнеры можно и напрямую через него (runc --help), однако при использовании containerd, runc list нам ничего не покажет. Это потому, что директория с информацией о запущенных контейнерах хранится в другом месте, в частности контейнеры бьются на каталоги соответствующие немспейсам containerd, например для куба это:  runc  --root /run/containerd/runc/k8s.io/ list Можете посмотреть состояние какого-нибудь контейнера, например:  root@kube03a:~# runc  --root /run/containerd/runc/k8s.io/ state 2d538b1bdc00a5f6251c9f47babca6163794a065133bcd2a0a0264a37a533644 Но runc, за счет своей низкоуровневости, не самое лучшее место для просмотра состояния контейнеров. Containerd распологает двумя утилитами для взаимодействия пользователя с ним: crictl и ctr. crictl является основной утилитой для взаимодействия с containerd. Помимо аналога действий, присущих docker cli (наподобие create, exec, images и тд), есть и более интересные. К примеру, containerd знает о существовании таких сущностей, как кубовые поды (runp, rmp, pods, stopp, inspectp). Попробую вкратце упомянуть некоторые интересные вещи. Если вдруг containerd демон запущен, а crictl ругается что не может найти его, укажите сокет напрямую, например:  crictl --runtime-endpoint /var/run/containerd/containerd.sock Начнем с info: root@kube03a:~# crictl info 2d538b1bdc00a | jq -r '.status'  crictl inspect и inspectp выведет крайне много интересной информации. Описывать все это бессмыслено, да и все вполне очевидно. Например перечисляются маунты:  crictl inspect 2d538b1bdc00a | jq -r '.info.runtimeSpec.mounts[]'  Или сетевые устройства в поде:  crictl inspectp aae43202632ad | jq -r '.info.cniResult.Interfaces'  Из этого вывода или с помощью команды:  crictl inspectp aae43202632ad | jq -r '.info.runtimeSpec.linux.namespaces'  вы сможете обнаружить имя изолированного сетевого немспейса (это уже совсем-совсем другой немспейс) Вбиваем  ip netns exec cni-6070de8e-4e69-99c0-e619-63535af42ce5 ip a show type veth  и получаем параметры сети в испектируемом поде. Возвращаемся к crictl.   crictl stats -a вернет нам табличку с потребляемыми ресурсами (cpu, disk, mem, inodes), а флаг -o json вернет нам все еще и в json виде, на случай если вы вдруг что-то мониторите. К слову, crictl imagefsinfo вернет вам что-то вроде:  Еще мы можем, например, посмотреть на процесс внутри контейнера:  root@kube03a:~# cat "/proc/$(crictl inspect 2d538b1bdc00a  | jq -r '.info.pid')/cmdline"  ...вернет: nginx: master process nginx -g daemon off; А в корневой каталог попасть через /proc/$PID/root/  root@kube03a:~# cat "/proc/$(crictl inspect 2d538b1bdc00a  | jq -r '.info.pid')/root/etc/hostname"  nginx-7848d4b86f-xztfp  Мы видим что все, что было в inpect в списке для монтирования, на этом этапе уже на своем месте. Можем еще получить, например, id контейнера:  сrictl inspect 2d538b1bdc00a  | jq -r '.status.id'  2d538b1bdc00a5f6251c9f47babca6163794a065133bcd2a0a0264a37a533644 Через этот id мы можем найти каталог с его конфигами:  root@kube03a:~# ls /var/run/containerd/io.containerd.runtime.v1.linux/k8s.io/$(crictl inspect 2d538b1bdc00a  | jq -r '.status.id')  address  config.json  init.pid  log.json  rootfs  shim.pid init.pid содержит уже известный нам pid процесса в контейнере, а shim.pid - pid родительского containerd-shim. В каталоге rootfs содержится собранный из снапшотов (слоев) overlayfs запущенного контейнера, но без дополнительных монтирований. Если посмотреть на cgroups, то тут есть два варианта, в зависимости от выбранного драйвера cgroups. Если выбран драйвер systemd, то путь в cgroups_v1 будет примерно следующий:  root@kube03a:~# cat /sys/fs/cgroup/pids/system.slice/containerd.service/kubepods-besteffort-pod$(crictl inspectp aae43202632ad | jq -r '.status.metadata.uid' | sed  's/-/_/g').slice:cri-containerd:$(crictl inspect 2d538b1bdc00a  | jq -r '.status.id')/cgroup.procs по человечески:  cat /sys/fs/cgroup/pids/system.slice/containerd.service/kubepods-besteffort-podc7205bb2_8c97_4f79_b4c9_915e402cc7d3.slice:cri-containerd:2d538b1bdc00a5f6251c9f47babca6163794a065133bcd2a0a0264a37a533644/cgroup.procs crictl inspectp aae43202632ad | jq -r '.status.metadata.uid' - вернет нам uid пода, а crictl inspect 2d538b1bdc00a  | jq -r '.status.id' - уже известный нам id контейнера. По аналогии можно обратиться к другим cgroups директориям. Если же у вас драйвером выбран cgroups:  cat /sys/fs/cgroup/pids/kubepods/pod7d5e31f8-8797-457d-aaf2-f55464d338c6/eb2c3ad61742de7ed7a8758cc563a1470b969632f857429787668e1f354e357a/cgroup.procs В реалтайме вы можете посмотреть cgroups через systemd-cgtop -m. Тут ведь все любят systemd, так? Дошли наконец-таки до ctr  Для начала можно посмотреть доступные встроенные плагины.  ctr plugins ls - здесь можно посмотреть доступные снапшоттеры, которые составляют из слоев докер-образа конечный образ. Есть поддержа ZFS и BTRFS. Далее смотрим доступные немспейсы containerd:  ctr namespaces ls По умолчанию доступен немспейс "k8s.io". В дальнейших командах необходимо его явно указать: ctr --namespace=k8s.io containers ls  Так же можно посмотреть images (образы), events (отлов событий), content (бинарные данные из образов), snapshots (слои из образов), leases (аренда каких-либо ресурсов, подробней ), tasks (запущенные в контейнерах процессы). Из необычного, вы можете взаимодействовать напрямую с shim или установить бинари и библиотеки из образа через crt install (это, видимо, для особо прогрессивных). Напоследок ссылка на описание запуска контейнера через crictl для дебага. DevOps инженер