Provisionamento Bare-Metal do tipo faça você mesmo ou preparação automática de servidores do zero

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

Provisionamento Bare-Metal do tipo faça você mesmo ou preparação automática de servidores do zero

Por preparação queremos dizer: transformar um novo servidor pronto para uso em um servidor totalmente configurado com sistema operacional. Linux ou com o hipervisor ESXi (a implantação de servidores Windows não é discutida neste artigo).

condições:

  • 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 a automação é necessária?

Digamos que haja uma tarefa: preparar massivamente servidores do zero, no pico – 30 por dia. Neles podem ser instalados servidores de diferentes fabricantes e modelos, diferentes sistemas operacionais, podendo ou não possuir hipervisor.

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

  • conecte um teclado, mouse e 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);

Observação. Alternativamente, a implantação do SO é 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 que adicionar essa funcionalidade não é difícil.

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

Com esta abordagem, as mesmas configurações são executadas sequencialmente em cada servidor. A eficiência desse trabalho é muito baixa.

A essência da automação é eliminar a participação humana no processo de preparação do servidor. Tanto quanto possível.

A automação reduz o tempo de inatividade entre as operações e possibilita o provisionamento de vários servidores simultaneamente. A probabilidade de erros devido a fatores humanos também é bastante reduzida.

Provisionamento Bare-Metal do tipo faça você mesmo ou preparação automática de servidores do zero

Como os servidores são configurados automaticamente?

Vamos analisar detalhadamente todas as etapas.

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

Assim, inicializamos o servidor (que precisa ser configurado) via PXE. Vamos lembrar como funciona:

  • A inicialização de rede é selecionada no servidor.
  • O servidor carrega o PXE-ROM da placa de rede e contata o servidor de instalação via DHCP para obter um endereço de rede.
  • O servidor de instalação DHCP emite um endereço, bem como instruções para download adicional via PXE.
  • O servidor carrega o bootloader de rede do servidor de instalação via PXE, o carregamento adicional ocorre de acordo com o arquivo de configuração PXE.
  • A inicialização ocorre com base nos parâmetros recebidos (kernel, initramfs, pontos de montagem, imagem squashfs, etc.).

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

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

Arquivo pxelinux.cfg/default:

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 nesta fase são uma imagem intermediária do Linux, com a ajuda da qual ocorrerá a preparação e configuração principal do servidor.

Como você pode ver, o bootloader 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á discutido mais tarde, mas por enquanto você pode apenas lembrar que todos os parâmetros passados ​​estarão disponíveis na imagem intermediária do Linux via /proc/cmdline.

Onde posso obtê-los, kernel e 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 (disponibilidade de drivers, capacidade de instalação de utilitários adicionais);
  • Provavelmente, você precisará personalizar o initramfs.

Como isso é feito em nossa solução para X5? Como base foi escolhido o CentOS 7. Vamos tentar o seguinte truque: preparar a futura estrutura da imagem, empacotá-la em um arquivo e criar um initramfs, dentro do qual estará nosso arquivo do sistema de arquivos. Ao carregar a imagem, o arquivo será expandido para a partição tmpfs criada. Dessa forma, obteremos uma imagem Linux ao vivo mínima, mas 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

Portanto, especificamos o kernel e o initramfs que devem ser carregados. Como resultado, nesta fase, ao carregar a imagem intermediária do Linux via PXE, receberemos o console do SO.

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

Isso pode ser feito assim.

Suponhamos que após carregar a imagem planejemos transferir o controle para o script mount.sh.
Vamos incluir o script mount.sh na execução automática. Para fazer isso você precisará modificar o initramfs:

  • descompacte o initramfs (se usarmos a opção initramfs acima, isso não é necessário)
  • inclua código na inicialização que analisará os parâmetros passados ​​​​por /proc/cmdline e transferirá ainda mais o controle;
  • empacotar initramfs.

Observação. No caso do kit de ferramentas X5, o controle de carregamento é transferido para o script /opt/x5/toolkit/bin/hook.sh с помощью override.conf в getty tty1 (ExecStart=…)

Assim, é carregada a imagem, na qual o script mount.sh inicia na execução automática. Em seguida, o script mount.sh analisa os parâmetros passados ​​(script_cmd=) durante a execução e inicia o programa/script necessário.

kit de ferramentas de etiqueta-auto
núcleo...
anexar...nfs_toolkit_script=scripts/mount.sh script_cmd=master-install.sh

kit de ferramentas de etiqueta-concha
núcleo...
anexar...nfs_toolkit_script=scripts/mount.sh script_cmd=/bin/bash

Provisionamento Bare-Metal do tipo faça você mesmo ou preparação automática de servidores do zero

Aqui à esquerda está o menu PXE, à direita está o diagrama de transferência de controle.

Descobrimos a transferência de controle. Dependendo da escolha do menu PXE, o script de configuração automática ou o console de depuração é iniciado.

No caso de configuração automática, os diretórios necessários são montados a partir do servidor de instalação, que contém:

  • roteiros;
  • modelos BIOS/UEFI salvos para vários servidores;
  • firmware;
  • utilitários de servidor;
  • Histórico

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

A árvore de scripts (a ordem em que são iniciados) é mais ou menos assim:

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

um de:

  • pré-instalação (transferência de controle para o sistema operacional ou instalador do hipervisor, como ESXi)
  • merged-install (início imediato de descompactação da imagem)

Agora sabemos:

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


Vamos continuar. As seguintes questões tornaram-se 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

Tudo que você precisa está aqui: fornecedor, modelo, número de série. Se não tiver certeza de que esta informação está presente em todos os servidores, você pode identificá-los pelo endereço MAC. Ou nos dois sentidos ao mesmo tempo, se os fornecedores de servidores forem diferentes e em alguns modelos simplesmente não houver informações sobre o número de série.

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

Quais utilitários e como configurar o servidor?

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

Provisionamento Bare-Metal do tipo faça você mesmo ou preparação automática de servidores do zero

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

BIOS e IPMI geralmente são configurados por meio de modelos. Se necessário, o modelo pode ser editado antes do download.

Os utilitários RAID de alguns fornecedores também podem ser configurados usando um modelo. Se este não for o caso, você terá que escrever um script de configuração.

O procedimento para configurar o RAID é geralmente o seguinte:

  • Solicitamos a configuração atual.
  • Se já existirem arrays lógicos, nós os apagamos.
  • Vejamos quais discos físicos estão presentes e quantos existem.
  • Crie uma nova matriz lógica. Interrompemos o processo em caso de erro.

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

Vamos supor que as configurações de todos os servidores serão armazenadas no servidor de instalação. Neste caso, para responder à nossa pergunta, devemos primeiro decidir como transferir as configurações para o servidor de instalação.

No início, você pode conviver com arquivos de texto. (No futuro, você pode querer usar um arquivo de texto como método alternativo para transferir configurações.)

Você pode “compartilhar” um arquivo de texto no servidor de instalação. E adicione sua montagem ao script mount.sh.

As linhas ficarão, por exemplo, assim:

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

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

Mas, a longo prazo, é melhor usar um banco de dados para armazenar configurações, estados e logs de instalações de servidores.

É claro que um banco de dados por si só não é suficiente, e você precisará criar uma parte cliente com a ajuda da qual as configurações serão transferidas para o banco de dados. Isso é mais difícil de implementar em comparação com um arquivo de texto, mas na verdade nem tudo é tão difícil quanto parece. É bem possível escrever uma versão mínima de um cliente que simplesmente transferirá você mesmo os dados para o banco de dados. E futuramente será possível melhorar o programa cliente em modo livre (relatórios, impressão de etiquetas, envio de notificações, etc. que vier à cabeça).

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

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

Podemos gravar o log de configuração no banco de dados em todas as etapas e controlar o processo de instalação por meio de eventos e flags das etapas de preparação.

Agora sabemos como:

  • inicialize o servidor via PXE;
  • transferir o controle para nosso script;
  • identificar o servidor que precisa ser preparado pelo seu número de série;
  • configure o servidor usando os utilitários apropriados;
  • transferir configurações para o banco de dados do servidor de instalação usando a parte do cliente.

Descobrimos 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 quanto aos diferentes tipos de software que você instala? Como instalar um hipervisor, copiar uma VM e configurar tudo?

No caso de implantar uma imagem de sistema de arquivos (Linux) em hardware, tudo é bastante simples:

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

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

  • Organizamos a transferência de controle do nosso script para o instalador do hipervisor usando o arquivo de resposta automática (kickstart):
  • Excluímos as partições atuais do disco.
  • Crie uma partição com tamanho de 500 MB.
  • Nós o marcamos como inicializável.
  • Formate para FAT32.
  • Copiamos os arquivos de instalação do ESXi para a raiz.
  • Instalando o Syslinux.
  • Copie syslinux.cfg para /syslinux/

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

  • Copie mboot.c32 para /syslinux.
  • Boot.cfg deve ter kernelopt=ks=ftp:// /ks_esxi.cfg
  • Reiniciamos o servidor.

Após a reinicialização do servidor, o instalador ESXi será baixado do disco rígido do servidor. Todos os arquivos do instalador necessários serão carregados na memória e então 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:[email protected]
/vmfs/volumes/datastore1/ovftool/tools/ovftool --acceptAllEulas --noSSLVerify --datastore=datastore1 --name=VM2 /vmfs/volumes/nfsshare1/VM_T/VM2.ova vi://root:[email protected]

# получаем строку с настройками нашего сервера

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

Nesta fase, o hipervisor é instalado e configurado e as máquinas virtuais são copiadas.

Como configurar máquinas virtuais agora?

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

Agora, após iniciar, 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 (conhece o número de série do host físico), fazer uma solicitação ao banco de dados do servidor de instalação e receber os parâmetros que precisam ser configurados. Tudo isso é compilado em um script, que deve ser iniciado automaticamente quando o guestos vm for iniciado (mas uma vez: RunOnce).

Agora sabemos como:

  • inicialize o servidor via PXE;
  • transferir o controle para nosso script;
  • identificar o servidor que precisa ser preparado pelo seu número de série;
  • configure o servidor usando os utilitários apropriados;
  • transferir configurações para o banco de dados do servidor de instalação usando a parte cliente;
  • configurar vários tipos de software, incluindo a implantação do hipervisor esxi e a configuração de máquinas virtuais (tudo automaticamente).

Descobrimos 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).


A linha inferior:

Acredito que a singularidade desta solução reside na sua flexibilidade, simplicidade, capacidades e versatilidade.

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

Fonte: habr.com

Adicionar um comentário