← Все статьи

Vault запечатывался сам. Причиной была 15-минутная заморозка VM ниже кластера

Четыре seal'а Vault за три недели, каждый разбирали как отдельный инцидент. Анализ пауз в journald показал, что гипервизор замораживает VM во время бэкапа, а Longhorn превращает это в каскад.

В Optimacros Vault в одном из наших Kubernetes-кластеров запечатался четыре раза за три недели — и каждый раз на другом поде. Каждый раз за ним замерзал Vault Secrets Operator, и 53 из 55 синхронизируемых секретов переставали обновляться с 503 Vault is sealed. Каждый случай обрабатывали как отдельный инцидент и чинили руками.

Деталь, которая изменила ход расследования: поды Vault не перезапускались. restartCount оставался нулевым. Их пересоздавали с новыми UID — и всегда в одно и то же ночное окно.

Цепочка

Триггер оказался ниже кластера. Гипервизор «оглушает» VM во время бэкапа на уровне VM, а остальное доделал Kubernetes:

гипервизор замораживает VM (13-15 мин, ночью)
  -> liveness-пробы истекают
     -> Longhorn объявляет engine мёртвым через 8-10 с
        -> под instance-manager пересоздан, iSCSI-сессии рвутся
           -> пересоздаются все поды с томами Longhorn на ноде
              -> Vault возвращается новым подом -> Shamir -> sealed
                 -> синхронизация секретов ловит 503 и зависает

Как я доказал, что VM была заморожена

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

  • Метки времени journald. Записи kubelet с меткой 21:27 попали в journald в 21:42. Процесс ничего не писал 15 минут, а потом сбросил буфер. В собственных данных Prometheus была такая же дыра.
  • dmesg в тот же момент: массовый EXT4-fs unmounting, attempt to access beyond end of device, затем новая сессия iSCSI-инициатора. Тома отсоединялись и подключались заново.
  • Диск простаивал. IO time и iowait во время паузы были около нуля. Всплеск I/O случился после — при переподключении.
  • Память и близко не подходила к пределу: минимум доступной памяти за семь дней — от 48 до 71 процента.

Решающим тестом стал анализ пауз в journald за 14 дней на каждой ноде: вывести каждое место, где ОС ничего не писала дольше десяти минут. Замерзали только две ноды из семи, каждый раз на 13–15 минут, и instance-manager пересоздавался сразу после каждой «разморозки». Ровно на этих нодах были включены бэкапы VM.

Ещё один урок из тех же данных: steal time и заморозки — разные явления. Нода control plane на том же перегруженном гипервизоре имела столько же steal, сколько замерзающий воркер, но не замерзала ни разу. Бэкапы включаются на уровне отдельной VM, а steal — свойство физического хоста. И 15-минутное «оглушение» — это патология: у здорового снапшота оно меньше секунды.

Что мы могли исправить со своей стороны

Первопричина была в зоне команды виртуализации, поэтому её эскалировали с точными метками времени. В кластере:

  1. Longhorn engine-replica-timeout с 8 до 30 секунд — его максимум, применено без пересоздания единого instance-manager.
  2. Оператор секретов теперь ходит в Service vault-active. Обычный Service публикует и неготовые адреса, поэтому запечатанный пир оставался в ротации, и примерно треть запросов попадала в него. vault-active выбирает только распечатанного лидера.
  3. Алерты на реальную цепочку: пересоздан instance-manager, нода не отвечает как при заморозке VM, под Vault не готов.

Таймаут liveness у instance-manager я сознательно не поднимал: его изменение пересоздаёт instance-manager на всех нодах разом, а 15-минутную заморозку не переживёт никакой таймаут.

Неудобная оговорка

Исключить ноды из бэкапов VM выглядело быстрым решением, но у Longhorn на тот момент не был настроен backup target. Вредные бэкапы VM были единственными существующими бэкапами, поэтому их пришлось оставить до появления нормального хранилища бэкапов.

Что взять с собой

  • Рестарт и пересоздание — разные сигналы. Новый UID пода в фиксированное окно указывает куда-то ниже пода.
  • Анализ пауз в journald — дешёвый и решающий тест на «оглушённую» VM.
  • Исключайте диск и память цифрами, прежде чем их обвинять.
  • Steal — свойство хоста; заморозки приходят от операций над отдельной VM вроде бэкапов.
  • Длинные таймауты — смягчение для коротких задержек, а не лечение 15-минутной заморозки.