Автозапуск и порядок старта виртуалок после перезагрузки узла
Узел перезагрузился — плановое обслуживание, обновление ядра или банальный сбой питания — и через пару минут в чат посыпались алерты: приложение не может подключиться к базе, сайт отдаёт 500-ю, авторизация не работает. При этом сами виртуалки живы и вроде бы стартовали. Проблема почти всегда не в том, что VM не поднялись, а в том, в каком порядке и с какой задержкой они это сделали. Разберём, как включить автозапуск правильно и — что важнее — как не дать зависимым сервисам стартовать раньше, чем то, от чего они зависят.
Содержание
- Почему автозапуск в Proxmox не включён по умолчанию
- Включаем автозапуск для конкретной VM
- Почему порядок старта критичен: живой пример с базой и приложением
- Order и up delay: как назначить приоритет и задержку
- Практическая схема: три уровня приоритета
- Честно о пределах: order — это эвристика, а не гарантия готовности
Почему автозапуск в Proxmox не включён по умолчанию
Когда вы создаёте виртуальную машину в Proxmox через мастер или qm create, параметр автозапуска при старте узла по умолчанию выключен. Это осознанное поведение гипервизора: он не может знать, нужна ли вам конкретная тестовая VM после каждой перезагрузки железа, и не должен решать это за вас. В результате многие сталкиваются с этим уже postfactum — сервер перезагрузился (по расписанию хостера, из-за апдейта, из-за отключения электричества), а половина виртуалок так и осталась выключенной, потому что никто явно не сказал Proxmox их поднимать.
Если вы только разворачиваете первую виртуалку на узле и ещё не сталкивались с базовыми параметрами Proxmox — стоит сначала закрыть этот пробел, прежде чем переходить к автозапуску: proxmox-ve-s-nulya-pervaya-virtualka.
Проверить текущее состояние легко:
qm config 101 | grep onboot
Если строки onboot нет вообще или стоит onboot: 0 — при следующей перезагрузке узла эта VM не стартует сама. То же самое актуально для контейнеров LXC, только команда другая:
pct config 201 | grep onboot
Практический момент, который часто упускают: наличие галочки «Start at boot» в веб-интерфейсе — это ровно тот же параметр onboot, ничего дополнительного через GUI не настраивается. Поэтому дальше проще и надёжнее работать через консоль — так вы сразу видите и меняете оба нужных параметра, onboot и startup, одной командой.
Включаем автозапуск для конкретной VM
Базовая настройка — один флаг:
qm set 101 --onboot 1
Для LXC-контейнера аналогично:
pct set 201 --onboot 1
Это изменение попадает прямо в конфиг гостя — для VM это /etc/pve/qemu-server/101.conf, для контейнера /etc/pve/lxc/201.conf. Можно открыть файл и убедиться, что появилась строка onboot: 1. Если у вас десятки виртуалок и включать автозапуск руками для каждой утомительно, можно пройтись циклом по списку ID:
for vmid in 101 102 103; do
qm set "$vmid" --onboot 1
done
На этом шаге у большинства администраторов настройка и заканчивается — кажется, что раз все нужные VM помечены на автозапуск, дело сделано. Формально это правда: после перезагрузки узла все они действительно поднимутся. Но именно здесь и начинается вторая, куда менее очевидная часть задачи — то, в каком порядке они это сделают.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверПочему порядок старта критичен: живой пример с базой и приложением
Возьмём типичную связку из трёх виртуалок на одном узле: db (PostgreSQL или MySQL), app (веб-приложение, которое подключается к этой базе при старте) и, скажем, dns/auth-сервис, от которого зависят оба. Служба pve-guests.service, отвечающая за автозапуск при загрузке Proxmox, без дополнительных настроек стартует все помеченные onboot: 1 виртуалки практически одновременно — с точки зрения гипервизора это независимые задачи, и он не обязан знать, что app не имеет смысла поднимать раньше db.
Дальше сценарий разворачивается так: узел загрузился, гипервизор параллельно запускает qm start для всех VM. Пока db только проходит POST виртуального BIOS, монтирует диски и запускает саму СУБД (а если предыдущее выключение было аварийным — ещё и накатывает журнал предзаписи, что может занять заметно больше времени, чем обычный старт), app уже полностью загрузила ОС и на старте пытается открыть соединение с базой. Соединение отклоняется — порт ещё не слушается, либо СУБД отвечает «ещё не готова принимать подключения». И здесь всё зависит от того, как написано приложение: часть фреймворков и оркестраторов (например, Kubernetes с readinessProbe, или сервисы под systemd с Restart=on-failure) переживут это спокойно и переподключатся через несколько секунд. Но очень многие приложения — особенно написанные без явной оглядки на такие сценарии — просто падают с необработанным исключением при первой неудачной попытке подключения на старте и не поднимаются заново сами. В результате узел загрузился штатно, все VM «зелёные» в интерфейсе Proxmox, а сервис недоступен, пока кто-то вручную не перезапустит app уже после того, как база реально поднялась.
Это не гипотетическая история — с ней сталкиваются практически на каждом узле, где есть связка «база + зависящее от неё приложение» и включён автозапуск без настройки порядка. Разбор похожего симптома, только на уровне самой СУБД, а не гипервизора: mysql-ne-startuet-posle-perezagruzki. Хорошая новость: у Proxmox есть штатный механизм именно для этого случая.
Order и up delay: как назначить приоритет и задержку
За порядок старта и задержки между группами отвечает параметр startup в конфиге гостя, а не отдельная настройка в GUI (в вебе она тоже доступна — вкладка Options → Start/Shutdown order — но синтаксис проще увидеть через CLI). Три поля:
- order — номер группы приоритета. Меньшее значение стартует раньше. VM без указанного
orderстартуют после всех, у кого он задан явно. - up — задержка в секундах после запуска этой VM, прежде чем гипервизор начнёт поднимать следующую по очереди группу.
- down — аналогичная задержка при выключении, но в обратном порядке (что стартовало последним — выключается первым; критичная инфраструктура типа базы выключается последней).
Настройка для нашего примера с тремя ролями:
# DNS/auth — стартует первым, приоритет 1
qm set 100 --startup order=1,up=30
# База данных — стартует вторым, приоритет 2
qm set 101 --startup order=2,up=60
# Приложение — стартует третьим, приоритет 3, задержка на выключение не нужна
qm set 102 --startup order=3,up=30
После этого в /etc/pve/qemu-server/101.conf появится строка:
onboot: 1
startup: order=2,up=60
Логика следующая: гипервизор при старте узла сначала поднимает всё с order=1 (в нашем случае — DNS/авторизацию), ждёт 30 секунд, затем поднимает всё с order=2 (базу данных), ждёт уже 60 секунд — потому что СУБД обычно инициализируется дольше, чем DNS-сервис, — и только после этого стартует order=3 (приложение). Если у вас несколько VM с одинаковым order, они запускаются параллельно внутри своей группы, а задержка up отсчитывается один раз на всю группу, а не на каждую VM внутри неё по отдельности.
Для LXC-контейнеров синтаксис идентичен:
pct set 201 --startup order=2,up=60
Проверить итоговый порядок для всех гостей узла разом:
qm list --full 2>/dev/null | awk '{print $1}' | while read -r id; do
[ "$id" = "VMID" ] && continue
echo "VM $id: $(qm config "$id" 2>/dev/null | grep -E 'onboot|startup')"
done
Практическая схема: три уровня приоритета
На практике удобно заранее договориться о трёх-четырёх уровнях приоритета для всех виртуалок на узле, а не подбирать order для каждой VM отдельно по ситуации:
| Уровень | order | Роль | Типичный up delay |
|---|---|---|---|
| 1 | 1 | Базовая инфраструктура: DNS, LDAP/авторизация, время (NTP), если поднято отдельной VM | 20-30 сек |
| 2 | 2 | Базы данных, брокеры сообщений (PostgreSQL, MySQL, Redis, RabbitMQ) | 45-90 сек |
| 3 | 3 | Бэкенд-приложения, API, воркеры, которые обращаются к уровню 2 | 20-40 сек |
| 4 | без order | Веб-фронтенды, статика, всё, что не имеет жёстких зависимостей на старте | — |
Задержку на уровне баз данных стоит закладывать с запасом именно на случай аварийного (не штатного) выключения предыдущей загрузки — если СУБД перед этим не завершилась штатно, а была прибита вместе с узлом при отключении питания, время восстановления из WAL/redo-логов может быть в разы больше обычного холодного старта. Ориентировочно: если ваша база в норме поднимается за 15-20 секунд, закладывайте up=60, а не up=20 — запас здесь дешевле, чем ручной перезапуск приложения посреди ночи. Точные цифры у вас будут свои — зависят от объёма базы, диска (NVMe заметно быстрее восстанавливает журнал, чем сетевое хранилище) и от того, как часто у вас случаются именно аварийные, а не плановые перезагрузки.
Если несколько VM зависят друг от друга каскадно (DNS → база → бэкенд → воркер очередей → фронтенд), просто продолжайте нумерацию: order=1,2,3,4,5. Работать с задержками в этом случае надёжнее, чем пытаться уложить всё в два уровня «инфраструктура/приложения» — реальные зависимости почти всегда длиннее одной ступени. Если же вы прикидываете, сколько виртуалок вообще имеет смысл держать на одном узле с учётом таких цепочек зависимостей — отдельно разбирали в skolko-virtualok-vlezet-na-server.
Честно о пределах: order — это эвристика, а не гарантия готовности
Здесь важно не питать иллюзий насчёт того, что именно делает up. Это не проверка готовности сервиса — это просто таймер. Гипервизор запускает VM с нужным order, ждёт заданное число секунд и переходит к следующей группе, вообще не заглядывая внутрь гостевой ОС и не проверяя, ответил ли уже PostgreSQL на порту 5432 или ещё нет. Если реальное время инициализации базы в этот раз оказалось больше, чем заложенный up delay — например, диск был занят другой операцией, или база восстанавливалась после нештатного выключения дольше обычного, — приложение всё равно стартует раньше, чем база готова принимать соединения, и мы возвращаемся к исходной проблеме, только реже.
Поэтому для по-настоящему критичных production-систем order/up стоит считать дополнительной страховкой, снижающей вероятность гонки при старте, а не гарантией её отсутствия. Более надёжный (и по-хорошему единственный полностью надёжный) уровень защиты — это логика повторных попыток подключения внутри самого приложения: retry с экспоненциальной задержкой (backoff) при установлении соединения с базой на старте, вместо падения с первой же ошибки. Это относится к коду приложения или к его обвязке — обычно правится в одном месте:
- в Python-приложениях — обёртка над
psycopg2.connect()/asyncpg.connect()с циклом повторов и нарастающей паузой (0.5с, 1с, 2с, 4с...) вместо однократной попытки; - в Node.js — то же самое для клиента
pg/mysql2, часто уже встроено в ORM (Sequelize, TypeORM) как опцияretry, но по умолчанию не всегда включено на этапе первого подключения; - в Docker Compose — паллиатив
depends_on: condition: service_healthyс health-check на самой базе (не решает проблему полностью, но не даёт контейнеру приложения даже пытаться стартовать, покаpg_isreadyне ответит успешно); - на уровне systemd внутри гостевой ОС —
Restart=on-failureиRestartSec=5для юнита приложения, чтобы даже при падении на старте сервис поднимался снова сам, без вмешательства человека.
Если такая логика в приложении уже есть — настройка order/up в Proxmox становится просто способом сократить количество этих повторов и ускорить штатный старт после перезагрузки. Если её нет — order/up снижает частоту проблемы, но не убирает её полностью, и рано или поздно совпадение медленного диска с нештатным выключением всё равно даст сбой при старте. Это стоит явно проговорить с командой разработки, а не оставлять как молчаливое допущение инфраструктуры.
Проверить, как реально отработал порядок старта после последней перезагрузки узла, можно через журнал:
journalctl -u pve-guests.service --since "1 hour ago"
Там видно, в каком порядке и с какими метками времени гипервизор поднимал каждую VM — полезно, если хочется свериться с ожидаемым order или разобраться, почему что-то пошло не по плану. Если же приложение всё-таки упало с ошибкой подключения при старте — симптомы и причины со стороны самой базы разобраны в postgresql-ne-prinimaet-podklyucheniya-prichiny-i-reshenie, а если непонятно, почему вообще случилась перезагрузка узла — в server-sam-perezagruzilsya-kak-ponyat-pochemu.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Что будет, если у двух VM одинаковый order?
Они стартуют одновременно (параллельно), а up delay для следующей группы отсчитывается от момента запуска этой группы, а не от готовности каждой VM внутри неё.
Нужно ли указывать order всем виртуалкам на узле?
Нет. VM без явного order стартуют после всех пронумерованных групп, обычно этого достаточно для сервисов без строгих зависимостей — фронтендов, статики, тестовых окружений.
Как узнать, сколько реально занимает старт базы, чтобы правильно выставить up?
Замерьте вручную: перезагрузите узел в тестовое окно, зафиксируйте время команды qm start и время, когда СУБД начинает отвечать на подключения (pg_isready для PostgreSQL, mysqladmin ping для MySQL), и заложите задержку с запасом 2-3x от этого значения — на случай нештатного выключения.
Влияет ли startup order на плановое выключение узла, а не только на старт?
Да, down работает в обратном порядке относительно order при плановом qm shutdown/выключении узла — то, что стартовало последним, выключается первым, что логично: сначала гасим приложения, потом базу.
Можно ли настроить то же самое для контейнеров LXC вперемешку с VM?
Да, order/up/down работают одинаково для qm и pct, и гипервизор учитывает их совместно вне зависимости от типа гостя — важен только сам номер order, а не то, VM это или контейнер.
Что делать, если приложение всё равно падает при холодном старте, несмотря на настроенные задержки?
Это сигнал добавить retry-логику на уровне самого приложения или его systemd-юнита (Restart=on-failure) — задержки Proxmox снижают вероятность гонки, но не заменяют устойчивость к временной недоступности зависимости.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →