DEV Community

Cover image for Cómo montar un servidor de arranque PXE en Ubuntu 22.04
Daniel M.
Daniel M.

Posted on • Updated on

Cómo montar un servidor de arranque PXE en Ubuntu 22.04

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Para aplicar los cambios, ejecutamos:

sudo netplan apply
Enter fullscreen mode Exit fullscreen mode

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}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Clonamos el repositorio de iPXE en GitHub en nuestro servidor:

git clone https://github.com/ipxe/ipxe.git
Enter fullscreen mode Exit fullscreen mode

Accedemos a la carpeta ipxe/src:

cd ipxe/src
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Copiando el siguiente contenido:

#!ipxe
dhcp
chain tftp://192.168.1.180/config/boot.ipxe
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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/
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Creamos un archivo vacío:

sudo nano /etc/dnsmasq.conf
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Para que los cambios tengan efecto, reiniciamos el servidor de dnsmasq:

sudo systemctl restart dnsmasq
Enter fullscreen mode Exit fullscreen mode

Para comprobar que el servicio está ejecutándose, podemos comprobarlo de la siguiente manera:

sudo systemctl status dnsmasq
Enter fullscreen mode Exit fullscreen mode
● 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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Abrimos el archivo de configuración de NFS /etc/exports de la siguiente manera:

sudo nano /etc/exports
Enter fullscreen mode Exit fullscreen mode

Y añadimos la siguiente línea al final:

/pxeboot           *(ro,sync,no_wdelay,insecure_locks,no_root_squash,insecure,no_subtree_check)
Enter fullscreen mode Exit fullscreen mode

Para efectuar los cambios y compartir la nueva configuración para que sea visible, ejecuta:

sudo exportfs -av
Enter fullscreen mode Exit fullscreen mode

Obteniendo el siguiente resultado por pantalla:

user@serverpxe:$ sudo exportfs -av
*:/pxeboot
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode
wget https://releases.ubuntu.com/jammy/ubuntu-22.04.4-live-server-amd64.iso
Enter fullscreen mode Exit fullscreen mode

Una vez descargado, montamos la imagen en el directorio /mnt:

sudo mount -o loop ubuntu-22.04.4-live-server-amd64.iso /mnt
Enter fullscreen mode Exit fullscreen mode

Creamos un directorio dedicado a Ubuntu 22.04 en /pxeboot/images/:

sudo mkdir -pv /pxeboot/images/ubuntu-22.04
Enter fullscreen mode Exit fullscreen mode

Para copiar los contenidos de la ISO, ejecutamos rsync de la siguiente manera:

sudo rsync -avz /mnt/ /pxeboot/images/ubuntu-22.04
Enter fullscreen mode Exit fullscreen mode

Desmontamos la imagen de Ubuntu 22.04 LTS de '/mnt':

sudo umount /mnt
Enter fullscreen mode Exit fullscreen mode

Creamos el archivo de configuración /pxeboot/config/boot.ipxe:

sudo nano /pxeboot/config/boot.ipxe
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Accedemos, en este caso, a la imagen creada de Ubuntu 20.04:

cd ubuntu-20.04
Enter fullscreen mode Exit fullscreen mode

y creamos la carpeta nocloud dentro de ella:

sudo mkdir nocloud && cd nocloud
Enter fullscreen mode Exit fullscreen mode

Creando dos archivos nuevos:

sudo touch meta-data
Enter fullscreen mode Exit fullscreen mode

meta-data se quedará así vacío, quedando el que nos interesa:

sudo nano user-data
Enter fullscreen mode Exit fullscreen mode

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!

Oldest comments (7)

Collapse
 
gpothier profile image
gpothier

Hola, muy buen artículo, muchas gracias! Unos comentarios:

  • Hay un par de lugares donde pusiste ixpe en vez de ipxe
  • La versión actualmente disponible de Ubuntu Jammy es la 22.04.2, la 22.04.1 ya no está.
Collapse
 
daniconil profile image
Daniel M.

Gracias, corregido.

Collapse
 
h3ct0rjs profile image
Héctor F. Jiménez. S

El articulo estuvo genial, yo aun recuerdo cuando tenia que hacer algo similar, normalmente utilizaba Clonezilla.

Clonezilla Live is a Debian-based live CD containing Clonezilla, a partition and disk cloning software similar to Norton Ghost. It saves and restores only used blocks in hard drive.

Collapse
 
estebanldu7 profile image
Esteban

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

Collapse
 
daniconil profile image
Daniel M.

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.

Collapse
 
joseramospt profile image
joseramospt

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.

Collapse
 
wasosky11 profile image
Wasosky

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!