Миграция с Docker на rootless Podman: когда оправдано и как сделать
Я Семёнов Евгений Сергеевич, руковожу АйТи Фреш. На наших 8 серверах Dell Xeon Platinum 8280 в дата-центре МТС Москва крутятся десятки клиентских контейнеров. Последние два года часть продакшн-нагрузки мы переводим с Docker на rootless Podman. Не везде — там, где это даёт реальную выгоду по безопасности и systemd-интеграции. Делюсь опытом миграции: что получилось гладко, а на чём споткнулись.
Зачем вообще менять Docker
У Docker есть одна архитектурная проблема: демон работает от root. Любой пользователь, состоящий в группе docker, фактически получает root-доступ к хосту — может через -v /:/mnt смонтировать файловую систему и писать куда угодно. Для мультитенантных серверов это бесполезный уровень изоляции.
Podman rootless работает иначе:
- Нет демона. Контейнеры — просто процессы пользователя, управляемые через fork/exec.
- Каждый пользователь имеет свой маппинг UID через
/etc/subuidи user namespaces. - Интеграция с systemd из коробки (
systemctl --user, quadlet). - OCI-совместимость — те же образы, что в Docker Hub.
Когда НЕ надо мигрировать
Я всегда предупреждаю клиентов: миграция ради миграции не нужна. Оставляйте Docker, если:
- У вас один сервер, admin = root, и всё работает.
- Используете Docker Swarm для оркестрации (Podman его не умеет).
- Приложение требует сетевых привилегий (VPN, raw-сокеты) — rootless тут ограничен.
- CI/CD завязан на Docker-in-Docker глубоко.
Мигрируйте, если: сервер общий между разработчиками, нужна изоляция, есть требования безопасности по ФСТЭК/ISO, используется RHEL/Rocky 9 (там Podman родной).
Установка Podman
# Rocky Linux 9 / RHEL 9
sudo dnf install -y podman podman-compose
# Ubuntu 24.04
sudo apt install -y podman podman-compose
# Проверка
podman version
podman info | grep -i rootless
Для rootless нужны /etc/subuid и /etc/subgid. В свежих дистрибутивах заводятся автоматически при создании пользователя. Проверить:
grep $USER /etc/subuid /etc/subgid
# Должно быть что-то вроде
# /etc/subuid:operator:100000:65536
Docker → Podman: словарь команд
| Docker | Podman | Комментарий |
|---|---|---|
| docker run | podman run | Совместимо на 99% |
| docker ps | podman ps | Одинаково |
| docker build | podman build | Используется buildah внутри |
| docker-compose up | podman-compose up | Или quadlet-файлы |
| docker network | podman network | Под капотом netavark/CNI |
| docker volume | podman volume | Хранилище в ~/.local/share/containers |
Я всегда делаю в ~/.bashrc:
alias docker=podman
alias docker-compose="podman-compose"
Миграция compose-проекта
Берём существующий docker-compose.yml. Большинство работает без правок. Что часто ломается:
- Порты ниже 1024. Rootless не может слушать 80/443 напрямую. Либо переназначайте на 8080/8443 + ставьте nginx на хосте, либо правьте
sysctl net.ipv4.ip_unprivileged_port_start=80. - Bind-mount с абсолютными путями. Из-за user namespace UID внутри и снаружи могут не совпадать. Проверяйте права.
- privileged-контейнеры. В rootless часть флагов ограничена. Перечитайте, нужен ли реально privileged.
cd /opt/app
podman-compose up -d
podman-compose ps
Quadlet: systemd-юниты для контейнеров
Это моя любимая фича Podman 4.4+. Вместо compose-файла описываете контейнер в systemd-юните *.container, и systemd сам поднимает его при старте.
# ~/.config/containers/systemd/nginx.container
[Unit]
Description=Nginx reverse proxy
After=network-online.target
[Container]
Image=docker.io/library/nginx:1.27-alpine
PublishPort=8080:80
Volume=/home/operator/nginx/conf:/etc/nginx/conf.d:ro,Z
AutoUpdate=registry
[Service]
Restart=always
[Install]
WantedBy=default.target
systemctl --user daemon-reload
systemctl --user start nginx
journalctl --user -u nginx -f
Плюсы: логи в journalctl, автозапуск через loginctl enable-linger, обновление через podman auto-update по расписанию.
Реальный кейс: мониторинговый стек для производственного холдинга
В октябре 2025 года клиент — металлообработка на 180 рабочих местах — пришёл с задачей: «хотим Grafana + Prometheus + Loki, но служба безопасности запрещает запускать сервисы от root». Идеальный кейс для Podman rootless. Мы создали отдельного пользователя monitor, дали ему subuid 100000:65536, развернули 8 контейнеров через quadlet.
Сроки: 2 рабочих дня на развёртывание, 1 день на интеграцию с экспортёрами на 6 серверах клиента. Стоимость — 54 000 руб. Через полгода заказчик отметил: zero инцидентов безопасности с контейнерами, обновления по расписанию через podman auto-update, единый журнал в journalctl.
Сетевые грабли
В rootless сеть отличается от Docker bridge. Используется slirp4netns или pasta для user-mode networking. Следствия:
- Источник соединений снаружи виден как
10.0.2.100, а не реальный IP клиента. Для nginx логов ставьте--network=pasta:--map-guest-addr,169.254.1.2или используйте реверс-прокси на хосте. - Скорость сети в rootless ниже, чем в root-mode (~40% на моих тестах).
- Мульти-хост сеть (overlay) — только через отдельные костыли, штатно нет.
Для высокопроизводительных сервисов (базы, видеостримы) — оставляйте Docker или переходите на rootful Podman.
Миграционный чек-лист
- Инвентаризация контейнеров — что запущено, какие ресурсы, какие порты.
- Тест миграции на одном второстепенном сервисе.
- Установка Podman параллельно Docker, создание пользователя для rootless.
- Адаптация compose: порты, privileged, bind-mounts.
- Переезд образов (
podman pull) и данных (томов). - Запуск через podman-compose или quadlet, тест 3–5 дней в параллель с Docker.
- Отключение Docker-контейнеров, архивация данных.
- Удаление Docker (если больше не нужен).
- Настройка auto-update, бэкапов, мониторинга.
Поможем с переходом на Podman
У нас на практике десятки миграций compose-проектов на rootless Podman. 15+ лет администрирования корпоративных Linux-инфраструктур, 8 серверов Dell Xeon Platinum 8280 с 40G Mellanox в дата-центре МТС Москва для резервного размещения. Аудит вашей инфраструктуры — бесплатно.
Телефон: +7 903 729-62-41
Telegram: @ITfresh_Boss
Семёнов Евгений Сергеевич, директор АйТи Фреш
FAQ — переход с Docker на Podman
- Чем rootless Podman безопаснее Docker?
- Docker-демон запускается от root и эффективно даёт root-доступ всем, кто в группе docker. Podman rootless работает под обычным пользователем с user namespaces — уязвимость в контейнере даёт права пользователя, не root. Нет демона — нет единой точки отказа.
- Podman совместим с Docker CLI?
- Да, alias docker=podman работает для 90% команд: pull, run, ps, exec, logs, build. Отличия — в сетевых командах (podman использует netavark/slirp4netns) и в рабочих каталогах. Скрипты обычно переезжают с минимальными правками.
- Нужен ли podman-compose или лучше сразу quadlet?
- Для быстрой миграции — podman-compose, он читает docker-compose.yml. Для продакшна рекомендую quadlet — systemd-юниты с описанием контейнеров, чистая интеграция с journalctl, автозапуск при перезагрузке.
- Можно ли пробросить порты 80 и 443 в rootless?
- По умолчанию нет — rootless пользователь не имеет права на привилегированные порты. Решения: net.ipv4.ip_unprivileged_port_start=80 в sysctl, setcap, либо reverse proxy (nginx/haproxy) на хосте, а контейнеры слушают 8080/8443.
- Podman поддерживает GPU и CUDA?
- Да, через CDI (Container Device Interface). NVIDIA предоставляет nvidia-container-toolkit с поддержкой Podman. Настраивается чуть сложнее Docker, но работает стабильно на RHEL 9, Rocky 9, Ubuntu 24.04.