Как AVM переживает обновления и рост инфраструктуры

Пока обновляются агенты AVM, на нодах могут работать разные версии, а запущенные VM продолжают обслуживать клиентов. Первые две статьи были об устройстве платформы и выполнении задач. Эта часть уже о том, как мы обновляем AVM, не останавливая клиентские машины, что ломалось по дороге и где система первой упрётся в потолок.
Где принимаются решения
Управляющая часть AVM, или же control plane, составляет последовательность шагов, а агенты выполняют команды на нодах. В изначальном варианте сервиса задач агент сам отправлял сообщения о переходах состояния. Когда операция затрагивала несколько узлов, её полный ход было трудно увидеть в одном месте. Сложнее становилось задать общие правила повторов, дождаться результата шага и решить, что делать после ошибки. Поэтому все решения – в каком порядке идти, что повторять и как откатываться – мы забрали в управляющую часть.
Обновление агентов без остановки VM
Пока идёт выпуск, часть агентов уже работает на новой версии, а управляющая часть ещё на прежней. Новый агент понимает предыдущие версии формата команд. А вот наоборот оно не работает, поскольку новая управляющая часть может попросить у старого агента то, чего он ещё не умеет.
При критическом обновлении мы раскатываем новую версию сразу на всех агентах, это занимает в среднем 30–60 минут. И только когда проход закончится, обновляем управляющую часть. Такой порядок был заложен в схему с самого начала.

Перезапуск агента не трогает работающие виртуальные машины, так как они от него не зависят. С текущими задачами сложнее. Им мы даём завершиться, а слишком долгую задачу можем прервать и запустить заново после обновления. При этом AVM различает, какой шаг можно просто повторить, а после какого сначала нужно прибрать за прошлой попыткой.
Во второй статье мы назвали задачи идемпотентными. Точнее будет так: повторить можно любую задачу, но безопасным повтор делают по-разному. Повторный запуск VM можно выполнить сколько угодно раз, ничего не изменится. Повторное уведомление уже нельзя, клиент получит два одинаковых сообщения. При сбое создания диска на ноде может остаться недописанный файл, который удаляют перед новой попыткой. По нашей оценке, около 0,25 % задач не проходят с первого раза.
Отказ одного экземпляра control plane
Сейчас работают два равноправных экземпляра control plane. Сервис задач отдаёт каждое задание ровно одному из них, а к нодам экземпляры не привязаны, так что под новые ноды отдельный экземпляр не нужен. Лидер нужен только внутреннему планировщику AVM, чтобы не запускать его задания дважды. Предел у экземпляра есть, и задаёт его число одновременных задач, а не количество нод.
Ход задачи хранится в сервисе задач, а не в памяти принявшего её экземпляра. Если тот пропадёт, другой продолжит выполнение с сохранённого шага, то есть уже пройденную часть цепочки заново запускать не нужно. Но если связь оборвалась посреди отдельного действия, сначала нужно выяснить, успело ли оно завершиться, и только потом повторять.
С доставкой задач у нас уже была неприятная история, и она мешала выпустить AVM в продакшен. При неполадках сети сторонняя библиотека неправильно обрабатывала ошибки подключения к очереди по AMQP. Снаружи всё выглядело нормально: сервис задач работал, но очередь не разбиралась. В итоге мы написали собственный механизм переподключения. Сейчас у нас настроены оповещения о сбоях компонентов агента, control plane и самих серверов.
Сколько задач агент выполняет одновременно?
У параллельного выполнения есть два ограничения. На каждой ноде работают два экземпляра исполнителя агента, и у каждого есть ограниченное число мест для одновременных операций. Но даже свободное место не поможет, если задачи пытаются изменить один и тот же ресурс. Перед работой с диском или резервной копией агент берёт эксклюзивную блокировку на выбранный объект. Вторая операция с тем же диском будет ждать первой.

Поэтому одним числом ответить на вопрос из заголовка не получится. Десять операций с разными дисками пойдут параллельно, пока у исполнителя есть свободные места. Те же десять операций с одним диском выстроятся в очередь.
Кто решает, когда делать бэкап?
Своего расписания бэкапов у AVM нет, и это сделано специально. Когда клиенту нужна копия и сколько их хранить – вопрос тарифа, а не управления машинами. К тому же в биллинге планировщик копий уже работал, и переносить его в AVM значило бы написать то же самое второй раз. В нужный момент биллинг присылает команду, и дальше для AVM это обычная задача: снять копию диска VM и положить её в хранилище тем же механизмом, что и создание или миграция.
У нас ломался и этот механизм. Не так давно после релиза перестали создаваться новые копии: тестовое окружение не повторяло некоторые редкие особенности продакшена. Мы откатились на прежнюю версию образа, исправили ошибку и выкатили релиз заново.
Живая миграция и её сложный финальный шаг
Переносить VM между нодами AVM умеет двумя способами: с остановкой и вживую. Для живой миграции нужны три условия: машина запущена, гостевой агент работает, а на исходной и целевой нодах стоит одинаковая версия системы. Если хотя бы одно условие не выполнено, машину нужно переносить с остановкой.
Сначала мы готовим на целевой ноде диски нужного размера и переносим туда резервные копии. Затем гипервизор итеративно копирует память и данные дисков, пока исходная VM продолжает работать. Переключение происходит только после того, как передано полное состояние машины. Если перенос оборвётся раньше, VM так и останется работать на исходной ноде. Параллельно AVM сравнивает хеши перенесённых резервных копий на обеих нодах и при расхождении останавливает операцию.

После переключения остаётся только прибраться, то есть удалить данные на исходной ноде и обновить запись о расположении VM. Сама пауза в момент переключения занимает миллисекунды, а вся миграция длится от нескольких минут до нескольких часов, в зависимости от локации и размера машины.
Самым сложным оказалось другое: добиться, чтобы AVM и гипервизор одинаково понимали, где сейчас находится машина. На раннем этапе бывало, что AVM считал живую миграцию несостоявшейся, а операция в libvirt всё-таки доходила до конца. VM уже находилась на новой ноде, тогда как AVM помнил старую. Такие машины приходилось исправлять вручную, а обработку миграции мы в итоге переделали. С тех пор подобных расхождений не было.
Миллионы записей телеметрии и следующий предел роста
У AVM два хранилища, потому что данные у него двух совершенно разных видов. Разница примерно как между бухгалтерской книгой и складом.
PostgreSQL | ClickHouse | |
Что хранится | VM, диски и ноды | Поток измерений |
Как меняется | Записи обновляются, но редко | Записи только дописываются |
Как читается | Текущее состояние объектов | Сводные показатели за период |
Что важно | Транзакционная целостность | Срок хранения, сворачивание при вставке, сжатие временных рядов |
Почему AVM использует два хранилища
Первая версия хранилища статистики не ограничивала срок жизни данных. В это мы упёрлись довольно быстро, и теперь старые измерения постепенно сводят к более крупным временным интервалам, а через несколько месяцев удаляют.
Сейчас в поток поступает около 1,2–1,3 млн записей каждые несколько секунд. Это только текущая нагрузка, а не измеренный предел одного сборщика или всего кластера. Если AVM во что-то и упрётся первым, то, скорее всего, именно в обработку статистики.
Агенты складывают измерения в общую очередь. Несколько равноправных сборщиков могут читать её одновременно, а брокер сообщений распределяет между ними записи. Закреплять часть нод за каждым сборщиком не нужно, так как отдельную запись может обработать любой экземпляр. Где предел у нынешнего сборщика, мы пока не мерили. Вместо этого следим за очередью, если начнёт расти – добавим экземпляров.
Новый кластер мы заводим, когда открываем новую локацию или дата-центр. Внутри локации новую ноду может обслуживать любой экземпляр управляющей части, поэтому число нод для нас не главная метрика. Следим мы за двумя вещами: сколько задач выполняется одновременно и успевают ли сборщики разбирать очередь.
Что изменилось для команды
Главное, что дала собственная платформа – независимость от поставщика. Теперь ошибки мы разбираем и чиним сами.
AVM в цифрах
Несколько дней → минуты или часы | 30–60 минут |
Около 0,25 % | 1,2–1,3 млн |
Над AVM сейчас работают пять инженеров, код разнесён по 12 репозиториям. Часть работы мы по-прежнему делаем вручную: развёртываем агентов, регистрируем новые ноды и разбираемся с серверами в статусе «неисправен».
Начни мы сегодня, иначе организовали бы кодовую базу и сразу выбрали бы декларативную модель вместо императивной: в ней описывают, каким должен быть ресурс, а система сама доводит его до этого состояния. К ней мы и собираемся переходить.
В историях с очередью задач и миграцией повторилась одна проблема: мало видеть, что сервис запущен. Нужно понимать, движутся ли задачи и совпадают ли данные AVM о машине с её фактическим состоянием.
KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.