Skip to content
Snippets Groups Projects
Commit 52294ed1 authored by Fernando K's avatar Fernando K
Browse files

feat: add remote boot move proposal

parent 85da69f4
No related branches found
No related tags found
No related merge requests found
......@@ -73,3 +73,11 @@ pages/switches/*
pages/virtuals/*
```
```{toctree}
:caption: "Propostas de melhoria"
:glob: true
:maxdepth: 1
pages/proposals/*
```
# Proposta de Arquitetura
```{svgbob}
| POP
|
|
.---.
|edr| Firewall
'---'
|
|
```
# PM001: Mover o boot remoto da urquell
Esta proposta de melhoria tem como objetivo mover o sistema de boot remoto
da urquell para uma máquina virtual separada. A principal motivação é que
a urquell tem serviços demais altamente não documentados. Movendo um dos
serviços que a urquell faz pra outra máquina, reduzimos a complexidade da urquell
em si, e podemos documentar mais profundamente o seu funcionamento, permitindo
que ele seja modificado mais facilmente.
## Funcionamento atual
Hoje o processo do boot remoto das máquinas é feito através das seguintes etapas:
1. O sistema PXE da máquina conversa com o [servidor de DHCPv4 da urquell](/pages/services/urquell-dhcpv4). O servidor além de configurar o IPv4 da máquina, responde com as seguintes configurações:
* Opção `root-path`: geralmente algo como `/exports/terminais/imagem/{}/`,
a localização da imagem atual dos terminais no NFS.
* Opção `next-server`: geralmente `10.254.222.3`, o IP da própria urquell.
* Opção `filename`: aponta pra um binário de boot relativo ao servidor de
TFTP, como o do GRUB localizado em `/tftpboot/boot/grub/x86_64-efi/core.efi`.
Essa informação é configurada nos arquivos de mapas em `/root/mapas/dns-dhcp`
lidos pelo script `/root/bin/atualiza-dns-dhcp`.
O `root-path` vem do arquivo `/tftpboot/pxelinux.cfg/{login}`, onde `{login}`
é o login no mapa (por exemplo, `loginlocal`) na linha `nfsroot`:
```
default default
label default
kernel kernel/vmlinuz
ipappend 2
append initrd=kernel/initrd.img root=/dev/nfs ro ip=dhcp
# o seguinte parametro sera passado pelo DHCP
#
# >>>>>> NAO PODE PASSAR VIA PARAMETRO DO KERNEL (APPEND) <<<<<<
#
# deixar a linha comentada! O script vai pegar daqui NAO REMOVER!
#nfsroot=10.254.221.2:/exports/terminais/imagem/lmde5.202309121153/
```
O `next-server` vem direto do mapa, mas o padrão é o próprio IP da urquell.
O `filename` está configurado no `dhcpd.conf` e ele varia se o boot é
via UEFI ou BIOS:
```
group {
if option arch=00:07 {
filename "boot/grub/x86_64-efi/core.efi";
} else {
filename "boot/grub/i386-pc/core.0";
}
include "/etc/dhcp/includes/xlab12.dhcp";
}
```
2. A máquina vai atrás do `nextserver` utilizando o protocolo TFTP procurando
pelo arquivo indicado pelo `filename`. Baixa o arquivo, e executa. O GRUB segue
os comandos de `/tftpboot/boot/grub/grub.cfg`:
```
set net_pxe_mac=$net_default_mac
echo $net_default_mac
regexp --set=1:m1 --set=2:m2 --set=3:m3 --set=4:m4 --set=5:m5 --set=6:m6 '^([0-9a-f]{1,2})\:([0-9a-f]{1,2})\:([0-9a-f]{1,2})\:([0-9a-f]{1,2})\:([0-9a-f]{1,2})\:([0-9a-f]{1,2})' "$net_default_mac"
mac=${m1}-${m2}-${m3}-${m4}-${m5}-${m6}
configfile /pxelinux.cfg/01-$mac
```
Que basicamente diz para carregar a configuração relativa ao MAC da máquina
em `/tftpboot/pxelinux.cfg/01-$mac`. É responsabilidade do script
`/root/bin/atualiza-dns-dhcp` criar os links simbólicos dos arquivos de configuração,
isto é, linkar o login da tabela de cada MAC para o respectivo configuração do
login. Poara ficar mais fácil de humanos entenderem, o script também
cria um link simbólico de hostname para o MAC. Assim, dá para humanos
descobrirem para um determinado hostname qual configuração de boot ele está
usando.
1. O sistema boota usando o kernel encontrado pelo script de configuração respectivo,
por exemplo no caso da linha `kernel kernel/vmlinuz`, ele usa o arquivo
em `/ftpboot/kernel/vmlinuz`. E além disso, ele usa o initrd também apontado,
no caso em `/tftpboot/kernel/initrd.img`. O kernel boota usando as configurações
do script e o `nfs-root` do DHCP, pegando o resto dos arquivos necessários
via NFS.
1. Dentro do próprio initrd, há um script que monta o overlay da máquina via NFS.
Ele pode ser encontrado em `/etc/initramfs-tools/scripts/init-bottom/overlay`:
```bash
/bin/sh -x
PREREQ=""
prereqs() {
echo "$PREREQ"
}
case $1 in
prereqs)
prereqs
exit 0
;;
esac
HOSTNAME=$(cat /proc/sys/kernel/hostname)
NEWROOT=/overlay
RW=/rw
RO=/ro
# nao implementei o brddiff
DIFF=/diff
BRDIFF="$DIFF=ro:"
URQUELL=200.17.202.3
# diretório para os overlays
mkdir $NEWROOT
mkdir $RW
mkdir $RO
mount --move $rootmnt $RO
mkdir $DIFF
MOUNT=$(/bin/mount -n -o vers=3,nolock,ro $URQUELL:/exports/terminais/diferenciais/$HOSTNAME $DIFF)
if [ "$?" != "0" ]; then
rm -rf $DIFF
BRDIFF=""
fi
# Montando branche RW
mount -n -o rw,nosuid,nodev,mode=0755 -t tmpfs tmpfs $RW
# The "workdir" needs to be an empty directory on the same filesystem as upperdir.
mkdir $RW/upper $RW/work
TARGET=$NEWROOT/.overlay
# Monta nova raiz
modprobe overlay
if [ "$BRDIFF" != "" ]; then
mount -n -t overlay overlay -o noatime,lowerdir=$DIFF:$RO,upperdir=$RW/upper,workdir=$RW/work $NEWROOT
mkdir -p ${TARGET}${DIFF}
mount --move $DIFF ${TARGET}${DIFF}
else
mount -n -t overlay overlay -o noatime,lowerdir=$RO,upperdir=$RW/upper,workdir=$RW/work $NEWROOT
fi
# Pontos de montagem para o move dos overlays
mkdir -p ${TARGET}${RW}
mkdir -p ${TARGET}${RO}
# Movimentando branches para dentro da nova raiz
mount --move $RW ${TARGET}${RW}
mount --move $RO ${TARGET}${RO}
echo $HOSTNAME > $NEWROOT/etc/hostname
# preparando o /var/log por nfs
MOUNT=$(/bin/mount -n -o vers=3,nolock $URQUELL:/exports/terminais/syslog_terminais/$HOSTNAME $NEWROOT/var/log)
# Movendo a nova raiz para o lugar correto
mount --move $NEWROOT ${rootmnt}
exit 0
```
É assim que cada dispositivo ganha um diretório diferenciado de raiz,
através da aplicação de diferenciais no overlay que se encontram
em `/exports/terminais/diferenciais/$HOSTNAME/`.
Note que os sistemas de arquivos exportados pelo NFS são configurados em
`/etc/exports`.
## Alterações propostas
* Criaremos uma máquina virtual chamada `boot`.
* Para testar, podemos criar uma máquina virtual ou usar alguma máquina configurada
para um `nextserver` localizado na nossa virtual `boot`. É possível configurar
o `nextserver` usando um hostname como `boot.c3sl.ufpr.br`, faça desta maneira.
* É necessário configurar o firewall para que seja possível acessar a máquina
virtual `boot` dos laboratórios nas portas do protocolo TFTP.
* Será necessário alterar o script do GRUB e o `/root/bin/atualiza-dns-dhcp`
para que a virtual `boot` não precise saber o MAC de todo mundo. Para tal,
recomenda-se que o DHCP mande mais uma configuração, por exemplo o nome do login
(como `loginlocal`) para o script do GRUB então ler e configurar usando
o arquivo correspondente.
As opções de DHCP de código 126 a 254 são de livre uso.
Podemos utilizar a opção 209 que é o que o antigo protocolo de boot
(antes do GRUB) utilizava, é só inventá-la no `/etc/dchdp.conf`:
```
option loginconfigfile code 209 = text;
```
E daí na configuração DHCP de cada máquina será necessário incluir essa opção
que inventamos com o valor correspondente, por exemplo, `loginlocal`.
No script do GRUB, daí precisamos ler através do `net_get_dhcp_option` para
decidir qual arquivo de configuração carregar.
* Após tudo isso testado, é possível testar numa máquina do laboratório
para ver se funciona.
* Para o futuro próximo podemos estudar o uso do [iPXE](https://ipxe.org/).
Ele substitui o GRUB, e utilizaríamos fazendo [chainloading](https://ipxe.org/howto/chainloading). Assim, podemos trocar o servidor de TFTP por um servidor HTTP. É possível
até criar menus de boot dinâmicos com senha e tudo mais. É possível também
[usar NFS diretamente](https://ipxe.org/gsoc/nfs), sem necessidade de servidor
adicional.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment