Saltar al contenido principal
IT BIBLEIniciar sesión

Blog

Esta publicación fue traducida del inglés por IA. Leer el original

Cómo construir una plantilla cloud-init de Proxmox que puedas reconstruir desde Git

Una plantilla cloud-init convierte una nueva VM de Proxmox en un comando de clonado más unos pocos ajustes. Así estoy construyendo la mía a partir de una imagen cloud oficial, y estas son las partes de las que aún no estoy seguro.

PriyaInTheCloset
· 6 min read
Cómo construir una plantilla cloud-init de Proxmox que puedas reconstruir desde Git

Durante mucho tiempo mis VMs de Proxmox fueron construidas a mano. Pasaba por el instalador a base de clics, añadía mi usuario, pegaba una clave SSH, instalaba el guest agent y, para cuando llegaba a la siguiente VM, ya se me había olvidado la mitad. Funcionaban. Simplemente no eran reproducibles, y no podría decirte qué diferencia había entre dos máquinas que construí con un mes de separación.

Una plantilla cloud-init resuelve la mayor parte de eso. Este post explica cómo estoy construyendo una a partir de una imagen cloud oficial, usando la CLI qm para que cada paso pueda vivir en un script en Git. No llevo mucho tiempo con esta configuración, así que tómalo como un método que funciona. Señalaré las partes de las que no estoy seguro.

Si todavía no tienes un host Proxmox donde probarlo, el laboratorio Install Proxmox VE cubre la instalación base.

Practicarás la instalación de Proxmox VE en dos SSD en espejo con ZFS y la asignación de una dirección fija al host.

Por qué una imagen cloud y no una VM clonada

La alternativa habitual es instalar una VM a mano, dejarla ordenada y convertirla en plantilla. Funciona, pero la plantilla arrastra cualquier estado que hayas dejado atrás: host keys, machine ID, historial del shell, algún paquete suelto. Limpiar todo eso es una checklist en sí misma, y prefiero no tener que mantenerla.

Una imagen cloud oficial parte limpia. Espera que cloud-init la configure en el primer arranque: usuario, claves SSH, red, hostname. Proxmox puede suministrar esos valores a través de una unidad cloud-init virtual. La plantilla se mantiene genérica y cada clon recibe su identidad en el momento de crearse.

La contrapartida es que renuncias al instalador gráfico y tienes que saber de antemano lo que quieres. Para mí eso es una ventaja. La lista de lo que quiero es justo la documentación que siempre me prometo escribir.

Construir la plantilla

Aquí uso la imagen cloud de Ubuntu. Cualquier distro que publique una imagen cloud funciona de la misma manera. Ejecuta esto en el nodo de Proxmox. El ID de la VM, el nombre del storage y el bridge son los míos, así que cámbialos por los tuyos.

cd /var/lib/vz/template/iso
wget https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img

qm create 9000 --name ubuntu-2404-ci \
  --memory 2048 --cores 2 \
  --net0 virtio,bridge=vmbr0 \
  --ostype l26 --agent enabled=1

qm importdisk 9000 noble-server-cloudimg-amd64.img local-zfs
qm set 9000 --scsihw virtio-scsi-pci --scsi0 local-zfs:vm-9000-disk-0
qm set 9000 --ide2 local-zfs:cloudinit
qm set 9000 --boot order=scsi0
qm set 9000 --serial0 socket --vga serial0

Algunas notas sobre por qué está cada pieza:

  • importdisk convierte la imagen descargada en un disco de VM en tu storage. Las versiones más recientes de Proxmox también tienen qm disk import. Comprueba qué soporta tu versión.
  • La unidad cloudinit en ide2 es donde Proxmox escribe los ajustes de usuario, clave y red que cloud-init lee al arrancar.
  • La consola serie está ahí porque muchas imágenes cloud esperan una. Sin ella, he visto que la consola web no muestra nada útil. No estoy seguro de que sea imprescindible en todas las imágenes.

Todavía no la conviertas. Primero, ocúpate del guest agent.

El problema del guest agent

La imagen cloud no incluye qemu-guest-agent. Sin él, Proxmox no puede ver la dirección IP de la VM, y los apagados limpios y el quiescing en los backups son menos fiables. Podría instalarlo a mano y convertir el resultado, pero eso devuelve el problema de la plantilla construida a mano.

En su lugar, uso un snippet de vendor-data que cloud-init aplica en el primer arranque:

#cloud-config
package_update: true
packages:
  - qemu-guest-agent
runcmd:
  - systemctl enable --now qemu-guest-agent

Guárdalo como /var/lib/vz/snippets/vendor.yaml. Los snippets necesitan un storage de tipo directorio con el tipo de contenido Snippets habilitado. El storage local por defecto puede hacerlo, pero un storage sobre ZFS como local-zfs no puede almacenar snippets. Después adjúntalo:

qm set 9000 --cicustom "vendor=local:snippets/vendor.yaml"
qm template 9000

Una advertencia para clusters: ese archivo de snippet está en el storage local de un solo nodo. Si un clon cae en un nodo que no lo tiene, el clon no arrancará. Todavía no he decidido cómo manejarlo. Las opciones que veo son copiar el archivo a todos los nodos desde el mismo script, o poner los snippets en un storage compartido. Copiar es más simple, así que me inclino por eso.

Clonar con ajustes

La plantilla contiene lo que es común. Cada clon añade lo que es específico:

qm clone 9000 120 --name devvm --full
qm set 120 --ciuser priya --sshkeys ~/.ssh/lab_keys.pub
qm set 120 --ipconfig0 ip=dhcp
qm resize 120 scsi0 32G
qm start 120

El flag --sshkeys recibe un archivo con claves públicas. Solo las claves públicas van a la VM. No configuro ninguna contraseña, así que no hay nada que pueda filtrarse ni que rotar. Si quieres una dirección estática, --ipconfig0 ip=10.0.20.50/24,gw=10.0.20.1 lo hace. Yo prefiero una reserva DHCP, ya que mantiene el direccionamiento en un solo lugar.

Tras uno o dos minutos, qm guest cmd 120 network-get-interfaces debería devolver datos una vez que el agente esté activo. Si da timeout, probablemente el agente todavía no está en marcha, o el snippet de vendor no se aplicó.

Qué comprobaría antes de fiarme de ella

Una plantilla que arranca no es lo mismo que una plantilla correcta. Esta es mi checklist corta después de cada reconstrucción:

  1. Entrar por SSH con la clave y confirmar que el acceso con contraseña está desactivado.
  2. Confirmar que el hostname coincide con el nombre de la VM, no con el de la plantilla.
  3. Revisar cloud-init status --long en busca de errores.
  4. Confirmar que el guest agent está en ejecución y que Proxmox muestra la IP.
  5. Asegurarse de que dos clones no comparten machine ID: cat /etc/machine-id en ambos.

El último punto es la razón por la que elegí una imagen cloud. También es el que menos me gustaría descubrir por las malas.

Llevarlo a Git

La idea es justamente que nada de esto viva en mi cabeza. Los comandos de construcción van en un único script de shell, el snippet de vendor está junto a él, y ambos están en un commit. Reconstruir la plantilla pasa a ser: borrar la VM 9000 y ejecutar el script. Todavía no lo he integrado en Ansible. Ese es el siguiente paso, y espero que sea más molesto que la versión en shell, ya que los módulos de Proxmox requieren gestionar credenciales de API. Me gustaría saber si vale la pena para un flujo de trabajo de un nodo a la vez.

De qué no estoy seguro

  • Actualizaciones de la imagen. La imagen current se reemplaza upstream. Quiero fijarla o al menos registrar un checksum para que una reconstrucción sea realmente el mismo build. No he decidido cómo.
  • Deriva de la plantilla. Los clones no se actualizan cuando se actualiza la plantilla. Trato las VMs como desechables, con los datos en un storage aparte, así que reconstruir es más barato que parchear un linaje de plantillas. No estoy seguro de que eso valga para todas las VMs que ejecuto.
  • Comportamiento en cluster. Solo lo he probado en un nodo a la vez.

¿Cómo lo manejas tú? ¿Construyes plantillas con la CLI qm, Terraform, Packer o algo distinto? Y ¿fijaste tus imágenes base, o las dejas flotar y lidias con las sorpresas?

homelabproxmoxcloud-init
Compartir

Have a question about this guide?

Create a free account to ask the community and join the discussion. Members who run the real thing answer every day.