Выберите продукт

containerd и nerdctl на VDS: как заменить Docker и Compose и мигрировать без боли

Нужны контейнеры без Docker-демона, но с привычной CLI? Связка containerd + nerdctl совместима с Docker-образами и Compose, упрощает стек и повышает безопасность. Разберём установку на VDS, cgroup v2, rootless, systemd-юниты и миграцию.
containerd и nerdctl на VDS: как заменить Docker и Compose и мигрировать без боли

Если вы используете контейнеры на VDS и хотите упростить стек, уменьшить накладные расходы и усилить безопасность, переход на связку containerd + nerdctl — логичный шаг. containerd — это контейнерный рантайм промышленного уровня (его использует Kubernetes), а nerdctl — совместимая с Docker CLI, которая предоставляет привычные команды вроде run, pull, logs и даже compose. В этой статье покажу, как поднять связку на VDS, включить cgroup v2, настроить rootless-режим, автозапуск через systemd, а также как мигрировать с Docker/Compose без простоя.

Зачем переходить с Docker на containerd + nerdctl

Docker удобен «из коробки»: демоны, CLI, compose, buildx. Но за удобство мы платим избыточной сложностью и зависимостями. containerd — это ядро выполнения контейнеров, без лишних прослоек. Вместе с nerdctl вы получаете:

  • Привычные команды и совместимость с Docker-образами (images, pull/push, run, exec, logs, compose).
  • Меньше движущихся частей и демонов — проще сопровождать на VDS.
  • Нативную поддержку cgroup v2 и интеграцию с systemd (SystemdCgroup=true).
  • Безопасный rootless-режим без привилегий root.
  • Гибкую работу с реестрами (авторизация, зеркала, политики, TLS).

Главная мысль: вы сохраняете привычные воркфлоу и формат образов, но упрощаете базовую платформу. На VDS это означает меньше рисков и меньше накладных расходов.

Подготовка VDS: ядро, cgroup v2, overlay

Для стабильной работы containerd важно включить cgroup v2, иметь overlayfs и актуальное ядро с поддержкой необходимых пространств имён. Проверьте окружение:

uname -r
stat -fc %T /sys/fs/cgroup
lsmod | grep overlay

Идеально, если вывод показывает cgroup2fs и загруженный модуль overlay. Если у вас старая система, включите единое древо групп (для старых релизов):

sudo sed -i 's/GRUB_CMDLINE_LINUX="\(.*\)"/GRUB_CMDLINE_LINUX="\1 systemd.unified_cgroup_hierarchy=1"/' /etc/default/grub
sudo update-grub
sudo reboot

Проверьте сетевой стек (форвардинг и nftables/iptables):

sudo sysctl net.ipv4.ip_forward
sudo sysctl net.ipv6.conf.all.forwarding
sudo iptables -L -n
sudo nft list ruleset

Для большинства случаев хватит стандартной конфигурации ядра современных дистрибутивов (Debian 12, Ubuntu 22.04+, AlmaLinux/Rocky 9). Если overlay не загружается автоматически, добавьте модуль в автозагрузку:

echo overlay | sudo tee /etc/modules-load.d/overlay.conf
sudo modprobe overlay

Установка containerd и nerdctl

В дистрибутивах пакеты containerd и nerdctl есть в репозиториях. На Debian/Ubuntu:

sudo apt update
sudo apt install -y containerd nerdctl runc

На RHEL-совместимых системах:

sudo dnf install -y containerd nerdctl runc

Сгенерируйте и отредактируйте конфиг /etc/containerd/config.toml:

sudo containerd config default | sudo tee /etc/containerd/config.toml
sudo editor /etc/containerd/config.toml

Минимально рекомендую:

  • SystemdCgroup = true в секции [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options].
  • snapshotter = "overlayfs" в [plugins."io.containerd.grpc.v1.cri".containerd].
  • Отключить устаревшие или неиспользуемые плагины по необходимости.

Перезапуск и проверка:

sudo systemctl enable --now containerd
sudo systemctl status containerd
nerdctl info

nerdctl info должен показать доступные snapshotter’ы, поддержку cgroup v2 и информацию о рантайме (runc или crun, если установлен).

Проверка конфигурации containerd и вывод nerdctl info на сервере

Первый запуск: образы, контейнеры, volumes, networks

Стандартные операции эквивалентны Docker:

nerdctl pull nginx:1.27
nerdctl images
nerdctl run -d --name web -p 8080:80 nginx:1.27
nerdctl ps
nerdctl logs -f web
nerdctl exec -it web bash

Директории данных по умолчанию:

  • /var/lib/containerd — данные containerd.
  • /var/lib/nerdctl — namespace’ы, сети, тома, состояние команд nerdctl.

Создаём том и сеть:

nerdctl volume create webdata
nerdctl network create --subnet 10.12.0.0/24 appnet

Примонтируем том и подключим сеть:

nerdctl run -d --name app --network appnet -v webdata:/var/www/html php:8.2-apache

Миграция с Docker: образы, теги, перенос compose

Образы совместимы: можно использовать docker save/docker load или напрямую тянуть из registry. Варианты переноса:

  • Через registry: nerdctl pull нужные теги, затем nerdctl tag и nerdctl push в свой реестр.
  • Файловый экспорт/импорт:
# На старом хосте с Docker
docker save myapp:1.0 | gzip > myapp-1.0.tar.gz

# На новом хосте
zcat myapp-1.0.tar.gz | nerdctl load
nerdctl images | grep myapp

Команды docker run часто можно перевести простым поиском-заменой на nerdctl run. Посмотрите внимательно на:

  • Монтирование томов и права (uid/gid).
  • Сетевые ключи: --network, алиасы, публикация портов.
  • Ограничения ресурсов: --cpus, --memory, --pids-limit, --ulimit.
  • Политику рестартов: --restart=always и т. п.

Перенос docker-compose.yml

nerdctl compose поддерживает привычные сценарии up / down / logs / ps и многое из формата Compose. В простых случаях достаточно выполнить:

cd /srv/myapp
nerdctl compose pull
nerdctl compose up -d
nerdctl compose ps

Обратите внимание на нюансы:

  • Ключи deploy (Swarm) игнорируются.
  • Плагины сетей/томов должны быть поддержаны (в типичных кейсах bridge/host/volume без экзотики — всё работает).
  • Если используете profiles, проверьте совместимость в вашей версии nerdctl.
  • Включите режим SystemdCgroup в containerd, чтобы лимиты CPU/памяти сходились с ожиданиями. О нюансах cgroup и системных слайсов читайте в материале Настройка cgroup через systemd slices.
FastFox VDS
Облачный VDS-сервер в России
Аренда виртуальных серверов с моментальным развертыванием инфраструктуры от 195₽ / мес

Логи и ротация: json-file и journald

По умолчанию nerdctl пишет логи контейнеров в собственные файлы в каталоге состояния. Можно переключить драйвер на journald (если сборка поддерживает), чтобы логи уходили в системный журнал:

nerdctl run -d --name web --log-driver=journald nginx:1.27
journalctl -u containerd --no-pager | tail -n 100
nerdctl logs web | tail -n 100

Для json-файлов используйте ротацию штатными средствами системы (logrotate) либо периодические очистки с учётом ретенции. Учитывайте, что высокочастотные логи на VDS быстро заполняют диск — задайте ретенцию и контроль объёмов.

Интеграция с systemd: автозапуск контейнеров и compose-стека

Базовая автоматизация — использовать --restart у контейнеров. Но для управляемых стэков удобнее отдельный unit, который поднимает и гасит nerdctl compose атомарно.

sudo tee /etc/systemd/system/myapp-compose.service > /dev/null << 'EOF'
[Unit]
Description=MyApp stack via nerdctl compose
After=network-online.target containerd.service
Wants=network-online.target

[Service]
Type=oneshot
WorkingDirectory=/srv/myapp
RemainAfterExit=yes
ExecStart=/usr/bin/nerdctl compose up -d
ExecStop=/usr/bin/nerdctl compose down
TimeoutStartSec=300
TimeoutStopSec=300

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable --now myapp-compose.service
sudo systemctl status myapp-compose.service

Такой unit гарантирует запуск после сети и containerd. Если у вас несколько проектов, создайте отдельные юниты на каждый. Для отдельных контейнеров можно аналогично оформить oneshot-юнит с ExecStart=nerdctl run ... и ExecStop=nerdctl stop. Про готовность сервисов лучше заботиться healthcheck-ами; про рестарты и healthchecks см. материал Перезапуски и проверки живости контейнеров.

Rootless: запуск без root, cgroup v2 и подводные камни

Rootless повышает безопасность: процессы не получают привилегий root на хосте. Требования:

  • cgroup v2, поддержка user namespaces, пакеты newuidmap/newgidmap.
  • Настроенные /etc/subuid и /etc/subgid для пользователя.
  • Сетевой стек для непривилегированных: slirp4netns и при желании rootlesskit.
sudo apt install -y slirp4netns uidmap
id -u
id -g
echo "$(whoami):100000:65536" | sudo tee -a /etc/subuid
echo "$(whoami):100000:65536" | sudo tee -a /etc/subgid

Установите и запустите rootless-containerd от своего пользователя. На многих системах доступна утилита настройки:

containerd-rootless-setuptool.sh install
systemctl --user enable --now containerd.service
loginctl enable-linger $(whoami)

Проверьте:

nerdctl --namespace k8s.io info
nerdctl --namespace default info

В rootless-режиме публикация «низких» портов (<1024) невозможна без дополнительных трюков. Обычно используют порты ≥1024 и проксируют наружу обратным прокси на хосте (например, Nginx) или системой порт-форвардинга на VDS. Сети bridge реализуются через slirp4netns — MTU может отличаться, что иногда влияет на производительность. Для быстрой диагностики сети в rootless проверьте iptables/nft и DNS из контейнера.

Registry: авторизация, зеркала, политики, TLS

С nerdctl вы можете пушить и тянуть образы в любой совместимый реестр. Авторизуйтесь:

nerdctl login registry.example.com
nerdctl push registry.example.com/myproj/myapp:1.0
nerdctl pull registry.example.com/myproj/myapp:1.0

Глобальные настройки зеркал и правил подключения к реестрам делаются через hosts.toml и конфиг containerd. Для конкретного реестра создайте каталог с хост-файлом, например:

sudo mkdir -p /etc/containerd/certs.d/registry.example.com
sudo tee /etc/containerd/certs.d/registry.example.com/hosts.toml > /dev/null << 'EOF'
server = "https://registry.example.com"
[host."https://registry.example.com"]
  capabilities = ["pull", "resolve", "push"]
  skip_verify = false
EOF

sudo systemctl restart containerd

Если у вас внутренний test-реестр с самоподписанным сертификатом, положите доверенные CA в соответствующий каталог и не отключайте проверку без крайней необходимости. Для продакшн-проектов оформляйте валидные SSL-сертификаты, чтобы избежать проблем с цепочкой доверия.

FastFox SSL
Надежные SSL-сертификаты
Мы предлагаем широкий спектр SSL-сертификатов от GlobalSign по самым низким ценам. Поможем с покупкой и установкой SSL бесплатно!

Compose: типовая структура проекта и приёмы

Типичная структура:

/srv/myapp
├── docker-compose.yml
├── .env
├── app
│   └── Dockerfile
└── config

Запуск:

cd /srv/myapp
nerdctl compose build
nerdctl compose up -d
nerdctl compose logs -f --tail=100
nerdctl compose ps

Несколько практических приёмов:

  • Явно задавайте версии образов (pinning), избегайте :latest.
  • Выносите секреты и конфиги в файлы, монтируйте как bind или используйте механизм secrets Compose; детали — в статье Секреты в Compose и их ротация.
  • Сеть назовите уникально, чтобы избежать пересечения с другими проектами на VDS.
  • Используйте depends_on только для порядка запуска, а готовность проверяйте healthcheck-скриптами внутри контейнеров и ретраями клиентов.

Структура проекта Compose и команды nerdctl compose

Ограничения и отличия от Docker

Несмотря на высокую совместимость, есть моменты:

  • Не все возможности Docker Engine воспроизводимы один-в-один (особенно вокруг Swarm/stack, экзотических сетевых плагинов). Для Compose-стека это обычно не критично.
  • На старых системах могут встретиться шероховатости с cgroup v2, CPU/IO лимитами и совместимостью с конкретной версией nerdctl.
  • Некоторые флаги логирования и драйверов в nerdctl отличаются. Проверьте, что вы используете поддерживаемые варианты: json-file и/или journald.
  • Rootless неизбежно накладывает сетевые ограничения и особенности производительности.

Обновления, резервное копирование и перенос

Процедуры обслуживания простые и прозрачные:

  • Обновления образов: nerdctl compose pull, затем nerdctl compose up -d с перезапуском изменившихся сервисов.
  • Бэкапы образов: nerdctl image save и хранение тарболов вместе с lock-файлами сборки.
  • Бэкапы томов: файловая копия каталогов из /var/lib/nerdctl/<ns>/volumes/<name>/_data с остановкой контейнеров или с использованием снапшотов ФС.
  • Перенос на другой VDS: перенесите compose-файлы, .env, образы (pull/save) и содержимое томов, затем поднимите через nerdctl compose up -d.

Диагностика и типичные проблемы

Что проверить в первую очередь:

  • containerd не стартует: смотрим journalctl -u containerd, путь к config.toml, права каталогов /var/lib/containerd.
  • Лимиты ресурсов не применяются: включите SystemdCgroup=true, убедитесь в cgroup v2, проверьте версию runc/crun.
  • Сеть не работает: проверьте nftables/iptables, net.ipv4.ip_forward, конфликты подсетей, DNS в контейнере.
  • Порты заняты: ss -lntp на хосте и в контейнерах, избегайте пересечений публикации портов между стэками.
  • Rootless не пускает на 80/443: публикуйте на 8080/8443 и проксируйте через Nginx на хосте, либо используйте cap_net_bind_service с осторожностью.
  • Compose ругается на опции: проверьте версию nerdctl и соответствие ключей формату, избегайте Swarm-специфичных deploy в простых сценариях.

Безопасность и политика обновлений

Несколько практик для продакшн-стэков на VDS:

  • Ограничивайте capabilities контейнерам (--cap-drop=ALL и точечные добавления).
  • Старайтесь использовать read-only rootfs, монтируйте только нужные каталоги и под нужными uid/gid.
  • Переходите на crun для более быстрой и строгой работы с cgroups (где доступно).
  • Поддерживайте актуальные версии containerd/runc/nerdctl и ядра. Обновляйте базовые образы регулярно.
  • Сканируйте образы на уязвимости до пуша в registry в вашем CI.

Итоги

Связка containerd + nerdctl на VDS даёт лёгкую и предсказуемую платформу для контейнеров с минимальным отрывом от привычного Docker-опыта. С включённым cgroup v2, корректной интеграцией с systemd, поддержкой rootless и compose можно безопасно мигрировать существующие проекты, сократив сложность и повысив управляемость. Начните с тестового стенда, переведите один сервис в продакшн и постепенно выведите целиком стек Docker/Compose на containerd.

Поделиться статьей

Вам будет интересно

Debian/Ubuntu: как исправить stale file handle в NFS OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: как исправить stale file handle в NFS

Ошибка stale file handle в NFS на Debian и Ubuntu обычно появляется после перезагрузки сервера, failover, отката snapshot или пере ...
Debian/Ubuntu: как исправить device or resource busy при mdadm --stop RAID OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: как исправить device or resource busy при mdadm --stop RAID

Ошибка device or resource busy при mdadm --stop в Debian или Ubuntu обычно означает, что RAID-массив всё ещё занят: его держат LVM ...
Debian/Ubuntu: как исправить LVM device is busy при lvremove и vgchange OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: как исправить LVM device is busy при lvremove и vgchange

Если в Debian или Ubuntu команды lvremove, lvchange -an или vgchange -an отвечают device is busy, почти всегда логический том всё ...