Actualización de mi homelab Proxmox VE de cinco nodos: errores, recuperación y lecciones

Caso real de actualización de Proxmox VE 8 a 9 en cinco servidores: systemd-boot, GRUB, repositorios, conflictos de Ceph y recuperación.

Este post está disponible en: English

Actualizar un servidor Proxmox VE es relativamente sencillo cuando los repositorios, el boot loader y las dependencias de almacenamiento ya son consistentes. Actualizar cinco servidores de un mini datacenter revela las diferencias acumuladas por instalaciones y actualizaciones anteriores.

Mi laboratorio tiene cinco hosts Proxmox VE. Los actualicé uno por uno para reducir el impacto de cualquier falla. Antes de trabajar en cada nodo detuve sus máquinas virtuales y contenedores LXC, actualicé por completo la instalación existente de Proxmox VE 8, cambié los repositorios de Debian y Proxmox, ejecuté la actualización de distribución y validé el nodo antes de continuar con el siguiente.

+---------------------------+
| Administrador |
+-------------+-------------+
|
Migración nodo por nodo
Proxmox VE 8 → PVE 9.2.6
|
v
+-------------------------------------------+
| Proceso por cada nodo |
| |
| 1. Detener máquinas virtuales y CT |
| 2. Actualizar completamente PVE 8 |
| 3. Ejecutar pve8to9 --full |
| 4. Cambiar repositorios a Trixie |
| 5. Simular apt full-upgrade |
| 6. Actualizar y reiniciar |
| 7. Validar servicios y workloads |
+---------------------+---------------------+
|
v
+--------------------------------+
| CDMX - Principal |
| 172.16.10.100 |
| PVE 8 → PVE 9.2.6 |
+---------------+----------------+
|
+----------------------+----------------------+
| | |
v v v
+-----------------------+ +-----------------------+ +-----------------------+
| Mazatlán | | Mérida | | Guadalajara |
| 172.16.10.101 | | 172.16.10.102 | | 172.16.10.103 |
| PVE 8 → PVE 9.2.6 | | PVE 8 → PVE 9.2.6 | | PVE 8 → PVE 9.2.6 |
+-----------+-----------+ +-----------+-----------+ +-----------+-----------+
| | |
+-------------------------+-------------------------+
|
v
+-----------------------+
| Puebla |
| 172.16.10.104 |
| PVE 8 → PVE 9.2.6 |
+-----------+-----------+
|
v
+-------------------------------------------+
| Mini datacenter actualizado |
| 5 nodos con Proxmox VE 9.2.6 |
+-------------------------------------------+

Ese era el plan. Durante el proyecto encontré cuatro problemas importantes:

  1. El metapaquete systemd-boot, que el verificador pve8to9 me pidió eliminar.

  2. Un cargador GRUB removible que no estaba configurado para recibir actualizaciones.

  3. Repositorios duplicados y mezclados entre Bookworm y Trixie.

  4. Paquetes de Ceph provenientes de un backport de Bookworm que provocaron que APT intentara eliminar proxmox-ve.

En dos nodos, el stack de administración de Proxmox terminó ausente después de la transición de paquetes. Las máquinas virtuales no necesariamente se detuvieron de inmediato, pero pveversion y los servicios pveproxy, pvedaemon y pvestatd dejaron de estar disponibles. La interfaz web mostró:

Connection error 595: Connection refused

Este artículo documenta el incidente y, sobre todo, las validaciones que agregué antes de actualizar los nodos restantes.

Después de reparar los hosts afectados y aplicar esas validaciones, completé la actualización de los cinco servidores. Los nodos problemáticos funcionaron como canarios y mejoraron el procedimiento para los siguientes.

Este texto es el reporte de un incidente de laboratorio, no un reemplazo de la documentación oficial. Las versiones cambian. Utiliza siempre la guía vigente de actualización de Proxmox VE 8 a 9 y revisa cada transacción de APT antes de aceptarla.

Mi estrategia de actualización

Traté el entorno de cinco servidores como un mantenimiento gradual:

  1. Confirmar acceso por SSH y mediante consola local o fuera de banda.

  2. Respaldar los huéspedes y configuraciones críticas.

  3. Detener las VM y los contenedores LXC del nodo objetivo.

  4. Actualizar por completo Proxmox VE 8 antes de cambiar los repositorios.

  5. Ejecutar pve8to9 --full y resolver cada falla.

  6. Cambiar los repositorios de Debian y Proxmox de Bookworm a Trixie.

  7. Simular la actualización completa y revisar qué paquetes se eliminarían.

  8. Ejecutar la actualización real únicamente si el stack de Proxmox permanece instalado.

  9. Validar paquetes, servicios, almacenamiento, red, arranque y huéspedes.

  10. Reiniciar y observar el nodo antes de continuar con el siguiente servidor.

Detener los huéspedes fue una decisión conservadora, pero simplificó la recuperación y evitó cambios en las cargas de trabajo mientras el host cambiaba de generación de paquetes.

Línea base antes de actualizar

Antes de cambiar repositorios ahora recopilo una línea base en cada host:

hostname
pveversion -v
cat /etc/os-release
uname -r
pvesm status
qm list
pct list
df -h / /boot /boot/efi 2>/dev/null
pve8to9 --full

También guardo el estado de paquetes y repositorios:

dpkg-query -W -f='${binary:Package}\t${Version}\n' > /root/packages-before-pve9.txt
grep -RnsE \
'^[[:space:]]*deb|^[[:space:]]*(Types|URIs|Suites|Components|Enabled):' \
/etc/apt/sources.list /etc/apt/sources.list.d/ 2>/dev/null

El script pve8to9 debe ejecutarse varias veces. Sus recomendaciones pueden cambiar después de eliminar un paquete conflictivo, instalar una dependencia o avanzar a otra etapa.

Problema 1: advertencia del metapaquete systemd-boot

La primera falla fue:

FAIL: systemd-boot meta-package installed. This will cause problems on upgrades
of other boot-related packages. Remove 'systemd-boot'.

En Debian Trixie, systemd-boot se dividió en varios paquetes. El metapaquete systemd-boot incluye hooks que pueden administrar automáticamente el cargador. Proxmox normalmente gestiona las particiones EFI aplicables mediante proxmox-boot-tool, por lo que el metapaquete puede interferir con ese proceso.

Sin embargo, no debe eliminarse sin verificar. Primero identifiqué la ruta de arranque real:

test -d /sys/firmware/efi \
&& echo 'Boot mode: UEFI' \
|| echo 'Boot mode: BIOS'
bootctl status
efibootmgr -v
findmnt /boot /boot/efi
dpkg -l | grep -E 'proxmox-boot-tool|systemd-boot|grub'

En el nodo cdmx encontré:

Boot mode: UEFI
systemd-boot not installed in ESP.
BootCurrent: 0000
File: \EFI\proxmox\shimx64.efi

El nodo arrancaba mediante el shim firmado de Proxmox y GRUB, no mediante systemd-boot. /etc/kernel/proxmox-boot-uuids no existía porque esta instalación GRUB no administraba un conjunto de ESP con proxmox-boot-tool. Primero simulé la eliminación:

apt -s remove systemd-boot

APT propuso eliminar solamente systemd-boot, así que continué:

apt remove systemd-boot

Conservé systemd-boot-efi y no ejecuté apt autoremove. Los kernels anteriores seguían siendo opciones útiles de recuperación.

La excepción es un host donde systemd-boot fue instalado manualmente y realmente se utiliza como cargador. Esa configuración requiere una evaluación separada. El verificador oficial define si el metapaquete debe eliminarse.

Problema 2: GRUB no actualizaba el cargador EFI removible

Durante la generación del initramfs, un nodo mostró:

Removable bootloader found at '/boot/efi/EFI/BOOT/BOOTX64.efi',
but GRUB packages not set up to update it!

El hook indicó la configuración necesaria:

echo 'grub-efi-amd64 grub2/force_efi_extra_removable boolean true' \
| debconf-set-selections -v -u

Después pidió reinstalar GRUB:

apt install --reinstall grub-efi-amd64

El primer intento falló porque el host tenía paquetes GRUB de dos versiones:

grub-efi-amd64 depends on grub-efi-amd64-bin (= 2.12-9+pmx2)
but 2.06-13+pmx7 is to be installed

La lección fue no forzar un paquete GRUB individual. Todos sus componentes deben pertenecer a la misma generación. Pausé la reparación, corregí los repositorios, completé la transición de paquetes y sólo entonces reinstalé GRUB.

apt install --reinstall grub-efi-amd64
update-grub
efibootmgr -v

No reinicié mientras los paquetes GRUB estaban mezclados. Un cargador alternativo desactualizado en EFI/BOOT/BOOTX64.EFI podría cargar módulos de otra versión y dejar el servidor en el prompt de rescate de GRUB.

Problema 3: repositorios duplicados y mezclados

Varios nodos tenían archivos .list tradicionales y archivos Deb822 .sources. APT reportó:

Target Packages (pve-no-subscription/binary-amd64/Packages)
is configured multiple times

En un nodo, el repositorio de Proxmox seguía en Bookworm mientras otro ya usaba Trixie. En otro momento no había un repositorio base de Debian activo: APT podía ver paquetes nuevos de Proxmox, pero no versiones Trixie compatibles de systemd, LVM, AppArmor y otras dependencias.

Revisé todas las definiciones activas en lugar de reemplazar texto globalmente:

grep -RnsE \
'^[[:space:]]*deb|^[[:space:]]*(Types|URIs|Suites|Components|Enabled):' \
/etc/apt/sources.list /etc/apt/sources.list.d/ 2>/dev/null

Para PVE 9, el conjunto debe ser consistente:

  • Debian trixie

  • Debian trixie-updates

  • Debian trixie-security

  • Proxmox VE trixie

  • El repositorio Ceph correcto, cuando existan paquetes de Ceph

  • Ningún bookworm, bpo12 o repositorio duplicado activo

Conservé una sola definición por repositorio y renombré los archivos obsoletos con .disabled para que el cambio fuera reversible. Las definiciones vigentes deben consultarse en la documentación de repositorios de Proxmox.

Problema 4: APT intentó eliminar proxmox-ve

La advertencia más grave apareció durante la actualización completa:

W: (pve-apt-hook) You are attempting to remove the meta-package 'proxmox-ve'!

El hook detuvo correctamente la transacción. Crear /please-remove-proxmox-ve y continuar habría sido la respuesta incorrecta. Ese archivo autoriza explícitamente la eliminación del metapaquete; no repara la actualización.

APT proponía una transición grande de Debian, incluidos reemplazos de bibliotecas antiguas por variantes t64. Esos reemplazos son esperados en Trixie. La eliminación de proxmox-ve, pve-manager, pve-qemu-kvm, qemu-server o libpve-storage-perl no lo es.

Diagnostiqué el grafo de dependencias con:

apt -s install proxmox-ve
apt-cache policy \
proxmox-ve pve-manager pve-qemu-kvm \
ceph-common librados2 librbd1 libcephfs2

El conflicto real estaba en Ceph:

ceph-common requires librbd1 (= 19.2.3-pve1)
but 19.2.5-1~bpo12+2 is selected

Los nodos afectados tenían clientes Ceph Squid compilados como backports de Debian 12 (~bpo12+2), mientras el repositorio Ceph configurado para PVE 9 ofrecía una familia -pve1 consistente. APT prefería el backport con número de versión mayor, pero sus dependencias exactas eran incompatibles con Trixie/PVE.

La cadena era:

paquetes Ceph incompatibles
-> libpve-storage-perl no se puede instalar
-> pve-manager no se puede instalar
-> proxmox-ve queda seleccionado para eliminación

Límite de seguridad para Ceph

Antes de modificar paquetes Ceph comprobé si el nodo prestaba servicios de almacenamiento:

ceph -s
ceph version
dpkg -l | grep -E '^ii[[:space:]]+ceph-(mon|osd|mgr)'

Mis hosts afectados tenían bibliotecas cliente, pero no paquetes MON, OSD o MGR. Por ello pude alinear los clientes con el repositorio Proxmox Ceph Squid.

Si el nodo pertenece a un clúster Ceph activo, debe seguirse el procedimiento coordinado de actualización de Ceph. La guía de PVE 8 a 9 exige que los despliegues correspondientes lleguen a Squid antes de actualizar el host. No debe copiarse un downgrade de bibliotecas cliente en un nodo de almacenamiento Ceph.

Alineación específica de mi incidente

En mis nodos con clientes solamente tuve que seleccionar la familia completa en una sola transacción, porque muchos paquetes exigen versiones exactas:

apt -s install --allow-downgrades \
ceph-common=19.2.3-pve1 \
ceph-fuse=19.2.3-pve1 \
libcephfs2=19.2.3-pve1 \
librados2=19.2.3-pve1 \
libradosstriper1=19.2.3-pve1 \
librbd1=19.2.3-pve1 \
librgw2=19.2.3-pve1 \
python3-ceph-common=19.2.3-pve1 \
python3-ceph-argparse=19.2.3-pve1 \
python3-cephfs=19.2.3-pve1 \
python3-rados=19.2.3-pve1 \
python3-rbd=19.2.3-pve1 \
python3-rgw=19.2.3-pve1 \
liblttng-ust1t64 \
proxmox-ve

La versión anterior documenta mi caso y eventualmente quedará obsoleta. Antes de ejecutar un comando equivalente se deben consultar los candidatos actuales con apt-cache policy. Sólo quité -s después de comprobar que la simulación instalaba o conservaba todo el stack de Proxmox.

Recuperación cuando falta el stack de administración

En los nodos afectados falló:

pveversion: command not found

También faltaban las unidades:

Unit pvedaemon.service not found.
Unit pvestatd.service not found.
Unit pveproxy.service not found.

Esto confirmó que no se trataba simplemente de un proxy detenido. Era necesario restaurar pve-manager y sus paquetes relacionados.

Antes de recuperar evité reiniciar y comprobé los procesos huéspedes:

ps -eo pid,cmd | grep -E '[k]vm|[l]xc-start'

Después de alinear los clientes Ceph y reinstalar proxmox-ve, completé la configuración y reinicié el plano de administración:

dpkg --configure -a
apt-get check
systemctl daemon-reload
systemctl enable --now pve-cluster
systemctl restart pvedaemon pvestatd pveproxy

Probé la API local:

curl -k -sS -o /dev/null -w 'HTTP %{http_code}\n' \
https://127.0.0.1:8006/api2/json/version

Una respuesta HTTP 200 o 401 confirma que el endpoint responde. Después verifiqué pveversion -v y la interfaz web en el puerto 8006.

Procedimiento mejorado para los nodos restantes

1. Completar las actualizaciones de PVE 8

Mientras los repositorios todavía apuntan a Bookworm/PVE 8:

apt update
apt full-upgrade
pve8to9 --full

Todas las fallas deben resolverse antes de cambiar las suites.

2. Revisar Ceph antes de cambiar repositorios

ceph version 2>/dev/null
dpkg -l | grep -E '^ii[[:space:]]+ceph-(mon|osd|mgr)'
dpkg-query -W -f='${binary:Package}\t${Version}\n' 2>/dev/null \
| grep -E 'ceph|librados|librbd|librgw'

Un clúster Ceph real necesita su propia secuencia compatible. Incluso los paquetes cliente necesitan un repositorio que entregue una familia consistente.

3. Cambiar repositorios y verificar cada suite

apt update
grep -RnsE \
'^[[:space:]]*deb|^[[:space:]]*(Types|URIs|Suites|Components|Enabled):' \
/etc/apt/sources.list /etc/apt/sources.list.d/ 2>/dev/null

No debe quedar ningún Bookworm activo ni definiciones duplicadas.

4. Exigir que APT conserve Proxmox

apt -s install proxmox-ve
apt -s full-upgrade

Debemos detenernos si la sección REMOVED contiene:

proxmox-ve
pve-manager
pve-qemu-kvm
qemu-server
pve-container
pve-ha-manager
libpve-storage-perl

El hook de Proxmox no debe evadirse: es la última protección contra un error de repositorios o dependencias.

5. Utilizar una actualización completa

Una transición mayor de Debian necesita instalar reemplazos y eliminar bibliotecas obsoletas. apt upgrade dejó cientos de paquetes retenidos en mi entorno. Una vez validada la simulación utilicé:

apt full-upgrade

6. Validar antes de reiniciar

dpkg --audit
apt-get check
pveversion -v
systemctl --no-pager --full status \
pve-cluster pvedaemon pvestatd pveproxy
pvesm status
qm list
pct list
update-grub
efibootmgr -v
ls -1 /boot/vmlinuz-*-pve

Conservé al menos un kernel funcional de PVE 8 hasta completar el primer arranque correcto en PVE 9. No ejecuté apt autoremove durante la ventana de actualización.

Lecciones aprendidas

Importa más la lista de eliminación que el número de paquetes

Un resumen como “569 actualizados, 131 nuevos y 64 eliminados” no es necesariamente incorrecto durante una transición mayor de Debian. Importa cuáles paquetes serían eliminados. Las bibliotecas antiguas pueden reemplazarse; el stack de Proxmox no.

La consistencia de repositorios incluye clientes de almacenamiento

Al principio me enfoqué en Debian y PVE. El conflicto decisivo provino de clientes Ceph con dependencias exactas. Los repositorios de almacenamiento necesitan la misma revisión previa que el sistema operativo.

Un metapaquete tiene importancia operativa

proxmox-ve contiene poco software por sí mismo, pero fija el conjunto soportado. Su eliminación propuesta indica que APT ya no puede satisfacer ese conjunto. Debe repararse el grafo de dependencias, no autorizar la eliminación.

GRUB sólo debe repararse con paquetes consistentes

Reinstalar GRUB mientras sus componentes pertenecían a versiones diferentes habría creado un riesgo de arranque. Primero corregí repositorios y paquetes.

Actualizar un nodo a la vez limitó el impacto

Cada falla se convirtió en una validación nueva para el siguiente servidor. El proyecto confirmó un principio simple: utilizar un nodo como canario, validar cada punto de control y después repetir el procedimiento.

Checklist final

  • Existen respaldos recientes y conocemos el procedimiento de restauración.

  • Funcionan SSH y la consola fuera de banda.

  • Los huéspedes del nodo objetivo están detenidos o migrados.

  • PVE 8 está completamente actualizado antes de cambiar repositorios.

  • pve8to9 --full no tiene fallas pendientes.

  • Identifiqué el cargador de arranque activo.

  • Conocemos los roles y versiones de Ceph.

  • Todos los repositorios usan la suite esperada y no hay duplicados.

  • apt -s install proxmox-ve funciona.

  • apt -s full-upgrade conserva el stack Proxmox.

  • No existe /please-remove-proxmox-ve.

  • Paquetes, servicios, almacenamiento, red y arranque pasan la validación.

  • Validé el nodo después del reinicio antes de actualizar el siguiente.

Conclusión

Actualizar Proxmox VE 8 a 9 no fue un solo comando: fue una migración de dependencias, repositorios, clientes de almacenamiento y cargador de arranque a través de cinco historiales de instalación diferentes.

La advertencia de systemd-boot sólo pudo resolverse después de identificar que el host utilizaba GRUB. El cargador alternativo de GRUB únicamente podía actualizarse cuando todos sus paquetes pertenecían a la misma versión. Los repositorios duplicados y mezclados explicaron los paquetes retenidos. Finalmente, los clientes Ceph incompatibles explicaron por qué APT quería eliminar proxmox-ve.

El comando más valioso no fue apt full-upgrade, sino la simulación inmediatamente anterior:

apt -s full-upgrade

Cuando una actualización mayor propone eliminar su propia plataforma de administración, hay que detenerse. La advertencia no es el problema: es la evidencia del problema.

Comentarios