Из за чего неизменяемая инфраструктура уменьшает расхождение конфигураций между экземплярами?

Из-за чего неизменяемая инфраструктура уменьшает расхождение конфигураций между экземплярами?

Проходите собеседования с ИИ помощником Hintsage

Краткий ответ

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

Благодаря этому экземпляры одного развёртывания проходят одинаковый путь создания. Однако сам подход не гарантирует идентичность автоматически: нужно версионировать образы, декларации инфраструктуры и внешние настройки.

Исторический контекст

В изменяемой инфраструктуре серверы часто настраивали последовательностью ручных действий или скриптов. Со временем отдельные экземпляры начинали отличаться: на одном появлялся срочный патч, на другом оставалась старая библиотека, а часть изменений вообще не фиксировалась в системе управления.

Так возникал configuration drift — расхождение фактического состояния с заявленным и между самими экземплярами. Неизменяемый подход перенёс изменения из этапа эксплуатации на этап сборки и сделал замену экземпляра предпочтительнее его ручного ремонта.

Постановка проблемы

Предположим, что за балансировщиком работают несколько экземпляров приложения. Если инженер исправляет проблему непосредственно на одном из них, трафик временно стабилизируется, но после масштабирования или восстановления новый экземпляр не получит это исправление.

Такое расхождение усложняет диагностику, делает результаты развёртывания непредсказуемыми и может привести к повторному появлению дефекта. Дополнительный риск возникает при автоматическом масштабировании: оркестратор создаёт экземпляры из базового шаблона, не учитывая ручные изменения старых узлов.

Подробное решение

При неизменяемом подходе жизненный цикл обычно разделён на этапы:

  1. Исходные файлы, зависимости и настройки сборки фиксируются в версиях.
  2. Из них создаётся артефакт: например, образ контейнера или образ виртуальной машины.
  3. Артефакт проверяется тестами и сканированием, после чего получает неизменяемую версию или digest.
  4. При развёртывании создаются новые экземпляры именно из этого артефакта.
  5. Трафик переводится на новые экземпляры, а старые удаляются после успешной проверки.

Ключевой механизм — замена, а не накопление изменений внутри работающего экземпляра. Поэтому новый экземпляр не наследует случайные исправления, временные файлы и неизвестное состояние старого.

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

Неизменяемость не означает, что данные нельзя менять. Состояние приложения должно храниться во внешних управляемых системах: базе данных, объектном или постоянном хранилище. Сам экземпляр приложения рассматривается как заменяемый и не должен быть единственным местом хранения данных.

Основные компромиссы — необходимость зрелого конвейера сборки, более быстрый и надёжный rollback за счёт хранения старых артефактов, а также дополнительные требования к миграциям данных. Замена экземпляров не решает автоматически проблему несовместимых изменений схемы базы данных или неправильных внешних настроек.

Ситуация из практики

В веб-сервисе один из виртуальных серверов получил ручное исправление конфигурации после инцидента. Через несколько дней группа автоматического масштабирования создала новые серверы из прежнего образа, и часть запросов снова стала завершаться ошибкой.

Рассматривались три варианта. Первый — продолжить ручные исправления: это быстро для единичного инцидента, но плохо воспроизводится и сохраняет drift. Второй — запускать скрипт настройки после создания сервера: подход лучше, но результат зависит от состояния внешних репозиториев и порядка выполнения шагов. Третий — собирать новый версионированный образ и заменять все экземпляры.

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

Что кандидаты часто упускают

  1. Вопрос: Делает ли неизменяемая инфраструктура все экземпляры полностью идентичными?

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

  1. Вопрос: Почему ручное исправление работающего экземпляра считается проблемой, даже если оно устранило инцидент?

Ответ: Такое исправление меняет фактическое состояние, но обычно не меняет источник истины: код сборки, образ или декларацию инфраструктуры. После пересоздания экземпляра изменение исчезнет, а другие экземпляры останутся в прежнем состоянии. Допустимая практика — использовать ручное изменение как временную диагностику, затем перенести подтверждённое исправление в версионируемый процесс и выполнить замену.

  1. Вопрос: Как выполнять откат, если новая версия уже изменила схему базы данных?

Ответ: Откат приложения не всегда означает безопасный откат данных. Поэтому миграции часто проектируют по принципу backward compatibility: сначала добавляют совместимые структуры, затем переводят приложение, а удаление старых структур выполняют отдельным этапом после стабилизации. Старый артефакт приложения можно вернуть быстро, но его совместимость с уже изменённой схемой должна быть заранее предусмотрена.