Bare-metal provisioning selv, eller automatisk opstilling af servere fra bunden

Hej, jeg er Denis, og et af mine arbejdsområder er udvikling af infrastrukturløsninger i X5. I dag vil jeg dele med dig, hvordan man kan oprette et automatiseret system til serverforberedelse ved hjælp af offentligt tilgængelige værktøjer. Jeg synes, det er en interessant, enkel og fleksibel løsning.

Bare-metal provisioning selv, eller automatisk opstilling af servere fra bunden

Med forberedelse menes: at gøre en ny server fra kassen til en fuldt konfigureret server med Linux OS eller med hypervisoren ESXi (installationen servere Windows diskuteres ikke i denne artikel).

Termer:

  • servere – servere, der skal konfigureres.
  • install-server – den primære server, der sikrer hele forberedelsesprocessen over netværket.

Hvorfor er automatisering nødvendig?

Antag, at der er en opgave: at forberede servere massivt fra bunden, i spidsen – 30 om dagen. Servere fra forskellige producenter og modeller, hvorpå forskellige OS kan installeres, og der kan være eller ikke være en hypervisor.

Hvilke operationer indgår i konfigurationsprocessen (uden automatisering):

  • tilslutte tastatur, mus, skærm til serveren;
  • konfigurere BIOS, RAID, IPMI;
  • opdatere firmwarekomponenter;
  • udrulle billedet af filsystemet (eller installere hypervisoren og kopiere virtuelle maskiner);

Bemærk. Som et alternativ kan OS installeres via en installation med en svarfil. Men dette vil ikke blive drøftet i artiklen. Dog vil du se nedenfor, at det ikke er svært at tilføje denne funktionalitet.

  • konfigurere OS-parametre (hostname, IP, mm.).

Med denne tilgang udføres identiske indstillinger sekventielt på hver server. Effektiviteten af en sådan proces er meget lav.

Essensen af automatisering er at udelukke menneskelig deltagelse i serverforberedelsesprocessen så meget som muligt.

Takket være automatiseringen reduceres nedetiden mellem operationerne, og det bliver muligt at forberede flere servere samtidig. Derudover reduceres sandsynligheden for fejl betydeligt på grund af den menneskelige faktor.

Bare-metal provisioning selv, eller automatisk opstilling af servere fra bunden

Hvordan sker automatisk serverkonfiguration?

Lad os gennemgå alle faser i detaljer.

Du har en linux-server, som du bruger som PXE install-server. Den har installerede og konfigurerede tjenester: DHCP, TFTP.

Så, lad os starte serveren (som skal konfigureres) via PXE. Lad os huske, hvordan det fungerer:

  • Serveren er indstillet til at starte via netværket.
  • Serveren indlæser PXE-ROM fra netværkskortet og kontakter installationsserveren via DHCP for at få en netværksadresse.
  • DHCP installationsserveren udleverer adressen samt instruktionen om videre indlæsning via PXE.
  • Serveren indlæser netværksbootloaderen fra installationsserveren via PXE, og den videre indlæsning foregår ifølge PXE konfigurationsfilen.
  • Indlæsningen foregår baseret på de modtagne parametre (kerne, initramfs, monteringspunkter, squashfs billede osv.).

Bemærk. Artiklen beskriver indlæsningen via PXE gennem BIOS mode. I øjeblikket implementeres UEFI bootmode aktivt af producenterne. For PXE vil forskellen være i konfigurationen af DHCP-serveren og tilstedeværelsen af en ekstra bootloader.

Lad os se på et eksempel på konfigurationen af PXE-serveren (pxelinux menu).

Fil 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 // standardmenu
	MENU LABEL Linux Scripting Toolkits
	MENU default
	KERNEL menu.c32
	APPEND pxelinux.cfg/toolkit // overgang til næste menu

Fil 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 // standard — automatisk tilstand
        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 // til debugging - konsol
        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="…"

Kernen og initramfs på dette stadium er et mellemliggende linux-billede, som vil blive brugt til den grundlæggende forberedelse og konfiguration af serveren.

Som du kan se, videregiver bootloaderen mange parametre til kernen. Nogle af disse parametre bruges af selve kernen, mens andre kan bruges til vores egne formål. Dette vil blive forklaret senere, men indtil videre kan man blot huske, at alle videregivne parametre vil være tilgængelige i det mellemliggende linux-billede via /proc/cmdline.

Hvor kan man finde dem, kernen og initramfs?
Man kan vælge enhver linux-distribution som basis. Hvad skal vi være opmærksomme på, når vi vælger:

  • bootbilledet skal være universelt (have drivere, muligheder for installation af ekstra værktøjer);
  • det vil sandsynligvis være nødvendigt at tilpasse initramfs.

Hvordan er dette gjort i vores løsning til X5? Som grundlag er CentOS 7 valgt. Vi vil udføre følgende trick: forberede den fremtidige struktur af billedet, pakke det i en arkivfil og oprette initramfs, som vil indeholde vores arkiv af filsystemet. Ved opstart af billedet vil arkivet blive udpakket til den oprettede tmpfs-partition. På den måde får vi et minimalt, men fuldt fungerende live-billede af Linux med alle nødvendige værktøjer, der kun består af to filer: vmkernel og 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

Så vi har angivet kernen og initramfs, der skal indlæses. Som resultat, ved at indlæse det midlertidige Linux-billede via PXE, vil vi få OS-konsollen.

Fremragende, men nu skal vi overføre styringen til vores "automatisering".

Dette kan gøres som følger.

Lad os antage, at vi planlægger at overføre styringen til scriptet mount.sh efter indlæsning af billedet.
Vi incluirer scriptet mount.sh i automatisk opstart. For dette er det nødvendigt at modificere initramfs:

  • udpakke initramfs (hvis vi bruger den nævnte variant af initramfs, er dette ikke nødvendigt)
  • includere i boot-koden, der vil analysere de overførte parametre via /proc/cmdline og overføre styringen videre;
  • pakke initramfs.

Bemærk. I tilfælde af X5 toolkit overføres bootstyringen til scriptet /opt/x5/toolkit/bin/hook.sh с помощью override.conf в getty tty1 (ExecStart=…)

Så indlæses billedet, hvori scriptet mount.sh starter i automatisk opstart. Derefter analyserer scriptet mount.sh under udførelsen de overførte parametre (script_cmd=) og starter det nødvendige program/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 selv, eller automatisk opstilling af servere fra bunden

Her i venstre side er PXE-menuen, og i højre side – skemaet for overførsel af kontrol.

Vi har forstået overførslen af kontrol. Afhængigt af valg af PXE-menuen starter enten scriptet til automatisk konfiguration eller konsollen til fejlfinding.

I tilfælde af automatisk konfiguration monteres de nødvendige biblioteker fra install-serveren, som indeholder:

  • scripts;
  • gemte BIOS/UEFI-skabeloner for forskellige servere;
  • firmware;
  • værktøjer til servere;
  • logfiler.

Derefter overfører scriptet mount.sh kontrollen til scriptet master-install.sh i scripts-mappen.

Scripttræet (rækkefølgen af deres kørsel) ser omtrent sådan ud:

  • master-install
  • sharefunctions (fælles funktioner)
  • info (information output)
  • models (installation parametre baseret på servermodel)
  • prepare_utils (installation af nødvendige værktøjer)
  • fwupdate (firmwareopdatering)
  • diag (grundlæggende diagnose)
  • biosconf (bios/uefi konfiguration)
  • clockfix (opsætning af tid på hovedkortet)
  • srmconf (konfiguration af fjerninterface)
  • raidconf (konfiguration af logiske volumener)

én af:

  • preinstall (overførsel af kontrol til OS- eller hypervisorinstallatøren, f.eks. ESXi)
  • merged-install (direkte opstart af billedudpakning)

Nu ved vi:

  • hvordan man indlæser serveren via PXE;
  • hvordan man overfører kontrol til eget script.


Lad os fortsætte. Følgende spørgsmål er blevet relevante:

  • Hvordan identificerer vi serveren, som vi forbereder?
  • Hvilke værktøjer og hvordan konfigurerer vi serveren?
  • Hvordan får vi indstillingerne for den specifikke server?

Hvordan identificerer vi serveren, som vi forbereder?

Det er enkelt – DMI:

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

Her er alt, hvad der er nødvendigt: producent, model, serienummer. Hvis du er usikker på, om denne information er tilgængelig for alle servere, kan du identificere dem via MAC-adressen. Eller begge metoder samtidig, hvis serverproducenterne er forskellige, og informationen om serienummeret mangler på nogle modeller.

Baseret på den indsamlede information monteres netværksmapper fra install-serveren, og alt nødvendigt (værktøjer, firmware osv.) hentes.

Hvilke værktøjer og hvordan konfigurerer vi serveren?

Jeg vil give nogle værktøjer til Linux til visse producenter. Alle værktøjer er tilgængelige på producenternes officielle hjemmesider.

Bare-metal provisioning selv, eller automatisk opstilling af servere fra bunden

Med firmware er alt klart, tror jeg. De leveres normalt som pakkerede eksekverbare filer. Den eksekverbare fil kontrollerer firmwareopdateringsprocessen og rapporterer en returkode.

BIOS og IPMI konfigureres normalt via skabeloner. Om nødvendigt kan skabelonen redigeres lige før opstart.

RAID-værktøjer fra nogle producenter kan også konfigureres via skabeloner. Hvis det ikke er tilfældet, skal der skrives et konfigurationsscript.

Forløbet af RAID-konfiguration er oftest som følger:

  • Vi anmoder om den aktuelle konfiguration.
  • Hvis der allerede er logiske array, sletter vi dem.
  • Vi ser, hvilke fysiske diske der er til stede, og hvor mange der er.
  • Vi opretter et nyt logisk array. Vi afbryder processen i tilfælde af fejl.

Hvordan får vi indstillingerne for den specifikke server?

Lad os antage, at indstillingerne for alle servere vil blive gemt på install-serveren. I så fald, for at besvare vores spørgsmål, skal vi først afgøre: hvordan vi skal overføre indstillingerne til install-serveren.

I begyndelsen er det helt i orden at bruge tekstfiler. (I fremtiden kan man bruge tekstfilen som en backupmetode til at overføre indstillinger).

Man kan "delekort" en tekstfil på installationsserveren og tilføje dens montering i mount.sh-scriptet.

Linjerne vil være af følgende format:

Disse linjer vil blive overført til filen af ingeniøren fra hans arbejdsstation. Og senere, ved opsætningen af serveren, vil parametre for den specifikke server blive læst fra filen.

Men på sigt er det bedre at anvende en database til at gemme indstillinger, tilstande og installationslogfiler for serverne.

Selvfølgelig er en enkelt database ikke tilstrækkelig, og det vil være nødvendigt at oprette en klientdel, der kan overføre indstillinger til databasen. Det er mere kompliceret at implementere i forhold til tekstfilen, men i virkeligheden er det ikke så svært, som det virker. Den minimumsversion af klienten, der blot vil overføre data til databasen, kan man sagtens skrive selv. Og man kan forbedre klientprogrammet senere i fritiden (rapporter, udskrivning af etiketter, sending af meddelelser osv., hvad man nu kan finde på).

Ved at lave en bestemt forespørgsel til databasen og angive serverens serienummer, vil vi få de nødvendige parametre til serveropsætningen.

Plus, vi skal ikke finde på låsningsmetoder for samtidige adgang, som i tilfælde af tekstfilen.

Vi kan skrive konfigurationsloggen i databasen på alle trin og kontrollere installationsprocessen gennem begivenheder og faseflag.

Nu ved vi, hvordan:

  • man indlæser serveren via PXE;
  • man overfører kontrol til vores script;
  • man identificerer den server, der skal forberedes, ved serienummeret;
  • man konfigurerer serveren med de relevante værktøjer;
  • man overfører indstillinger til installationsserverens database ved hjælp af klientdelen.

Vi har fundet ud af, hvordan:

  • den installerede server modtager de nødvendige indstillinger fra databasen;
  • fremskridtene i forberedelsen registreres i databasen (logs, begivenheder, faseflag).

Hvad med de forskellige typer installeret software? Hvordan installerer man hypervisoren, kopierer VM og konfigurerer det hele?

I tilfælde af udrulning af en filsystemafbildning (linux) til hardware er alt ret simpelt:

  • Efter konfiguration af alle serverkomponenter rulles billedet ud.
  • Vi installerer bootloaderen grub.
  • Vi udfører chroot og konfigurerer alt, hvad der er nødvendigt.

Hvordan man overfører kontrol til operativsysteminstallatøren (på eksempel ESXi).

  • Vi organiserer overførslen af kontrol fra vores script til hypervisorinstallatøren via en svarfil (kickstart):
  • Vi sletter de nuværende partitioner på disken.
  • Vi opretter en partition på 500MB.
  • Vi markerer den som bootbar.
  • Vi formaterer den til FAT32.
  • Vi kopierer installationsfilerne for ESXi til roden af den.
  • Vi installerer syslinux.
  • Vi kopierer syslinux.cfg til /syslinux/

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

  • Vi kopierer mboot.c32 til /syslinux.
  • I boot.cfg skal der stå kernelopt=ks=ftp:///ks_esxi.cfg
  • Genstart serveren.

Når serveren genstarter fra sin hårde disk, vil ESXi-installationsprogrammet blive indlæst. Alle nødvendige installationsfiler vil blive indlæst i hukommelsen, og installationen af ESXi vil derefter begynde i henhold til den angivne svarfil.

Her er et par linjer fra svarfilen ks_esxi.cfg:

%firstboot --interpreter=busybox
…
# få serialnummer

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

# få IP

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

# tilslut NFS installationsserver

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

# kopier midlertidige ssh indstillinger, til brug for ssh-klienten

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

# kopier ovftool, til implementering af VM nu, plus vi kan muligvis få brug for det senere

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

# implementer 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

# få en række med indstillingerne for vores 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
...
# generer netværk konfigurations script

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

# angiv parameter guestinfo.esxihost.id, angi dets serielle nummer

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

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\/$//g' | 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 ...""

# gendan SSH indstillinger

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

# konfigurer netværket og genstart

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

På dette tidspunkt er hypervisoren installeret og konfigureret, og virtuelle maskiner er blevet kopieret.

Hvordan konfigurerer vi nu de virtuelle maskiner?

Vi har været lidt snedige: under installationen satte vi parameteren guestinfo.esxihost.id = "$SYSSN" i filen VM1.vmx, hvor vi angav det serielle nummer af den fysiske server.

Nu, efter opstart kan den virtuelle maskine (med den installerede vmware-tools pakke) få adgang til denne parameter:

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

Det vil sige, at VM'en vil være i stand til at identificere sig selv (den kender det fysiske hosts serienummer), lave en forespørgsel til install-serverens database og få de parametre, der skal konfigureres. Alt dette udformes i et script, der skal køres automatisk ved opstart af guestos vm (men kun én gang: RunOnce).

Nu ved vi, hvordan:

  • man indlæser serveren via PXE;
  • man overfører kontrol til vores script;
  • man identificerer den server, der skal forberedes, ved serienummeret;
  • konfigurere serveren med de relevante værktøjer;
  • overføre indstillinger til install-serverens database ved hjælp af klientdelen;
  • konfigurere forskellige typer software, herunder at implementere hypervisoren esxi og konfigurere virtuelle maskiner (og alt automatisk).

Vi har fundet ud af, hvordan:

  • den installerede server modtager de nødvendige indstillinger fra databasen;
  • fremskridtene i forberedelsen registreres i databasen (logs, begivenheder, faseflag).


Konklusion:

Jeg mener, at unikheden ved denne løsning ligger i dens fleksibilitet, enkelhed, muligheder og alsidighed.

Skriv venligst i kommentarerne, hvad du synes.

Kilde: habr.com

Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere 🔥 Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere | ProHoster