Bare-Metal Provisioning zelf doen, of Automatische serverconfiguratie vanaf nul

Hallo, ik ben Denis en een van mijn aandachtsgebieden is het ontwikkelen van infrastructuuroplossingen bij X5. Vandaag wil ik delen hoe je met behulp van openbare tools een automatisch systeem voor serverconfiguratie kunt opzetten. Naar mijn mening is dit een interessante, eenvoudige en flexibele oplossing.

Bare-Metal Provisioning zelf doen, of Automatische serverconfiguratie vanaf nul

Met configuratie bedoelen we: een nieuwe server uit de doos omvormen tot een volledig geconfigureerde server met een Linux-besturingssysteem of met hypervisor ESXi (de installatie van servers Windows wordt in dit artikel niet besproken).

Termen:

  • servers – servers die geconfigureerd moeten worden.
  • install-server – de hoofdserver die het hele proces van netwerkinstallatie verzorgt.

Waarom is automatisering nodig?

Stel, we hebben de taak om personeel om te zetten naar servers vanaf de basis, met een piek van 30 per dag. Servers van verschillende fabrikanten en modellen, die verschillende besturingssystemen kunnen hebben, met of zonder hypervisor.

Welke handelingen zijn onderdeel van het configuratieproces (zonder automatisering):

  • koppel een toetsenbord, muis en monitor aan de server;
  • configureer BIOS, RAID, IPMI;
  • update firmware van componenten;
  • zet een image van het bestandssysteem op (of installeer de hypervisor en kopieer virtuele machines);

Opmerking. In principe kan OS-deployment ook plaatsvinden via een installatie met een antwoordbestand. Maar dit zal in het artikel niet worden besproken. Maar je zult hieronder zien dat het toevoegen van deze functionaliteit niet moeilijk is.

  • configureer de parameters van het besturingssysteem (hostname, IP, enz.).

Bij deze aanpak worden dezelfde instellingen opvolgend op elke server toegepast. De effectiviteit van dit werk is erg laag.

De essentie van automatisering is om de menselijke betrokkenheid bij het configureren van de server te elimineren. Zo ver mogelijk.

Dankzij automatisering wordt de stilstandtijd tussen handelingen verkort en kan je meerdere servers gelijktijdig configureren. Ook wordt de kans op fouten door menselijke factoren sterk verminderd.

Bare-Metal Provisioning zelf doen, of Automatische serverconfiguratie vanaf nul

Hoe vindt automatische serverconfiguratie plaats?

Laten we alle stappen gedetailleerd doorlopen.

Je hebt een Linux-server die je gebruikt als PXE-installatieserver. Hierop zijn de diensten DHCP en TFTP geïnstalleerd en geconfigureerd.

Laten we de server (die geconfigureerd moet worden) dus opstarten via PXE. Laten we herinneren hoe dit werkt:

  • Op de server is netwerkboot geselecteerd.
  • De server laadt de PXE-ROM van de netwerkkaart en vraagt het installatieserver om een netwerkadres via DHCP.
  • De DHCP van de installatieserver geeft een adres en ook instructies voor verdere opstart via PXE.
  • De server laadt de netwerkopstartloader van de installatieserver via PXE, de verdere opstart gebeurt volgens het PXE-configuratiebestand.
  • De opstart vindt plaats op basis van de ontvangen parameters (kern, initramfs, montagemogelijkheden, squashfs-beeld, enzovoort).

Opmerking. Dit artikel beschrijft het opstarten via PXE in BIOS-modus. Fabrikanten implementeren momenteel actief de UEFI-bootmodus. Voor PXE zal het verschil zitten in de configuratie van de DHCP-server en de aanwezigheid van een extra opstartloader.

Laten we een voorbeeld van een PXE-serverconfiguratie bekijken (pxelinux-menu).

Bestand 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 // standaardmenu
	MENU LABEL Linux Scripting Toolkits
	MENU default
	KERNEL menu.c32
	APPEND pxelinux.cfg/toolkit // overgang naar het volgende menu

Bestand pxelinux.cfg/toolkit:

prompt 0
timeout 100
menu title X5 PXE Boot Menu
label mainmenu
    menu label ^Terug naar hoofdmenu
    kernel menu.c32
    append pxelinux.cfg/default
label x5toolkit-auto // standaard - automatische modus
        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 // voor debugging - console
        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="…"

De kernel en initramfs op dit punt zijn een tussenliggende linux-image, waarmee de hoofdconfiguratie en -instelling van de server zal plaatsvinden.

Zoals u ziet, verstrekt de bootloader veel parameters aan de kernel. Een deel van deze parameters wordt door de kernel zelf gebruikt. En sommige kunnen we voor onze doeleinden gebruiken. Hierover zal later worden gesproken, maar voor nu kunt u gewoon onthouden dat alle doorgegeven parameters beschikbaar zullen zijn in de tussenliggende linux-image via /proc/cmdline.

Waar krijgen we de kernel en initramfs vandaan?
U kunt elke linux-distributie als basis kiezen. Waar we op letten bij de keuze:

  • de opstart-image moet universeel zijn (beschikbaarheid van stuurprogramma's, mogelijkheden om extra hulpprogramma's te installeren);
  • waarschijnlijk moet initramfs worden aangepast.

Hoe is dit gedaan in onze oplossing voor X5? We hebben CentOS 7 als basis gekozen. We gaan de volgende truc gebruiken: we bereiden de toekomstige structuur van de afbeelding voor, verpakken deze in een archief en creëren initramfs, waarin ons archief van het bestandssysteem zich bevindt. Bij het opstarten van de afbeelding wordt het archief uitgepakt in de te creëren tmpfs-partitie. Op deze manier krijgen we een minimale, maar volwaardige live-linux afbeelding met alle benodigde hulpprogramma's, bestaande uit slechts twee bestanden: vmkernel en 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

Dus we hebben de kernel en initramfs opgegeven die geladen moeten worden. Als resultaat krijgen we, op dit stadium, bij het opstarten van de tussenliggende linux afbeelding via PXE, de OS-console.

Geweldig, maar nu moeten we de controle overdragen aan onze 'automatisering'.

Dit kan op de volgende manier.

Stel dat we na het opstarten van de afbeelding de controle willen overdragen aan het script mount.sh.
We voegen het script mount.sh toe aan de autostart. Hiervoor moeten we initramfs aanpassen:

  • uitpakken van initramfs (als we de bovenstaande variant van initramfs gebruiken, is dit niet nodig)
  • de code die de doorgegeven parameters via /proc/cmdline analyseert, toevoegen aan de autostart en de controle verder overdragen;
  • initramfs opnieuw verpakken.

Opmerking. In het geval van de X5 toolkit wordt de opstartcontrole overgedragen aan het script /opt/x5/toolkit/bin/hook.sh с помощью override.conf в getty tty1 (ExecStart=…)

Dus de afbeelding wordt geladen, waarin het script mount.sh automatisch wordt gestart. Vervolgens analyseert het script mount.sh tijdens de uitvoering de doorgegeven parameters (script_cmd=) en start het het benodigde programma/script.

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

Bare-Metal Provisioning zelf doen, of Automatische serverconfiguratie vanaf nul

Hier links is het PXE-menu, rechts het schema van de controle-overdracht.

We hebben de controle-overdracht begrepen. Afhankelijk van de keuze in het PXE-menu wordt ofwel het auto-configuratiescript ofwel de debugconsole gestart.

Bij automatische configuratie worden de benodigde mappen van de install-server gemonteerd, waarin aanwezig zijn:

  • scripts;
  • opgeslagen BIOS/UEFI sjablonen van verschillende servers;
  • firmware;
  • hulpmiddelen voor servers;
  • logs.

Vervolgens geeft het script mount.sh de controle door aan het script master-install.sh uit de scriptdirectory.

De boom van scripts (de volgorde van hun uitvoering) ziet er ongeveer als volgt uit:

  • master-install
  • sharefunctions (gemeenschappelijke functies)
  • info (weergave van informatie)
  • models (instelling van installatieparameters op basis van het servermodel)
  • prepare_utils (installatie van benodigde hulpprogramma's)
  • fwupdate (firmware update)
  • diag (elementary diagnostics)
  • biosconf (BIOS/UEFI configuration)
  • clockfix (time adjustment on the motherboard)
  • srmconf (configuration of remote interface)
  • raidconf (configuration of logical volumes)

one of:

  • preinstall (handing control to the OS or hypervisor installer, e.g., ESXi)
  • merged-install (immediate start of image unpacking)

Now we know:

  • how to boot the server via PXE;
  • how to hand control to our own script.


Let's continue. The following questions have become relevant:

  • How to identify the server we are preparing?
  • What utilities and how to configure the server?
  • How to obtain settings for a specific server?

How to identify the server we are preparing?

It's simple – DMI:

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

Here you have everything you need: vendor, model, serial number. If you're not sure that this information is available on all servers, you can identify them by MAC address. Or use both methods simultaneously if the server vendors differ and some models lack serial number information.

Based on the obtained information, network folders from the install server are mounted, and all necessary tools, firmware, and more are loaded.

What utilities and how to configure the server?

I will provide utilities for Linux for some manufacturers. All utilities are available on the vendors' official websites.

Bare-Metal Provisioning zelf doen, of Automatische serverconfiguratie vanaf nul

Regarding firmware, I think everything is clear. They are usually provided as packaged executable files. The executable file controls the firmware update process and reports the return code.

BIOS and IPMI are usually configured via templates. If necessary, the template can be edited just before boot.

RAID utilities for some vendors can also configure via templates. If not, a configuration script will need to be written.

The typical order of RAID configuration is as follows:

  • Request the current configuration.
  • If logical arrays already exist – delete them.
  • Check which physical disks are present and how many there are.
  • Create a new logical array. Interrupt the process in case of an error.

How to obtain settings for a specific server?

Assuming all server settings will be stored on the install server. In that case, to answer our question, we need to first determine: how to transmit settings to the install server.

In het begin kan men prima uit de voeten met tekstbestanden. (In de toekomst kan een tekstbestand worden gebruikt als een reserve manier om instellingen over te dragen).

Men kan het tekstbestand op de installatieserver "delen" en de montage ervan aan het script mount.sh toevoegen.

De regels zullen bijvoorbeeld als volgt zijn:

Deze regels worden door een engineer vanaf zijn werkcomputer naar een bestand overgedragen. En vervolgens worden tijdens de serverconfiguratie de parameters voor de specifieke server uit het bestand gelezen.

Maar op lange termijn is het beter om een database te gebruiken voor de opslag van instellingen, toestanden en installatielogs van servers.

Natuurlijk kan men niet zonder een database, en het zal nodig zijn om een clientgedeelte te creëren waarmee de instellingen naar de database worden overgebracht. Dit is moeilijker te realiseren dan met een tekstbestand, maar in werkelijkheid is het niet zo moeilijk als het lijkt. Een minimale versie van de client, die simpelweg gegevens naar de database zal overdragen, kan je zelf maken. En later kan de clientprogramma verder verbeterd worden in een vrije modus (rapporten, etiketten afdrukken, meldingen verzenden en andere zaken die in je opkomen).

Door een specifieke query naar de database te doen en het serienummer van de server op te geven, krijgen we de benodigde instellingen voor de serverconfiguratie.

Bovendien hoeven we geen blokkeringen te verzinnen voor gelijktijdige toegang, zoals in het geval van een tekstbestand.

We kunnen de configuratielog op alle stadia in de database schrijven en het installatieproces controleren via gebeurtenissen en vlaggen van de voorbereidingstappen.

Nu weten we hoe:

  • de server op te starten via PXE;
  • de controle over te dragen aan ons script;
  • de server te identificeren die moet worden voorbereid, op basis van het serienummer;
  • de server te configureren met de juiste tools;
  • de instellingen naar de database van de installatieserver te sturen met behulp van het clientgedeelte.

We hebben vastgesteld hoe:

  • de te installeren server de benodigde instellingen uit de database ontvangt;
  • de voortgang van de voorbereiding in de database wordt vastgelegd (logs, gebeurtenissen, voorbereidingstappen).

Wat betreft verschillende soorten te installeren software? Hoe installeer je een hypervisor, kopieer je een VM en configureer je dit alles?

Bij het uitrollen van een bestandssysteem-image (linux) op hardware is het vrij eenvoudig:

  • Na het instellen van alle servercomponenten, rollen we de image uit.
  • We installeren de bootloader grub.
  • We maken chroot en stellen alles in wat nodig is.

Hoe de controle over te dragen aan de OS-installateur (met ESXi als voorbeeld).

  • We organiseren de overdracht van de controle van ons script naar de hypervisor-installateur via het antwoordbestand (kickstart):
  • We verwijderen de huidige partities op de schijf.
  • We maken een partitie van 500MB.
  • We markeren deze als opstartbaar.
  • We formatteren in FAT32.
  • We kopiëren de installatiebestanden van ESXi naar de root.
  • We installeren syslinux.
  • We kopiëren syslinux.cfg naar /syslinux/

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

  • We kopiëren mboot.c32 naar /syslinux.
  • In boot.cfg moet kernelopt=ks=ftp:///ks_esxi.cfg staan.
  • Herstart de server.

Na het opnieuw opstarten van de server vanaf de harde schijf, zal de ESXi-installateur opstarten. Alle noodzakelijke installatiebestanden worden in het geheugen geladen en vervolgens begint de installatie van ESXi, volgens het opgegeven antwoordbestand.

Hier geef ik een paar regels uit het antwoordbestand ks_esxi.cfg:

%firstboot --interpreter=busybox
…
# verkrijg serienummer

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

# verkrijg IP

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

# verbind NFS install-server

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

# kopieer tijdelijke ssh-configuraties voor gebruik met ssh-client

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

# kopieer ovftool voor het implementeren van VM's nu, plus mogelijk later nuttig

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

# implementeer VM

\/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

# verkrijg instellingen van onze server

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
...
# genereer netwerkconfiguratiescript

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

# stel guestinfo.esxihost.id parameter in, zet serienummer erin

echo "guestinfo.esxihost.id = "$SYSSN"" >> \/vmfs\/volumes\/datastore1\/VM1\/VM1.vmx
echo "guestinfo.esxihost.id = "$SYSSN"" >> \/vmfs\/volumes\/datastore1\/VM2\/VM2.vmx
...
# update informatie in de database

SYSNAME=$(esxcli hardware platform get | grep Product | sed 's\/Product Name:\/\/g' | 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 ...""

# herstel SSH-instellingen

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

# configureer netwerk en herstart

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

Op dit punt is de hypervisor geïnstalleerd en geconfigureerd en zijn de virtuele machines gekopieerd.

Hoe configureer je nu de virtuele machines?

We hebben een beetje gesjoemeld: tijdens de installatie hebben we de parameter guestinfo.esxihost.id = "$SYSSN" ingesteld in het bestand VM1.vmx, waarin het serienummer van de fysieke server is opgegeven.

Nu kan de virtuele machine (met het geïnstalleerde vmware-tools pakket) na opstarten toegang krijgen tot deze parameter:

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

Dat wil zeggen dat de VM zichzelf kan identificeren (ze kent het serienummer van de fysieke host), een aanvraag kan doen bij de installatieserver database en de parameters kan ontvangen die geconfigureerd moeten worden. Dit alles wordt vastgelegd in een script dat automatisch moet worden uitgevoerd bij de opstart van de guestos vm (maar slechts één keer: RunOnce).

Nu weten we hoe:

  • de server op te starten via PXE;
  • de controle over te dragen aan ons script;
  • de server te identificeren die moet worden voorbereid, op basis van het serienummer;
  • de server configureren met de bijbehorende hulpmiddelen;
  • instellingen doorgeven aan de installatieserver database via de clientzijde;
  • verschillende soorten software configureren, waaronder het implementeren van de hypervisor esxi en het instellen van virtuele machines (en dat alles automatisch).

We hebben vastgesteld hoe:

  • de te installeren server de benodigde instellingen uit de database ontvangt;
  • de voortgang van de voorbereiding in de database wordt vastgelegd (logs, gebeurtenissen, voorbereidingstappen).


Conclusie:

Ik denk dat de uniciteit van deze oplossing ligt in de flexibiliteit, eenvoud, mogelijkheden en veelzijdigheid.

Laat alstublieft weten wat je ervan vindt in de opmerkingen.

Bron: habr.com

Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers 🔥 Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers | ProHoster