SSD Nodes Learn Hosting plans →
Руководства Matt ConnorАвтор: Matt Connor

Неизменяемые дистрибутивы Linux на сервере: обзор

Узнайте, как работают Fedora CoreOS, Flatcar и Talos. Разбираем особенности image mode, где обновление системы происходит через перезагрузку, и оцениваем риски для VPS.

Что такое неизменяемый дистрибутив Linux

Неизменяемый дистрибутив Linux поставляет операционную систему как единый образ, поэтому вы заменяете систему целиком вместо обновления файлов на месте. В работающей системе нет apt upgrade перезаписи файлов в /usr. Вы собираете или загружаете новый образ, машина подготавливает его параллельно с текущим, а при следующей перезагрузке происходит переключение на новый. Предыдущий образ остается на диске, поэтому отмена неудачного обновления выполняется простой перезагрузкой.

Термин «неизменяемый» (immutable) несколько преувеличен. Ничто физически не мешает пользователю root записывать данные на диск. Эти системы монтируют системные директории в режиме «только для чтения» и передают права владения ими образу. Постоянные данные хранятся в /var. Конфигурация, специфичная для конкретной машины, находится в /etc. Все, что находится в /usr, принадлежит образу, поэтому два сервера с одним и тем же тегом образа содержат идентичные системные файлы.

Наиболее четко две модели описывает Red Hat: пакетный режим (package mode) и образный режим (image mode). Пакетный режим — это работающая система плюс менеджер пакетов, который вносит в нее изменения. Образный режим — это этап сборки где-то на стороне, результатом которого является артефакт, а задача сервера сводится лишь к загрузке того артефакта, на который вы его направили. Все, что описано ниже, вытекает из этого единственного различия.

Почему файловая система только для чтения важна для сервера

Сервер, проработавший два года, обладает историей, которую никто не фиксировал. make install, сделанный в спешке вечером. Сторонний репозиторий, добавленный ради одного пакета. Файл конфигурации, отредактированный во время аварии и не возвращенный в систему управления конфигурациями. Это называется «дрейфом конфигурации» (configuration drift), и именно поэтому пересборка «такого же» сервера по вашим заметкам часто приводит к тому, что новая машина ведет себя иначе. Заметки содержат намерения. Диск содержит истину.

Режим образа (image mode) устраняет место, где накапливается дрейф. /usr доступна только для чтения во время выполнения, поэтому ручная установка либо сразу завершается ошибкой, либо записывается как слой, который можно вывести одной командой. Это делает различия между двумя машинами видимыми, а не археологическими. Это та же проблема, которую стандартный чек-лист обслуживания Linux-сервера решает с помощью дисциплины, но здесь она решается на уровне файловой системы.

Откат — это перезагрузка, и в этом вся суть

Этот подход рассчитан на сбой, который мы уже описывали: VPS, который не загружается после обновления ядра. В пакетном режиме восстановление выполняется через консоль восстановления провайдера. Вы монтируете диск, делаете chroot и вручную удаляете пакет ядра. Это работает, так как загрузчик сохраняет старые ядра, но версионируется только ядро. Обновление glibc и изменения в systemd, пришедшие в той же транзакции, уже применены, и нет единой команды, которая откатила бы их все вместе.

В режиме образа единицей управления является вся система. На хосте bootc:

sudo bootc status
sudo bootc rollback
sudo systemctl reboot

bootc rollback меняет порядок в загрузчике на предыдущую запись — это тот образ, который работал час назад, включая ядро и пользовательское пространство. Ничего не скачивается и не пересобирается, так как старый образ не удалялся с диска. Если вы включили таймер автоматического обновления, описанный ниже, сначала остановите его: документация bootc предупреждает, что агент, выполняющий автоматические обновления, может отменить откат.

Fedora CoreOS делает то же самое, но под другими названиями:

sudo systemctl stop zincati.service
sudo rpm-ostree rollback -r

Сначала остановите Zincati. Zincati — это агент, который поддерживает актуальную версию Fedora CoreOS. Он не будет переустанавливать развертывание, к которому вы только что вернулись, но продолжит искать обновления и установит любое новое, как только оно появится, поэтому выполните sudo systemctl disable --now zincati.service, если машина должна оставаться на текущей версии до выхода исправления. -r перезагружает систему после подготовки отката. Чтобы защитить доверенное развертывание от удаления сборщиком мусора:

sudo ostree admin pin 0
rpm-ostree status

rpm-ostree status выводит список развертываний в порядке, в котором их предлагает загрузчик, отмечает текущее точкой и показывает Pinned: yes для того, которое вы закрепили.

Talos выполняет это одним вызовом API с вашей рабочей станции:

talosctl rollback --nodes 10.20.30.40

Flatcar использует два раздела /usr и переключается между ними. Каждый слот имеет приоритет и счетчик попыток в таблице разделов, поэтому слот, который не загружается успешно, исчерпывает попытки, и загрузчик выбирает другой. Проверьте, в каком слоте вы находитесь и был ли он помечен как исправный:

sudo cgpt show "$(rootdev -s /usr)" | grep successful=1

Исправный работающий слот выводит строку, содержащую tries=0 successful=1. Число приоритета в той же строке лишь определяет предпочтение загрузчика, поэтому на полностью исправной машине там может быть 1 или 2. Отсутствие такой строки означает, что текущий слот не был подтвержден — это состояние, в котором машина находится между обновлением и первой успешной загрузкой.

Чем заменить «установку пакета»: bootc и Containerfile

bootc — это инструмент, который обобщает данный подход. Он позиционируется как средство для транзакционных обновлений операционной системы «на месте» с использованием образов OCI (Open Container Initiative) и является проектом CNCF Sandbox. Ваш сервер превращается в Containerfile. По состоянию на август 2026 года базовым образом Fedora является quay.io/fedora/fedora-bootc:44, а базовым образом CentOS Stream — quay.io/centos-bootc/centos-bootc:stream10.

FROM quay.io/fedora/fedora-bootc:44
RUN dnf -y install nginx && dnf clean all
RUN systemctl enable nginx

Сборка и отправка образа выполняются так же, как и для любого другого образа:

sudo podman build -t registry.example.com/edge/web:2026-08-19 .
sudo podman push registry.example.com/edge/web:2026-08-19

Затем на сервере:

sudo bootc upgrade --check
sudo bootc upgrade --apply

bootc upgrade опрашивает источник образа и ставит новый образ в очередь на следующую загрузку. --check сообщает о наличии обновлений, не внося никаких изменений. --apply выполняет перезагрузку в новую версию. bootc switch registry.example.com/edge/web:next переключает машину на другой образ, сохраняя при этом /etc и /var; именно так можно переводить сервер между потоками образов без переустановки.

Для автоматических обновлений включите таймер, поставляемый в составе проекта:

sudo systemctl enable --now bootc-fetch-apply-updates.timer

Это ответ image-mode на автоматические обновления в Ubuntu и на dnf-automatic в Rocky и Alma. Разница заключается в том, что именно попадает в систему. Таймер в пакетном режиме применяет те версии, которые оказались в репозитории на текущую ночь, поэтому итоговый набор пакетов на каждой машине будет немного отличаться. Таймер в image-mode применяет один и тот же артефакт, который вы уже протестировали при загрузке где-то еще.

Из использования Containerfile вытекают два правила сборки. Данные, доступные для записи, должны находиться в /var, поэтому для ПО, которое требует записи в собственный каталог установки, необходимо создать символическую ссылку или добавить параметр BindPaths= в systemd на этапе сборки. А /etc при обновлении объединяется методом трехстороннего слияния: это означает, что файл, который вы не изменяли, получит новую версию из образа, а файл, который вы редактировали локально, будет сохранен.

Если вам нужен инструмент на работающей системе для разовой сессии отладки:

sudo bootc usr-overlay
sudo dnf -y install strace

Эта команда добавляет временный оверлей с возможностью записи в /usr, который удаляется при следующей перезагрузке. Это нужно для анализа проблемы, а не для её исправления. Таким способом нельзя изменить ядро, и всё, что вы установите, по замыслу исчезнет после перезагрузки.

Fedora CoreOS: развертывание один раз, обновления навсегда

В Fedora CoreOS нет интерактивного установщика. Вы создаете YAML-файл Butane, транслируете его в JSON-файл Ignition и передаете его машине при первой загрузке:

podman run --interactive --rm quay.io/coreos/butane:release \
       --pretty --strict < your_config.bu > transpiled_config.ign

Ignition выполняется в initramfs только при первой загрузке. Это тот момент, на котором часто ошибаются пользователи, переходящие с cloud-init. Если в конфигурации нет SSH-ключа, машина загрузится без возможности доступа, и исправить это можно только повторным развертыванием с нуля. Протестируйте конфигурацию на тестовой машине, прежде чем применять ее к важному серверу.

Установка на диск из live-окружения:

sudo coreos-installer install /dev/sda \
    --ignition-url https://example.com/example.ign

Обновления по умолчанию автоматические. Вы управляете тем, когда они происходят, а не тем, будут ли они вообще. Создайте TOML-файл в /etc/zincati/config.d/55-updates-strategy.toml, который задает периодическую стратегию:

[updates]
strategy = "periodic"

В рамках этой стратегии вы добавляете по одному окну обслуживания на каждую запись в массиве таблиц. Каждое окно начинается с имени updates.periodic.window, указанного в двойных квадратных скобках в качестве заголовка, за которым следуют три ключа:

  • days, список названий дней недели, например "Sat" и "Sun".
  • start_time, время открытия окна, записанное как "22:30".
  • length_minutes, длительность окна, например 60.

Это время указано в UTC. Чтобы полностью остановить обновления, выполните sudo systemctl disable --now zincati.service и примите на себя ответственность за график установки патчей.

Наслоение пакетов (package layering) существует как запасной вариант:

sudo rpm-ostree install --allow-inactive vim
sudo systemctl reboot

Эта команда создает новое развертывание с добавленным пакетом, и изменения вступают в силу только после перезагрузки. Последствия проявляются позже. Ваш набор слоев применяется поверх каждого нового базового образа, поэтому пакет, который исчез из репозитория в день обновления, приведет к сбою этого обновления. Документация Fedora рекомендует использовать контейнеры для любых значимых задач и образы bootc, если вам действительно необходимо изменить ОС.

Flatcar Container Linux: отсутствие пакетного менеджера

Flatcar является продолжением CoreOS Container Linux и наиболее строгим из дистрибутивов общего назначения. В системе нет пакетного менеджера, на который можно было бы положиться. Всё, что вы запускаете, работает в контейнерах. Для подготовки системы используется Ignition, как и в Fedora CoreOS. Обновления выполняются через два раздела A/B /usr, описанных выше, под управлением update_engine, при этом locksmithd определяет время перезагрузки.

update_engine_client -status
update_engine_client -check_for_update

UPDATE_STATUS_UPDATED_NEED_REBOOT означает, что пассивный раздел уже содержит новый образ и требуется только перезагрузка. Стратегия перезагрузки по умолчанию — reboot с пятиминутной задержкой, поэтому отдельный рабочий VPS перезапустится по собственному расписанию, если вы не укажете иное. Установите временное окно в /etc/flatcar/update.conf:

REBOOT_STRATEGY=reboot
LOCKSMITHD_REBOOT_WINDOW_START="Thu 04:00"
LOCKSMITHD_REBOOT_WINDOW_LENGTH=1h

REBOOT_STRATEGY=off оставляет решение о перезагрузке за вами. SERVER=disabled в том же файле полностью отключает проверку обновлений. Для кластера REBOOT_STRATEGY=etcd-lock в сочетании с locksmithctl set-max 4 ограничивает количество узлов, которые могут перезагружаться одновременно, чтобы обновление не вывело из строя весь парк серверов целиком.

Talos Linux: отсутствие shell, SSH и консоли

Talos — самая узкоспециализированная из четырех систем, и ее назначение предельно ясно. Она предназначена для работы узлов Kubernetes. В ней нет SSH-демона, нет командной оболочки для входа и нет входа через консоль. Физическая консоль отображает дашборд для проверки состояния машины, а не приглашение для входа. Любая операция выполняется через gRPC API с помощью talosctl с вашей рабочей станции на основе конфигурации машины, которую вы храните в git.

talosctl upgrade --nodes 10.20.30.40 \
  --image factory.talos.dev/metal-installer/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba:v1.14.2

Начиная с Talos 1.14, образ ghcr.io/siderolabs/installer больше не публикуется, а образы установщика теперь создаются через Image Factory. Длинный идентификатор в этом пути — это пустая схема для машины без каких-либо настроек. Используйте ту схему, с помощью которой был установлен ваш узел, чтобы системные расширения сохранились, и замените тег на версию, на которую вы переходите. Обновление использует схему A-B, которая сохраняет предыдущее ядро и образ ОС, поэтому, если новая версия не загружается, Talos автоматически выполняет откат без вмешательства администратора. Отладка выглядит иначе, так как нет командной оболочки для входа: вместо journalctl на самой машине вы используете talosctl logs и talosctl dmesg. Когда вам нужны инструменты на узле, talosctl debug запускает привилегированный контейнер из предоставленного вами образа и переводит вас в его оболочку; после выхода контейнер удаляется.

Если ваша рабочая нагрузка не связана с Kubernetes, Talos вам не подходит. Если же связана, то Talos устраняет целый класс инцидентов, поскольку ситуация, когда «кто-то зашел на узел и что-то изменил», становится невозможной.

От чего на самом деле отказывается арендатор VPS

Установка пакетов «на лету» в работающей системе. Это самый важный момент. Выполнение sudo apt install htop в 2 часа ночи во время инцидента становится невозможным. В bootc вы получаете временный оверлей, который исчезает после перезагрузки. В Fedora CoreOS вы получаете послойное развертывание, требующее перезагрузки. В Flatcar и Talos вы не получаете ничего.

Конвейер сборки, которого у вас раньше не было. Добавление пакета означает редактирование Containerfile, сборку образа, отправку его в реестр и обновление серверов. Это недорого, если конвейер уже существует. Но если его нет, создание инфраструктуры требует реальных усилий. Кроме того, необходим реестр, доступный серверам, а это либо еще один сервис для поддержки, либо дополнительные расходы.

Модули ядра. Ядро поставляется в составе образа, поэтому модуль, скомпилированный для текущего ядра, не сохранится после следующего обновления. Внешние модули и пакеты DKMS (dynamic kernel module support) должны быть встроены в образ и собраны для ядра этого образа. Любой компонент, требующий модуль, отсутствующий в базовом образе, превращается из проблемы установки в задачу сборки.

Агенты вендоров и провайдеров. Агенты мониторинга и резервного копирования обычно поставляются в виде .deb или .rpm со скриптом установки, который записывает данные в /usr и активирует systemd-юнит. В системе с файловой системой «только для чтения» такой скрипт завершится ошибкой. Некоторые вендоры предоставляют контейнеры или описывают процесс установки в режиме образа. Многие этого не делают. Проверьте это до начала работы, так как парк серверов, который невозможно отслеживать, хуже, чем парк с конфигурационным дрейфом.

Сам образ. Почти ни одна панель управления VPS не предлагает Fedora CoreOS, Flatcar или Talos наряду с Ubuntu и Debian. Вам придется предоставить диск самостоятельно, о чем пойдет речь в следующем разделе.

Развертывание на арендованном VPS

Сначала убедитесь в двух вещах: у вас есть внеполосный (out-of-band) доступ к консоли, то есть VNC или последовательная консоль, и вы можете загрузить систему восстановления (rescue system). Без консоли машина, которая не вернулась в строй, превращается в тикет в техподдержку вместо пятиминутного исправления.

Если провайдер разрешает использовать собственные образы, загрузите raw или qcow2 образ от поставщика, но сама по себе загрузка не даст вам машину, в которую можно войти. У пользователя core в Fedora CoreOS нет пароля или SSH-ключа по умолчанию, поэтому вам всё равно нужно передать Ignition-конфигурацию с вашим ключом или, если облачная платформа поддерживает Afterburn, использовать встроенную функцию провайдера для добавления SSH-ключей. В противном случае запишите образ на диск самостоятельно из системы восстановления. Flatcar поставляет готовый скрипт именно для этой цели, он работает из любого Linux:

curl -fsSLO https://raw.githubusercontent.com/flatcar/init/flatcar-master/bin/flatcar-install
chmod +x flatcar-install
sudo ./flatcar-install -d /dev/sda -i ignition.json

Запускайте его из системы восстановления, а не с сервера, который вы заменяете, так как скрипт переразмечает целевое устройство в процессе работы. Ему требуется не менее 8 GB свободного места на устройстве, а окружение восстановления должно предоставлять bash, bzip2 или lbzip2, lsblk, wget, udevadm, gpg и gawk. Ваш ignition.json должен содержать SSH-ключ, иначе у установленной системы не будет способа пустить вас внутрь.

Fedora CoreOS имеет схожую структуру, и её установщик запускается как контейнер:

sudo podman run --pull=always --privileged --rm \
    -v /dev:/dev -v /run/udev:/run/udev -v .:/data -w /data \
    quay.io/coreos/coreos-installer:release \
    install /dev/vdb -i config.ign

Проверьте имя устройства с помощью lsblk перед запуском. Запись на неверное устройство уничтожит всё, что на нём было, и запрос на подтверждение не появится.

bootc предлагает единственный путь, позволяющий обойтись без режима восстановления, так как он преобразует работающую систему Linux на месте:

sudo podman run --rm --privileged -v /dev:/dev -v /var/lib/containers:/var/lib/containers -v /:/target \
             --pid=host --security-opt label=type:unconfined_t \
             quay.io/fedora/fedora-bootc:44 \
             bootc install to-existing-root

Перед запуском прочитайте документацию к базовому образу, который вы используете, и протестируйте процесс на сервере, который не жалко потерять. После перезагрузки машина будет работать на базе образа, а прежний набор пакетов будет удалён.

Кому стоит использовать неизменяемые серверы, а кому нет

Этот подход подходит вам, если вы относитесь к серверам как к «скоту». Множество машин, созданных по одному шаблону. CI-раннеры (continuous integration), которые живут один час. Узлы k3s или Kubernetes, которые проще заменить, чем чинить. Любые сценарии, где на поломку сервера есть готовый ответ: «удалить и создать новый». Это также выгодно, когда нужно доказать аудитору, что именно запущено на машине, так как ответом будет дайджест образа, а не список установленных пакетов.

Этот подход не подходит вам, если у вас один VPS, который вы обслуживаете вручную, на нем работают три сервиса, вы устанавливаете софт по мере необходимости и у вас нет конвейера сборки. Режим работы с образами не избавляет от работы. Он переносит её с сервера на этап сборки и требует наличия реестра и конвейера. Если у вас есть инфраструктура для этой работы, вы получаете идентичные серверы и откат к предыдущей версии через перезагрузку. Если инфраструктуры нет, вы просто добавите лишние сложности в работающую систему и усложните себе жизнь в случае инцидента в 2 часа ночи.

Скучный средний вариант всё ещё работает: обычный дистрибутив с автоматическими обновлениями безопасности плюс процедура пересборки, которую вы реально тестировали. Выбор базовой системы — это отдельное решение, оно описано в выборе ОС для вашего VPS. Режим работы с образами — это лишь новый виток очень старого спора о том, как программное обеспечение должно попадать на машину, и история дистрибутивов Linux по большей части состоит из повторения этого спора.

FAQ

Является ли неизменяемый (immutable) дистрибутив Linux действительно неизменяемым?

Нет, и само название вводит в заблуждение. Пользователь root по-прежнему может записывать данные на диск. В действительности /usr монтируется в режиме только для чтения во время выполнения и полностью заменяется при обновлении образа, тогда как /etc и /var остаются доступными для записи и сохраняются между обновлениями. Изменения, которые вы вносите в /usr, либо отклоняются системой, либо удаляются при следующем обновлении, поэтому на практике системные директории меняются только при смене самого образа.

Могу ли я запустить Fedora CoreOS или Flatcar на VPS, который не предлагает их в списке образов?

Обычно да, если провайдер предоставляет систему восстановления (rescue system) и доступ к консоли. Вы загружаетесь в rescue, записываете образ диска дистрибутива на блочное устройство и перезагружаетесь. Скрипт flatcar-install от Flatcar позволяет сделать это из любого Linux, а Fedora CoreOS поставляет coreos-installer в виде контейнера, который можно запустить аналогичным образом. Оба варианта требуют наличия файла Ignition с вашим SSH-ключом, так как при первой загрузке нет возможности задать пароль. Без доступа к консоли не пытайтесь это делать: если машина не загрузится, у вас не будет инструментов для диагностики.

Как установить пакет на неизменяемый сервер?

Вы добавляете его в образ и переразвертываете систему. В bootc это делается через строку RUN dnf -y install ... в Containerfile, после чего следует пересборка, отправка образа в реестр и выполнение sudo bootc upgrade --apply на целевой машине. В Fedora CoreOS вы можете добавить пакет через sudo rpm-ostree install и перезагрузиться, но при этом пакет будет переустанавливаться при каждом последующем обновлении. В Flatcar и Talos нет пакетного менеджера, поэтому единственный вариант — использовать контейнер. Для разовой отладки на хосте bootc команда sudo bootc usr-overlay предоставляет доступ к записываемой директории /usr, которая очищается после следующей перезагрузки.

Исправляет ли режим образа (image mode) ситуацию, когда VPS не загружается после обновления ядра?

Это превращает восстановление из сложной задачи с использованием консоли в обычную перезагрузку. Предыдущий образ, включая ядро и пользовательское пространство, остается на диске, поэтому sudo bootc rollback или sudo rpm-ostree rollback -r позволяют вернуться к нему. Talos и Flatcar идут дальше и выполняют откат автоматически, если новый слот не загружается, так как запись загрузчика становится основной только после одной успешной загрузки. Ничто из этого не предотвращает неудачное обновление, но делает отмену изменений простой и быстрой.

Какой неизменяемый дистрибутив выбрать для сервера?

Выбирайте bootc, если вам нужен Linux-сервер общего назначения, который вы собираете как контейнерный образ и можете установить на имеющееся оборудование. Выбирайте Fedora CoreOS, если вам нужна та же модель, но с готовой инфраструктурой сборки и автоматическими обновлениями «из коробки». Выбирайте Flatcar, если вам нужен минималистичный контейнерный хост с A/B-схемой обновлений и без пакетного менеджера, чтобы избежать соблазна вносить изменения вручную. Выбирайте Talos только в том случае, если машина будет узлом Kubernetes, так как в нем нет командной оболочки для входа и он не предназначен для запуска чего-либо другого.

#bootc#immutable#atomic#coreos#updates