Привет, Хабр!
Думаю, вам не надо рассказывать обо всех плюсах Kubernetes и о том, как его использование упрощает жизнь. Так что поговорим о другом — о дистрибутивах Linux, заточенных чисто под K8s: почему они вообще появились, чем они лучше классических дистров, как их ставить, куда душе угодно, а также про Talos OS и её плюшки.
Именно по этой теме я делал доклад для прошлой Kuber Conf от АОТ (видео тут, если вам так проще воспринимать информацию). А для любителей букв я и подготовил эту текстовую версию. Меня зовут Денис Романенко, я техдир Deckhouse Platform во «Фланте».
И начнём мы с базы.
K8s де-факто — это набор Go-контроллеров, для установки которых вам нужен Linux. На заре времён с кубером работали просто: собирали нужные кластеры на стандартном дистрибутиве (почти всегда — серверном), куда и накатывали компоненты Kubernetes.
Да, подход простой и надёжный, почти формата «работает — не трогай», но минусы у него тоже есть.
Компоненты Kubernetes требуют отдельной установки.
За обновлениями надо следить.
Так как используется дистр общего назначения, значит, для чисто контейнерных нагрузок он не очень оптимизирован, и надо многое допиливать вручную.
Большая поверхность атаки из-за большого числа компонентов.
Ресурсы используются неоптимально (см. п. 3).
Много компонентов = много шума для сканеров безопасности.
Все эти минусы — следствие того, что любой линуксовый дистрибутив создавался для использования в одной из трёх ипостасях:
решение обычных задач;
сервер;
тонкий клиент.
Как видите, ни одна из трёх не заточена «из коробки» под контейнеризацию. Как следствие — чем чаще люди работали с K8s на привычном линуксе, тем чаще они задумывались о том, как было бы круто иметь специализированный дистр для этого.
И именно так в мир пришли Kubernetes-native-дистрибутивы.
Какие же они и чем отличаются от привычных линуксов
Ориентированы на выполнение одной функции: выполнение контейнеров.
Дают возможность управления узлом и дистрибутивом именно посредством API.
Отказались от использования пакетных менеджеров в пользу обновления всего дистрибутива одномоментно.
Используют преднастроенные ядра.
И readonly-файловые системы.
За несколько лет таких дистрибутивов создали довольно много, на любой вкус и цвет, я же расскажу о самых популярных (если вам по душе другой — напишите в комментариях, за что именно любите свой).

Red Hat CoreOS
В 2018 Red Hat купила проект CoreOS, чтобы потом на его базе выпустить свою Red Hat CoreOS. Это часть OpenShift, есть и бесплатная версия — Fedora CoreOS.
Тут у нас иммутабельная файловая система RootFS на базе RPM-ostree. Все скрипты, запускаемые в системе, и компоненты системы изолируются друг от друга в контейнерах. Пакетов в базе мало, их список контролируется. Есть автообновление, акцент — на безопасности (SELinux), из коробки доступны Podman и Docker.
Flatcar
Упомянутая в пункте выше покупка CoreOS устроила не всех — энтузиасты CoreOS решили её форкнуть и сделали Flatcar, развивающий идеи сообщества.
Тут тоже иммутабельная файловая система RootFS и полный минимализм — ни пакетного менеджера, ни каких-то лишних утилит. Есть свой конфигуратор при загрузке (Ignition). Поддерживается модульность, есть бесшовная миграция с CoreOS. Акцент на безопасность (SELinux, AppArmor). Из коробки — Docker и Kubernetes.
K3OS
Немного выбивается из общего списка. Снова иммутабельная ФС и минимализм.
А вот что занятно: когда узел становится частью кластера, управлять им можно через Kubernetes-утилиту по API. Все компоненты control plane на Kubernetes упакованы в один бинарник, так что они потребляют очень мало ресурсов.
Для примера — если в Deckhouse Platform (наша разработка) мы используем конфигурацию 4 CPU + 8 ГБ RAM для узла control plane, то K3OS может работать буквально с 1-2 гигабайтами памяти. Kubernetes тут из коробки. Отличный вариант для создания различных встраиваемых систем, либо для песочниц.
Bottlerocket
Операционная система AWS для их собственного облака. Тоже иммутабельная файловая система, точно так же минимализм. Особенности — SSH-доступ отключен по умолчанию, предусмотрено атомарное обновление.
Talos
Пожалуй, дистрибутив, вобравший в себя множество хороших идей из других дистрибутивов этого рода.
Иммутабельная файловая система, атомарные обновления — снапшоты с возможностью отката. Полный минимализм (нет командной оболочки, стандартных утилит, SSH, вообще пусто). Все управление — через API, для работы с которым есть специальный клиент. Полная интеграция с Kubernetes — он поставляется как часть Talos. Кроме стандартных протоколов и систем типа SELinux / AppArmor тут есть ещё и принудительное шифрование, проверка подписей и многое другое.
Несмотря на некоторые отличия, у Kubernetes-native-дистрибутивов схожая философия.
Иммутабельность — файловая система должна быть неизменной.
Изоляция ПО. Всё, что запускается, должно быть изолировано от других компонентов, запускающихся на этом же узле.
Минималистичность — только то, что необходимо. Самый-самый минимум.
Контейнеризация из коробки. K8s-компоненты обычно поставляются вместе с базовым образом.
Управление по API. Никаких SSH-доступов и конфиг-файлов, всё управляется по API.
Акцент на безопасности.
Как от обычного дистрибутива пришли к Kubernetes-native
Давайте максимально упрощённо представим себе обычный линуксовый дистрибутив. Получится подобное.

Ко всему этому добру сверху накручивается внешний доступ к хосту (SSH для сервера), дополнительные утилиты, необходимые для работы, и система обновлений.
Так вот, если мы планируем этот хост как узел кластера — надо накатить ещё и компоненты K8s.
А что сделать для того, чтобы из обычного дистра получить тот самый Kubernetes-native? Тут шесть простых шагов:
Переносим K8s-компоненты сразу в базовый образ.
Ставим управляющий агент для доступа к этому узлу через API.
Отключаем внешний доступ.
Убираем ненужные утилиты.
Делаем файловую систему Readonly.
Используем hardened-ядро.
Поздравляю, теперь у вас K8s-native-дистрибутив.

Преимущества Kubernetes-native-дистрибутивов
Мало компонентов = малая поверхность атаки
Всё просто, атакующему банально нечего атаковать. Даже если он каким-то образом добрался до хоста, то просто не найдёт компоненты, уязвимости которых можно было бы эксплуатировать для повышения своих привилегий.
Нет внешнего доступа = сложнее проникнуть в систему в принципе.
Иммутабельная файловая система
Нельзя записать собственный бинарник, который мог бы жить в памяти. Ладно, записать-то можно при желании. Но до первой перезагрузки.
Компоненты Kubernetes «из коробки»
Вся система сразу настроена на максимальную производительность — дополнительно ставить или настраивать ничего не надо. У вас уже есть всё, что нужно.
Малый размер
ОС быстро скачивается и развёртывается, вопрос скорости тут полностью решён.
Символично, что каждый из этих пунктов при рассмотрении с другой стороны становится минусом.
Мало компонентов
Почти невозможно установиться на нестандартное железо. Каждый дистрибутив по умолчанию уже ориентирован на конкретные популярные компоненты. Если у вас специфичное железо — явно будет непросто.
В Talos эту проблему решили — есть визуальный конструктор, позволяющий собрать образ из нужных компонентов. Если попробовать собрать что-то универсальное, то в итоге количество компонентов, файлов и размер этого дистрибутива начнут приближаться к любому другому дистрибутиву общего назначения, что не очень удобно. А ещё это получится кастом, который надо поддерживать, наблюдать и дебажить.
Отсутствие внешнего доступа
Без него страдают наблюдаемость и возможность подебажить проблемы.
Философия Kubernetes и Talos клауд-ориентирована. Проблема на узле? Просто перезакажите его, а не дебажьте. Это не всегда хорошо срабатывает в случае, если у вас используются stateful-нагрузки, либо если у вас используются bare-metal-сервера. В этом случае узел невозможно перезаказать, нужно дебажить, что на нем произошло.
В случае Kubernetes-native-дистрибутива без внешнего доступа сделать это достаточно сложно. Вот вам для примера пост моего коллеги, который столкнулся с необходимостью добавить Talos на bare metal.
Предустановленные компоненты Kubernetes
У вас ванильный кубер? Тогда всё ОК. А если у вас есть какие-то свои наработки в этой области, то будут проблемы — придётся снова собирать кастом с собственными компонентами.
Как дела с совместимостью
Так или иначе, все эти истории с K8s-дистрибутивами про их использование в компаниях и в настоящей продуктивной среде, а не просто в качестве сферического коня в вакууме. Пока же практика показывает, что такие дистры (и Talos в частности), не всегда подходят для крупных отечественных решений.
И у них на это семь причин.
Импортозамещение. В критичных отраслях, например при обработке финансовых транзакций, требуются сертифицированные дистрибутивы. Увы, в России пока нет таких Kubernetes-native-решений. Основные игроки — Astra Linux, РЕД ОС и «Альт» — выпускают только дистрибутивы общего назначения. Да, у «Базальт СПО» есть Talos-подобный дистрибутив на компонентах «Альт Сизиф», он зарегистрирован в реестре российского ПО, но пока не сертифицирован. Может, ситуация в скором времени изменится и появится отечественный сертифицированный Kubernetes-native-дистрибутив.
Уже имеющийся лицензированный дистрибутив. Если какой-то дистр уже в принципе куплен и используется, то смысл в другом драматически падает.
Клауд-поддержка. Отечественные публичные и приватные облака пока слабо поддерживают K8s-native-дистрибутивы, что делает их использование неудобным.
Собственная экспертиза. У больших ИТ-компаний свои практики, подходы и сценарии работы, которые уже устоялись. Внедрение нового дистрибутива потребует переработки процессов, переписывания документации и переобучения сотрудников.
Работа на bare metal. Много где используют собственный парк bare-metal-серверов. Философия Kubernetes-native-дистрибутивов («перезаказать узел, а не разбираться») здесь плохо применима. Отладка становится сложной, поэтому использование на bare metal остаётся под вопросом. Такая же история и со stateful-приложениями: узел нельзя просто удалить, требуется разбираться с проблемой.
Нестандартное оборудование (специфические полки хранения и другие устройства) также плохо совместимо с Kubernetes-native подходом и требует дополнительной кастомизации.
Отсутствие поддержки. Большинство таких дистрибутивов разработаны иностранными компаниями, которые пока не оказывают полноценной поддержки в России. Кроме того, они хорошо заточены под контейнерные нагрузки, но установка собственных сервисов мониторинга или средств информационной безопасности вызывает серьёзные трудности.
Что в итоге? А в итоге необходимость создания кастомного K8s-дистра.
Как в итоге выбрать решение для компании? Тут нельзя опираться только на популярность решения в сообществе. На выбор влияют:
используемое оборудование;
требования вашей ИБ и регуляторов;
устоявшиеся практики организации;
количество обученных инженеров;
другие факторы.
Скажем, вы — стартап, у которого ещё нет платформы, нет устоявшихся процессов и сформированной DevOps-команды. Тогда выбор Kubernetes-native-дистрибутива выглядит разумным. А вот в случае зрелого проекта с отработанными практиками, документацией, тестами и обученной командой внедрение нового дистрибутива становится дополнительной нагрузкой, плюсы которой часто не особо перевешивают минусы.
Что делать? Научиться работать с любым дистрибутивом
Если переход на Kubernetes-native дистрибутив неоптимален, можно использовать уже принятые в организации дистрибутивы и научиться работать с ними так, как будто они Kubernetes-native.
Надо осилить четыре условия.
Научиться устанавливать на узел необходимые компоненты кластера (контроллеры, CRI, containerd, при необходимости Docker).
Настраивать это установленное ПО.
Иметь reconcile-машину, которая поддерживает узел в желаемом состоянии.
Минимизировать вмешательство в базовый дистрибутив.
Поскольку разные дистрибутивы используют разные наборы библиотек и пакетные менеджеры, единой точки привязки тут у нас нет. Поэтому всё ПО, устанавливаемое на узлы, надо поставлять либо вместе с необходимыми библиотеками, либо в статически собранном виде. Последний вариант тут, конечно, предпочтительнее.
В нашей практике единственным источником истины мы считаем registry, в котором хранятся образы, включая образы собственного ПО. Компоненты доставляются в виде образов и устанавливаются в отдельный путь (/opt/deckhouse), не пересекающийся с системным. Все (вообще все) компоненты содержат цифровые подписи и проходят контроль целостности. Это фишка нашей платформы. Подробностями в рамках этой статьи грузить не буду, но если вам интересно — вот доклад моего коллеги, Максима Набоких, на Highload++ (и вот он текстом).
Reconcile-машина и процесс bootstrap
Наша Reconcile-машина называется Bashible и состоит из двух частей:
Bashible — фреймворк на узле (набор shell-скриптов, выполняющихся постоянно);
Bashible API Server — сервер рендеринга шаблонов, которые передаются на ноды для выполнения.
Это не наш велосипед, аналогичный подход используется в OpenShift (там для подобных нужд используется Machine Config Operator).
Как осуществляется bootstrap на примере клаудного узла.

На узле запускается cloud-init, который скачивает небольшой скрипт. Это так называемый бутстрап первой фазы, он совсем маленький, не более 16 КБ — ограничение некоторых облаков на cloud-init, в частности AWS.
Скрипт идёт к Bashible API Server и получает вторую фазу бутстрапа. Она устанавливает сам фреймворк на узле Bashible, CRI, containerd, компоненты Kubernetes, конфигурирует систему, CRI и Kubernetes. И после всего этого узел становится полноценным членом кластера. Если в этом процессе что-то идёт не так, у нас открывается специальный порт с логами, поэтому SSH-доступ на узел обычно не требуется.
Инсталляция ПО на узел
Я писал, что всё, что ставится на узлы, у нас ставится из registry. Так вот, если registry находится далеко или канал нестабилен, прямая загрузка компонентов растягивает bootstrap до 5–7 минут, мы с таким сталкивались, и это недопустимо для прода.
Для решения этой проблемы мы отказались от прямой закачки из registry и сделали компонент в прокси-кластере, который отдаёт компоненты из локального кэша, а сам подгружает их из registry (после первой подкачки). Этот же компонент у нас занят проверкой целостности и цифровых подписей.
Reconcile-машина запускается каждую минуту — набор скриптов запускается на узле, затем идёт в Bashible-узел и получает свою обновлённую копию, после чего запускает её. Если надо — обновляет компоненты узла, CRI, компоненты узла и Kubernetes, переконфигурирует систему и CRI, после чего засыпает до следующего цикла.
Архитектура решения
Система построена вокруг единого источника правды — registry. Все компоненты загружаются из него. ПО защищено цифровыми подписями и контролем целостности на всех этапах, не имеет внешних зависимостей и может быть установлено на любой дистрибутив.

Установка выполняется в отдельный путь, systemd-юниты имеют префикс d8, чтобы не пересекаться с системными.
Есть Reconcile-машина для поддержания узлов в желаемом состоянии.
SSH-доступ требуется только при работе с bare-metal-узлами (либо через секрет со скриптом bootstrap, либо через написанный нами оператор Cluster API Provider Static, который конфигурирует статические узлы).
Ограничения подхода
Python (необходим для работы фреймворка, обычно уже присутствует на узлах с cloud-init);
базовый набор утилит (grep, awk, find, bash, curl и прочие);
мы рассчитываем, что узел использует систему инициализации systemd (ибо с другими мы не работаем, по крайней мере — пока).
Чем мы можем управлять
У нас есть понятие Node Groups — групповая конфигурация однотипных узлов. Параметры передаются через шаблонизацию Bashible API Server.
Можно управлять:
параметрами kubelet (где хранить логи, как и сколько);
параметрами CRI;
фенсингом узла;
параметрами GPU;
параметрами обновления узла (параллельно, последовательно, указать интервалы).
А ещё у нас есть ресурс под названием Node User — он позволяет создавать системных пользователей и прописывать ключи (в том числе для временного SSH-доступа).
И третий ресурс — Node Group Configuration — даёт возможность выполнять произвольные скрипты на узле, требуется при подключении нестандартных железных компонентов и подобного. Пользоваться надо с осторожностью.
Что дальше
Хотим заменить набор shell-скриптов на клиент, написанный на Go, — будет такой единый бинарник с управлением через API, выполняющий всю работу.
Планируем убрать зависимость от Python на этапе первичной загрузки — с помощью небольшого бинарника (менее 2 КБ), передаваемого через cloud-init.
Думаем про собственный metadata-сервер для bare metal, чтобы устанавливать такие узлы аналогично клауд-узлам, тогда сможем отказаться от SSH.
А ещё планируем размещать утилиты в EROFS-слоях и запускать компоненты в выделенных неймспейсах, чтобы они не аффектили всю систему.
Вместо вывода
K8s-native-дистрибутивы — ответ на запрос в оптимизации под контейнерные нагрузки. У них много преимуществ, и со временем они вполне себе могут занять доминирующее положение. Надеюсь, что всё, связанное с кубером, будет использовать такие дистрибутивы.
Есть и минусы: заточенность на облака и отсутствие простой кастомизации «на лету» (обновления требуют перезагрузки). Решение этой проблемы и поможет доминировать на рынке.
Что же с Talos, так он хорош не везде — в устоявшихся проектах, особенно с bare metal и stateful-нагрузками, переход на дистрибутив нужно тщательно оценивать.
Наш подход тоже не идеален и содержит ряд минусов, например, безопасностью надо заниматься отдельно. Но зато мы можем плавно интегрироваться с принятыми в компании практиками, ничего не ломая по пути.
Идеальным решением в будущем стал бы дистрибутив, сочетающий достоинства Kubernetes-native-дистрибутивов с возможностью гибкой кастомизации и замены компонентов без полной перезагрузки.
Мне кажется, что это вполне реальная задача.
P. S. Держите гитхаб нашей Deckhouse Platform — если интересно, можете познакомиться с ним и самостоятельно изучить.
Совсем немного времени осталось до новой конференции Kuber Conf от АОТ, отмечайте в календарях 23 ноября.
Главная тема — инженерные задачи без привязки к конкретным облакам: практика эксплуатации Kubernetes, разбор инцидентов и обмен опытом.
Участники будут говорить о построении инфраструктуры вокруг K8s и о способах удержания падающего SLO. Программа и регистрация — по ссылке.
Комментарии (4)

aal27
29.10.2026 12:33Чем это лучше ProxMox, там контейнеры вроде тоже бегают native?

RomanenkoDenys Автор
29.10.2026 12:33Это вопрос технологий. Чем libvirt лучше или хуже kubernetes ? В целом ничем, зависит от задач.
xitriy87
Что-то я не совсем понял, в статье вы говорите, что если у вас on-premise архитектура, то не очень подходит использование k8s дистрибутивов, так как нужна возможность дебага. Тогда где она применима? Потому как в облаке проще использовать уже managed ресурсы и тогда вам как потребителю , уже без разницы, что провайдер у себя использует под капотом?
RomanenkoDenys Автор
тут скорее важно понимать ограничения которые несет каждый вариант. И не использовать k8s дистрибутивы только потому что это модно. У. них есть неоспоримые преимущества, но и недостатки тоже есть. В целом применимы они в облаках, именно из-за парадигмы перезаказать а не дебажить