Instalação Automatizada de Servidores com Kickstarts – Parte II – Integrando com Servidores PXE

No último post comentamos como podemos automatizar a instalação de vários servidores utilizando kickstarts dinâmicos, entretanto ainda era preciso utilizar uma mídia bootável para inicializar o processo de instalação.
Nesse post, entederemos como montar um servidor de instalação utilizando o PXE (Pre-boot eXecution Environment) e integrando-o com  kickstarts já criados anteriormente.
Iremos dividir esse post em 3 etapas que na verdade são os 3 sub-sistemas envolvidos na configuração de um servidor de instalação PXE: DHCP,  TFTP-SERVER, FILE SHARE.
1) Configurando DHCP Server
Para quem desconhece a sigla DHCP (Dynamic Host Configuration Protocol) saiba que muito provavelmente você já tenha utilizado esse serviço sem perceber. O serviço de DHCP (resumindo de maneira bem coloquial) é muito útil quando o cliente não sabe qual IP configurar em sua estação e passa a pedir essa informação à um servidor de endereços IP que irá processar o pedido informando ao cliente qual endereçamento correto(IP) para aquele segmento de rede. Uma informação que acaba passando despercebido quanto ao serviço de DHCP é que ele não serve somente para informar o endereço IP, mas também máscara de rede, roteador padrão, sufixo de pesquisa de DNS(domínio), servidores de DNS, servidores de NTP, servidores NetBios e também servidores TFTP(Trivial File Transfer Protocol).
A informação de TFTP server por sua vez será usada pelo cliente para fazer o download do bootloader, kernel, e initrd para inicializar o processo de instalação. Mas isso é um assunto para a próxima parte deste texto. Por enquanto vamos nos concentrar na configuração do DHCP.
Vamos começar instalando o serviço de DHCP em nosso servidor.


[root@server ~]# rpm -q dhcp-4.1.1-9.fc12.x86_64
[root@server ~]#

Uma vez instalado, precisamos definir em seu arquivo de configuração localizado em /etc/dhcp/dhcpd.conf (em outros distribuições esse arquivo geralmente esta em /etc/dhcpd.conf). Se você prestar atenção, o arquivo padrão irá sugerir que você visite o diretório de documentação do serviço para utilizar um arquivo de exemplo. Utilizando o arquivo de documentação, deixe-o com essa aparência:


[root@server ~]# ifconfig eth0
eth0 Link encap:Ethernet HWaddr 52:54:00:73:59:6E
inet addr:192.168.240.10 Bcast:192.168.240.255 Mask:255.255.255.0
inet6 addr: fe80::5054:ff:fe73:596e/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:22239 errors:0 dropped:0 overruns:0 frame:0
TX packets:15888 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000
RX bytes:22604353 (21.5 MiB) TX bytes:2421924 (2.3 MiB)

[root@server ~]# cat /etc/dhcp/dhcpd.conf
authoritative;
ddns-update-style none;

subnet 192.168.240.0 netmask 255.255.255.0 {
range 192.168.240.50 192.168.240.100;
option domain-name-servers 192.168.240.1;
option domain-name "blog.tchello.mello";
option routers 192.168.240.1;
option broadcast-address 192.168.240.255;
default-lease-time 600;
max-lease-time 7200;
}

host inst-automatico {
hardware ethernet 52:54:00:24:4d:78;
fixed-address 192.168.240.49;
filename "pxelinux.0";
next-server 192.168.240.10;
}

[root@server ~]# cat /etc/sysconfig/dhcpd
# Command line options here
DHCPDARGS=eth0
[root@server ~]# chkconfig dhcpd on
[root@server ~]#

Como vocês podem ver, já compilamos acima uma série de informações que precisarão ser alteradas nos arquivos de configuração. Temos o IP do servidor como 192.168.240.1.  O arquivo de configuração do DHCP é muito intuitivo porém gostaria de salientar 2 parâmetros de configuração:
filename “pxelinux.0″; esse parâmetro irá informar ao cliente nominado como inst-automatico que possui o endereço MAC 52:54:00:24:4d:78 qual arquivo será oferecido a ele no caso de uma solicitação via TFTP.
next-server 192.168.240.10; esse parâmetro informa ao cliente qual é o servidor TFTP disponível para o cliente inst-automatico, ou seja, o servidor que irá transmitir o arquivo pxelinux.0.
Detalhe: Colocamos essas informações dentro das chaves sendo válidas somente a máquina inst-automatico, porém poderiam estar dentro da seção global acima do arquivo.
Alterações executadas, já estamos prontos para inicializar o serviço de DHCPD e partir para a próxima etapa.


[root@server ~]# service dhcpd start
Starting dhcpd: [ OK ]
[root@server ~]#

2) Configurando TFTP Server
Uma vez configurado nosso servidor DHCP, precisamos agora preparar nosso servidor TFTP para enviar o bootloader (pxelinux.0) pela rede e os demais arquivos que serão utilizados no startup de instalação da máquina inst-automatico.
O Trivial File Transfer Protocol é o escolhido para esse serviço por basear suas conexões sem a necessidade de autenticação e por utilizar o protocolo UDP.  Outro detalhe sobre o TFTP é que ele é um serviço baseado no SuperDaemon XINETD, isto é, precisamos do xinetd para executar o TFTP. Para habilitarmos o serviço, basta:


[root@server ~]# rpm -q tftp-server tftp-server-0.49-5.fc12.x86_64
[root@server ~]# rpm -q xinetd xinetd-2.3.14-29.fc12.x86_64
[root@server ~]# chkconfig xinetd on
[root@server ~]# chkconfig tftp on
[root@server ~]# cat /etc/xinetd.d/tftp | grep -v ^#
service tftp {
disable = no
socket_type = dgram
protocol = udp
wait = yes
user = root
server = /usr/sbin/in.tftpd
server_args = -s /var/lib/tftpboot
per_source = 11
cps = 100 2
flags = IPv4
}
[root@server ~]# service xinetd start
Starting xinetd: [ OK ]
[root@server ~]#

No arquivo acima podemos observar como é fácil a configuração do TFTP no sistema. Não será necessário nenhuma customização no serviço por enquanto. Um detalhe imprescindível na configuração é o parâmetro server_args = -s /var/lib/tftpboot que cria uma espécia de chroot para o serviço. Desta forma, nossos arquivos de configuração irão se localizar dentro do diretório proposto.
Para continuarmos de forma segura e termos certeza que tudo que configuração até o momento esta funcionando, podemos copiar um arquivo qualquer para dentro do diretório /var/lib/tftpboot e baixá-lo via tftp, a fim de testar o serviço. Caso o comando tftp não esteja disponível no sistema, instale o pacote tftp.

[root@server ~]# rpm -q tftp-0.49-5.fc12.x86_64
[root@server ~]# cp /etc/hosts /var/lib/tftpboot/
[root@server ~]# ls -la /var/lib/tftpboot/
total 12
drwxr-xr-x. 2 root root 4096 2010-04-04 03:31 .
drwxr-xr-x. 30 root root 4096 2010-04-04 03:22 ..
-rw-r--r--. 1 root root 264 2010-04-04 03:31 hosts
[root@server ~]# tftp 192.168.240.10 -c get hosts
[root@server ~]# ls -la hosts
-rw-r--r--. 1 root root 264 2010-04-04 03:31 hosts
[root@server ~]#
Se você conseguiu fazer o download do arquivo utilizando um cliente TFTP, estamos indo muito bem.  Nosso próximo passo será copiar para o diretório /var/lib/tftpboot o bootloader chamado de pxelinux.0. Para fazer uso do PXE, sua máquina cliente deve ter esse suporte na placa de rede que as vezes deve ser habilitado na própria placa ou no caso de placas on-board, na BIOS do cliente com uma opção geralmente identificada como “Boot Onboard Lan Support” ou “PXE Onboard Support”.
O processo de boot via PXE consiste em inicializar o cliente pela placa de rede sem a necessidade de ter um sistema operacional instalado localmente, pois o cliente irá solicitar um endereço IP via DHCP (já temos o servidor DHCP configurado) e utilizará o parâmetro next-server 192.168.240.10 para solicitar o bootloader que é informado pelo parâmetro filename “pxelinux.0″ ambos no arquivo dhcpd.conf. A transfêrencia do bootloader será dada sob o protocolo TFTP.
Por conta disto, devemos então colocar o arquivo pxelinux.0 dentro do diretório /var/lib/tftpboot. Para isso:


[root@server ~]# rpm -q syslinux-3.75-4.fc12.x86_64
[root@server ~]# rpm -ql syslinux | grep pxelinux.0
/usr/share/syslinux/gpxelinux.0/usr/share/syslinux/pxelinux.0
[root@server ~]# cp /usr/share/syslinux/pxelinux.0 /var/lib/tftpboot/
[root@server ~]# ls -la /var/lib/tftpboot/
total 28
drwxr-xr-x. 2 root root 4096 2010-04-04 03:43 .
drwxr-xr-x. 30 root root 4096 2010-04-04 03:22 ..
-rw-r--r--. 1 root root 264 2010-04-04 03:31 hosts
-rw-r--r--. 1 root root 15702 2010-04-04 03:43 pxelinux.0
[root@server ~]#

Ta ficando bonito!!! O que precisamos entender agora é o funcionamento do bootloader pxelinux.0.
Por padrão o pxelinux.0 irá procurar um arquivo de configuração dentro de um diretório chamado pxelinux.cfg. O bootloader irá procurar os arquivos de configuração nessa ordem, onde no match de alguns deles o próximo não será consultado.

  1. MAC Address: como primeira etapa, o pxelinux.0 irá procurar o arquivo nomeado com o MAC Address do cliente;
  2. IP em Hexadecimal: irá procurar o arquivo convertendo o ip do cliente para hexadecimal e irá decrementar sempre um caracter da direita a fim de encontrar alguma configuração do cliente ou da subnet informada. Para a conversão do IP para hexadecimal, podemos utilizar o utilitário gethostip.
  3. Default: por fim, se não for localizado nenhum arquivo acima, o bootloader procurará um arquivo chamado default

Abaixo segue um exemplo retirado do arquivo de documentação do projeto:

/mybootdir/pxelinux.cfg/01-88-99-aa-bb-cc-dd
/mybootdir/pxelinux.cfg/C000025B
/mybootdir/pxelinux.cfg/C000025
/mybootdir/pxelinux.cfg/C00002
/mybootdir/pxelinux.cfg/C0000
/mybootdir/pxelinux.cfg/C000
/mybootdir/pxelinux.cfg/C00
/mybootdir/pxelinux.cfg/C0
/mybootdir/pxelinux.cfg/C
/mybootdir/pxelinux.cfg/default

Nesses arquivos teremos as configurações de qual kernel, initrd e kickstart iremos utilizar para a instalação do cliente.


[root@server tftpboot]# pwd
/var/lib/tftpboot
[root@server tftpboot]# mkdir pxelinux.cfg
[root@server tftpboot]# cd pxelinux.cfg/
[root@server pxelinux.cfg]# pwd
/var/lib/tftpboot/pxelinux.cfg
[root@server pxelinux.cfg]# gethostip -x 192.168.240.49
C0A8F031
[root@server pxelinux.cfg]# touch C0A8F031

Como nosso arquivo C0A8F031 ainda não possui conteúdo, uma boa dica é utilizar um cdrom de boot para utilizar alguns arquivos como exemplos, bem como para copiarmos o kernel e o initrd do sistema que queremos instalar. Irei instalar um cliente com o Fedora12. Esses arquivos podem ser encontrados dentro do DVD ou CD bootável do sistema.


[root@server ~]# mount -o loop fedora12-x86_64.iso /mnt
[root@server ~]# cd /mnt
[root@server mnt]# ls
EFI images media.repo repodata RPM-GPG-KEY-fedora-12-primary
RPM-GPG-KEY-fedora-ppc RPM-GPG-KEY-fedora-x86_64GPL isolinux
Packages RPM-GPG-KEY-fedora RPM-GPG-KEY-fedora-i386
RPM-GPG-KEY-fedora-ppc64 TRANS.TBL
[root@server mnt]# cd images/pxeboot/
[root@server pxeboot]# ls
initrd.img README TRANS.TBL vmlinuz
[root@server pxeboot]# cp vmlinuz initrd.img /var/lib/tftpboot/
[root@server pxeboot]# cd ../../isolinux/
[root@server isolinux]# ls
boot.cat boot.msg grub.conf initrd.img isolinux.bin isolinux.cfg memtest splash.jpg TRANS.TBL vesamenu.c32 vmlinuz
[root@server isolinux]# cp boot.msg /var/lib/tftpboot/
[root@server isolinux]# cp isolinux.cfg /var/lib/tftpboot/pxelinux.cfg/C0A8F031
cp: overwrite `/var/lib/tftpboot/pxelinux.cfg/C0A8F031'? y
[root@server isolinux]#[root@server isolinux]# cd /var/lib/tftpboot/
[root@server tftpboot]# pwd/var/lib/tftpboot
[root@server tftpboot]# ls
boot.msg hosts initrd.img pxelinux.0 pxelinux.cfg vmlinuz
[root@server tftpboot]# cat boot.msg
- Para instalar o Fedora12, digite: fedora12

[root@server tftpboot]# cat pxelinux.cfg/C0A8F031
prompt 1
timeout 600
display boot.msg
default fedora12

label fedora12
kernel vmlinuz
append initrd=initrd.img network ksdevice=eth0 ks=http://192.168.240.10/kickstart-fedora12.cfg
[root@server tftpboot]#

Alterado os arquivos como segue o exemplo acima, nosso servidor PXE já esta pronto!! No arquivo C0A8F031 configuramos para exibir o menu para o usuário (prompt 1, display boot.msg) por 60 segundos (timeout 600) e caso o usuário não escreva a opção informada (boot.msg) o padrão será bootar com o fedora12 (default fedora12).
Na configuração do label, informamos o kernel, o initrd e o kickstart que será utilizado para a instalação do servidor.
Para maiores informações, consulte os arquivos no diretório /usr/share/doc/syslinux*
3) Configurando File Share
Precisamos agora configurar uma maneira de oferecer os arquivos de instalação (pacotes RPM) para nosso cliente. Você pode escolher nesse momento qual serviço irá escolher. Pode ser via FTP, NFS ou HTTP. Em nosso caso de estudo, irei tomar o serviço via HTTP para disponibilizar os arquivos, uma vez que já o utilizei para informar o arquivo de kickstart para o cliente.


[root@server ~]# rpm -q httpd httpd-2.2.14-1.fc12.x86_64<
[root@server ~]# chkconfig httpd on
[root@server ~]# cd /var/www/html/
[root@server html]# mkdir fedora12
[root@server html]# mount -o loop /root/fedora12-x86_64.iso /var/www/html/fedora12
[root@server html]# service httpd start
[ OK ]
[root@server html]#

Feito!! Você já esta com todos os sub-sistemas configurados e prontos para começar a instalação de seus clientes sem a necessidade de uma mídia de boot. Lembre-se também que o arquivo de kickstart precisa ser enviado para o servidor web, pois no arquivo C0A8F031 informamos que o mesmo estaria disponível na url http://192.168.240.10/kickstart-fedora12.cfg.
Outro detalhe importante é informar dentro do arquivo de kickstart que source   de instalação (que antes era cdrom) agora estará disponível no via web também no endereço http://192.168.240.10/fedora12.
# Use network installation
url –url=http://192.168.240.10/fedora12

Agora vivente, é só configurar o cliente para bootar pela rede (PXE) e testar o seu ambiente de instalação automatizada.

Espero ter contribuido na compreensão de como funciona um ambiente de instalação automatizado utilizando PXE. Caso vocês tenham alguma dúvida em relação ao funcionamento dos sub-sistemas envolvidos meu email esta disponível como também o espaço para comentários aqui do blog.
Grande abraço.