Прямой ответ
Дрейф конфигурации (config drift) — расхождение между описанным и фактическим состоянием инфраструктуры. Он накапливается незаметно и проявляется в худший момент: развёртывание, которое работает в одной среде, падает в другой, а восстановление после сбоя даёт конфигурацию, которой никто не ожидает.
Симптомы дрейфа:
| Симптом | Вероятная причина |
|---|---|
| Развёртывание работает в тесте, падает в продуктиве | Различие версий или настроек между средами |
| Восстановленный узел ведёт себя иначе | Конфигурация узла менялась вручную |
| Ошибка исчезает после перезапуска | Накопленное состояние, не описанное в коде |
| Один узел кластера отличается от остальных | Ручная правка на конкретном узле |
Основной источник дрейфа — ручные правки на сервере. Срочное исправление во время инцидента выполняется напрямую и не возвращается в описание инфраструктуры:
# правка на сервере во время инцидента
sudo sysctl -w net.core.somaxconn=4096
sudo sed -i 's/worker_connections 1024/worker_connections 4096/' /etc/nginx/nginx.conf
sudo systemctl reload nginx
Изменение работает, инцидент закрыт, а описание инфраструктуры осталось прежним. При следующем развёртывании узла значение возвращается к прежнему, и проблема повторяется в худший момент.
Обнаружение дрейфа выполняется сравнением описанного и фактического состояния. Terraform показывает расхождения без применения изменений:
terraform plan -detailed-exitcode
# код 0 — расхождений нет
# код 2 — есть отличия фактического состояния от описанного
Ansible проверяет состояние в режиме проверки:
ansible-playbook site.yml --check --diff
Режим показывает, какие задачи изменили бы состояние, не изменяя его. Регулярный прогон в этом режиме выявляет дрейф до инцидента; о подходе — в статье про Ansible.
Для Kubernetes расхождение возникает между манифестами в репозитории и объектами в кластере. Прямое изменение объекта через kubectl edit создаёт дрейф, который исчезает при следующем применении манифестов; о подходе — в статье про инфраструктуру как код.
Диагностика: где искать расхождение
Поиск дрейфа начинается не со всей инфраструктуры, а с мест, где расхождение возникает чаще.
Уровень операционной системы. Параметры ядра, лимиты открытых файлов, настройки сети. Изменяются вручную при устранении проблем с производительностью и редко возвращаются в описание.
Конфигурация промежуточного слоя. Настройки веб-сервера, прокси и балансировщика. Правки вносятся для конкретного случая и остаются навсегда.
Переменные окружения и секреты. Значения, добавленные напрямую на сервер либо в объект конфигурации кластера, минуя описание.
Версии компонентов. Версия базы данных, среды выполнения и системных пакетов, установленная при развёртывании и не обновлявшаяся вместе с описанием.
Объекты кластера. Изменения, внесённые напрямую через командную строку вместо применения манифестов.
Проверка выполняется в этом же порядке: сначала параметры системы, затем конфигурация сервисов, затем версии и объекты кластера. Сравнение версий между средами выявляет расхождение быстрее, чем поштучная проверка каждого узла.
Практика: устранение и предотвращение дрейфа
1. Проверяйте состояние по расписанию. Прогон terraform plan или ansible-playbook --check раз в сутки выявляет дрейф в течение дня, а не в момент инцидента.
2. Возвращайте срочные правки в описание. Правило: правка на сервере допустима как временная мера и сопровождается задачей на перенос в код в тот же день.
3. Запретите ручные изменения там, где это возможно. Доступ на запись к продуктивным узлам ограничивается, а изменения вносятся только через конвейер; о подходе — в статье про неизменяемую инфраструктуру.
4. Делайте среды одинаковыми по структуре. Различие версий и настроек между средами — источник дрейфа. Отличаться должны только параметры, зависящие от окружения.
5. Описывайте все уровни конфигурации. Параметры ядра, настройки веб-сервера, переменные окружения и манифесты кластера описываются в коде, а не настраиваются вручную.
6. Фиксируйте дрейф как инцидент. Обнаруженное расхождение требует разбора: как оно возникло и почему не было предотвращено.
7. Автоматизируйте приведение к описанному состоянию. Обнаруженное расхождение устраняется применением кода, а не повторной ручной правкой.
8. Проверяйте конфигурацию при развёртывании. Сборка образа из описания исключает расхождение между средой сборки и средой выполнения.
Рекомендации:
- Не считайте дрейф безобидным. Расхождение проявляется при восстановлении, когда времени на разбор нет.
- Различайте временную правку и постоянное изменение. Временная правка допустима при инциденте, но требует переноса в код.
- Ведите перечень исключений. Узел с обоснованным отличием фиксируется в описании, а не существует вне его.
- Проверяйте конфигурацию после инцидентов. Срочные правки во время инцидента — основной источник дрейфа.
- Сравнивайте среды между собой. Различие тестовой и продуктивной среды по версии компонента обнаруживается сравнением, а не падением при развёртывании.
Практический сценарий: сбой после восстановления узла из-за накопленных ручных правок
Контекст: один из четырёх узлов кластера вышел из строя. Новый узел развернули стандартным образом, но сервис на нём работал с ошибками.
- Диагностика. Сравнение конфигурации показало три отличия: параметр ядра
somaxconn, число рабочих соединений веб-сервера и лимит открытых файлов. Все три были изменены вручную во время инцидентов за предыдущий год. - Причина. Правки вносились напрямую на узел и не возвращались в описание инфраструктуры. Описание отражало состояние годичной давности, поэтому новый узел получил прежние значения.
- Действия. (а) Найденные отличия перенесли в описание инфраструктуры; (б) добавили ежесуточный прогон проверки конфигурации с тревогой при расхождении; (в) ограничили доступ на запись к продуктивным узлам; (г) провели проверку остальных узлов и нашли ещё два расхождения; (д) добавили пункт в разбор инцидентов: перенос временных правок в описание.
- Результат. Конфигурация всех узлов приведена к описанию, а ежедневная проверка обнаруживает расхождение в течение суток после его появления.
Вывод: дрейф конфигурации накапливается через срочные правки, которые не возвращаются в описание. Обнаружение требует регулярного сравнения описанного и фактического состояния, а предотвращение — ограничения ручного доступа и правила переноса временных правок в код.
FAQ
Как быстро обнаружить дрейф?
Регулярным прогоном проверки: terraform plan показывает расхождения, Ansible в режиме проверки — отличия от описанного состояния.
Допустимы ли ручные правки? Как временная мера при инциденте — да, с обязательным переносом в описание инфраструктуры. Постоянное изменение вносится только через код.
Чем опасен дрейф в Kubernetes? Изменение объекта напрямую теряется при следующем применении манифестов, поэтому состояние оказывается непредсказуемым.
Как предотвратить расхождение сред? Единым описанием для всех сред с параметрами, зависящими от окружения. Различие версий компонентов между средами недопустимо.
Источники: Terraform CLI (plan), Ansible docs (ansible-playbook), Kubernetes docs (конфигурация) — ссылки в шапке.