Provisionamento bare-metal do tipo faça você mesmo ou preparação automática do servidor do zero

Olá, sou Denis e uma das minhas áreas de atividade é o desenvolvimento de soluções de infraestrutura no X5. Hoje eu gostaria de compartilhar com você sobre como você pode implantar um sistema automatizado de preparação de servidores com base em ferramentas disponíveis publicamente. Na minha opinião, esta é uma solução interessante, simples e flexível.



Por preparação, entende-se: para fazer de um novo servidor pronto para uso, um servidor totalmente configurado com SO Linux ou com o hypervisor ESXi (a conversão do servidor Windows não é discutida neste artigo).

Termos :

  • servidores - servidores que precisam ser configurados.
  • servidor de instalação - o servidor principal que fornece todo o processo de preparação pela rede.

Por que você precisa de automação?


Digamos que haja um problema: prepare em massa o servidor a partir do zero, no pico - 30 por dia. Servidores de diferentes fabricantes e modelos, sistemas operacionais diferentes podem ser instalados neles, um hipervisor pode ou não existir.

Quais operações estão incluídas no processo de instalação (sem automação):

  • conecte o teclado, mouse, monitor ao servidor;
  • configurar BIOS, RAID, IPMI;
  • atualizar o firmware do componente;
  • implantar uma imagem do sistema de arquivos (ou instalar um hipervisor e copiar máquinas virtuais);

Nota. Como alternativa, a implantação do sistema operacional é possível através da instalação com um arquivo de resposta automática. Mas isso não será discutido no artigo. Embora você veja abaixo, é fácil adicionar essa funcionalidade.

  • configurar parâmetros do sistema operacional (nome do host, IP etc.).

Com essa abordagem, as mesmas configurações são executadas seqüencialmente em cada servidor. A eficácia desse trabalho é muito baixa.

A essência da automação é excluir o envolvimento humano do processo de preparação do servidor. Tanto quanto possível.

Graças à automação, o tempo de inatividade entre as operações é reduzido e torna-se possível preparar vários servidores ao mesmo tempo. A probabilidade de erros devido ao fator humano também é bastante reduzida.



Como os servidores são configurados automaticamente?


Analisaremos todas as etapas em detalhes.

Você tem um servidor Linux que você usa como servidor de instalação do PXE. Os serviços são instalados e configurados nele: DHCP, TFTP.

Então, carregamos o servidor (que precisa ser configurado) pelo PXE. Lembre-se de como funciona:

  • O servidor selecionado para inicializar pela rede.
  • O servidor carrega o PXE-ROM da placa de rede e entra em contato com o servidor de instalação via DHCP para obter o endereço de rede.
  • O DHCP do servidor de instalação fornece o endereço, bem como instruções para download adicional via PXE.
  • O servidor baixa o carregador de inicialização de rede do servidor de instalação via PXE; o download adicional ocorre de acordo com o arquivo de configuração do PXE.
  • O download é realizado com base nos parâmetros recebidos (kernel, initramfs, pontos de montagem, imagem squashfs, etc.).

Nota. Este artigo descreve a inicialização do PXE via modo BIOS. Atualmente, os fabricantes estão introduzindo ativamente o modo de inicialização UEFI. Para o PXE, a diferença estará na configuração do servidor DHCP e na presença de um carregador de inicialização adicional.

Considere um exemplo de configuração do servidor PXE (menu pxelinux).

Arquivo pxelinux.cfg / padrão:

default menu.c32
prompt 0
timeout 100
menu title X5 PXE Boot Menu
LABEL InstallServer Menu
	MENU LABEL InstallServer
	KERNEL menu.c32
	APPEND pxelinux.cfg/installserver
LABEL VMware Menu
	MENU LABEL VMware ESXi Install
	KERNEL menu.c32
	APPEND pxelinux.cfg/vmware
LABEL toolkit //   
	MENU LABEL Linux Scripting Toolkits
	MENU default
	KERNEL menu.c32
	APPEND pxelinux.cfg/toolkit //    

Arquivo pxelinux.cfg / toolkit:

prompt 0
timeout 100
menu title X5 PXE Boot Menu
label mainmenu
    menu label ^Return to Main Menu
    kernel menu.c32
    append pxelinux.cfg/default
label x5toolkit-auto //   —  
        menu label x5 toolkit autoinstall
        menu default
        kernel toolkit/tkcustom-kernel
        append initrd=toolkit/tk-initramfs.gz quiet net.ifnames=0 biosdevname=0 nfs_toolkit_ip=192.168.200.1 nfs_toolkit_path=tftpboot/toolkit nfs_toolkit_script=scripts/mount.sh script_cmd=master-install.sh CMDIS2=”…”
label x5toolkit-shell //   - 
        menu label x5 toolkit shell
        kernel toolkit/tkcustom-kernel
        append initrd=toolkit/tkcustom-initramfs.gz quiet net.ifnames=0 biosdevname=0 nfs_toolkit_ip=192.168.200.1 nfs_toolkit_path=tftpboot/toolkit nfs_toolkit_script=scripts/mount.sh script_cmd=/bin/bash CMDIS2=”…”

O kernel e o initramfs neste estágio são uma imagem linux intermediária, com a ajuda da qual a preparação e configuração básicas do servidor ocorrerão.

Como você pode ver, o carregador de inicialização passa muitos parâmetros para o kernel. Alguns desses parâmetros são usados ​​pelo próprio kernel. E podemos usar alguns para nossos próprios propósitos. Isso será descrito mais adiante, mas por enquanto você pode se lembrar que todos os parâmetros passados ​​estarão disponíveis na imagem intermediária do linux via / proc / cmdline.

Onde obtê-los, o kernel e o initramfs?
Como base, você pode escolher qualquer distribuição Linux. O que prestamos atenção ao escolher:

  • a imagem de inicialização deve ser universal (drivers disponíveis, capacidade de instalar utilitários adicionais);
  • provavelmente, o initramfs precisará ser customizado.

Como isso é feito em nossa solução para o X5? O CentOS 7. foi escolhido como base.Vamos fazer o seguinte truque: preparar a estrutura futura da imagem, compactá-la no arquivo morto e criar initramfs, dentro do qual será nosso arquivo do sistema de arquivos. Ao carregar a imagem, o arquivo morto será implantado na seção tmpfs criada. Assim, obtemos uma imagem live-linux mínima, porém completa, com todos os utilitários necessários, consistindo em apenas dois arquivos: vmkernel e initramfs.

# : 

mkdir -p /tftpboot/toolkit/CustomTK/rootfs /tftpboot/toolkit/CustomTK/initramfs/bin

# :

yum groups -y install "Minimal Install" --installroot=/tftpboot/toolkit/CustomTK/rootfs/
yum -y install nfs-utils mariadb ntpdate mtools syslinux mdadm tbb libgomp efibootmgr dosfstools net-tools pciutils openssl make ipmitool OpenIPMI-modalias rng-tools --installroot=/tftpboot/toolkit/CustomTK/rootfs/
yum -y remove biosdevname --installroot=/tftpboot/toolkit/CustomTK/rootfs/

#  initramfs:

wget https://busybox.net/downloads/binaries/1.31.0-defconfig-multiarch-musl/busybox-x86_64 -O /tftpboot/toolkit/CustomTK/initramfs/bin/busybox
chmod a+x /tftpboot/toolkit/CustomTK/initramfs/bin/busybox
cp /tftpboot/toolkit/CustomTK/rootfs/boot/vmlinuz-3.10.0-957.el7.x86_64 /tftpboot/toolkit/tkcustom-kernel

#  /tftpboot/toolkit/CustomTK/initramfs/init (  ):

#!/bin/busybox sh
/bin/busybox --install /bin
mkdir -p /dev /proc /sys /var/run /newroot
mount -t proc proc /proc
mount -o mode=0755 -t devtmpfs devtmpfs /dev
mkdir -p /dev/pts /dev/shm /dev/mapper /dev/vc
mount -t devpts -o gid=5,mode=620 devpts /dev/pts
mount -t sysfs sysfs /sys
mount -t tmpfs -o size=4000m tmpfs /newroot
echo -n "Extracting rootfs... "
xz -d -c -f rootfs.tar.xz | tar -x -f - -C /newroot
echo "done"
mkdir -p /newroot/dev /newroot/proc /newroot/sys
mount --move /sys  /newroot/sys
mount --move /proc /newroot/proc
mount --move /dev  /newroot/dev
exec switch_root /newroot /sbin/init

#  rootfs  initramfs:

cd /tftpboot/toolkit/CustomTK/rootfs
tar cJf /tftpboot/toolkit/CustomTK/initramfs/rootfs.tar.xz --exclude ./proc --exclude ./sys --exclude ./dev .
cd /tftpboot/toolkit/CustomTK/initramfs
find . -print0 | cpio --null -ov --format=newc | gzip -9 > /tftpboot/toolkit/tkcustom-initramfs-new.gz

Então, nós especificamos um kernel e initramfs que devem ser carregados. Como resultado, nesta fase, ao baixar a imagem intermediária do linux via PXE, obtemos o console do SO.

Ótimo, mas agora precisamos transferir o controle para a nossa "automação".

Isso pode ser feito assim.

Suponha que, depois de carregar a imagem, planejemos transferir o controle para o script mount.sh.
Incluímos o script mount.sh na execução automática. Para fazer isso, você precisa modificar o initramfs:

  • descompacte initramfs (se usarmos a versão acima do initramfs, isso não será necessário)
  • inclua no código de inicialização que analisará os parâmetros passados ​​por / proc / cmdline e transfira o controle ainda mais;
  • pacote initramfs.

Nota. No caso do kit de ferramentas X5, o controle de inicialização é transferido para /opt/x5/toolkit/bin/hook.sh override.conf getty tty1 (ExecStart=…)

o script.Portanto, a imagem é carregada, na qual o script mount.sh inicia na inicialização. Em seguida, o script mount.sh no processo de análise analisa os parâmetros passados ​​(script_cmd =) e inicia o programa / script necessário.

label toolkit- auto
kernel ...
append ... nfs_toolkit_script = scripts / mount.sh script_cmd = master-install.sh

label toolkit- shell
kernel ...
append ... nfs_toolkit_script = scripts / mount.sh script_cmd = / bin / bash



Aqui, no lado esquerdo, está o menu PXE , à direita é o esquema de transferência de controle.

Com a transferência de controle, descobrimos isso. Dependendo da escolha do menu PXE, o script de ajuste automático ou o console de depuração é iniciado.

No caso da configuração automática, os diretórios necessários do servidor de instalação são montados, nos quais existem:

  • scripts;
  • salvou modelos de BIOS / UEFI de vários servidores;
  • firmware;
  • utilitários para servidores;
  • Histórico.

Em seguida, o script mount.sh transfere o controle para o script master-install.sh do diretório scripts.

A árvore de scripts (a ordem do lançamento) é mais ou menos assim:

  • instalação principal
  • sharefunctions (funções comuns)
  • informação (saída de informação)
  • modelos (configurando parâmetros de instalação com base no modelo do servidor)
  • prepare_utils (instalando os utilitários necessários)
  • fwupdate (atualização de firmware)
  • diag (diagnóstico elementar)
  • biosconf (configuração do BIOS / UEFI)
  • clockfix (definindo a hora na placa-mãe)
  • srmconf (configurando a interface remota)
  • raidconf (configurando volumes lógicos)

um de:

  • pré-instalação (transferindo o controle para o instalador do SO ou hypervisor, por exemplo ESXi)
  • instalação mesclada (início direto da descompactação da imagem)

Agora sabemos:

  • como inicializar o servidor via PXE;
  • como transferir o controle para seu próprio script.

Vamos continuar. Os seguintes problemas se tornaram relevantes:

  • Como identificar o servidor que estamos preparando?
  • Quais utilitários e como configurar o servidor?
  • Como obter configurações para um servidor específico?

Como identificar o servidor que estamos preparando?


É simples - DMI:

dmidecode –s system-product-name
dmidecode –s system-manufacturer
dmidecode –s system-serial-number

Tem tudo o que você precisa: um fornecedor, um modelo, um número de série. Se você não tiver certeza de que essas informações são apresentadas em todos os servidores, é possível identificá-las pelo endereço MAC. Ou nos dois sentidos ao mesmo tempo, se os fornecedores do servidor forem diferentes e, em alguns modelos, as informações do número de série simplesmente não estiverem disponíveis.

Com base nas informações recebidas, as pastas de rede do servidor de instalação são montadas e todo o necessário é carregado (utilitários, firmware, etc.).

Quais utilitários e como configurar o servidor?


Vou dar utilitários para Linux para alguns fabricantes. Todos os utilitários estão disponíveis nos sites oficiais dos fornecedores.



Com o firmware, acho que está tudo claro. Eles geralmente vêm em arquivos executáveis ​​compactados. O arquivo executável controla o processo de atualização do firmware e relata um código de retorno.

BIOS e IPMI geralmente são configurados através de modelos. Se necessário, o modelo pode ser editado antes do carregamento.

Os utilitários RAID para alguns fornecedores também podem configurar de acordo com o modelo. Se não for esse o caso, você precisará escrever um script de configuração.

O procedimento para configurar o RAID geralmente é o seguinte:

  • Solicitamos a configuração atual.
  • Se já existem matrizes lógicas, nós as apagamos.
  • Examinamos quais discos físicos estão presentes e quantos deles.
  • Crie uma nova matriz lógica. Interrompemos o processo em caso de erro.

Como obter configurações para um servidor específico?


Suponha que todas as configurações do servidor sejam armazenadas no servidor de instalação. Nesse caso, para responder à nossa pergunta, primeiro você precisa decidir: como transferir as configurações para o servidor de instalação.

No começo, é bem possível fazer com arquivos de texto. (No futuro, você pode usar um arquivo de texto como forma de backup para transferir configurações).

Você pode "compartilhar" um arquivo de texto no servidor de instalação. E adicione-o ao script mount.sh.

As linhas, por exemplo, terão a seguinte aparência:

<número de série> <nome do host> <sub-rede>

Essas linhas serão transferidas para o arquivo pelo engenheiro a partir de sua máquina em funcionamento. E então, ao configurar o servidor, os parâmetros para um servidor específico serão lidos no arquivo.

Porém, no futuro, é melhor usar o banco de dados para armazenar as configurações, estados e logs de instalação do servidor.

Obviamente, um banco de dados não pode funcionar e você precisará criar uma parte do cliente, com a ajuda da qual as configurações serão transferidas para o banco de dados. É mais difícil de implementar do que um arquivo de texto, mas na verdade não é tão difícil quanto parece. A versão mínima do cliente, que simplesmente transfere dados para o banco de dados, é bastante viável para se escrever. No futuro, será possível melhorar o programa cliente também no modo livre (relatórios, impressão de etiquetas, envio de notificações, etc., o que vier à mente).

Após fazer uma solicitação específica ao banco de dados e indicar o número de série do servidor, obtemos os parâmetros necessários para a configuração do servidor.

Além disso, não precisamos inventar bloqueios para acesso simultâneo, como é o caso de um arquivo de texto.

Podemos escrever o log de configuração em todas as etapas do banco de dados e controlar o processo de instalação através de eventos e sinalizadores das etapas de preparação.

Agora sabemos como:

  • carregar o servidor via PXE;
  • transferir controle para o nosso script;
  • identifique o servidor a ser preparado pelo número de série;
  • configurar o servidor com utilitários apropriados;
  • transfira as configurações para o banco de dados do servidor de instalação usando a parte do cliente.

Descobri como:

  • o servidor instalado recebe as configurações necessárias do banco de dados;
  • todo o progresso da preparação é registrado no banco de dados (logs, eventos, sinalizadores de estágio).

E os diferentes tipos de software que estão sendo instalados? Como instalar um hypervisor, copiar uma VM e configurar tudo isso?


No caso de implantar uma imagem do sistema de arquivos (linux) no hardware, tudo é bem simples:

  • Após configurar todos os componentes do servidor, implante a imagem.
  • Instale o carregador de inicialização grub.
  • Fazemos chroot e configuramos tudo o que é necessário.

Como transferir o controle para o instalador do SO (usando o ESXi como exemplo).

  • Organizamos a transferência de controle do nosso script para o instalador do hypervisor usando o arquivo de resposta automática (kickstart):
  • Exclua as partições atuais no disco.
  • Crie uma partição de 500 MB.
  • Marcamos como inicialização.
  • Formato em FAT32.
  • Copiamos os arquivos de instalação do ESXi para a raiz.
  • Instale o syslinux.
  • Copie o syslinux.cfg para / syslinux /

default esxi
prompt 1
timeout 50
label esxi
kernel mboot.c32
append -c boot.cfg

  • Copie o mboot.c32 para / syslinux.
  • No boot.cfg deve haver kernelopt = ks = ftp: // <IP do servidor de instalação> /ks_esxi.cfg
  • Reinicie o servidor.

Após a reinicialização do servidor, o instalador do ESXi será inicializado a partir do disco rígido. Todos os arquivos do instalador necessários serão carregados na memória e a instalação do ESXi começará, de acordo com o arquivo de resposta automática especificado.

Aqui estão algumas linhas do arquivo de resposta automática ks_esxi.cfg:

%firstboot --interpreter=busybox
#   

SYSSN=$(esxcli hardware platform get | grep Serial | awk -F " " '{print $3}')

#  IP

IPADDRT=$(esxcli network ip interface ipv4 get | grep vmk0 | awk -F " " '{print $2}')
LAST_OCTET=$(echo $IPADDRT | awk -F'.' '{print $4}')

#  NFS -

esxcli storage nfs add -H is -s /srv/nfs_share -v nfsshare1

#    ssh,   ssh-

mv /etc/ssh /etc/ssh.tmp
cp -R /vmfs/volumes/nfsshare1/ssh /etc/
chmod go-r /etc/ssh/ssh_host_rsa_key

#  ovftool,    ,    

cp -R /vmfs/volumes/nfsshare1/ovftool /vmfs/volumes/datastore1/

#  

/vmfs/volumes/datastore1/ovftool/tools/ovftool --acceptAllEulas --noSSLVerify --datastore=datastore1 --name=VM1 /vmfs/volumes/nfsshare1/VM_T/VM1.ova vi://root:esxi_password@127.0.0.1
/vmfs/volumes/datastore1/ovftool/tools/ovftool --acceptAllEulas --noSSLVerify --datastore=datastore1 --name=VM2 /vmfs/volumes/nfsshare1/VM_T/VM2.ova vi://root:esxi_password@127.0.0.1

#      

ssh root@is "mysql -h'192.168.0.1' -D'servers' -u'user' -p'secretpassword' -e \"SELECT ... WHERE servers.serial='$SYSSN'\"" | grep -v ^$ | sed 's/NULL//g' > /tmp/servers
...
#    

echo '#!/bin/sh' > /vmfs/volumes/datastore1/netconf.sh
echo "esxcli network ip interface ipv4 set -i=vmk0 -t=static --ipv4=$IPADDR --netmask=$S_SUB || exit 1" >> /vmfs/volumes/datastore1/netconf.sh
echo "esxcli network ip route ipv4 add -g=$S_GW -n=default || exit 1" >> /vmfs/volumes/datastore1/netconf.sh
chmod a+x /vmfs/volumes/datastore1/netconf.sh

#   guestinfo.esxihost.id,     

echo "guestinfo.esxihost.id = \"$SYSSN\"" >> /vmfs/volumes/datastore1/VM1/VM1.vmx
echo "guestinfo.esxihost.id = \"$SYSSN\"" >> /vmfs/volumes/datastore1/VM2/VM2.vmx
...
#    

SYSNAME=$(esxcli hardware platform get | grep Product | sed 's/Product Name://' | sed 's/^\ *//')
UUID=$(vim-cmd hostsvc/hostsummary | grep uuid | sed 's/\ //g;s/,$//' | sed 's/^uuid="//;s/"$//')
ssh root@is "mysql -D'servers' -u'user' -p'secretpassword' -e \"UPDATE servers ... SET ... WHERE servers.serial='$SYSSN'\""
ssh root@is "mysql -D'servers' -u'user' -p'secretpassword' -e \"INSERT INTO events ...\""

#   SSH

rm -rf /etc/ssh
mv /etc/ssh.tmp /etc/ssh

#    

esxcli system hostname set --fqdn=esx-${G_NICK}.x5.ru
/vmfs/volumes/datastore1/netconf.sh
reboot

Nesse estágio, um hipervisor é instalado e configurado, as máquinas virtuais são copiadas.

Como configurar máquinas virtuais agora?

Nós trapaceamos um pouco: durante a instalação, definimos o parâmetro guestinfo.esxihost.id = "$ SYSSN" no arquivo VM1.vmx, indicando o número de série do servidor físico nele.

Agora, após o início, a máquina virtual (com o pacote vmware-tools instalado) pode acessar este parâmetro:

ESXI_SN=$(vmtoolsd --cmd "info-get guestinfo.esxihost.id")

Ou seja, a VM poderá se identificar (sabe o número de série do host físico), fazer uma solicitação ao banco de dados do servidor de instalação e obter os parâmetros que precisam ser configurados. Tudo isso é executado em um script que deve ser iniciado automaticamente quando o guestos vm é iniciado (mas uma vez: RunOnce).

Agora sabemos como:

  • carregar o servidor via PXE;
  • transferir controle para o nosso script;
  • identifique o servidor a ser preparado pelo número de série;
  • configurar o servidor com utilitários apropriados;
  • transferir configurações para o banco de dados do servidor de instalação usando a parte do cliente;
  • Configure vários tipos de POs, incluindo a implantação do hipervisor esxi e a configuração de máquinas virtuais (e todas automaticamente).

Descobri como:

  • o servidor instalado recebe as configurações necessárias do banco de dados;
  • todo o progresso da preparação é registrado no banco de dados (logs, eventos, sinalizadores de estágio).

Conclusão:

acredito que a singularidade desta solução reside em sua flexibilidade, simplicidade, capacidade e versatilidade.

Por favor, escreva nos comentários o que você pensa.

All Articles