Si alguna vez te pasó que actualizaste el kernel, reiniciaste tu VM en Google Cloud y te quedaste viendo el mensaje más temido del universo: No bootable device, bienvenido al club.

Te voy a contar cómo lo resolví, paso a paso, con el humor de quien estuvo 3 horas peleando con una máquina que no quería arrancar.

El diagnóstico: Google Cloud muestra “No bootable device”

La VM estaba encendida, pero no respondía ping ni SSH. La consola serial mostraba esto:

Booting from Hard Disk 0...
Boot failed: not a bootable disk
No bootable device.

Básicamente, el sistema no encontraba el bootloader. El kernel update había dejado GRUB en el suelo, noqueado.

Antes de empezar: identificar la instancia y el proyecto

Primero, asegúrate de tener el proyecto correcto:

gcloud config get-value project

Si no es el que esperabas, cámbialo:

gcloud config set project MI-PROYECTO

Lista las instancias en tu proyecto para identificar la que tiene problemas:

gcloud compute instances list

O si sabes la zona, puedes filtrar:

gcloud compute instances list --zones=us-east1-c

Para ver los detalles de la instancia afectada, incluyendo sus discos:

gcloud compute instances describe NOMBRE-VM --zone=ZONA

Esto te mostrará algo como:

disks:
  - boot: true
    deviceName: disco-principal
    diskSizeGb: '100'
    source: https://www.googleapis.com/.../disks/disco-principal

Con eso confirmas el nombre del disco que necesitas rescatar.

Primer intento fallido: consola serial deshabilitada

Intenté conectar a la consola serial para ver qué pasaba:

gcloud compute connect-to-serial-port NOMBRE-VM --zone=ZONA

Pero me salió el clásico:

The serial-port-enable metadata attribute is not set on this VM.

Así que lo habilité:

gcloud compute instances add-metadata NOMBRE-VM \
    --metadata=serial-port-enable=TRUE \
    --zone=ZONA

Y ahí confirmé que el disco no era booteable.

La solución: VM de rescate con AlmaLinux 9

No quería crear una VM extra por el costo, pero la verdad es que una e2-micro sale dos pesos con cincuenta, y el tiempo perdido vale mucho más. Así que creé una VM de rescate con AlmaLinux 9, porque es compatible con CloudLinux (ambas son primas hermanas de RHEL).

gcloud compute instances create rescue-vm \
    --zone=ZONA \
    --machine-type=e2-micro \
    --image-family=almalinux-9 \
    --image-project=almalinux-cloud \
    --boot-disk-size=10GB

Desconectar el disco problemático

Primero apagué la VM original y le desconecté el disco de arranque:

gcloud compute instances stop NOMBRE-VM --zone=ZONA

gcloud compute instances detach-disk NOMBRE-VM \
    --disk=NOMBRE-DISCO --zone=ZONA

Luego lo adjunté a la VM de rescate:

gcloud compute instances attach-disk rescue-vm \
    --disk=NOMBRE-DISCO --zone=ZONA

Verificar los discos desde la VM de rescate

Me conecté a la VM de rescate:

gcloud compute ssh rescue-vm --zone=ZONA

Listé los discos y vi que el problemático aparecía como /dev/sdb:

sudo lsblk

Para ver las particiones en detalle:

sudo fdisk -l /dev/sdb

Y también se puede listar la info de los discos desde Cloud Shell:

gcloud compute disks list --filter="name=NOMBRE-DISCO"

Montar el disco desde la VM de rescate

En mi caso, tenía dos particiones:

  • sdb1 → 200 MB (EFI)
  • sdb2 → 99.8 GB (raíz)

Las monté así:

sudo mkdir -p /mnt/rescue
sudo mount /dev/sdb2 /mnt/rescue
sudo mkdir -p /mnt/rescue/boot/efi
sudo mount /dev/sdb1 /mnt/rescue/boot/efi

Y preparé el chroot:

sudo mount --bind /dev /mnt/rescue/dev
sudo mount --bind /proc /mnt/rescue/proc
sudo mount --bind /sys /mnt/rescue/sys

Entré al sistema dañado:

sudo chroot /mnt/rescue /bin/bash

El GRUB no estaba instalado

Dentro del chroot, el primer intento de reinstalar GRUB falló con un error que decía que faltaban los módulos EFI:

grub2-install: error: /usr/lib/grub/x86_64-efi/modinfo.sh doesn't exist.

Así que instalé los paquetes necesarios:

dnf install grub2-efi-x64 grub2-efi-x64-modules shim-x64 -y

Eso bajó como 67 MB y reconstruyó el initramfs automáticamente.

Luego reinstalé GRUB forzando el modo EFI (porque Secure Boot estaba activo):

grub2-install --target=x86_64-efi \
    --efi-directory=/boot/efi \
    --bootloader-id=CLOUDLINUX \
    --force --recheck

Y generé la configuración:

grub2-mkconfig -o /boot/grub2/grub.cfg

Volver a armar la VM

Salí del chroot, desmonté todo, desconecté el disco de la VM de rescate y lo volví a adjuntar como disco de arranque a la VM original:

exit
sudo umount /mnt/rescue/boot/efi /mnt/rescue/dev /mnt/rescue/proc /mnt/rescue/sys /mnt/rescue

exit

gcloud compute instances detach-disk rescue-vm \
    --disk=NOMBRE-DISCO --zone=ZONA

gcloud compute instances attach-disk NOMBRE-VM \
    --disk=NOMBRE-DISCO --boot --zone=ZONA

gcloud compute instances start NOMBRE-VM --zone=ZONA

Final feliz

La VM arrancó sin problemas, el SSH respondió, y el ping volvió a la vida. Todo porque a GRUB se le ocurrió olvidar cómo bootear después de un update.

Consejos para la próxima

  • No actualices el kernel sin tener una VM de rescate a mano.
  • Habilita la consola serial antes de que la VM se muera.
  • Si usas CloudLinux, AlmaLinux es un excelente amigo para rescates.
  • El comando --force no es una solución mágica, pero a veces es lo único que funciona.

Y si algún día ves No bootable device, ya sabes: no es el fin del mundo, solo es tu amigo GRUB.

###Y si prefieres no descubrir cómo recuperar una VM a las tres de la mañana, también podemos encargarnos de la operación de tus plataformas GCP.

En OrangeBox administramos plataformas Linux y GCP, incluyendo operación, monitoreo, actualizaciones y seguridad.

Conoce nuestro servicio de administración Linux.