Proceso de conversión de VM a contenedor LXC en Proxmox VE¶
Escenario: VM Linux sin Docker, acceso a la VM mediante usuario con
sudo(sin login directo comorootpor SSH). Conversión manual usando solo la CLI de PVE.
Requisitos previos¶
Acceso SSH o consola a la VM de origen con un usuario que tenga
sudo.Acceso a la terminal del host PVE como
root.Conocer la versión exacta del sistema operativo de la VM de origen.
Espacio suficiente en el almacenamiento del host PVE para el contenedor.
Backup o snapshot de la VM de origen antes de empezar.
Proceso¶
Identificar el sistema operativo de la VM¶
En la VM de origen:
cat /etc/os-release
Anotar ID (ej. debian) y VERSION_ID (ej. 13).
Descargar la plantilla LXC en el host PVE¶
En el host PVE:
pveam update
pveam available --section system | grep -i "debian"
pveam download local debian-13-standard_13.6-1_amd64.tar.zst
pveam list local
Ajustar el nombre de la plantilla según la versión real de la VM.
Crear el contenedor LXC¶
pct create 201 local:vztmpl/debian-13-standard_13.6-1_amd64.tar.zst \
--hostname CTMigracion \
--ostype debian \
--arch amd64 \
--cores 2 \
--memory 4096 \
--swap 0 \
--storage Storage \
--rootfs volume=Storage:24 \
--unprivileged 0 \
--password CLAVEDELROOTDELCONTENEDOR \
--unprivileged 0 \
--features nesting=1,keyctl=1,fuse=1 \
--net0 name=eth0,bridge=vmbr0,ip=192.168.8.201/22,gw=192.168.8.1 \
--nameserver 192.168.8.2 \
--start false
⚠️ En este caso se creó un contenedor privilegiado (
--unprivileged 0). Esto simplifica la migración porque elrootinterno es elrootreal del host (mapeo de identidad), y no requiere ajustes de propietarios después delrsync.
Verificar la configuración:
pct config 201
Si el contenedor queda en estado lock: mounted por un pct mount previo:
pct unmount 201
Sincronizar los archivos desde la VM al contenedor¶
Montar el rootfs del contenedor en el host (si no está montado)¶
pct mount 201
La ruta del rootfs es /var/lib/lxc/201/rootfs/.
Ejecutar rsync desde la VM de origen¶
En la VM de origen (con sudo):
sudo rsync -aAXv \
--exclude={"/dev/*","/proc/*","/sys/*","/tmp/*","/run/*","/mnt/*","/media/*","/lost+found","/boot/*","/lib/modules/*"} \
/ root@PVE_HOST_IP:/var/lib/lxc/201/rootfs/
Lo que hace el rsync es copiar todo lo que no está incluido en esta lista.
Exclusiones obligatorias:
Directorio |
Motivo |
|---|---|
|
Sistemas de archivos virtuales; el contenedor los genera propios |
|
El contenedor comparte el kernel del host; no los necesita |
|
Datos efímeros |
|
Puntos de montaje (especialmente NFS/CIFS) que bloquearían el |
|
Específico del sistema de archivos de la VM |
Verificar propietarios¶
Para contenedor privilegiado (mapeo de identidad):
ls -alh /var/lib/lxc/201/rootfs/ | head
Limpiar enlaces simbólicos de kernel rotos¶
rm -f /var/lib/lxc/201/rootfs/vmlinuz \
/var/lib/lxc/201/rootfs/vmlinuz.old \
/var/lib/lxc/201/rootfs/initrd.img \
/var/lib/lxc/201/rootfs/initrd.img.old
Desmontar el rootfs¶
pct unmount 201
Verificar el tipo de contenedor (uid_map)¶
Arrancar el contenedor y comprobar el mapeo:
pct start 201
pct exec 201 -- cat /proc/self/uid_map
Salida |
Significado |
|---|---|
|
Contenedor privilegiado (mapeo de identidad) |
Ajustar la red dentro del contenedor¶
pct enter 201
Verificar el nombre de la interfaz:
ip addr showEditar la configuración de red según el gestor de la distro:
Ubuntu/Debian con netplan:
/etc/netplan/*.yamlDebian con ifupdown:
/etc/network/interfaces
Ajustar IP, gateway y DNS si es necesario (los parámetros de
pct createya aplican la red de Proxmox, pero la configuración interna puede sobrescribirla).Reiniciar el servicio de red o el contenedor.
Deshabilitar IPv6 (opcional)¶
Dentro del contenedor:
cat > /etc/sysctl.d/99-disable-ipv6.conf <<EOF
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
net.ipv6.conf.eth0.disable_ipv6 = 1
EOF
sysctl --system
Verificar:
ip addr show eth0
Si la dirección IPv6 persiste tras el reinicio, revisar la configuración de systemd-networkd o ifupdown dentro del contenedor.
Verificar servicios¶
Dentro del contenedor:
systemctl status ssh
systemctl status <otros-servicios>
journalctl -xe
Problemas comunes y solución:
Síntoma |
Causa probable |
Solución |
|---|---|---|
Servicio falla al iniciar |
Ruta a hardware o disco inexistente |
Editar la configuración del servicio |
Error de permisos |
Contenedor no privilegiado sin |
Aplicar |
Red no funciona |
Nombre de interfaz distinto ( |
Ajustar configuración de red interna |
|
Servicios específicos de VM |
Deshabilitarlos: |
Validación final¶
pct status 201
pct exec 201 -- id
pct exec 201 -- ip addr show eth0
pct exec 201 -- systemctl status ssh
Criterios de éxito:
pct status 201→status: runningid→uid=0(root) gid=0(root)eth0con la IP esperada y sin IPv6 (si se deshabilitó)SSH y servicios críticos activos
Notas y advertencias¶
No copiar
/bootni/lib/modules: el contenedor no usa kernel propio.Contenedor privilegiado vs no privilegiado:
Privilegiado: migración más simple (sin
chown), pero menor aislamiento de seguridad.No privilegiado: requiere
chown -R 100000:100000, mayor seguridad.
Puntos de montaje de red: desmontar NFS/CIFS en la VM antes del
rsyncpara evitar bloqueos.lock: mounted: si el contenedor queda bloqueado, usarpct unmount 201para liberarlo.Servicios específicos de VM:
cloud-init,qemu-guest-agent,systemd-networkdcon configuración de hardware virtual, deben revisarse o deshabilitarse.Backup: mantener la VM original intacta hasta validar completamente el contenedor.