Saltar al contenido
sudoquest@root
Proxmox

Clúster y HA

Varios nodos como uno: el clúster, el quórum y /etc/pve compartido, migrar en caliente, la HA y qué hacer cuando un nodo se cae.

50 min de lectura

Radio Onda Norte emite las veinticuatro horas. La emisión es una VM (la 100) y la web de la radio, con el reproductor, es un contenedor (el 101). Si el servidor se para, la radio se queda muda. Por eso tiene tres nodos de Proxmox (pve1, pve2 y pve3) y un NAS en la sala de máquinas. Hasta hoy cada nodo iba por su cuenta. Toca juntarlos en un clúster para que lo de uno pueda pasar a otro, incluso solo, cuando uno se caiga.

Un clúster: corosync y /etc/pve

Un clúster de Proxmox son varios nodos que se ven entre sí por la red (corosync, por su dirección de gestión) y que comparten /etc/pve. Esa carpeta no es un disco: es pmxcfs, un sistema de archivos en memoria que se copia entre todos. Lo que se escribe en uno (la configuración de una VM, storage.cfg, los usuarios) aparece al momento en los demás. Por eso, desde la web de cualquier nodo se ve y se maneja todo el clúster.

Cada nodo tiene un voto. El clúster tiene quórum cuando los que se ven entre sí suman más de la mitad de los votos: con tres nodos, dos. Sin quórum, ese nodo no se fía de lo que sabe (quizá los otros sigan sin él), y /etc/pve se queda de solo lectura.

Crear el clúster

Se crea en un nodo, con un nombre: pvecm create (en la web, Datacenter ▸ Cluster ▸ Create Cluster). El nombre no puede cambiarse después.

root@pve1:~# pvecm create onda
Corosync Cluster Engine Authentication key generator.
Gathering 2048 bits for key from /dev/urandom.
Writing corosync key to /etc/corosync/authkey.
Writing corosync config to /etc/pve/corosync.conf
Restart corosync and cluster filesystem

pvecm status lo cuenta todo: el clúster, el quórum y a quién ve este nodo.

root@pve1:~# pvecm status
Cluster information
-------------------
Name:             onda
Config Version:   1
Transport:        knet
Secure auth:      on

Quorum information
------------------
Date:             Thu Oct  8 09:12:41 2026
Quorum provider:  corosync_votequorum
Nodes:            1
Node ID:          0x00000001
Ring ID:          1.5
Quorate:          Yes

Votequorum information
----------------------
Expected votes:   1
Highest expected: 1
Total votes:      1
Quorum:           1  
Flags:            Quorate 

Membership information
----------------------
  Nodeid      Votes Name
0x00000001          1 192.168.70.11 (local)

Ejercicio

El clúster de la radio

La radio ya tiene tres nodos (pve1, pve2 y pve3), cada uno por su cuenta. Crea en pve1 un clúster llamado «onda»: de momento, solo con él.

Encendiendo el nodo…

Unir los demás

Los otros nodos se unen desde ellos, con pvecm add y la dirección de uno que ya esté. Pide la contraseña de root de ese nodo (no se ve al escribirla: salen asteriscos) y, la primera vez, si te fías de la huella de su certificado. Al unirse, el nodo pierde su /etc/pve y se queda con el del clúster.

root@pve2:~# pvecm add 192.168.70.11
Please enter superuser (root) password for '192.168.70.11': *************
Establishing API connection with host '192.168.70.11'
The authenticity of host '192.168.70.11' can't be established.
X509 SHA256 key fingerprint is 38:EA:9E:1A:6D:A0:2B:52:8E:76:FB:57:73:68:D2:F9:EE:CF:E3:42:6F:CF:E4:8E:68:04:2D:87:F5:A1:E1:B5.
Are you sure you want to continue connecting (yes/no)? yes
Login succeeded.
check cluster join API version
No cluster network links passed explicitly, fallback to local node IP '192.168.70.12'
Request addition of this node
Join request OK, finishing setup locally
stopping pve-cluster service
backup old database to '/var/lib/pve-cluster/backup/config-1791450771.sql.gz'
waiting for quorum...OK
(re)generate node files
generate new node certificate
merge authorized SSH keys
generated new node certificate, restart pveproxy and pvedaemon services
successfully added node 'pve2' to cluster.

En la web es lo mismo con dos ventanas. En el primero, Join Information da un texto (su dirección, su huella y lo de corosync, todo junto). En el que se une, Join Cluster: se pega ese texto y se escribe la contraseña de root del primero.

Lo que puede salir mal:

  • Un nodo que ya tiene invitados no se une: sus VMID podrían chocar con los del clúster. pvecm add lo dice antes de nada: * this host already contains virtual guests y Check if node may join a cluster failed!. Se unen vacíos; lo suyo se mueve después.
  • La contraseña mala: 401 authentication failure. Desde la web se abre la tarea, y acaba en ese error.

Ejercicio

Los otros dos nodos, dentro

pve1 ya tiene el clúster «onda». Une pve2 y pve3 a él: desde cada uno, con la contraseña de root de pve1 (Onda-Norte-26) y fiándote de su huella.

Encendiendo el nodo…

Un almacén compartido

Para que una VM pase de un nodo a otro sin copiar su disco, el disco tiene que estar donde lo ven todos: un NAS (NFS), Ceph… Un almacén se añade una vez (está en storage.cfg, dentro de /etc/pve) y lo montan todos los nodos. local y local-lvm son de cada nodo: lo que hay en ellos solo lo tiene ese.

root@pve3:~# cat /etc/pve/storage.cfg
dir: local
path /var/lib/vz
content import,vztmpl,iso,backup

lvmthin: local-lvm
thinpool data
vgname pve
content rootdir,images

nfs: nas
export /volume1/proxmox
path /mnt/pve/nas
server 192.168.70.20
content images,rootdir,backup

Ejercicio

El NAS, para los tres

El NAS de la radio (192.168.70.20) comparte /volume1/proxmox. Añádelo una sola vez como almacén «nas» (para discos, contenedores y copias): en un clúster, lo ven los tres nodos.

Encendiendo el nodo…

Migrar

Migrar es pasar un invitado a otro nodo (en la web, el botón Migrate):

  • Una VM en marcha, en caliente: qm migrate 100 pve2 --online. Se arranca en el otro, se le pasa la memoria y se cambia en un instante: quien escucha la radio no nota nada. Sin --online, Proxmox no lo hace: can't migrate running VM without --online.
  • Un contenedor en marcha no pasa en caliente: pct migrate 101 pve2 --restart lo apaga, lo pasa y lo arranca allí (unos segundos sin servicio).
  • Una VM parada pasa sin --online (en frío: qm migrate 102 pve2), y no hay nada que cortar.
  • Un disco local (en local-lvm) se copia entero al otro nodo: lento. Con el disco en el NAS solo se pasa la configuración. Aquí, una VM con un disco local no pasa en caliente: se para antes y se migra en frío.
root@pve1:~# qm migrate 100 pve2 --online
2026-10-08 09:31:02 conntrack state migration not supported or disabled, active connections might get dropped
2026-10-08 09:31:02 starting migration of VM 100 to node 'pve2' (192.168.70.12)
2026-10-08 09:31:02 starting VM 100 on remote node 'pve2'
2026-10-08 09:31:09 start remote tunnel
2026-10-08 09:31:12 ssh tunnel ver 1
2026-10-08 09:31:12 starting online/live migration on unix:/run/qemu-server/100.migrate
2026-10-08 09:31:12 set migration capabilities
2026-10-08 09:31:12 migration downtime limit: 100 ms
2026-10-08 09:31:12 migration cachesize: 64.0 MiB
2026-10-08 09:31:12 set migration parameters
2026-10-08 09:31:12 start migrate command to unix:/run/qemu-server/100.migrate
2026-10-08 09:31:13 average migration speed: 528.8 MiB/s - downtime 23 ms
2026-10-08 09:31:13 migration completed, transferred 3.9 MiB VM-state
2026-10-08 09:31:13 migration status: completed
2026-10-08 09:31:20 migration finished successfully (duration 00:00:18)

Después, su configuración ya no está en /etc/pve/nodes/pve1/qemu-server/ sino en la carpeta de pve2: un invitado es del nodo en cuya carpeta está su configuración.

Ejercicio

La emisión, a pve2 sin cortarla

Hay que actualizar pve1 y la emisión (la VM 100) no puede cortarse: pásala a pve2 en caliente, sin apagarla.

Encendiendo el nodo…

El quórum, de cerca

Si pve2 y pve3 se apagan, pve1 se queda solo: un voto de tres, sin quórum.

root@pve1:~# pvecm status | grep -E 'Quorate|Quorum:'; touch /etc/pve/prueba; qm create 200 --memory 128
Quorate:          No
Quorum:           2 Activity blocked
touch: cannot touch '/etc/pve/prueba': Permission denied
cluster not ready - no quorum?

Lo que ya estaba en marcha en pve1 sigue, pero no se puede cambiar nada: ni crear, ni arrancar, ni migrar. pvecm expected 1 le dice que con un voto basta, y vuelve a poder escribir. Es la trampa: si los otros dos siguen vivos (solo que pve1 no los ve, un cable), ellos también tienen quórum, y cada lado cambia /etc/pve por su cuenta (split brain). Al volver a verse, lo de uno de los lados se pierde. Solo se fuerza cuando se sabe seguro que los demás están apagados.

La alta disponibilidad (HA)

Con la HA, lo que se pone en ella vuelve solo si su nodo se cae. ha-manager add (en la web, Datacenter ▸ HA ▸ Add):

root@pve2:~# ha-manager add vm:100 --state started; ha-manager add ct:101 --state started --max_restart 1; ha-manager config
ct:101
max_restart 1
state started

vm:100
state started

Lo que ya está en la HA se cambia con ha-manager set: con --state stopped, la HA lo deja parado y no lo trae de vuelta; ha-manager set vm:100 --state started lo pone otra vez en marcha y a salvo.

Cómo funciona: un nodo hace de maestro (el CRM, que decide) y cada nodo tiene su LRM (el que arranca y para lo suyo). Un nodo con algo de la HA arma su watchdog: si se queda sin quórum, se reinicia solo al minuto. Así, cuando los demás lo dan por muerto (fencing), es seguro arrancar lo suyo en otro: no puede seguir en dos sitios a la vez.

root@pve2:~# ha-manager status
quorum OK
master pve3 (active, Thu Oct  8 09:44:16 2026)
fencing armed (CRM watchdog active)
lrm pve1 (idle, watchdog standby, Thu Oct  8 09:44:20 2026)
lrm pve2 (active, watchdog active, Thu Oct  8 09:44:20 2026)
lrm pve3 (idle, watchdog standby, Thu Oct  8 09:44:23 2026)
service ct:101 (pve2, started)
service vm:100 (pve2, started)

Cuando un nodo se cae de golpe, su LRM deja de dar señales (old timestamp - dead?). Pasados unos dos minutos y medio, lo suyo arranca en otro nodo (su tarea dice task started by HA resource agent). No es instantáneo: es un reinicio en otro sitio, no una migración en caliente.

Las reglas de afinidad dicen dónde prefiere estar cada cosa (HA ▸ Affinity Rules): por ejemplo, la emisión en pve2 (prioridad 2) mejor que en pve1 (1). Si pve2 se cae, va a pve1; y cuando pve2 vuelve, vuelve a él (failback).

root@pve2:~# ha-manager rules add node-affinity emision --resources vm:100 --nodes pve2:2,pve1:1

Ejercicio

La emisión y la web, en la HA

Si un nodo se cae, la emisión (VM 100) y la web de la radio (CT 101) tienen que volver solas en otro. Ponlas en la HA (que estén en marcha) y que la emisión prefiera pve2 (prioridad 2) a pve1 (prioridad 1).

Encendiendo el nodo…

Sin HA: sacarlo a mano

Si lo de un nodo caído no estaba en la HA, no vuelve solo. Mientras el clúster tenga quórum, se hace a mano lo mismo que haría la HA: pasar su configuración a la carpeta de otro nodo y arrancarlo allí. Su disco tiene que estar en el NAS.

root@pve1:~# mv /etc/pve/nodes/pve3/lxc/101.conf /etc/pve/nodes/pve1/lxc/ && pct start 101

Ejercicio

La web, fuera de un nodo caído

pve3 se ha apagado de golpe con la web de la radio (el CT 101) dentro, y aún no estaba en la HA. El clúster sigue con quórum (pve1 y pve2): pasa su configuración a pve1 y arráncala allí. Sin tocar los votos esperados.

Encendiendo el nodo…

Sacar un nodo del clúster

Un nodo se saca apagado, y desde otro: pvecm delnode pve3 (necesita quórum). Su carpeta en /etc/pve/nodes/pve3 se queda: se borra a mano cuando ya no hace falta. Sacar uno que sigue encendido es la otra trampa. Corosync le dice que se vaya (Killing node 3), pero él se queda con su configuración vieja y sin quórum (Cannot initialize CMAP service). Si vuelve a la red así, lía al clúster. Primero se apaga; si va a volver a usarse, se reinstala.

root@pve1:~# pvecm delnode pve3; pvecm nodes
Killing node 3

Membership information
----------------------
  Nodeid      Votes Name
       1          1 pve1 (local)
       2          1 pve2