Problema

En entornos de virtualización con Proxmox es frecuente que, después de un apagón inesperado o un reinicio forzado del host, alguna máquina virtual (VM) arranque sin problemas y sea accesible vía SSH, pero la consola integrada del panel web (noVNC) quede estática. El usuario ve una pantalla negra o un cursor que no responde, mientras que la VM sigue ejecutándose normalmente. Este comportamiento impide el uso rápido de la consola para tareas de diagnóstico o para máquinas sin acceso SSH.

Causa

Una consola noVNC depende de varios componentes:

  1. qemu‑guest-agent / QEMU monitor – mantiene el socket de VNC activo.
  2. pveproxy – proxy HTTP que entrega la sesión noVNC al navegador.
  3. pvedaemon – gestiona la creación y destrucción de los sockets VNC.
  4. archivos de lock en /var/run/qemu-server/ que indican que la consola está en uso.

Cuando el host se reinicia abruptamente, algunos de estos procesos pueden quedar en un estado inconsistente:

  • El socket VNC del QEMU sigue existiendo pero el proceso QEMU ya no lo controla.
  • Los archivos .lock o .pid de la VM no se borran, por lo que pveproxy cree que la consola está ocupada.
  • pvedaemon/pveproxy pueden iniciar con información de sesión corrupta y no reenviar datos al cliente.
  • En discos grandes, el proceso de fsck prolongado puede retrasar la liberación de recursos de I/O, provocando que el backend VNC se quede bloqueado.

En la práctica, la causa más habitual es un lock residual que impide que el proxy vuelva a abrir el socket VNC, aunque la VM ya esté operativa.

Solución

La estrategia consiste en restablecer el stack de consola sin interrumpir la VM. Los pasos son:

  1. Verificar que la VM sigue funcionando

    ssh user@vm-ip "echo ok"
    

    Si responde, podemos proceder.

  2. Reiniciar los servicios de gestión de consola

    systemctl restart pvedaemon.service
    systemctl restart pveproxy.service
    

    Esto obliga a Proxmox a volver a crear los sockets VNC.

  3. Eliminar locks y sockets huérfanos

    VMID=100
    LOCKFILE="/var/run/qemu-server/${VMID}.lock"
    SOCKET="/var/run/qemu-server/${VMID}.socket"
    [ -e "$LOCKFILE" ] && rm -f "$LOCKFILE"
    [ -e "$SOCKET" ] && rm -f "$SOCKET"
    

    Sólo elimine estos archivos si está seguro de que la VM está corriendo (qm status $VMID debe devolver running).

  4. Forzar la recreación del display
    Proxmox permite cambiar temporalmente el hardware de pantalla sin reiniciar la VM:

    qm set $VMID --vga std
    qm set $VMID --vga qxl
    

    El cambio hace que QEMU vuelva a abrir el servidor VNC con la nueva configuración.

  5. Comprobar el estado del proceso QEMU

    ps -ef | grep "[q]emu-system-x86_64.*${VMID}"
    

    Asegúrese de que el proceso tiene una opción -vnc activa. Si falta, reinicie la VM (solo como último recurso).

  6. Limpiar la caché del navegador (opcional)
    Aunque la mayoría de los problemas son del lado del host, una sesión WebSocket colgada puede quedar en la caché del cliente. Un “hard refresh” (Ctrl+Shift+R) o abrir la consola en modo incógnito suele ser suficiente.

Alternativas

  • Reiniciar la VM: Si los pasos anteriores no funcionan y la VM permite un reinicio controlado, qm shutdown $VMID && qm start $VMID garantiza una nueva sesión VNC limpia.
  • Usar una consola externa: qm terminal $VMID abre una consola serial sobre SSH, útil para validar que la VM sigue respondiendo mientras se arregla noVNC.

Cuándo aplicar esta solución

  • Síntomas: La VM responde a ping/SSH, pero la consola noVNC del panel web está congelada, muestra pantalla negra o cursor inmóvil.
  • Entorno: Proxmox VE (cualquier versión reciente) en hosts Linux, especialmente después de un reinicio inesperado o una reparación de disco prolongada.
  • No aplicar: Si la VM está apagada o en estado stopped, porque el problema radica en la propia VM y no en la consola. En ese caso, reinicie la VM antes de tocar locks.

Código

# 1. Reiniciar servicios de consola
systemctl restart pvedaemon.service
systemctl restart pveproxy.service

# 2. Eliminar lock y socket huérfanos (reemplazar 100 por el ID de tu VM)
VMID=100
LOCK="/var/run/qemu-server/${VMID}.lock"
SOCK="/var/run/qemu-server/${VMID}.socket"
[ -e "$LOCK" ] && rm -f "$LOCK"
[ -e "$SOCK" ] && rm -f "$SOCK"

# 3. Forzar recreación del display
qm set $VMID --vga std
qm set $VMID --vga qxl

Verificación

  1. Abrir la consola desde el panel web y comprobar que la pantalla muestra el arranque o el prompt de la VM.
  2. Revisar los logs de pveproxy y pvedaemon para asegurarse de que no aparecen errores de VNC:
    journalctl -u pveproxy -u pvedaemon | grep -i vnc
    
  3. Confirmar que el socket VNC está activo:
    ss -ltnp | grep ":590"
    
    Debería aparecer una línea con qemu-system y el puerto asignado a la VM.

Si la consola carga y la interacción funciona, la reparación fue exitosa.

Notas adicionales

  • Bloqueos persistentes: En clústers con alta disponibilidad, los locks pueden quedar en los nodos secundarios. Verifique /var/run/qemu-server/ en todos los nodos que comparten el almacenamiento.
  • Almacenamiento compartido: Cuando la VM usa discos en NFS o Ceph, un fsck prolongado puede retrasar la liberación de I/O y provocar que el socket VNC quede “pendiente”. Espere a que el proceso de reparación termine antes de limpiar locks.
  • Versiones de noVNC: Algunas versiones antiguas tenían problemas de reconexión automática. Mantener Proxmox actualizado reduce la probabilidad de que el problema reaparezca.
  • Monitoreo: Añada una alerta en su sistema de monitorización (pveproxy health check) para detectar sockets VNC sin actividad durante más de X minutos.