Введение#
В статье про Podman я подробно разбирал, почему Podman в моём homelab заменил Docker: daemonless-архитектура, полноценный rootless-режим из коробки, нативная интеграция с systemd через Quadlet. Всё это так, и я по-прежнему считаю, что у Podman много преимуществ для того, чтобы считать переход оправданным. Но было бы нечестно рассказывать только о преимуществах и умалчивать о том, с чем реально приходится мириться. Да и в комментариях у меня в тг-канале мне прямо указали, что я не рассказываю о недостатках Podman.
У Podman есть вполне конкретные недостатки - часть из них следствие тех же архитектурных решений, которые в других сценариях становятся плюсами. В этой статье я постараюсь описать недостатки, которые на практике доставляют более чем серьезные неудобства: от особенностей rootless-сети до менее зрелой экосистемы вокруг проекта.
Rootless режим - не только плюсы#
Rootless-режим - главная фишка Podman, но у него есть обратная сторона, и знать о ней стоит до того, как вы с ней столкнётесь.
Порты ниже 1024#
Непривилегированный процесс в Linux не может слушать порты ниже 1024 - это ограничение ядра, а не Podman, но именно rootless-контейнеры с ним и сталкиваются в первую очередь. Опубликовать PublishPort=80:80 из rootless-контейнера напрямую не получится: нужно либо вносить изменения в net.ipv4.ip_unprivileged_port_start через sysctl, либо ставить reverse-proxy на непривилегированном порту повыше и пробрасывать его дальше средствами хоста. При этом надо учитывать, что весь мир ждёт веб-сервер или обратный прокси на порту 80 и 443. Смысла разрешать публиковать порты ниже 1024 вроде как нелогично, это же фишка Podman. Я решил это переносом своего обратного прокси в отдельный LXC контейнер, тем самым отвязав его от любого бекэнда в принципе. Однако такой вариант не всем подходит по разным причинам.
Аналога Docker Swarm у Podman не существует#
Если вы всё ещё используете Swarm-режим (или планировали) - в rootless Podman его просто нет, и не предвидится. Это осознанное архитектурное решение, так что рассчитывать на него не стоит в принципе. Хотя, правды ради, лично я считаю, что у Docker Swarm всё равно нет будущего.
Права на bind-mount и UID-маппинг#
Rootless-контейнеры используют user namespaces: UID 0 внутри контейнера превращается в непривилегированный UID снаружи через subuid/subgid. Звучит элегантно, пока дело не доходит до bind-mount’ов существующих директорий с хоста. Файлы, созданные процессом внутри контейнера, на хосте принадлежат совершенно “инопланетному” UID из диапазона subuid, и обычный chown/chmod руками превращается в отдельное испытание, которое не для слабых духом.
Для этого существует podman unshare, который пускает вас в те же namespace’ы, что видит контейнер - но это ещё одна команда, которую нужно знать и объяснять новичкам, тогда как в Docker (особенно при работе от root) такой проблемы почти никогда не возникает.
Есть и более системный обход: флаг --userns=keep-id мапит UID 0 внутри контейнера не на случайный subuid, а на тот же UID, под которым вы залогинены на хосте, - тогда файлы на bind-mount’ах создаются с привычным владельцем без плясок с podman unshare.
В свежих версиях Podman то же самое можно получить точечно, на уровне одного volume, суффиксом :U - Podman сам сделает chown содержимого при монтировании. Но сделано это именно для упрощения обхода ограничений. Тебе не надо учить какие-то новые команды, но тем не менее, ты “обходишь” ограничения технологии, что придаёт некий налёт нелогичности происходящего.
Требования файловой системы к rootless-overlay#
Отдельная, менее очевидная проблема - rootless-overlay для хранилища образов требует от файловой системы поддержки d_type (то есть тип файла должен возвращаться прямо в записи каталога, без отдельного stat()). Без d_type rootless-overlay просто не поднимется - Podman откатится на vfs, который работает надёжно, но заметно медленнее и имеет более жесткие требования к месту на диске, так как не может использовать слои между образами так эффективно, как overlay. На практике для домашнего сервера с обычным ext4/XFS (XFS - в случае, если ты адепт Red Hat) d_type есть из коробки, и это редко становится проблемой, но на некоторых сетевых ФС вроде NFS или при переносе на какое-нибудь экзотическое хранилище об этом стоит помнить.
Неполная совместимость с Docker Compose#
Сам Podman CLI действительно почти что называется zero-effort совместим с Docker CLI. Я об этом рассказывал ещё в первой статье. А вот с Docker Compose всё не так гладко, как хотелось бы.
podman-compose - это отдельный, независимый от самого Podman проект, а не встроенный аналог docker compose.
Участники проекта честно предупреждают в своём README, что цель - запускать docker-compose.yml без изменений, но на практике так получается не всегда (в моем случае никогда):
- у сервисов, подключённых сразу к нескольким пользовательским сетям в одном compose-файле, DNS-резолвинг по имени сервиса не всегда стабильно работает из соседних сетей, к которым сервис был подключён не первым;
external: trueдля уже существующей сети иногда не распознаётся корректно, потому чтоpodman-composeпо умолчанию добавляет префикс имени проекта к имени сети - и, если имена не совпадают буквально, вместо переиспользования существующей сети получаем попытку создать новую;- имена контейнеров и сетей, которые генерирует
podman-compose, по умолчанию используют другой разделитель (_вместо принятого в новых версиях Docker Compose-) - для части автоматизации и скриптов, которые парсят имена контейнеров, это может сломать логику, хотя разработчики уже добавили отдельный флаг совместимости; - не все версии
docker-compose.yml(в частности сложные healthcheck-конструкции, depends_on с условиями, некоторые профили) поддерживаются идентично - часть фич работает “почти так же”, часть требует правок в самом compose-файле, а часть просто придется удалить.
Формально можно перейти на нативный Quadlet+Podlet, о которых я писал в отдельной статье, и это действительно снимает большинство проблем (причем это самый правильный способ использования Podman) - но это уже не “тот же самый docker-compose.yml без изменений”, а миграция на другой формат конфигурации. Если у вас в проекте десятки готовых compose-файлов из чужих репозиториев (а в self-hosting так всегда), надо быть готовым к тому, что нужны точечные правки.
На macOS и Windows Podman - тоже виртуальная машина#
Один из главных аргументов в пользу Podman - отсутствие демона. Но это верно только для Linux. На macOS и Windows контейнеры в принципе не могут работать нативно (другое ядро), и что Docker Desktop, что podman machine решают эту проблему одинаково - поднимают лёгкую Linux-VM и уже внутри неё запускают настоящий Podman.
То есть на macOS и Windows daemonless-преимущество отсутствует: у вас снова есть фоновый процесс (просто в этом случае это сама VM), которую нужно запускать, следить за её ресурсами и обновлять образ этой VM отдельно от самого Podman.
Причём есть и еще один мелкий нюанс. Фоновый процесс не один - на хосте параллельно с VM крутится ещё и gvproxy, который через SSH-туннель прокидывает сетевой доступ и Docker-совместимый сокет внутрь машины, так что “просто VM” на практике - это VM плюс обвязка вокруг неё.
Для homelab, где сервер обычно на Linux, это не критично - но если у вас прод, и часть команды работает на маках, часть на Винде, то разница с Docker Desktop по факту куда меньше, чем кажется из маркетинговых сравнений.
Нет встроенной оркестрации на несколько хостов#
Podman отлично закрывает задачи одного хоста - это, что называется, by design. Но если тебе завтра понадобится:
- горизонтальное масштабирование сервиса под нагрузкой;
- HA-кластер из нескольких физических узлов;
- service discovery между узлами “из коробки”;
то готового решения у Podman нет. Генерация Kubernetes-манифестов через podman generate kube облегчает миграцию, но сама миграция всё равно означает разворачивание полноценного Kubernetes (k3s, MicroK8s, RKE2 - не суть) со всеми сопутствующими прелестями: etcd или его аналог, control-plane, CNI-плагины.
Docker Swarm при всех своих недостатках хотя бы предлагает в меру простое родное решение по переходу от одного хоста к нескольким - у Podman такой “промежуточной ступеньки” нет вообще и не будет в обозримом будущем.
Экосистема и набор инструментов Podman пока догоняют Docker#
Технически Podman вроде достаточно зрелый проект, но по охвату экосистемы Docker всё ещё намного впереди, и это всегда ощущается на практике:
- GUI. Podman Desktop активно развивается и уже вполне пригоден для повседневной работы, но по количеству встроенных расширений, готовых интеграций и просто “вылизанности” интерфейса Docker Desktop далеко его обогнал;
- Готовые туториалы. Абсолютное большинство инструкций для self-hosted проектов в интернете по умолчанию написаны под
docker run/docker-compose up. Работать с ними приходится либо черезalias docker=podman(что может помочь в 90% случаев, но все-таки), либо вручную адаптировать под rootless-специфику - Volume-лейблы:Z/:zдля SELinux-систем, например, в оригинальных доках почти никогда не упоминаются, хотя, с моей точки зрения, такое упоминание обязательно. Не все в курсе особенностей SELinux; - Инструменты, которые жёстко завязаны на
docker.sock. Часть популярных self-hosted утилит (некоторые дашборды, отдельные CI-раннеры, кое-какие мониторинговые агенты) исторически обращаются напрямую к Docker socket и его API-шке. Podman предоставляет Docker-совместимый REST API черезpodman system service, но решение не идеальное, не всё в нём работает как надо, и для нишевых инструментов иногда приходится или искать форк с поддержкой Podman, или оставлять этот конкретный сервис на Docker; - Docker Hub vs реестры Red Hat. Сам Podman по умолчанию не привязан к одному реестру и это скорее плюс, но новичков первое время путает необходимость явно указывать полный путь до образа в реестре (
docker.io/library/nginxвместо простоnginx), если вregistries.confне настроены unqualified-search реестры так, как вам нужно. А на дистрибутивах, не связанных с Red Hat, их прописывать надо. Причем, в реальной жизни, - это даже наверно первая проблема, с которой столкнётся каждый, просто по логике статьи указываю её в конце.
Более высокий порог входа для новичков#
Отдельно стоит сказать про ментальную модель, как любят говорить за рубежом. Docker долгие годы был синонимом контейнеризации именно потому, что скрывал сложные решения под простой оболочкой: один демон, одна команда docker run, и всё “просто работает” (как требует большинство новичков) от root, без необходимости разбираться в user namespaces и прочей семиотике. Podman требует намного большего понимания происходящего под капотом и принципов работы системы:
- что такое subuid/subgid и что произойдёт, если диапазоны не настроены или пересекаются между пользователями;
- разница между rootless и rootful режимом и когда переключаться на второй оправданно;
- SELinux-лейблы на volume’ах в Fedora/RHEL-семействе, без которых контейнер просто так не увидит примонтированную директорию;
- cgroups v2 и то, как Podman себя ведёт на системах, где он ещё не включён по умолчанию.
Для человека, который уже не раз настраивал/перестраивал homelab-инфраструктуру и не боится читать man, это не проблема, а скорее естественная часть процесса. Но если ваша цель - просто побыстрее поднять сервис и не тратить несколько уютных вечеров на чтение документации, с последующим вырыванием волос на голове и бросанием их в монитор, то первое знакомство с Podman может ощущаться заметно более болезненным, чем с Docker.
Когда эти недостатки действительно важны#
Подытоживая всё вместе, я бы выделил три ситуации, где минусы Podman перевешивают его архитектурные плюсы:
- нужна оркестрация на несколько хостов здесь и сейчас, а не в перспективе - тогда либо Docker Swarm как временное решение, либо сразу переходить на Kubernetes;
- у тебя инфраструктура, которая завязана исключительно на инструменты, строго требующие доступа к
docker.sock, и альтернатив под Podman нет; - команда разработчиков работает преимущественно на macOS/Windows (а это наверно самый частый случай и лучший пример), а избавиться от VM-прослойки, переходя с Docker Desktop, не получится.
Во всех остальных сценариях - а для homelab и self-hosted серверов на Linux это подавляющее большинство случаев - недостатки скорее про “нужно один раз разобраться и настроить”, чем про “категорически не подходит”.
Выводы#
Ни один из перечисленных пунктов не отменяет того, что я писал в первой статье про преимущества Podman. Но недостатки у него более чем реальные, а не надуманные, как порой пишут в интернете при обсуждении того или иного решения:
- rootless-сеть иногда ограничивает больше, чем хотелось бы;
- совместимость с Docker Compose неполная;
- экосистема вокруг проекта пока в роли догоняющего Docker, как по охвату инструментов, так и инструкций.
Если вы планируете переход, разумный подход - не переписывать сразу всю инфраструктуру, а мигрировать по одному не самому критичному сервису за раз, как я и советовал в прошлый раз, и заранее закладывать время на то, чтобы упереться в один-два пункта из списка проблем настоящей статьи. Это не повод отказываться от Podman - это повод не разочаровываться, когда что-то пойдёт не так с первого раза. А это “не так” обязательно произойдёт.
Полезные ссылки:





