Feeds 3
Artículos recientes
Nube de tags
seguridad
mfa
dns
zerotrust
monitorizacion
kernel
bpf
sysdig
port knocking
iptables
linux
pxe
documentación
rsyslog
zeromq
correo
dovecot
cassandra
solandra
solr
systemtap
nodejs
redis
hadoop
mapreduce
firewall
ossec
psad
tcpdump
tcpflow
Categorías
Archivo
Proyectos
Documentos
Blogs
PXE para instalaciones básicas de CentOS y Debian Thu, 20 Oct 2011
Otro mini-post que vuelve a salirse completamente de la idea general de este blog. Ya hay mucha documentación sobre PXE y sobre instalaciones automatizadas tanto de CentOS como de Debian, pero bueno, a ver si le es útil a alguien.
En este caso, vamos a montar un sencillo servidor PXE, que podremos usar para hacer instalaciones de CentOS y Debian. Bueno, en realidad, podemos instalar cualquier cosa, pero en mi caso no suelo necesitar nada más.
Todo esto se debe a que, para las pruebas que hago en mi laboratorio, el mínimo de máquinas virtuales que necesito no baja de... tres, y al final tiendo a perder mucho tiempo con las instalaciones, y poco con el trabajo "de verdad". Por eso, nada mejor que PXE, kickstart y debian-installer para agilizar el proceso.
Ojo, que todo esto, aunque perfectamente válido, no es lo que yo usaría, a priori, en un entorno real. Hay mucho software que automatiza lo que vamos a hacer aquí, con un interfaz web, scripts para actualizar repositorios, .... Por eso, creo que aplicaciones como Cobbler (por citar una) deben ser la primera opción.
Aún así, para los que queréis aprender cómo se montan estos "inventos", aquí van unas pinceladas.
El problema
Necesitamos una forma rápida de instalar servidores. En mi caso, máquinas virtuales. Aunque hoy en día la gente de VmWare, RedHat o Virsh+libvirt ofrecen alternativas para clonar instancias como churros, vamos a optar por una solución genérica y mucho más divertida.
Las distribuciones que vamos instalar con este sistema son CentOS y Debian. Para el caso de las basadas en kickstart, la cosa está muy clara, pero para Debian, muchos os preguntaréis ¿Por qué no FAI? Bien, la respuesta rápida, en mi caso, es que no quiero instalar un servidor NFS, y la última vez que miré era un requisito. Como decía, buscad la solución que más os guste.
Otro problema posterior es la configuración "fina" de las instancias. Eso no lo voy a documentar aquí, pero como pista: cfengine, puppet, ....
La solución
He dicho que iba a ir rápido, y ya me estoy enrollando.... Venga, lo primero que necesitamos, como no, es una BIOS que permita instalar los clientes vía PXE. Por supuesto, tanto Qemu/KVM como VmWare lo permiten, así que ni una palabra más al respecto.
En cuanto al software necesario para el servidor de instalaciones, necesitamos un DHCPD razonable (por ejemplo el del ISC), un TFTPD (por ejemplo atftpd) y un servidor web, que en mi caso va a ser apache. Situemos todo en contexto:
- La máquina virtual arranca y "habla" con DHCPD.
- Además de la información IP, se trasmite, vía DHCP+TFTP, pxelinux.0.
- En el caso de Debian, también se aprovecha para dar una pista sobre dónde encontrar el fichero para debian-installer.
- Cargamos el menú de arranque con TFTP.
- El sistema usa apache para obtener los ficheros ks, debian-installer y los rpm, deb y demás parafernalia.
Empezamos por lo fácil: El contenido web. Tan sencillo como copiar el contenido de los CDs de instalación de las distribuciones a una ruta del arbol web.
# ls /var/www/instalaciones/centos/6.0-x86_64/ CentOS_BuildTag EULA images Packages repodata RPM-GPG-KEY-CentOS-Debug-6 RPM-GPG-KEY-CentOS-Testing-6 EFI GPL isolinux RELEASE-NOTES-en-US.html RPM-GPG-KEY-CentOS-6 RPM-GPG-KEY-CentOS-Security-6 TRANS.TBL # ls /var/www/instalaciones/debian/squeeze/ autorun.inf dists firmware g2ldr.mbr install.amd md5sum.txt pool README.mirrors.html README.source setup.exe win32-loader.ini css doc g2ldr install isolinux pics README.html README.mirrors.txt README.txt tools
Sigamos con la configuración para DHCP. Hemos dicho que, además de las obvias IPs, también van a ayudar a las Debian con la definición del fichero para debian-installer. Hay tres bloques de configuración que os quiero enseñar:
# less /etc/dhcp/dhcpd.conf ... subnet 192.168.10.0 netmask 255.255.255.0 { option routers 192.168.10.1; option domain-name-servers 192.168.10.1; option domain-name "forondarena.net"; option tftp-server-name "inst.forondarena.net"; filename "/instalaciones/pxelinux.0"; } host centos1 { hardware ethernet 52:54:00:30:38:c6; server-name "fn134.forondarena.net"; fixed-address 192.168.10.134; } host debian1 { hardware ethernet 52:54:00:da:4a:92; server-name "fn135.forondarena.net"; fixed-address 192.168.10.135; if substring (option vendor-class-identifier, 0, 3) = "d-i" { filename "http://inst.forondarena.net/instalaciones/squeeze_preseed_135.cfg"; } } ...
Como veis, para CentOS no trasmitimos nada relacionado con el fichero kickstart, pero para Debian sí. ¿Por qué? Pues para enriquecer un poco el post con algo diferente, la verdad. Hay más de una forma de hacerlo.
Con esto ya tenemos la primera fase del arranque. Lo siguiente: El "boot menu". Y para esto necesitamos TFTP:
/srv/tftp/instalaciones/ ├── pxelinux.0 ├── pxelinux.cfg │ ├── C0A80A86 │ └── C0A80A87 ├── squeeze-x86_64 │ ├── initrd.gz │ └── vmlinuz ├── centos-6.0-x86_64 │ ├── initrd.img │ └── vmlinuz ├── msgs │ ├── centos │ │ ├── boot.msg │ │ └── general.msg │ └── debian │ ├── f1.txt │ └── f2.txt
La mayoría de estos ficheros se pueden bajar casi desde cualquier sitio:
http://ftp.cz.debian.org/debian/dists/squeeze/main/installer-amd64/current/images/netboot/debian-installer/amd64/
Como el contenido de "msg" es obvio, vamos a los fichero importantes, C0A80A86 y C0A80A87. ¿Qué clase de nombres son estos? Pues son las IPs, en hexadecimal, de nuestras dos máquinas virtuales:
$ IP_ADDR="192.168.10.134"; printf '%02X' ${IP_ADDR//./ }; echo C0A80A86 $ IP_ADDR="192.168.10.135"; printf '%02X' ${IP_ADDR//./ }; echo C0A80A87
El contenido, para CentOS, en C0A80A86:
timeout 100 prompt 1 display msgs/centos/boot.msg F1 msgs/centos/boot.msg F2 msgs/centos/general.msg default Centos6 label Centos6 menu label ^Centos 6 amd64 kernel centos-6.0-x86_64/vmlinuz append initrd=centos-6.0-x86_64/initrd.img ramdisk_size=6878 ip=dhcp ks=http://192.168.10.40/instalaciones/ks_rh6_134.ks
Como veis, hemos especificado la ruta web para el fichero kickstart.
Para Debian, en C0A80A87:
# less C0A80A87 menu hshift 15 menu width 49 prompt 1 display msgs/debian/f1.txt timeout 100 f1 msgs/debian/f1.txt f2 msgs/debian/f2.txt menu title Installer boot menu menu color title * #FFFFFFFF * ... menu tabmsgrow 18 menu tabmsg Press ENTER to boot or TAB to edit a menu entry default install label install menu label ^Debian Squeeze Texto amd64 menu default kernel squeeze-x86_64/vmlinuz append video=vesa:ywrap,mtrr vga=788 initrd=squeeze-x86_64/initrd.gz auto=true priority=critical locale=es_ES console-keymaps-at/keymap=es --
En este caso, no hemos dicho dónde encontrar el fichero para debian-installer. Ya lo sabemos.
Y ya casi por último, veamos los ficheros kickstart y debian-installer, a los que vamos a acceder desde apache:
# ls -1 /var/www/instalaciones/ ... ks_rh6_134.ks squeeze_preseed_135.cfg
Todos conocéis el formato de los .ks; son simples y fáciles de leer.
#version=RHEL6 install url --url=http://192.168.10.40/instalaciones/centos/6.0-x86_64/ lang es_ES.UTF-8 keyboard es network --device eth0 --onboot yes --bootproto static --ip 192.168.10.134 --netmask 255.255.255.0 --gateway 192.168.10.1 --nameserver 192.168.10.1 --hostname fn134.forondarena.net rootpw --iscrypted contraseña firewall --service=ssh authconfig --enableshadow --passalgo=sha512 --enablefingerprint selinux --enforcing timezone --utc Europe/Madrid bootloader --location=mbr --driveorder=vda --append="crashkernel=auto rhgb quiet" clearpart --all --drives=vda part /boot --fstype=ext4 --size=200 part pv.gjsqnW-TYE3-SDwW-646R-0SSI-hhDa-ZF6bXm --grow --size=200 volgroup vg_primario --pesize=4096 pv.gjsqnW-TYE3-SDwW-646R-0SSI-hhDa-ZF6bXm logvol / --fstype=ext4 --name=lv_root --vgname=vg_primario --size=7400 logvol swap --name=lv_swap --vgname=vg_primario --size=588 ##repo --name="CentOS" --baseurl=http://192.168.10.1/instalaciones/centos/6.0-x86_64/ --cost=100 halt %packages @core @server-policy @spanish-support openssh* %end
Es un ejemplo autogenerado para una máquina virtual tipo KVM. No le hagáis mucho caso al contenido en sí. Lo dicho, tenéis un kilo de documentación, e incluso aplicaciones para hacer estos ficheros.
Otra cosa muy diferente es debian-installer. La verdad, no conozco a mucha gente que no se haya atascado con esto en algún momento. El concepto es sencillo, con una opción para cada una de las opciones de cada uno de los menús que pueden aparecer durante el proceso de instalación. El problema es que, esto tan fácil de decir, es un listado .... largo; y con algunos algoritmos, como el del cálculo de espacio para particiones, nada claros. Además, como suele ser demasiado frecuente, el que decidió los nombres de las opciones.... bueno, que no me parece demasiado intuitivo, aunque si estás familiarizado con Debian te haces enseguida.
No voy a escribir un ejemplo completo. Os vais a tener que conformar con una pequeña muestra:
# cat /var/www/instalaciones/squeeze_preseed_135.cfg ... # Keyboard selection. d-i console-tools/archs select at d-i console-keymaps-at/keymap select es d-i keyboard-configuration/xkb-keymap select es ### Network configuration d-i netcfg/choose_interface select eth0 d-i netcfg/disable_dhcp boolean true # Static network configuration. d-i netcfg/get_nameservers string 192.168.10.1 d-i netcfg/get_ipaddress string 192.168.10.135 d-i netcfg/get_netmask string 255.255.255.0 d-i netcfg/get_gateway string 192.168.10.1 d-i netcfg/confirm_static boolean true ... # Root password, encrypted using an MD5 hash. d-i passwd/root-password-crypted password contraseña ... ### Partitioning d-i partman-auto/disk string /dev/sda d-i partman-auto/method string lvm d-i partman-lvm/device_remove_lvm boolean true d-i partman-lvm/device_remove_lvm_span boolean true d-i partman-auto/purge_lvm_from_device boolean true d-i partman-auto-lvm/new_vg_name string vg_forondarenanet d-i partman-basicmethods/method_only boolean false d-i partman-auto/expert_recipe string boot-root :: \ 100 100 100 ext3 \ $defaultignore{ } \ $primary{ } \ device{ /dev/sda } \ $bootable{ } \ method{ format } \ format{ } \ use_filesystem{ } \ filesystem{ ext3 } \ mountpoint{ /boot } \ . \ 200 1000 -1 ext4 \ $defaultignore{ } \ $primary{ } \ device{ /dev/sda } \ method{ lvm } \ vg_name{ vg_forondarenanet } \ . \ 300 4000 -1 ext4 \ $lvmok{ } \ lv_name{ lvroot } \ in_vg{ vg_forondarenanet } \ method{ format } \ format{ } \ use_filesystem{ } \ filesystem{ ext4 } \ mountpoint{ / } \ . \ 512 512 512 linux-swap \ $lvmok{ } \ in_vg{ vg_forondarenanet } \ lv_name{ lvswap } \ method{ swap } \ format{ } \ . d-i partman-auto/choose_recipe select boot-root d-i partman/confirm_write_new_label boolean true d-i partman/choose_partition select finish d-i partman/confirm boolean true d-i partman/confirm_nooverwrite boolean true d-i partman/confirm_nochanges boolean true d-i partman-lvm/confirm boolean true d-i partman-lvm/confirm_nooverwrite boolean true d-i partman-lvm/confirm_nochanges boolean true ... # Individual additional packages to install d-i pkgsel/include string openssh-server less d-i pkgsel/upgrade select safe-upgrade popularity-contest popularity-contest/participate boolean false d-i finish-install/reboot_in_progress note d-i debian-installer/exit/halt boolean true # This will power off the machine instead of just halting it. d-i debian-installer/exit/poweroff boolean true ...
Y así podría seguir...
En este caso es una máquina virtual para ESX. Me interesa que veáis la parte de particionado. Aunque no os lo creáis, he definido una partición primaria /boot de unos 100M, y el resto en LVM, con aproximadamente 512M de swap, y el resto de espacio disponible para raíz.
Y poco más hace falta. Ahora bien, en este post, las notas que suelo añadir al final son más importantes que nunca.
Notas
Nota 1: Los ficheros de instalación automática de los ejemplos hacen un halt una vez finalizada la instalación. ¿Por qué? Porque no tengo automatizado que la BIOS cambie por arte de magia de arranque por PXE a arranque desde disco.
Nota 2: Más que una nota, un consejo. No os volváis locos con la configuración de ficheros de sistema, usuarios y aplicaciones. Tenéis herramientas mucho mejores para la configuración "fina", así que plantearos añadir puppet, cfengine, chef, ... en los bloques "%packages" y "d-i pkgsel/include", y dejarles que hagan su trabajo al arrancar la máquina. Para CentOS (desde puppetlabs):
%post .... /sbin/chkconfig --level 345 puppet on /bin/echo "$PUPPETIP puppet" >> /etc/hosts /bin/echo "nameserver $NAMESERVERIP" >> /etc/resolv.conf hostname $hostname # Write out the hostname to a file for reboot. /bin/echo -e "NETWORKING=yes\nHOSTNAME=$hostname" > /etc/sysconfig/network /usr/sbin/puppetd -tv
y, como mini-ejemplo, un poco diferente, para Debian:
d-i preseed/late_command string in-target wget -P /tmp/ http://servidor_web/script.sh; in-target chmod +x /tmp/script.sh; in-target /tmp/script.sh
dejando que ese "script.sh" haga cosas como "sed -i 's/START=no/START=yes/'", siguiendo la estructura de Debian de ficheros en default y todas estas cosas.
Nota 3: Lo más importante. Este post no es suficiente para hacer que las instalaciones automáticas os funcionen. Necesita trabajo. Si os atascáis con algo, tweet o comentario, y lo intentaremos solucionar.