[Перевод] От Podman до продакшена: сборка доверенных контейнерных образов с Konflux
Это перевод моей собственной статьи с dev.to: From Podman to Production: Building Trusted Container Images with Konflux.
Я работаю в Red Hat Senior SRE в команде Konflux Infra. Мы отвечаем за инфраструктуру вокруг Konflux CI,‑ системы сборки, которую развивает Red Hat. За кластеры, на которых он живёт, за Terraform под ними, за бэкапы и аварийное восстановление, за выкатку новых версий. За всю ту обвязку, которая обязана просто работать, чтобы команды, собирающие на Konflux свои продукты, о ней вообще не вспоминали.
Сам Konflux, пожалуй, стоит представить отдельно, потому что за пределами Red Hat о нём пока мало кто слышал. Это открытая Kubernetes‑native система сборки. Kubernetes‑native в самом буквальном смысле: пайплайны здесь — это кастомные ресурсы, которые лежат в кластере и выполняются как поды, и никакого отдельного сервера сборки рядом не стоит. От обычного раннера пайплайнов его отличает то, что он построен вокруг безопасности цепочки поставок. Сборка идёт с отключённой сетью, образы подписываются, на выходе появляются SBOM и провенанс SLSA, а перед релизом стоит гейт, который решает, можно ли вообще выпускать то, что получилось. Ничего из этого включать не надо. Это поведение по умолчанию.
Но вот в чём штука. Эксплуатировать инфраструктуру под инструментом и пользоваться самим инструментом, это две разные вещи. Konflux я неплохо знал со стороны самой инфраструктуры и куда хуже,‑ со стороны человека ('end‑user'), которому просто надо выкатить контейнерный образ. Поэтому я решил собрать что‑нибудь сам, от начала до конца, как это сделал бы любой пользователь. В основном чтобы наконец разобраться.
В июне 2026 года я выступал на DevConf.CZ в городе Брно (Чехия) с докладом «From Podman to Production», как раз про это. Идея простая: взять один Containerfile, собрать его дважды, сначала локально через podman, потом через Konflux CI, и посмотреть, что можно получить в каждом из результатов.
Всё держится на одном правиле, которое я повторял во время своего выступления: Containerfile не меняется. Ни одной строчки. Меняется всё вокруг него.

Демо приложение
Хотелось запустить чго‑то более интересное и интерактивное, чем 'hello world', поэтому демо, это небольшое Flask‑приложение, которое ходит в Pretalx, систему расписания DevConf.CZ. Оно вытаскивает настоящее расписание конференции: сколько всего докладов, разбивку по типам сессий, список залов.
Ещё у него есть эндпоинт /api/self, который ищет в расписании тот самый доклад, который я в этот момент читал. То есть прямо во время выступления приложение находило само себя в системе конференции.

Акт 1: сборка, которую все и так знают
Вот сам Containerfile. Ничего хитрого.
FROM registry.fedoraproject.org/fedora:44
RUN dnf install -y python3-pip && dnf clean all
COPY app/ /opt/app/
RUN pip3 install -r /opt/app/requirements.txt
EXPOSE 8080
CMD ["python3", "/opt/app/main.py"]
podman build -t devconf-api:latest .
podman run -p 8080:8080 devconf-api:latest
curl -4 localhost:8080/api/stats
Всего три команды, и у вас работающий API, отдающий живые данные конференции.

Podman работает без рута и без демона, нативно по OCI. Для внутреннего цикла разработки лучше и не придумаешь: быстрая обратная связь, никакой инфраструктуры, не надо ждать очереди.
И для разработки это нормально. Проблемы начинаются, когда вас просят это задеплоить.
Что вы не можете доказать
Представьте Security Review для этого образа. Можете доказать, из какого коммита он собран? Нет. Подписан он? Нет. Есть SBOM со списком всех зависимостей внутри? Нет. Была ли сборка изолирована от сети? Совершенно точно нет, у ноутбука всё это время был полный доступ в интернет. Его хоть чем‑то сканировали? Нет. Был ли гейт, который мог бы не пустить плохую сборку в релиз? Нет.

Это не значит, что образ плохой. Это значит, что у вас нет доказательств ни за, ни против, а в цепочке поставок «да нормально всё» доказательством не считается.
Вопрос в другом: можем ли мы использовать ровно этот же Containerfile и получить все эти метаданные, не описывая их в ручную?
Акт 2: что такое Konflux
Konflux — это открытая Kubernetes‑native «фабрика доверенного ПО». Ключевое слово здесь,‑ доверенного.

Внутри всё собрано из CNCF и других upstream‑проектов:
Задача | Инструмент |
|---|---|
Пайплайны | Tekton (кастомные ресурсы Kubernetes) |
Сборка | Buildah (тот же движок, что под Podman) |
Подпись | Sigstore / cosign, keyless |
Сканирование | Clair для CVE, ClamAV для малвари |
Политики | Conforma (Enterprise Contract) |
Провенанс | in‑toto, SLSA Level 3 |
Зависимости | Hermeto, герметичный prefetch |
Реестр | Quay с поддержкой OCI‑артефактов |
Обратите внимание на Buildah. Это тот самый движок, который вызывает Podman, и именно поэтому Containerfile не надо переписывать. Вы не изучаете новую систему сборки, вы оборачиваете ту, которой уже пользуетесь, в довольно серьёзную обвязку.
Дальше по тексту будут встречаться PipelineRun и TaskRun. Это кастомные ресурсы Tekton, в которые превращается сборка, когда она едет в кластере, и смотреть их можно обычным oc get.
Konflux можно развернуть на OpenShift, ROSA, EKS или на обычном ванильном Kubernetes, лицензия Apache 2.0, больше 150 репозиториев на GitHub.
И это не только история Red Hat. Например, у Fedora Project есть собственный инстанс Konflux, и туда постепенно переезжает реальная работа: для Fedora CoreOS принят Change на Fedora 44, по которому ветки stable, testing и next будут собираться там. Причина, указанная в самом начале той страницы, довести SBOM и аттестации до конечного пользователя. Ровно та же мотивация, что и в этой статье, только в масштабе дистрибутива. Кстати, ваш покорный слуга непосредственно разворачивал данную инфраструктуру для проекта Fedora.
Что нужно, чтобы начать
Три вещи:
Кластер Kubernetes. В моем демо я использовал OpenShift.
Инстанс Konflux, развёрнутый на этом кластере.
Интеграция с Git. Для GitHub это GitHub App, именно он включает Pipelines as Code. Для GitLab вместо него webhook и access token.

Онбординг, это всего лишь два YAML‑файла
Вот эта часть меня впечатила во всемя моей первой настройки. Чтобы завести репозиторий в Konflux, вы применяете два обычных ресурса Kubernetes. Привожу их целиком, ничего не вырезал.
apiVersion: appstudio.redhat.com/v1alpha1
kind: Application
metadata:
name: devconf-api
namespace: vsok-tenant
spec:
displayName: DevConf Schedule API
Application, просто логическая группировка, зонтик, под которым лежит всё, что выпускается вместе. Если бы у меня были фронтенд и бэкенд, это были бы два Component под одним Application. Обратите внимание на неймспейс vsok-tenant: Konflux выдаёт каждому тенанту собственный неймспейс, и всё хозяйство живёт там.
apiVersion: appstudio.redhat.com/v1alpha1
kind: Component
metadata:
name: devconf-api
namespace: vsok-tenant
spec:
application: devconf-api
componentName: devconf-api
source:
git:
url: https://github.com/vsokolen-redhat/devconf-demo
revision: main
Файл Component также максимально прост: относится вот к этому Application, лежит вот в этом Git‑репозитории, собирать вот эту ветку. Никакой конфигурации сборки в нём нет вообще. Ни базового образа, ни шагов сборки, ни даже упоминания Containerfile, ни credentials к реестру. Остальное Konflux выясняет сам.
oc apply -f application.yaml
oc apply -f component.yaml
Как только Component оказывается в кластере, просыпается сразу несколько контроллеров. Build Service находит Containerfile. Image Controller заводит репозиторий в Quay под будущий образ. Pipelines as Code открывает в вашем репозитории pull request с каталогом .tekton/.
Этот пайплайн я не писал. Konflux написал его за меня и положил в репозиторий, рядом с Containerfile, в виде кода, который можно прочитать и поправить.

Внутри два файла: on-push.yaml, который собирает во время merge в main, и on-pull-request.yaml, который собирает каждый PR. Оба файлы,‑ манифесты PipelineRun с CEL‑выражением, которое определяет, когда пайплайн запускается.
Я посмотрел его, сделал merge, и этот merge запустил первую настоящую сборку.
Сборка

То же output мы видим из терминала:.

По таскам стоит пройтись отдельно, потому что именно здесь и появляется «доверие».
init и clone‑repository. Ничего интересного, обычный git clone.
prefetch‑dependencies. Это Hermeto. Он разрешает и скачивает все нужные приложению pip‑пакеты, с доступом в сеть, и попутно формирует полный SBOM. Все зависимости фиксируются здесь и больше нигде.
build‑container. Самое интересное. Buildah запускается с --network=none. Сеть на время сборки физически отрезана. Доступно только то, что Hermeto притащил заранее. Аналогия, которую я приводил на презентации: повара заперли на кухне с теми продуктами, которые вы одобрили, и дверь для доставки заперли.
Вот это и есть «герметичная сборка» (Hermetic Builds) на практике, и ровно поэтому SBOM можно верить. По дороге ничего не «подмешается».
Сканирование на CVE и malware. Clair и ClamAV, автоматически. Никаких плагинов, никакого конфига.
Подпись и push. Tekton Chains наблюдает за каждой сборкой в кластере. Когда сборка завершается, Chains подписывает образ через cosign в режиме keyless, формирует провенанс SLSA Level 3 и прикрепляет и то, и другое к образу в Quay. Причём образ, аттестацию с провенансом и SBOM он подписывает по отдельности, так что каждый артефакт проверяется независимо.
И всё это произошло без единой строчки конфигурации с моей стороны, кроме тех двух YAML‑файлов.
Гейт
Когда сборка заканчивается, Konflux создаёт Snapshot. Snapshot по сути, это неизменяемуя запись о всех образах компонентов с точными дайджестами SHA256. Не тегами. Дайджестами.

Дальше отрабатывает Enterprise Contract. Это и есть «фейс контроль на входе». Он спрашивает: образ подписан? провенанс есть? сборка была герметичной? сканирование на CVE прошло? базовый образ ещё поддерживается?
Если хоть одна проверка падает, релиз блокируется. Флага «пропустить» нет, и в этом весь смысл.
Акт 3: проверяю сам
Гейты это хорошо, но мне хотелось показать всем на презентации доказательства напрямую, а не предлагать поверить интерфейсу на слово. Для этого хватает одной команды.
cosign tree quay.io/redhat-user-workloads-stage/vsok-tenant/devconf-api@sha256:ce0df74bba3fbfabc6469d931c774c0270f809edcf82bf658bee533cd35e0f77

Всё, что висит на одной‑единственной ссылке на образ:
три подписи cosign;
аттестация с провенансом SLSA Level 3;
полный SBOM;
отчёт Clair по CVE;
отчёт ClamAV по malware;
два отчёта SARIF от статического анализа.
Шесть типов артефактов цепочки поставок на одном контейнерном образе, и ни один из них я не настраивал сам.
Запускаем
Последним шагом демо было скачать образ обратно и запустить его так же, как я запускал локальную сборку в начале. Не по тегу, а по дайджесту, чтобы точно знать: это ровно тот образ, который подписали и аттестовали.

Тот же вывод. Те же данные конференции. То же приложение.
В этом вся суть, и тут стоит сказать прямо: разница не в том, что приложение делает. Разница в том, что вы можете доказать про то, как оно собрано.
Вернитесь к списку вопросов из начала статьи. Из какого коммита это собрано? Провенанс отвечает. Что внутри? Отвечает SBOM. Была ли сборка изолирована? Провенанс фиксирует флаг герметичности. Сканировали ли его? Два отчёта говорят, что да. Подписан ли он? Три подписи говорят, что да. И ни один из этих ответов не появился оттого, что я писал код пайплайна.
Пять вещей, которые стоит забрать с собой

Начинайте с Podman. Держите внутренний цикл быстрым. Ваш Containerfile переезжает в Konflux без изменений.
Герметичные сборки важны. Отключение сети на время сборки не даёт зависимости подмениться по дороге и делает SBOM полным, а не приблизительным.
Подпись происходит сама. Tekton Chains плюс cosign, keyless, на каждой сборке. Никаких ключей, которые надо хранить, ротировать и ухитряться не слить.
Гейты политик блокируют плохие релизы. Enterprise Contract проверяет провенанс и результаты сканирования до того, как что‑либо уедет дальше.
Свой YAML писать не нужно. У Konflux есть мнение по умолчанию. Показываете ему репозиторий, пушите код, получаете доверенные образы.
Или, как я закончил доклад: ваш ноутбук собирает контейнеры, Konflux собирает доверие.
Попробовать самому
Всё перечисленное, открытый код под Apache 2.0.
Мой доклад на DevConf.CZ: youtube
Konflux: konflux‑ci.dev
Быстрый старт: konflux‑ci.dev/docs/getting‑started/
Исходники: github.com/konflux‑ci
OpenShift Local (CRC), если хочется кластер прямо на ноутбуке: developers.redhat.com/products/openshift‑local
Podman: podman.io
Tekton: tekton.dev
Sigstore: sigstore.dev
SLSA: slsa.dev
Buildah: buildah.io
Слайды доклада лежат здесь.
Буду рад обсудить trusted pipelines, Tekton и Kubernetes‑native CI в целом. Найти меня можно в LinkedIn, ну или просто пишите в комментариях.
KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.