• Алексей
  • DevOps
  • 2 мин. чтения

Drift в Kubernetes: как мы обнаружили проблему и перешли на GitOps

Drift в Kubernetes: как мы обнаружили проблему и перешли на GitOps

Когда конфигурация начала жить своей жизнью

Configuration drift в Kubernetes — это состояние, когда реальное содержимое кластера отличается от того, что задумывалось изначально. Мы столкнулись с этой проблемой, когда инженеры начали вносить изменения прямо в production, минуя систему контроля версий. В результате кластер стал чёрным ящиком, где никто точно не знал, почему работает тот или иной сервис.

Симптомы были очевидны: одна сборка приложения работала в одной окружении и падала в другом, невозможно было воспроизвести конфигурацию на новом сервере, а откат изменений занимал часы вместо минут. Ситуация усугублялась тем, что у нас было пять разработчиков, которые одновременно что-то менял в кластере через kubectl, не оставляя истории изменений.

Обнаружение проблемы: инструменты и методы

Первым шагом была диагностика. Мы использовали несколько подходов:

  • Manual audit: экспортировали все манифесты из production через kubectl get all -A -o yaml и сравнивали с версией в репозитории
  • Drift detection tools: попробовали Kubecost и Kyverno для автоматического выявления несоответствий
  • Git-based сравнение: создали скрипт, который брал текущее состояние кластера и сравнивал с коммитами в git

Результаты оказались удручающими. Мы обнаружили 47 ресурсов, которые существовали только в кластере и не были задокументированы в git. Среди них были ConfigMap с хардкодированными переменными окружения, Secret с забытыми учётными данными и даже Deployment с выключенными probes, который был добавлен для быстрого исправления какой-то проблемы год назад.

Почему обычные IaC инструменты оказались недостаточными

Попытка решить проблему через Terraform и Helm была первым шагом, но мы столкнулись с новыми вызовами. Когда несколько человек работали с одним кластером, Terraform state начинал расходиться с реальностью. Helm charts требовали постоянного синхронизирования версий и значений параметров.

Главная проблема: инструменты IaC работают в режиме push — вы вносите изменение и применяете его. Но если кто-то изменит что-то напрямую в кластере, никто об этом не узнает до следующего развёртывания. Нам нужен был обратный процесс — кластер постоянно проверял бы, соответствует ли его состояние тому, что записано в git.

GitOps как решение: Flux и ArgoCD

Мы выбрали ArgoCD как решение благодаря его надёжности и интеграции с существующим стеком. ArgoCD работает по принципу pull: оператор внутри кластера регулярно проверяет git-репозиторий и применяет найденные там манифесты.

Как это работает на практике:

  • Разработчик коммитит изменение в git-репозиторий с манифестами
  • ArgoCD автоматически это замечает (через polling или webhook)
  • Система сравнивает текущее состояние кластера с git
  • Если есть различия, ArgoCD либо синхронизирует, либо показывает алерт
  • История всех изменений остаётся в git, включая автора и время

Мы создали два Application объекта: один для infrastructure (сертификаты, ingress-контроллер, monitoring), другой для приложений. Каждое приложение теперь имеет свой каталог с kustomize базой и overlays для разных окружений.

Структура репозитория, которая нас спасла

apps-manifests/
├── infrastructure/
│   ├── cert-manager/
│   ├── ingress-nginx/
│   └── monitoring/
├── applications/
│   ├── api-service/
│   │   ├── base/
│   │   └── overlays/
│   │       ├── staging/
│   │       └── production/
│   └── worker-service/
└── argocd/
    ├── applications.yaml
    └── appproject.yaml

Переход: больно, но необходимо

Миграция заняла две недели. Сначала мы экспортировали всё из production, разобрали на части, обогатили аннотациями и переместили в git. Затем постепенно переводили приложения на управление через ArgoCD.

Самый критический момент — когда мы впервые позволили ArgoCD автоматически синхронизироваться. Оказалось, что в кластере было несколько ресурсов, которые нужно было явно исключить из управления через аннотацию argocd.argoproj.io/compare-result: ignore.

Что нужно подготовить перед переходом:

  • Полный audit текущего состояния кластера
  • Определение, какие ресурсы управлять через git, какие создавать вручную
  • Обучение команды новому workflow’у
  • Настройка RBAC для ArgoCD
  • Интеграция с системой уведомлений (Slack, PagerDuty)

Результаты через месяц после внедрения

Эффект был очевиден сразу. Время на отладку проблем снизилось на 40% благодаря полной видимости истории изменений. Новый member команды смог поднять идентичное локальное окружение за пару часов вместо дня. Мы снизили количество инцидентов, вызванных конфигурационными ошибками, с пяти в месяц до одного.

Главное — теперь git является single source of truth. Если кто-то попытается изменить конфиг напрямую в кластере через kubectl, ArgoCD либо откатит это изменение, либо выведет алерт. Это дало команде уверенность, что состояние production всегда соответствует тому, что записано в репозитории.

Заключение

Configuration drift в Kubernetes — это не просто неудобство, это потенциальный источник серьёзных проблем. GitOps решает эту проблему радикально, сделав git источником истины и убрав необходимость в ручных изменениях кластера. ArgoCD позволил нам внедрить это при минимальных затратах на переход.

Если в вашей команде разработчики периодически делают kubectl apply изменений прямо в production — это верный знак, что пора переходить на GitOps. Инвестиция времени на правильную настройку окупится многократно через стабильность и скорость разработки.

Межтекстовые Отзывы
Посмотреть все комментарии
guest