Entrada

Template Cloud-Init Ready en Proxmox

Cómo crear una VM template con Rocky Linux 10 lista para Cloud-Init en Proxmox, base para despliegues reproducibles

Template Cloud-Init Ready en Proxmox

Si llevas un tiempo usando Proxmox, sabes que crear VMs una por una desde el instalador es lento, tedioso y poco reproducible. La solución a esto son los templates con Cloud-Init: una imagen base limpia que permite clonar nuevas máquinas virtuales ya configuradas con usuario, SSH key, red y hostname en segundos, sin intervención manual. Es exactamente lo que necesitamos para integrar Proxmox con Terraform u otras herramientas de IaC.

En este post vamos a crear un template de Rocky Linux 10 en Proxmox listo para Cloud-Init, que luego usaremos como base para despliegues automatizados.

¿Qué es Cloud-Init?

Cloud-Init es el estándar para la inicialización de instancias en la nube. Fué diseñado originalmente para proveedores como AWS o GCP, pero Proxmox lo soporta de forma nativa. Básicamente, permite que una VM reciba su configuración inicial (usuario, contraseña, clave SSH, hostname, red) desde una fuente de datos externa al arrancar por primera vez, sin que nosotros tengamos que entrar a configurarla manualmente.

Cuando se combina con un template bien preparado, el flujo se vuelve completamente automatizable: clonar → encender → listo.

¿Qué vamos a hacer?

El proceso tiene dos partes diferenciadas:

  1. Dentro de la VM: instalar Rocky Linux 10 Minimal, los paquetes necesarios (cloud-init, qemu-guest-agent) y preparar el sistema para que sea clonado (limpiar IDs, claves SSH, estado de cloud-init).
  2. En el host Proxmox: agregar el drive de Cloud-Init a la VM y convertirla en template.

El entorno de trabajo es el siguiente:

ComponenteValor
HypervisorProxmox VE 9.1.14
Guest OSRocky Linux 10 Minimal
VirtualizaciónIntel VT-x / KVM
VM ID8000

Requisitos

  • Un servidor Proxmox VE (probado en 9.x) con soporte KVM habilitado.
  • Acceso como root a la shell del nodo Proxmox (SSH o consola web).
  • Almacenamiento configurado en Proxmox con soporte para imágenes de disco (ej. local-lvm que viene por defecto).
  • ISO de Rocky Linux 10 Minimal o tu distribución de Linux favorita.

Hands-On

1. Verificar soporte KVM

Antes de empezar, confirmamos que el nodo tiene aceleración KVM disponible. Desde la shell del host Proxmox:

1
egrep -c '(vmx|svm)' /proc/cpuinfo

El resultado debe ser mayor a 0. Si queremos más detalle, instalamos cpu-checker y validamos:

1
2
apt install cpu-checker -y
kvm-ok

La salida esperada es:

1
2
INFO: /dev/kvm exists
KVM acceleration can be used

Sin KVM, las VMs corren por software y el rendimiento se degrada notablemente. Si el comando devuelve 0 o kvm-ok reporta que KVM no está disponible, revisar la BIOS/UEFI del servidor. La opción a buscar varía según el fabricante del procesador: en Intel suele llamarse Intel VT-x o Intel Virtualization Technology, mientras que en AMD aparece como AMD-V o SVM Mode. Generalmente se encuentra dentro de las secciones CPU Configuration, Advanced o Security del menú de la BIOS.

2. Descargar la ISO y subirla a Proxmox

Descargar la imagen Rocky Linux 10 Minimal (o el sabor de Linux de tu preferencia) desde la página oficial. La sección DVD/Boot ISO incluye tanto la imagen completa como la Minimal; para este caso la Minimal es suficiente ya que instalaremos solo los paquetes necesarios.

Idealmente utilizar una imagen mínima que no incluya paquetes innecesarios ni GUI, ya que el propósito es crear un template lo más ligero posible.

Una vez descargada, subirla al almacenamiento de Proxmox. Hay dos formas:

Opción A — Subir ISO desde máquina local:

  1. En el panel izquierdo, seleccionar el nodo → local (o el almacenamiento donde se guardan las ISOs).
  2. Ir a ISO ImagesUpload.
  3. Seleccionar el archivo .iso descargado y confirmar.

Una vez finalizado deberías ver un mensaje de output similar a esto:

1
2
3
4
5
6
7
starting file import from: /var/tmp/pveupload-886749f22502556e42786d2cf265a035
target node: prox-elite
target file: /var/lib/vz/template/iso/Rocky-10.1-x86_64-minimal.iso
file size is: 1528954880
command: cp -- /var/tmp/pveupload-886749f22502556e42786d2cf265a035 /var/lib/vz/template/iso/Rocky-10.1-x86_64-minimal.iso
finished file import successfully
TASK OK

Opción B — Descarga directa desde Proxmox (útil si el servidor tiene acceso directo a internet):

Desde el mismo menú anterior, en lugar de usar Upload le daremos a Download from URL y pegaremos la URL de descarga de la ISO obtenida desde la página oficial de Rocky Linux. Podremos chequear la URL y renombrar la ISO para luego descargarla a Proxmox.

3. Crear la VM base en Proxmox

Desde la interfaz web de Proxmox, crear una nueva VM con el ID 8000, utilizando la ISO descargada y la siguiente configuración (prácticamente todo por default):

ParámetroValor
Machinei440fx
BIOSSeaBIOS
CPU Typehost
RAM2048 MB
CPU Cores1
Disk BusSCSI
Network AdapterVirtIO

Estos valores son solo referenciales, ya que posteriormente podremos lanzar nuevas VM a base de este template con recursos ajustados a nuestras necesidades.

Usamos CPU Type: host para exponer las instrucciones nativas del procesador a la VM. Esto es importante para que Cloud-Init y algunas herramientas de sistema funcionen correctamente.

Para verificar que la VM quedó configurada con el tipo de CPU correcto, desde la shell del host:

1
qm showcmd 8000 --pretty | grep -- "-cpu"

La salida esperada:

1
-cpu host

4. Instalar Rocky Linux 10

Arrancar la VM desde la ISO e instalar normalmente como lo harías con una distribución Linux cualquiera.

Importante asegurarse de lo siguiente:

  • Crear un usuario dentro del grupo sudo/wheel (no habilitar el acceso directo como root).
  • Configurar una contraseña para el usuario.
  • Minimal install sin GUI, de ser posible.

Mis configuraciones básicas con el usuario rocky configurado, se ven así:

Una vez completada la instalación, iniciar sesión y actualizar el sistema:

Si escogiste una distribución de Linux distinta a Rocky, los comandos pueden diferir de los indicados en esta guía.

1
sudo dnf update -y

5. Instalar paquetes necesarios

Instalar los paquetes que necesita Cloud-Init junto con el agente de QEMU:

1
2
3
4
5
sudo dnf install -y \
  qemu-guest-agent \
  cloud-init \
  cloud-utils-growpart \
  sudo
  • qemu-guest-agent: permite que Proxmox se comunique con la VM (obtener IP, apagar limpiamente, ejecutar comandos).
  • cloud-init: el motor que procesa la configuración al primer arranque.
  • cloud-utils-growpart: necesario para que Cloud-Init pueda expandir el disco al tamaño configurado.

6. Configurar el datasource de Cloud-Init

Proxmox expone los datos de Cloud-Init a través de NoCloud o ConfigDrive. Hay que indicarle a Cloud-Init que busque en esas fuentes:

1
2
sudo mkdir -p /etc/cloud/cloud.cfg.d
sudo vi /etc/cloud/cloud.cfg.d/99-pve.cfg

Contenido del archivo:

1
datasource_list: [ NoCloud, ConfigDrive ]

Habilitar todos los servicios de Cloud-Init para que se ejecuten al arranque:

1
2
3
4
sudo systemctl enable cloud-init-local.service
sudo systemctl enable cloud-init.service
sudo systemctl enable cloud-config.service
sudo systemctl enable cloud-final.service

Sin este archivo de configuración, Cloud-Init puede ignorar los datos que Proxmox le pasa y la VM arrancará sin aplicar ninguna configuración.

7. Limpiar la VM antes de convertir a template

Este paso es crítico. El objetivo es dejar la VM en un estado completamente neutro para que cada clon que se genere a partir de ella sea único e independiente.

Limpiar el estado de Cloud-Init:

1
sudo cloud-init clean

Resetear el Machine ID (identificador único del sistema operativo):

1
2
sudo truncate -s 0 /etc/machine-id
sudo rm -f /var/lib/dbus/machine-id

Eliminar las claves SSH del host (se regeneran en el primer arranque):

1
sudo rm -f /etc/ssh/ssh_host_*

Si no se limpia el Machine ID, todos los clones del template compartirán el mismo identificador, lo que puede causar conflictos en DHCP, systemd y otras herramientas de red.

Apagar la VM:

1
sudo poweroff

8. Agregar el drive de Cloud-Init en Proxmox

Con la VM apagada, desde la shell del host Proxmox activar el guest agent y agregar el drive que Proxmox usará para pasar la configuración a la VM:

1
2
qm set 8000 --agent enabled=1
qm set 8000 --ide2 local-lvm:cloudinit

Verificar que la configuración quedó correcta:

1
qm config 8000

Entre los parámetros deberíamos ver al menos:

1
2
agent: enabled=1
ide2: local-lvm:cloudinit

9. Convertir la VM a template

1
qm template 8000

A partir de este momento la VM ya no se puede iniciar directamente; solo se puede clonar. En la interfaz web de Proxmox aparecerá con el icono de template.

10. Probar el template

Clic derecho sobre el template → Clone.

En la VM clonada, configurar los datos de Cloud-Init desde la pestaña Cloud-Init de la VM:

  • Username
  • Password o SSH Key
  • IP (DHCP o estática)

Arrancar la VM clonada. Si Cloud-Init funcionó correctamente, deberías poder iniciar sesión con el usuario y credenciales que configuraste en la pestaña Cloud-Init de Proxmox. Si no es posible autenticarse, hubo un problema con la configuración y conviene revisar los pasos anteriores antes de continuar.

Una vez dentro de la VM, verificar que Cloud-Init completó su ejecución sin errores:

1
cloud-init status --long

La salida esperada:

1
status: done

Si el estado no es done, revisar los logs para identificar qué módulo falló:

1
sudo journalctl -u cloud-init

Resultado

Al finalizar este proceso tenemos un template de Rocky Linux 10 completamente reproducible: cada clon arranca ya con el sistema operativo instalado y hardware configurado. A cada clon creado es posible cambiarle recursos y usuario inicial con Cloud-init. Esto nos ahorra bastante tiempo a la hora de configurar nuevos hosts en Proxmox, ya que no tendremos que instalar Linux desde 0 cada vez.

Próximamente

En el próximo post usaremos este template como base para aprovisionar VMs directamente desde Terraform: definir recursos, usuario, llaves SSH y red en código, y levantar un host nuevo en cosa de segundos sin incurrir en procedimientos manuales.

Referencias

Construye, automatiza, repite. ¡Nos vemos en el próximo post!

Esta entrada está licenciada bajo CC BY 4.0 por el autor.