Eres SysAdmin de una empresa y tienes por delante restaurar la distribución de 25 equipos que necesitan reinstalación. Puede considerarse una labor tediosa que piensas que es mejor automatizar, además añadiendo una configuración personalizada. Pero, ¿esto es posible? Sí. ¿Que puedo dejar instalados 25 equipos todos iguales de manera simultánea? ¡Sí! Existe PXE, como si tienes 90 o 100 equipos, pero, ¿qué es eso y cómo puedo montarlo? Vamos a ello, solo necesitaremos Ubuntu Server 22.04 instalado en una máquina virtual donde montaremos este servidor PXE para poder instalar imágenes de Ubuntu 22.04. Podemos elegir otra versión, como la 20.04, pero así comprobamos la compatibilidad con la más LTS más reciente. El último punto será crear la personalización que, como las opiniones, cada uno puede tener la suya.
Introducción
PXE es un protocolo utilizado para iniciar sistemas operativos a través de la red. Se puede usar este método para instalar nuestra distribución de GNU/Linux favorita en portátil, servidor u ordenador de escritorio a través de la red.
Configurando IP estática en Ubuntu Server 22.04 LTS
Antes de continuar, es mejor configurar el servidor de arranque PXE con una dirección IP estática. En esta primera sección, veremos cómo configurarla.
Para configurar una dirección IP estática en Ubuntu Server 22.04 LTS, abrimos el archivo de configuración de netplan con un editor de texto, en este caso nano:
sudo nano /ect/netplan/00-installer-config.yaml
E incluimos lo siguiente teniendo en cuenta que:
- La interfaz en este caso es enp0s3, puedes saber cuál es al teclear
ip a
en el terminal, - 192.168.180/24 es la IP que deseamos darle y la máscara de red de la configuración,
- 192.168.1.1 es la IP del router como servidor DHCP,
- 1.1.1.1 y 8.8.8.8 son direcciones DNS reconocidas
y podemos crearlo bajo nuestros propios parámetros.
#This is the network config written by 'subiquity'. IP addresses are an example
network:
ethernets:
enp0s3:
dhcp4: no
addresses:
- 192.168.1.180/24
routes:
- to: default
via: 192.168.1.1
nameservers:
addresses:
- 1.1.1.1
- 8.8.8.8
version: 2
Para aplicar los cambios, ejecutamos:
sudo netplan apply
Creando la estructura de directorios requerida
Nuestra estructura de directorios tendrá la siguiente forma:
/pxeboot
y como subdirectorios
-
/config/
, donde guardaremos los archivos de arranque. -
/firmware/
, donde guardaremos los firmware. -
/images/
, donde guardaremos las imágenes que pueden listarse en el menú.
En el directorio /pxeboot/images/
copiaremos el contenido de cada imagen ISO en un subdirectorio por cada distribución. Esto lo veremos más adelante.
Para crear todos los directorios requeridos en un solo comando, ejecutamos:
sudo mkdir -pv /pxeboot/{config,firmware,images}
Descargando el código fuente de iPXE y compilación en Ubuntu 22.04
Estos pasos los haremos en nuestra carpeta de \home\$USER
, lo último será moverlo todo a los directorios creados en el paso anterior.
En primer lugar, actualizamos los repositorios e instalamos los siguientes paquetes:
sudo apt update && sudo apt install build-essential liblzma-dev isolinux git -y
Clonamos el repositorio de iPXE en GitHub en nuestro servidor:
git clone https://github.com/ipxe/ipxe.git
Accedemos a la carpeta ipxe/src
:
cd ipxe/src
Para configurar iPXE como arranque automático, hemos de crear el script correspondiente y relacionarlo con los firmwares de BIOS y UEFI cuando ya esté todo compilado.
Creamos el script de arranque para iPXE bootconfig.ipxe y lo abrimos con nuestro editor favorito:
nano bootconfig.ipxe
Copiando el siguiente contenido:
#!ipxe
dhcp
chain tftp://192.168.1.180/config/boot.ipxe
Recordemos que la IP es la que hemos configurado como IP estática del servidor.
Para compilar los firmwares de iPXE tanto para BIOS como para UEFI y relacionadrlo con el menú de arranque, ejecutamos el siguiente comando:
make bin/ipxe.pxe bin/undionly.kpxe bin/undionly.kkpxe bin/undionly.kkkpxe bin-x86_64-efi/ipxe.efi EMBED=bootconfig.ipxe
Esta tarea tomará varios minutos.
Copiando los firmwares ya compilados
Una vez que los firmwares de iPXE estén compilados, los copiamos en /pxeboot/firmware
de nuestro servidor de arranque para que los equipos donde deseemos instalar los sistemas operativos puedan acceder vía TFTP.
sudo cp -v bin/{ipxe.pxe,undionly.kpxe,undionly.kkpxe,undionly.kkkpxe} bin-x86_64-efi/ipxe.efi /pxeboot/firmware/
Los archivos ipxe.pxe, undionly.kpxe, undionly.kkpxe, and undionly.kkkpxe son para arranques BIOS, mientras que ipxe.efi es para arranques UEFI.
Instalando y configurando DHCP y TFTP
Para que PXE arranque, necesitaremos un servidor DHCP y TFTP ejecutándose. En este caso, usaremos dnsmasq.
sudo apt install dnsmasq -y
Crearemos un nuevo archivo de configuración para dnsmasq. Renombramos el original /etc/dnsmasq.conf
a /etc/dnsmasq.conf.backup
de la siguiente manera:
sudo mv -v /etc/dnsmasq.conf /etc/dnsmasq.conf.backup
Creamos un archivo vacío:
sudo nano /etc/dnsmasq.conf
Y añadimos el siguiente contenido:
interface=enp0s3
bind-interfaces
domain=glampinghub.local
dhcp-range=192.168.1.181,192.168.1.190,255.255.255.0,12h
dhcp-option=option:router,192.168.1.1
dhcp-option=option:dns-server,1.1.1.1
dhcp-option=option:dns-server,8.8.8.8
enable-tftp
tftp-root=/pxeboot
# boot config for BIOS systems
dhcp-match=set:bios-x86,option:client-arch,0
dhcp-boot=tag:bios-x86,firmware/ipxe.pxe
# boot config for UEFI systems
dhcp-match=set:efi-x86_64,option:client-arch,7
dhcp-match=set:efi-x86_64,option:client-arch,9
dhcp-boot=tag:efi-x86_64,firmware/ipxe.efi
Para que los cambios tengan efecto, reiniciamos el servidor de dnsmasq:
sudo systemctl restart dnsmasq
Para comprobar que el servicio está ejecutándose, podemos comprobarlo de la siguiente manera:
sudo systemctl status dnsmasq
● dnsmasq.service - dnsmasq - A lightweight DHCP and caching DNS server
Loaded: loaded (/lib/systemd/system/dnsmasq.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2022-11-07 07:53:18 UTC; 3h 41min ago
Process: 697 ExecStartPre=/etc/init.d/dnsmasq checkconfig (code=exited, status=0/SUCCESS)
Process: 743 ExecStart=/etc/init.d/dnsmasq systemd-exec (code=exited, status=0/SUCCESS)
Process: 768 ExecStartPost=/etc/init.d/dnsmasq systemd-start-resolvconf (code=exited, status=0/SUCCESS)
Main PID: 766 (dnsmasq)
Tasks: 1 (limit: 4576)
Memory: 3.5M
CPU: 35ms
CGroup: /system.slice/dnsmasq.service
└─766 /usr/sbin/dnsmasq -x /run/dnsmasq/dnsmasq.pid -u dnsmasq -7 /etc/dnsmasq.d,.dpkg-dist,.dpkg-old,.dpkg-new --local-service --trust-anchor=.,20326,8,2,e06d44b80b8f1d39a95c0b0d7c65d08458e880409bbc683457104237c7f8ec8d
nov 07 07:53:18 ubuntu2204pxe dnsmasq[766]: read /etc/hosts - 7 addresses
nov 07 07:53:18 ubuntu2204pxe systemd[1]: Started dnsmasq - A lightweight DHCP and caching DNS server.
nov 07 07:58:56 ubuntu2204pxe dnsmasq-dhcp[766]: DHCPDISCOVER(enp0s3) 08:00:27:37:b9:ec
nov 07 07:58:56 ubuntu2204pxe dnsmasq-dhcp[766]: DHCPOFFER(enp0s3) 192.168.1.123 08:00:27:37:b9:ec
nov 07 07:58:56 ubuntu2204pxe dnsmasq-dhcp[766]: DHCPDISCOVER(enp0s3) 08:00:27:37:b9:ec
nov 07 07:58:56 ubuntu2204pxe dnsmasq-dhcp[766]: DHCPOFFER(enp0s3) 192.168.1.123 08:00:27:37:b9:ec
nov 07 07:59:14 ubuntu2204pxe dnsmasq-dhcp[766]: DHCPDISCOVER(enp0s3) 08:00:27:37:b9:ec
nov 07 07:59:14 ubuntu2204pxe dnsmasq-dhcp[766]: DHCPOFFER(enp0s3) 192.168.1.123 08:00:27:37:b9:ec
nov 07 07:59:15 ubuntu2204pxe dnsmasq-dhcp[766]: DHCPDISCOVER(enp0s3) 08:00:27:37:b9:ec
nov 07 07:59:15 ubuntu2204pxe dnsmasq-dhcp[766]: DHCPOFFER(enp0s3) 192.168.1.123 08:00:27:37:b9:ec
Instalando y configurando el servidor NFS
Ubuntu 22.04 usa casper para arrancar la instalación modo "live". casper soporta arranque PXE solo a través del protocolo NFS. Por ello, para arrancar Ubuntu Desktop 22.04 a través de PXE, necesitaremos un servidor NFS que sea accesible por toda la red local.
Para instalar NFS en el servidor, ejecutamos:
sudo apt install nfs-kernel-server
Abrimos el archivo de configuración de NFS /etc/exports
de la siguiente manera:
sudo nano /etc/exports
Y añadimos la siguiente línea al final:
/pxeboot *(ro,sync,no_wdelay,insecure_locks,no_root_squash,insecure,no_subtree_check)
Para efectuar los cambios y compartir la nueva configuración para que sea visible, ejecuta:
sudo exportfs -av
Obteniendo el siguiente resultado por pantalla:
user@serverpxe:$ sudo exportfs -av
*:/pxeboot
Configurando iPXE
⚠️ La imagen ISO que descargaremos será de servidor, convirtiéndola en una versión de escritorio a través del autoinstalador de cloud-init como veremos en el último paso.Descargamos la imagen de Ubuntu Server 22.04 en nuestro directorio de /home/$USER
.
cd
wget https://releases.ubuntu.com/jammy/ubuntu-22.04.4-live-server-amd64.iso
Una vez descargado, montamos la imagen en el directorio /mnt
:
sudo mount -o loop ubuntu-22.04.4-live-server-amd64.iso /mnt
Creamos un directorio dedicado a Ubuntu 22.04 en /pxeboot/images/
:
sudo mkdir -pv /pxeboot/images/ubuntu-22.04
Para copiar los contenidos de la ISO, ejecutamos rsync de la siguiente manera:
sudo rsync -avz /mnt/ /pxeboot/images/ubuntu-22.04
Desmontamos la imagen de Ubuntu 22.04 LTS de '/mnt':
sudo umount /mnt
Creamos el archivo de configuración /pxeboot/config/boot.ipxe
:
sudo nano /pxeboot/config/boot.ipxe
Y añadimos lo siguiente:
#!ipxe
set server_ip 192.168.1.180
set root_path /pxeboot
menu Select an OS to boot
item ubuntu-22.04 Install Ubuntu 22.04 LTS
choose --default exit --timeout 10000 option && goto ${option}
:ubuntu-22.04
set os_root ubuntu-22.04
kernel tftp://${server_ip}/images/${os_root}/casper/vmlinuz
initrd tftp://${server_ip}/images/${os_root}/casper/initrd
imgargs vmlinuz initrd=initrd boot=casper netboot=nfs ip=dhcp nfsroot=${server_ip}:${root_path}/images/${os_root} ds=nocloud;s=/cdrom/nocloud/ autoinstall quiet splash ---
boot
El ejemplo de arriba es si montamos una sola imagen en el servidor. En el caso de que tengamos dos, por ejemplo Ubuntu 22.04 y Ubuntu 20.04, tendríamos un archivo similar a esto repitiendo los procesos de descarga, creación y montaje descritos arriba:
#!ipxe
set server_ip 192.168.1.180
set root_path /pxeboot
menu Select an OS to boot
item ubuntu-20.04 Install Ubuntu 20.04 LTS
item ubuntu-22.04 Install Ubuntu 22.04 LTS
choose --default ubuntu-20.04 --timeout 10000 option && goto ${option}
:ubuntu-22.04
set os_root ubuntu-22.04
kernel tftp://${server_ip}/images/${os_root}/casper/vmlinuz
initrd tftp://${server_ip}/images/${os_root}/casper/initrd
imgargs vmlinuz initrd=initrd boot=casper maybe-ubiquity netboot=nfs ip=dhcp nfsroot=${server_ip}:${root_path}/images/${os_root} ds=nocloud;s=/cdrom/nocloud/ autoinstall quiet splash ---
boot
:ubuntu-20.04
set os_root ubuntu-20.04
kernel tftp://${server_ip}/images/${os_root}/casper/vmlinuz
initrd tftp://${server_ip}/images/${os_root}/casper/initrd
imgargs vmlinuz initrd=initrd boot=casper maybe-ubiquity netboot=nfs ip=dhcp nfsroot=${server_ip}:${root_path}/images/${os_root} ds=nocloud;s=/cdrom/nocloud/ autoinstall quiet splash ---
boot
Por comentar el menú de arriba, el parámetro ds=nocloud;s=/cdrom/nocloud/
captará la configuración de cloud-init y autoinstall
comenzará automáticamente la instalación. Eliminar este último es útil para cuando tenemos equipos que no descartan por defecto seguir eligiendo el arranque por red tras la instalación, entrando así en un bucle de instalaciones que no terminaría nunca. Si estamos con otra cosa y en un equipo ya está instalado y reiniciado, quitando autoinstall
nos encontraremos con una pregunta sobre proceder con la instalación y la necesidad de pulsar "Yes" o "No".
Autoinstall con cloud-init
Hasta ahora, hemos instalado una versión fresca de Ubuntu tal como vienen en las ISO. ¿Y si queremos hacer una instalación personalizada? Como introducción a este tema, cloud-init es un proyecto de Canonical, empresa responsable de Ubuntu, para hacer esas plantillas automatizadas. Es multiplataforma, por lo que funciona también con distribuciones como Fedora o Arch Linux.
cd /pxeboot/images
Accedemos, en este caso, a la imagen creada de Ubuntu 20.04:
cd ubuntu-20.04
y creamos la carpeta nocloud
dentro de ella:
sudo mkdir nocloud && cd nocloud
Creando dos archivos nuevos:
sudo touch meta-data
meta-data se quedará así vacío, quedando el que nos interesa:
sudo nano user-data
En este archivo, copiaremos el contenido de este gist de GitHub donde podemos observar algunas personalizaciones:
- Instalación de software concreto.
- Nombre del host.
- Creación de perfiles concretos con una configuración especial, tal la creación del archivo de claves públicas o la clave.
- Sección interactiva, para añadir aquella que queramos desarrollar manualmente durante la instalación.
- ¡y un largo etcétera! Te animo a que leas la documentación sobre cloud-init al respecto.
El archivo, al estar escrito en formato YAML, es fácilmente legible comprendiendo cada caso. Por ejemplo, que al final de todo el proceso haga una actualización general de los repositorios y cuando arranquemos, tengamos una distribución flamante.
Arrancando Ubuntu 22.04
Hecho todo lo anterior, arranca cualquier equipo con la opción por red y este detectará el servidor de arranque PXE presente en la red local.
¿Te ha sido difícil? Con este servidor configurado y con algunas pruebas previas, tienes un sistema de automatización para instalar imágenes en otros equipos muy interesante con el fin de no olvidar ningún detalle. ¡Ya puedes guardar la "checklist" en el cajón y anota todo en el cloud-init!
Top comments (7)
Muy bueno!!! Funcionó perfectamente con Ubuntu pero estaba intentando bootear archlinux y se queda parado a la hora de entrar al SO más específicamente a hora de montar /dev/disk-by-label!
se alguien me pudiera ayudar agradezco!
saludos!
Hola, muy buen artículo, muchas gracias! Unos comentarios:
ixpe
en vez deipxe
Gracias, corregido.
Hola Daniel, felicitaciones por tu tutorial, casi lo he logrado por completo, he creado un pequeño laboratorio en VirtualBox, sin embargo tienes idea por qué no funciona el autoinstall con cloud-init? realiza el boot por PXE, pero se abre la pantalla principal y me muestra la opción para selecionar el lenguaje
Saludos
Hola, Esteban:
Disculpa que responda después de tantos meses, tenía este perfil en reserva y no me llegaron las notificaciones de mensajes. Aunque quizás lo hayas resuelto después de este tiempo, a mí me pasaba cuando el archivo yaml no estaba correctamente identado, es decir, tenía más sangrías de la cuenta y el autoinstalador no lo "leía" bien en vertical. Parece que los archivos yaml son muy sensibles en ese aspecto.
Excelente!!! He seguido y lo he conseguido montar todo. Ya probé a arrancar é instalar una instalación de Ubuntu 20.04 y fue genial. Ahora solo me falta ver como añadir una instalación para Windows 10 y 11. Si alguien me puede echar un cable. Muchas gracias de antemano.
El articulo estuvo genial, yo aun recuerdo cuando tenia que hacer algo similar, normalmente utilizaba Clonezilla.