MAATRIX / Блог / Кластер Proxmox из двух узлов: почему это плохая идея

Кластер Proxmox из двух узлов: почему это плохая идея

MAATRIX

Купили второй сервер, объединили с первым в кластер Proxmox и выдохнули — теперь, если один узел упадёт, второй подхватит нагрузку. Логично? Да. Работает так на практике? Нет. Двухузловой кластер Proxmox — одна из самых частых ошибок при переходе от одиночного сервера к «отказоустойчивой» инфраструктуре, и разбираться с её последствиями обычно приходится ночью, когда что-то уже упало. Разберём, почему именно два узла — это не защита, а источник новой проблемы, и что делать вместо этого.

Зачем вообще нужен кластер и что вы на самом деле получаете

Кластер Proxmox — это не «два сервера, которые подстраховывают друг друга» в бытовом смысле. Технически это группа узлов, которые постоянно синхронизируют между собой конфигурацию (через corosync) и договариваются, кто сейчас имеет право управлять ресурсами кластера — включённостью VM, их миграцией, HA-переключением. Это распределённая система с общим состоянием, а не просто два сервера рядом.

Из кластера вы получаете:

  • Единый веб-интерфейс для управления всеми узлами.
  • Живую миграцию VM между узлами без остановки.
  • HA (High Availability) — автоматический перезапуск VM на другом узле, если исходный узел отказал.

Именно последний пункт чаще всего и есть цель, ради которой связку из двух серверов вообще решают делать кластером. И именно он ломается первым при двух узлах — потому что HA-переключение требует кворума, а кворум в кластере из двух узлов работает не так, как кажется интуитивно.

Что такое кворум и почему это не формальность

Кворум — это минимальное число узлов кластера, которые должны быть на связи друг с другом, чтобы кластер считал себя работоспособным и разрешал выполнять операции, меняющие состояние (включить/выключить VM через HA, смигрировать ресурс, изменить конфигурацию). Правило простое: у кластера должен быть кворум — простое большинство от общего числа голосов (по умолчанию по одному голосу на узел), — иначе он блокирует потенциально опасные операции.

Зачем это нужно? Представьте, что сеть между узлами оборвалась (переключился коммутатор, отвалился провайдер, кто-то не туда воткнул патч-корд), но оба узла живы и продолжают работать. Без механизма кворума каждая половина кластера решила бы, что она главная, и продолжила бы независимо запускать и переключать VM. Это состояние называется split-brain — обе части разделённого кластера считают себя единственно верной и активно работают, не зная друг о друге. Итог предсказуем: одна и та же VM может оказаться запущенной на двух узлах одновременно, оба экземпляра пишут в свой локальный диск, а после восстановления связи данные попросту не сходятся — и корректно смержить два разошедшихся образа диска уже нельзя. Кворум — это защита именно от такого сценария: если большинства голосов нет, кластер сознательно останавливает рискованные операции, а не пытается угадать, кто прав.

Мы не будем здесь разворачивать полную теорию кворума и работы corosync — это отдельная большая тема с весами голосов, QDevice-алгоритмами и поведением при разных топологиях сети. Для этой статьи важно только одно следствие из базового правила «нужно строгое большинство».

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Почему для двух узлов большинство — это тоже два

Вот здесь и кроется ловушка. Посчитаем простое большинство для разного числа узлов:

Всего узловГолосов нужно для кворумаСколько узлов может отказать
110 (кластера как такового нет)
220
321
431
532

Для кластера из двух узлов большинство от двух голосов — это два голоса. Не полтора, округлённых в вашу пользу, а именно два из двух. Значит, если откажет любой из двух узлов — неважно, основной или «резервный», у оставшегося в одиночестве узла есть только один голос из двух возможных. Большинства нет. Кворум потерян.

А без кворума Proxmox (точнее, встроенный в него HA-manager) намеренно блокирует операции, которые могли бы привести к рассинхронизации данных, — в том числе именно HA-перезапуск VM с упавшего узла на живой. Получается парадокс: ровно в момент, когда отказоустойчивость нужна больше всего — узел упал, — кластер отказывается делать то единственное, ради чего его строили.

Дополнительно нужно понимать: если рвётся только сеть между узлами (fencing по сети), а не сам узел, оставшийся в одиночестве узел тоже теряет кворум и точно так же блокирует операции с VM на себе — даже если физически он абсолютно исправен и продолжает выполнять уже запущенные VM. Он просто не может ничего *менять*: ни мигрировать, ни перезапускать по HA, ни безопасно изменять конфигурацию кластера.

Три сценария отказа и что происходит в каждом

Разберём по шагам, что реально случится в кластере из двух узлов (pve1 и pve2) при разных типах сбоя.

Сценарий 1: узел pve2 полностью выключился (аппаратный отказ, питание). pve1 теряет связь с pve2, видит 1 голос из 2 — кворума нет. HA-ресурсы, которые были на pve2, НЕ перезапускаются на pve1 автоматически, пока кворум не будет искусственно восстановлен. VM, которые были на pve1 и уже работали, продолжают работать (уже запущенные процессы не убиваются), но управлять кластером — мигрировать, менять HA-группы, включать выключенные VM через кластерный менеджер — нельзя.

Сценарий 2: разрыв сети между узлами, оба живы (split-brain по сети). Это самый опасный случай. Оба узла видят по 1 голосу из 2 и теряют кворум одновременно — оба блокируют операции. Это, кстати, «правильное» с точки зрения безопасности данных поведение: без fencing (принудительного отключения потерянного узла, STONITH) кластер не может быть уверен, что второй узел действительно мёртв, а не просто недоступен по сети. Поэтому он по умолчанию бездействует с обеих сторон — VM просто не переключаются никуда.

Сценарий 3: вы вручную выводите один узел на обслуживание (обновление, замена диска). Тот же эффект, что в сценарии 1, только предсказуемо: пока второй узел в оффлайне, оставшийся живёт без кворума. Если в этот момент откажет что-то ещё на живом узле — восстанавливать придётся вручную, кластер не поможет.

Проверить состояние кворума можно командой:

pvecm status

В выводе смотрите на строку QuorateYes означает, что кворум есть, No — что кластер сейчас не может выполнять операции, требующие консенсуса.

Как временно "победить" потерю кворума — и почему так делать не стоит на постоянку

В Proxmox есть ручной способ заставить единственный оставшийся узел работать так, будто кворум есть:

pvecm expected 1

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

Проблема в том, что если второй узел на самом деле жив (просто отвалилась сеть) и на нём тоже что-то продолжает крутиться, вы своими руками создаёте ровно тот split-brain, от которого кворум должен был защищать. Использовать pvecm expected 1 на постоянной основе или в автоматике (скрипт, который дёргает эту команду при потере соседа) — плохая идея: вы отключаете единственный механизм защиты от рассинхронизации данных, оставляя голую иллюзию отказоустойчивости.

Правильное решение: третий узел или QDevice

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

Вариант 1: третий полноценный узел. Три узла Proxmox — три голоса, кворум = 2. Отказ любого одного узла оставляет два живых с большинством 2 из 3 — HA работает штатно, VM с упавшего узла перезапускаются автоматически. Это самый надёжный вариант, если бюджет позволяет держать три сервера под виртуализацию (не обязательно одинаковой мощности — третий узел может быть скромнее по ресурсам, если на него не планируется реальная нагрузка VM, только участие в кворуме и, при необходимости, приём мигрировавших VM).

Вариант 2: QDevice. Если полноценный третий сервер виртуализации не оправдан по деньгам или по железу, Proxmox поддерживает QDevice — лёгкий внешний узел-свидетель, который участвует только в голосовании кворума и не несёт нагрузки VM вообще. Технически это отдельный, обычно совсем небольшой сервер (может быть даже минимальная VPS в третьей локации) с установленным corosync-qnetd, к которому оба «боевых» узла Proxmox подключаются как клиенты QDevice (corosync-qdevice). При такой схеме у вас формально 3 голоса (по одному от каждого PVE-узла плюс голос QDevice), кворум = 2, и отказ любого одного из двух рабочих узлов оставляет оставшемуся узлу и QDevice большинство 2 из 3.

Важный практический плюс QDevice: его стоит размещать в третьей, физически независимой локации (не в той же стойке и желательно не у того же провайдера, что и оба основных узла) — тогда авария целого дата-центра с обоими узлами кластера не превращается в дополнительную путаницу с голосованием, а сам QDevice как отдельная точка отказа не связан с инфраструктурой, от отказа которой вы защищаетесь.

Честный вывод: когда кластер вообще не нужен

Если бюджет реально ограничивает вас двумя физическими серверами и третий узел или QDevice в обозримом будущем не появится — часто разумнее вообще не объединять эти два сервера в кластер Proxmox.

Два независимых сервера без кластеризации, каждый со своим локальным Proxmox (или вовсе без него) и собственной стратегией резервного копирования VM на внешнее хранилище, дают вам:

  • Предсказуемое поведение при отказе — сервер, который жив, просто продолжает работать, никакого кворума и блокировок нет в принципе, потому что нет распределённого состояния, которое надо защищать.
  • Восстановление вручную, но осознанно — вы разворачиваете бэкап VM на живом сервере и включаете его, когда решите, а не ждёте, пока кластер согласится это разрешить.
  • Меньше движущихся частей — нет corosync, нет сетевых требований к latency между узлами (для кластера Proxmox рекомендуется низкая и стабильная задержка между узлами, что не всегда достижимо, если серверы физически разнесены), нет риска, что баг или временная сетевая проблема в самом кластерном ПО положит оба узла одновременно.

Двухузловой псевдокластер добавляет сложность (настройка corosync, сетевые требования, мониторинг кворума) не взамен на реальную защиту от отказа одного узла, а фактически без неё — при этом создавая новый режим отказа (потеря кворума), которого не было бы у двух независимых серверов. Это тот редкий случай в инфраструктуре, когда более «продвинутое» решение объективно менее надёжно, чем простое.

Если задача — просто иметь запасной сервер на случай отказа основного, взгляните на неё именно как на задачу резервного сервера, а не кластера: с решением, включаете ли вы резерв заранее (горячий или холодный режим), и трезвой оценкой того, сколько вообще стоит нужный вам уровень отказоустойчивости — иногда ответ «два независимых сервера с бэкапами» обходится дешевле и работает надёжнее, чем хрупкий кластер из двух узлов.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Можно ли добавить третий узел позже, когда бюджет позволит, не пересобирая кластер?

Да, pvecm add подключает новый узел к существующему кластеру без остановки VM на текущих узлах. Если изначально строите кластер из двух узлов с прицелом на будущий третий, это нормальный путь — просто явно держите в уме, что до появления третьего узла (или QDevice) HA не будет работать так, как ожидается.

А если использовать корневого свидетеля не через QDevice, а просто добавить третий узел Proxmox без единой VM на нём?

Это по сути и есть вариант 1 из этой статьи — работает, и даже проще в настройке, чем QDevice, потому что не нужен отдельный сервис corosync-qnetd. Минус — нужен ещё один полноценный сервер с установленным Proxmox, а не лёгкий свидетель.

Что будет, если в кластере из двух узлов вообще не включать HA, а мигрировать VM вручную?

Ручная миграция (qm migrate) при живом кворуме работает нормально. Но если кворум потерян (один узел упал), вы всё равно не сможете смигрировать или включить VM с упавшего узла через кластерный интерфейс, пока не восстановите кворум — вручную через pvecm expected 1 или подняв второй узел обратно. То есть проблема кворума актуальна независимо от того, используете вы HA-автоматику или мигрируете руками.

Три узла обязательно должны быть одинаковой мощности?

Нет. Для целей кворума важно только количество голосов (по умолчанию — по одному на узел), а не производительность узла. Третий узел может быть заметно слабее первых двух, если вы не планируете держать на нём боевую нагрузку постоянно — только принимать VM в аварийной ситуации или просто участвовать в голосовании.

QDevice можно разместить на VPS у другого провайдера?

Да, и это частая практика — небольшая VPS с минимальными ресурсами вполне подходит для роли QDevice, поскольку она не выполняет виртуализацию, а только участвует в голосовании кворума. Требование — стабильная сетевая связность до обоих основных узлов.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →