Обновили пакеты, перезагрузили сервер - и он не поднялся. По SSH не достучаться, а вся починка сводится к одному экрану, который вы обычно не видите: меню GRUB. Разбираем, как до него добраться через консоль панели, загрузиться со старым ядром и починить конфиг загрузчика.

Обычная история: apt upgrade, среди пакетов новое ядро, перезагрузка - и сервер не вернулся. Пинг молчит, SSH отвечает таймаутом, сайт лежит. Когда Ubuntu не загружается после обновления ядра, чинить по сети уже нечего: машина до сети просто не доходит, она застряла на экране, которого вы никогда не видели, потому что на VPS его никто не показывает. Этот экран - меню загрузчика GRUB, и вся починка происходит там. Разберём по порядку: как добраться до консоли сервера, как поймать меню, как вручную загрузиться со старым рабочим ядром и что потом сделать, чтобы следующее обновление не устроило то же самое.

Коротко. SSH не поможет, нужна VNC-консоль сервера из личного кабинета - она подключена к «монитору» виртуальной машины и работает, даже когда сети нет. Перезагрузите сервер из панели и сразу начните часто нажимать Esc (или держать Shift на BIOS-загрузке), пока не появится меню GRUB. В меню зайдите в «Advanced options for Ubuntu», выберите предыдущее ядро из списка - в большинстве случаев система на нём поднимется. Дальше уже по SSH: df -h /boot (самая частая причина - переполненный раздел), sudo dpkg --configure -a, sudo update-initramfs -u -k all, sudo update-grub. Если вместо меню появилось приглашение grub rescue>, загрузчик не нашёл свой рабочий каталог: путь задаётся вручную, потом чинится через grub-install. И обязательный финальный шаг - привести /etc/default/grub в вид, при котором меню на сервере вообще показывается. На машине без монитора спрятанное меню экономит три секунды и стоит часа простоя.

Где именно ломается загрузка

Загрузка сервера - цепочка из четырёх звеньев, и знать её полезно, потому что по картинке на экране сразу видно, на каком звене всё встало.

  • Прошивка (BIOS или UEFI - программа, зашитая в «материнскую плату» виртуальной машины) ищет на диске загрузчик и передаёт ему управление.
  • GRUB - загрузчик. Он читает свой конфиг /boot/grub/grub.cfg, рисует меню и загружает выбранное ядро.
  • Ядро Linux - файл /boot/vmlinuz-6.8.0-84-generic и ему подобные. Номер в имени и есть версия ядра.
  • initramfs - маленькая временная файловая система, которую ядро разворачивает в оперативной памяти, чтобы найти и подключить настоящий корневой диск. Лежит рядом, файлом /boot/initrd.img-6.8.0-84-generic. Если его нет или он битый, ядро стартует и тут же упирается в то, что корня не существует.

Дальше управление получает systemd, и это уже совсем другая история: если вы видите строки вида Started ... и [ OK ], загрузчик отработал нормально и проблема не в нём.

Что видно в консоли

На каком звене встало

Куда идти

Пустой чёрный экран, мигающий курсор, никакого меню

Прошивка не нашла загрузчик, либо меню просто скрыто

Шаг 2, затем раздел про grub rescue

grub rescue> или error: no such partition

GRUB запустился, но не нашёл свой каталог /boot/grub

Раздел «Если вместо меню - grub rescue»

Меню GRUB показано и висит, ничего не происходит

Прошлая загрузка не удалась, GRUB ждёт вашего выбора

Шаг 3 плюс правка GRUB_RECORDFAIL_TIMEOUT

error: file '/boot/vmlinuz-...' not found

В меню есть пункт, а файла ядра на диске уже нет

Шаг 3, затем «Почему Ubuntu не загружается»

Kernel panic - not syncing: VFS: Unable to mount root fs

Ядро стартовало, initramfs отсутствует или повреждён

Шаг 3, затем update-initramfs

Система грузится, но uname -r показывает старую версию

Загрузчик работает, просто помнит ваш прошлый выбор

Раздел «Сервер сам грузит старое ядро»

Строки [ OK ] Started ..., потом тишина

Это уже не GRUB, а сервисы или сеть

Частые проблемы Linux-сервера

Шаг 1. Консоль сервера в панели: SSH тут бесполезен

SSH - это служба внутри уже загруженной системы. Пока Ubuntu не дошла до запуска сервисов, подключаться некуда, и бесконечные попытки ssh root@... ничего не дадут. Нужен другой канал: VNC-консоль (она же веб-консоль) в личном кабинете. Технически это виртуальный монитор с клавиатурой, воткнутые прямо в виртуальную машину, поэтому она показывает всё с самого первого экрана прошивки, включая меню GRUB.

В личном кабинете my.weasel.cloud откройте страницу нужного сервера и найдите раздел консоли или VNC. В соседнем меню обычно лежит и кнопка перезагрузки - она понадобится через минуту. Открывайте консоль до перезагрузки: окно должно быть уже активно в момент старта, иначе вы пропустите те несколько секунд, когда меню ловится.

Одна особенность, из-за которой люди сдаются на этом месте: веб-консоль передаёт нажатия с задержкой и иногда теряет их. Работайте медленно, кликните мышью внутрь окна консоли перед началом ввода, чтобы фокус был там, а не на странице панели.

Шаг 2. Как поймать меню GRUB, если оно не показывается

На серверных образах Ubuntu меню почти всегда спрятано: когда на машине одна операционная система, GRUB настроен проскакивать выбор мгновенно. Ловится оно так: нажмите в панели перезагрузку и сразу же начните часто, раз в полсекунды, нажимать Esc. Это работает на UEFI-загрузке. Если у сервера классический BIOS, вместо этого нужно держать зажатым Shift с первой секунды. Не знаете, что у вас - делайте и то и другое по очереди в две попытки, ничего не сломается.

Появилось меню со списком вроде Ubuntu и Advanced options for Ubuntu - отлично, идите к шагу 3. Не появилось за две-три попытки - смотрите раздел про grub rescue: скорее всего, GRUB не доходит до отрисовки меню вообще.

Отдельный случай, который выглядит как зависший сервер: GRUB помечает неудачную загрузку флагом recordfail, и на следующий раз показывает меню с очень длинным ожиданием, вместо того чтобы грузиться самому. На машине с монитором это разумно, на VPS - катастрофа: сервер «не поднимается» часами, хотя на самом деле терпеливо ждёт, пока кто-нибудь нажмёт Enter. Если в консоли видно меню и таймер не тикает - просто выберите пункт руками. Как убрать это поведение насовсем, разберём ниже.

Шаг 3. Загрузиться со старым ядром и увидеть настоящую ошибку

Ubuntu не удаляет предыдущее ядро при обновлении именно на такой случай. Старые версии лежат в подменю: стрелками выберите Advanced options for Ubuntu, нажмите Enter, и вы увидите список - по две строки на каждую версию, обычная и (recovery mode).

Возьмите вторую сверху обычную строку, то есть предыдущее ядро, и нажмите Enter. Если система поднялась и SSH ответил - самое сложное позади, дальше чините уже по сети. Это разовая загрузка: следующая перезагрузка снова уйдёт на сломанное ядро, пока вы не почините конфиг.

Если вы не понимаете, на чём всё падает, стоит сначала увидеть саму ошибку. По умолчанию Ubuntu прячет сообщения ядра за параметрами quiet splash. Подсветите нужный пункт меню и нажмите e - откроется редактор этой записи. Найдите строку, начинающуюся с linux, сотрите в ней quiet splash и нажмите Ctrl+X (или F10), чтобы загрузиться с изменениями. Правка живёт до перезагрузки, файл на диске не меняется.

На экране пойдут все сообщения ядра, и последние строки перед остановкой обычно прямо называют причину: не найден корневой раздел, паника из-за initramfs, ошибка файловой системы. Их и записывайте, по ним ищется решение.

Если все ядра в списке падают одинаково, попробуйте тем же способом дописать в конец строки linux параметр systemd.unit=rescue.target. Система поднимется в минимальном режиме с одним пользователем и попросит пароль root. На WeaselCloud он у вас есть - показан в панели на странице сервера, подробности в разборе входа под root в Ubuntu. На провайдерах, где root заблокирован, этот путь просто не работает, и это ещё одна причина знать свой пароль root заранее.

Если вместо меню - приглашение grub rescue

Строка grub rescue> означает конкретную вещь: первая, крошечная часть GRUB запустилась с диска, а свой каталог с модулями и конфигом (/boot/grub) она не нашла. Бывает после переноса или восстановления сервера из образа, после изменения разделов, после прерванного обновления самого пакета grub-pc. Из этого приглашения доступно всего несколько команд, но их хватает, чтобы загрузиться один раз вручную.

Сначала посмотрите, какие разделы GRUB вообще видит:

ls

Вывод будет вида (hd0) (hd0,gpt2) (hd0,gpt1). Теперь нужно понять, на каком из них лежит система. Проверяйте по очереди:

ls (hd0,gpt2)/

  • увидели каталоги boot, etc, home - это корневой раздел, он и нужен;
  • увидели grub, vmlinuz-..., initrd.img-... - это отдельный раздел /boot, тогда путь до каталога GRUB будет короче, без /boot в начале;
  • ответ unknown filesystem - не тот раздел, пробуйте следующий номер.

Дальше скажите GRUB, где его дом, и подгрузите модуль обычного режима:

set prefix=(hd0,gpt2)/boot/grub
set root=(hd0,gpt2)
insmod normal
normal

  • prefix - каталог, откуда GRUB берёт модули и grub.cfg;
  • root - раздел, относительно которого считаются все пути;
  • insmod normal подгружает модуль полноценного режима, normal его запускает. Если всё указано верно, на экране появится обычное меню GRUB.

Загрузитесь из меню любым рабочим ядром и сразу закрепите починку, иначе следующая перезагрузка вернёт вас в то же приглашение. На машине с обычной BIOS-загрузкой загрузчик переустанавливается на диск целиком, не на раздел:

sudo grub-install /dev/vda
sudo update-grub

На UEFI-машине команда другая, и диск в ней не указывается - загрузчик ставится в служебный раздел EFI:

sudo grub-install --target=x86_64-efi --efi-directory=/boot/efi
sudo update-grub

Как отличить одно от другого: если каталог /sys/firmware/efi существует, у вас UEFI. Команда [ -d /sys/firmware/efi ] && echo UEFI || echo BIOS отвечает одним словом.

Почему Ubuntu не загружается после обновления ядра

Вы уже внутри системы, дальше ищем причину. В подавляющем большинстве случаев виновато одно из трёх, и проверяются они за минуту.

Первое: закончилось место в /boot. Если этот каталог вынесен в отдельный маленький раздел, пары лишних ядер хватает, чтобы он заполнился. Тогда пакет ядра ставится, а initramfs для него собрать не удаётся - в выводе apt мелькает ошибка про нехватку места, которую легко пропустить между сотней других строк.

df -h /boot
ls -l /boot

Смотрите на столбец Use%. Если там 100% или около того - причина найдена. И сразу сверьте списки файлов: у каждой версии должна быть пара vmlinuz-версия и initrd.img-версия. Ядро без своего initrd не загрузится, это и есть та самая паника про unable to mount root fs.

Чистим лишние ядра штатным способом, не руками через rm:

sudo apt autoremove --purge

Команда удаляет пакеты старых ядер, которые больше ничем не удерживаются, и сама перегенерирует конфиг GRUB в конце. Удалять файлы из /boot напрямую нельзя: пакетная система продолжит считать, что ядро на месте, и конфиг получится ещё более неправильным, чем был.

Второе: обновление оборвалось на середине. Потеряли соединение во время apt upgrade, нажали Ctrl+C, сервер ушёл в перезагрузку сам - и часть пакетов осталась в настроенном наполовину состоянии. Лечится двумя командами:

sudo dpkg --configure -a
sudo apt --fix-broken install

Первая досоздаёт всё, что не докрутилось, включая сборку initramfs и обновление меню GRUB. Вторая доставляет недостающие зависимости. Обе безопасно запускать, даже если проблема была не в этом: на здоровой системе они просто ничего не сделают.

Третье: initramfs есть, но собран неправильно. Такое бывает после ручных экспериментов с модулями или дисковыми настройками. Пересобрать для конкретной версии:

sudo update-initramfs -u -k 6.8.0-84-generic

Вместо 6.8.0-84-generic подставьте свою версию из ls /boot. Ключ -u означает «обновить существующий», -k - для какого ядра. Чтобы пересобрать сразу для всех установленных версий, вместо номера пишется all.

После любой из этих операций обязательно перечитайте меню:

sudo update-grub

В выводе вы должны увидеть строки Generating grub configuration file ..., затем по одной строке Found linux image: и Found initrd image: на каждую версию, и done в конце. Если какой-то версии в списке нет - значит, её файлов действительно нет на диске, и дело не в загрузчике. Если нет ни одной строки Found initrd image - initramfs не собрались, возвращайтесь к первому пункту про место.

Чиним /etc/default/grub: меню, таймаут и куда идёт вывод

Файл /etc/default/grub - это настройки, из которых update-grub собирает готовый /boot/grub/grub.cfg. Правится всегда первый, второй трогать бессмысленно: он перезаписывается при каждом обновлении ядра, и ваши правки исчезнут в самый неподходящий момент.

sudo nano /etc/default/grub

Разумный набор значений для сервера, к которому есть VNC-консоль:

GRUB_TIMEOUT_STYLE=menu
GRUB_TIMEOUT=5
GRUB_RECORDFAIL_TIMEOUT=5

  • GRUB_TIMEOUT_STYLE=menu - показывать меню всегда, а не прятать его. Пять секунд задержки на старте не стоят того, чтобы ловить экран нажатиями Esc в панике.
  • GRUB_TIMEOUT=5 - через пять секунд грузится пункт по умолчанию. Ноль означает «не показывать вовсе», минус единица - «ждать вечно», и вот этого на сервере точно не надо.
  • GRUB_RECORDFAIL_TIMEOUT=5 - тот самый параметр, который не даст серверу зависнуть в меню после неудачной загрузки. Без него сервер после первого же сбоя может простоять в ожидании нажатия клавиши, пока вы не откроете консоль.

Дальше - ловушка, на которую тратят по часу. Вы правите /etc/default/grub, запускаете update-grub, а поведение не меняется. Причина в том, что рядом есть каталог /etc/default/grub.d/, и файлы оттуда читаются после основного, то есть переопределяют его. В облачных образах Ubuntu там обычно лежит готовый файл с настройками для облака, который как раз и выставляет нулевой таймаут.

ls -l /etc/default/grub.d/
grep -r "GRUB_TIMEOUT" /etc/default/grub /etc/default/grub.d/

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

sudo nano /etc/default/grub.d/99-console.cfg

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

sudo update-grub

Проверить результат, не перезагружаясь, можно грепом по собранному конфигу: grep -E "^set timeout|^\s+set timeout" /boot/grub/grub.cfg покажет, какие значения реально попали в меню.

Сервер сам грузит старое ядро

Отдельный симптом: система загружается нормально, но uname -r показывает не ту версию, которую вы ставили. Чаще всего это последствие ручного выбора в меню. Если в настройках включено запоминание выбора, GRUB честно сохраняет последний вариант и с тех пор грузит его всегда.

sudo grub-editenv list

Строка saved_entry=... в выводе и есть залипший выбор. Снять его:

sudo grub-editenv /boot/grub/grubenv unset saved_entry
sudo update-grub

После этого сервер снова будет грузить первый пункт меню, то есть самое свежее установленное ядро. Обратная задача - наоборот, закрепить конкретное старое ядро, пока разбираетесь с новым. Тогда в /etc/default/grub ставится GRUB_DEFAULT с точным именем пункта; список имён выдаёт команда sudo grep -E "menuentry |submenu " /boot/grub/grub.cfg | cut -d"'" -f2. Вариант проще и надёжнее - на время запретить установку новых ядер через sudo apt-mark hold linux-image-generic, но держать так долго нельзя: вместе с новыми версиями вы перестанете получать исправления безопасности ядра.

Как закрепить, чтобы не повторилось

Три вещи, которые реально снижают шанс повторения, по убыванию пользы.

  • Перезагружайтесь сразу после обновления ядра, а не «когда-нибудь потом». Если перезагрузка случится через месяц, вы уже не вспомните, что именно поменялось, и связь между апдейтом и отказом придётся искать заново. Делайте это тогда, когда у вас есть полчаса на разбор, а не вечером пятницы.
  • Держите два-три ядра, но следите за местом. Одно оставлять опасно - откатываться будет некуда. Пять держать незачем: на маленьком /boot это и есть причина отказа. Регулярный sudo apt autoremove --purge плюс взгляд на df -h /boot раз в месяц закрывают вопрос.
  • Сделайте снимок диска перед крупным обновлением, если он доступен в панели. Откат к снимку занимает минуты, а разбор сломанной загрузки по VNC - часы.

И отдельно про вывод на экран. Убедитесь, что в GRUB_CMDLINE_LINUX_DEFAULT есть console=tty1 - это обычный экран, тот самый, который показывает VNC-консоль. В облачных образах туда часто добавляют ещё console=ttyS0 для последовательного порта, и порядок имеет значение: последнее указанное устройство становится основным для сообщений системы. Если в консоли панели пусто, а загрузка явно идёт - почти наверняка весь вывод уехал в последовательный порт.

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

Как войти в меню GRUB на VPS без монитора?

Через VNC-консоль или веб-консоль в личном кабинете провайдера: она подключена к виртуальному монитору машины и показывает экран с самого старта, в отличие от SSH. Откройте консоль, отправьте перезагрузку и сразу начните часто нажимать Esc (для UEFI) или держать Shift (для BIOS). Окно консоли должно быть активно и в фокусе до начала перезагрузки, иначе первые нажатия потеряются.

Что делать, если вместо меню появилось grub rescue?

Это значит, что GRUB стартовал, но не нашёл каталог /boot/grub со своими модулями. Выполните ls, найдите нужный раздел через ls (hd0,gpt2)/, затем задайте set prefix=(hd0,gpt2)/boot/grub, set root=(hd0,gpt2), insmod normal и normal. Это загрузит систему один раз; после входа закрепите результат командами sudo grub-install и sudo update-grub, иначе следующая перезагрузка вернёт то же приглашение.

Почему update-grub не видит новое ядро?

Потому что файлов ядра нет на диске, а не потому, что загрузчик их пропустил. Проверьте ls /boot: у каждой версии должна быть пара vmlinuz- и initrd.img-. Самая частая причина отсутствия - переполненный раздел /boot, из-за которого initramfs не собрался, вторая - прерванное обновление, которое лечится командой sudo dpkg --configure -a.

Можно ли просто удалить старые ядра, чтобы освободить /boot?

Удалять нужно пакетами, а не файлами: sudo apt autoremove --purge. Если стереть vmlinuz и initrd.img командой rm, пакетная система по-прежнему будет считать ядро установленным, а в меню GRUB останется пункт, ведущий в несуществующий файл, с ошибкой error: file not found при загрузке. Одно рабочее ядро кроме текущего оставляйте всегда, иначе откатываться будет некуда.

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

Да, иначе новое ядро просто лежит на диске и не используется: работающее ядро заменяется только при перезагрузке. Проверить, требуется ли она, можно наличием файла /var/run/reboot-required. Сравните uname -r (что работает прямо сейчас) с самой свежей версией в ls /boot: если они разошлись, перезагрузка ещё не сделана.

Коротко

  • Когда сервер не поднялся после обновления, единственный рабочий канал - VNC-консоль из панели, SSH к незагруженной системе не подключается в принципе.
  • Меню GRUB на серверных образах скрыто: ловится частыми нажатиями Esc на UEFI или удержанием Shift на BIOS сразу после команды перезагрузки.
  • Предыдущее ядро лежит в подменю «Advanced options for Ubuntu» - это штатный путь отката, ради него Ubuntu и хранит старые версии.
  • Клавиша e в меню открывает разовую правку записи: уберите quiet splash, чтобы увидеть настоящую ошибку, изменения не сохраняются на диск.
  • grub rescue> - это не поломанный диск, а потерянный путь к /boot/grub: задаётся вручную через set prefix, закрепляется через grub-install.
  • Три главные причины сбоя после апдейта: переполненный /boot, оборванное обновление (sudo dpkg --configure -a) и не собранный initramfs (sudo update-initramfs -u -k all).
  • Правится только /etc/default/grub и свой файл в /etc/default/grub.d/; /boot/grub/grub.cfg генерируется и перезаписывается сам.
  • Файлы из /etc/default/grub.d/ читаются после основного и переопределяют его - поэтому свой файл называйте так, чтобы он был последним по алфавиту.
  • Любая правка вступает в силу только после sudo update-grub.
  • На сервере без монитора меню должно показываться: GRUB_TIMEOUT_STYLE=menu, GRUB_TIMEOUT=5 и обязательно GRUB_RECORDFAIL_TIMEOUT=5, иначе после первого сбоя машина будет вечно ждать нажатия клавиши.

Что дальше

Если система загрузилась, но по сети всё равно недоступна, проблема уже не в загрузчике - смотрите разбор как перезапустить сеть в Ubuntu и Debian. Пароль root из панели пригодится не только в rescue-режиме: чем отличаются su -, sudo -i и прямой вход, разложено в статье про вход под root в Ubuntu. Общий список того, что чаще всего ломается на свежем сервере, собран в материале частые проблемы Linux-сервера.