Bare-Metal Provisioning för egen hand, eller automatisk förberedelse av servrar från grunden

Hej, jag heter Denis och en av mina verksamhetsområden är utveckling av infrastrukturlösningar på X5. Idag skulle jag vilja dela med mig av hur man med offentligt tillgängliga verktyg kan implementera ett automatiskt system för serverförberedelse. Enligt min mening är detta en intressant, enkel och flexibel lösning.

Bare-Metal Provisioning för egen hand, eller automatisk förberedelse av servrar från grunden

Med förberedelse menas: att göra om en ny server ur lådan till en helt konfigurerad server med Linux OS eller med hypervisorn ESXi (denna artikel diskuterar inte Windows). servrar Windows diskuteras inte i denna artikel.

Termer:

  • servrar – servrar som måste konfigureras.
  • install-server – den huvudsakliga servern som säkerställer hela förberedelseprocessen över nätverket.

Varför behövs automatisering?

Anta att det finns en uppgift: att massförbereda servrar från grunden, i toppar – 30 per dag. Servrar av olika tillverkare och modeller, de kan ha olika operativsystem installerade och kan ha eller sakna en hypervisor.

Vilka operationer ingår i konfigurationsprocessen (utan automatisering):

  • Anslut tangentbord, mus och monitor till servern;
  • Konfigurera BIOS, RAID, IPMI;
  • Uppdatera komponenternas firmware;
  • Distribuera en filsystemavbildning (eller installera hypervisorn och kopiera virtuella maskiner);

Obs. Som ett alternativ kan OS-deployment göras genom installation med en svarfil. Men detta kommer inte att diskuteras i artikeln. Även om du längre ner kommer att se att det inte är svårt att lägga till denna funktionalitet.

  • Konfigurera OS-inställningar (hostname, IP, etc.).

Vid denna metod utförs identiska inställningar sekventiellt på varje server. Effektiviteten av sådant arbete är mycket låg.

Syftet med automatisering är att utesluta människans deltagande i serverförberedelseprocessen. Så mycket som möjligt.

Tack vare automatiseringen minskar tiden för driftstopp mellan operationerna och möjligheten att förbereda flera servrar samtidigt ökar. Risken för fel på grund av mänskliga faktorer minskar också avsevärt.

Bare-Metal Provisioning för egen hand, eller automatisk förberedelse av servrar från grunden

Hur sker automatisk serverkonfiguration?

Låt oss gå igenom alla steg i detalj.

Du har en linux-server som du använder som PXE install-server. På den är tjänsterna DHCP, TFTP installerade och konfigurerade.

Så, vi startar servern (som ska konfigureras) via PXE. Låt oss påminna oss om hur detta fungerar:

  • Servern är inställd för nätverksboot.
  • Servern laddar PXE-ROM för nätverkskortet och kontaktar installationsservern via DHCP för att få en nätverksadress.
  • DHCP-installationsservern utfärdar en adress och instruktioner för vidare nedladdning via PXE.
  • Servern laddar nätverksbootloadern från installationsservern via PXE, och den fortsatta nedladdningen sker enligt PXE-konfigurationsfilen.
  • Nedladdning sker baserat på de mottagna parametrarna (kärna, initramfs, monteringspunkter, squashfs-avbildning och andra).

Observera. I artikeln beskrivs nedladdning via PXE genom BIOS-läge. För närvarande implementeras UEFI bootmode aktivt av tillverkarna. För PXE kommer skillnaden att ligga i DHCP-serverkonfigurationen och närvaron av en ytterligare bootloader.

Låt oss titta på ett exempel på konfiguration av PXE-server (pxelinux-meny).

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 // standardmenyn
	MENU LABEL Linux Scripting Toolkits
	MENU default
	KERNEL menu.c32
	APPEND pxelinux.cfg/toolkit // gå till nästa meny

Fil pxelinux.cfg/toolkit:

prompt 0
timeout 100
menu title X5 PXE Boot Menu
label mainmenu
    menu label ^Återvänd till huvudmenyn
    kernel menu.c32
    append pxelinux.cfg/default
label x5toolkit-auto // standardläget - automatiskt läge
        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 // för felsökning - 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="…"

Kärnan och initramfs vid detta stadium är en mellanliggande linux-avbildning, med hjälp av vilken den huvudsakliga förberedelsen och konfigurationen av servern kommer att ske.

Som ni ser överför bootloadern många parametrar till kärnan. Vissa av dessa parametrar används av själva kärnan. Andra kan vi använda för våra egna ändamål. Mer om detta kommer att diskuteras senare, men för nu kan ni helt enkelt komma ihåg att alla överförda parametrar kommer att vara tillgängliga i den mellanliggande linux-avbildningen via /proc/cmdline.

Var kan man få tag på kärnan och initramfs?
Som grund kan man välja valfri linux-distribution. Vad man ska tänka på vid valet:

  • den bootbara avbildningen måste vara universell (innehålla drivrutiner, möjligheter att installera ytterligare verktyg);
  • Det kommer troligen att krävas att vi anpassar initramfs.

Hur gör vi det i vår lösning för X5? Som grund har vi valt CentOS 7. Vi kommer att göra följande trick: förbereda den framtida bildstrukturen, packa den i ett arkiv och skapa initramfs, där vårt arkiv av filsystemet kommer att finnas. Vid start av bilden kommer arkivet att extraheras till den skapade tmpfs-partitionen. På så sätt får vi en minimal, men ändå fullständig live-bild av Linux med alla nödvändiga verktyg, bestående av bara två filer: vmkernel och 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 specificerat kärnan och initramfs som ska laddas. Som ett resultat, i detta skede, genom att ladda den mellanliggande Linux-bilden via PXE, får vi OS-konsolen.

Utmärkt, men nu behöver vi överföra kontrollen till vår "automatisering".

Detta kan göras så här.

Anta att vi planerar att överföra kontrollen till skriptet mount.sh efter att bilden har laddats.
Vi kommer att inkludera skriptet mount.sh i autostart. För detta krävs det att vi modifierar initramfs:

  • extrahera initramfs (om vi använder det ovanstående alternativet för initramfs, är detta inte nödvändigt)
  • inkludera i autostart koden som kommer att analysera de överlämnade parametrarna via /proc/cmdline och överföra kontrollen vidare;
  • packa initramfs.

Observera. När det gäller X5 toolkit överförs kontrollen till skriptet /opt/x5/toolkit/bin/hook.sh с помощью override.conf в getty tty1 (ExecStart=…)

Så, bilden laddas där skriptet mount.sh startar i autostart. Efter det analyserar skriptet mount.sh de överlämnade parametrarna (script_cmd=) under körningen och startar det nödvändiga programmet/skriptet.

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 för egen hand, eller automatisk förberedelse av servrar från grunden

Här på vänster sida - PXE-menyn, på höger sida - schemat för överföring av kontroll.

Vi har förstått överföringen av kontrollen. Beroende på valet i PXE-menyn antingen startas autoinställningsskrift eller konsol för felsökning.

Vid automatisk inställning monteras nödvändiga kataloger från installationsservern som innehåller:

  • skript;
  • sparade BIOS/UEFI-mallar för olika servrar;
  • firmware;
  • verktyg för servrar;
  • loggar.

Därefter överför skriptet mount.sh kontrollen till skriptet master-install.sh från skriptkatalogen.

Skriptträd (ordningen för deras utförande) ser ungefär ut så här:

  • master-install
  • sharefunctions (gemensamma funktioner)
  • info (visar information)
  • models (installerar installationsparametrar baserat på servermodell)
  • prepare_utils (installerar nödvändiga verktyg)
  • fwupdate (firmwareuppdatering)
  • diag (grunddiagnos)
  • biosconf (BIOS/UEFI-inställningar)
  • clockfix (tidsinställning på moderkortet)
  • srmconf (inställning av fjärrgränssnittet)
  • raidconf (inställning av logiska volymer)

en av:

  • preinstall (överföring av kontroll till installationsprogrammet för operativsystemet eller hypervisorn, t.ex. ESXi)
  • merged-install (direkt start av bilduppackning)

Nu vet vi:

  • hur man startar servern via PXE;
  • hur man överför kontrollen till ett skräddarsytt skript.


Vi fortsätter. Nästa frågor har blivit aktuella:

  • Hur identifierar vi servern som vi förbereder?
  • Vilka verktyg och hur konfigurerar vi servern?
  • Hur får vi inställningar för en specifik server?

Hur identifierar vi servern som vi förbereder?

Det är enkelt – DMI:

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

Här finns allt som behövs: tillverkare, modell, serienummer. Om du är osäker på att denna information finns på alla servrar kan du identifiera dem via MAC-adressen. Eller båda metoderna samtidigt, om serverleverantörerna är olika och information om serienumret saknas på vissa modeller.

Baserat på den information som erhållits monteras nätverksmappar från installationsservern och allt nödvändigt laddas ner (verktyg, firmware osv.).

Vilka verktyg och hur konfigurerar vi servern?

Jag anger verktyg för Linux för vissa tillverkare. Alla verktyg finns tillgängliga på tillverkarnas officiella webbplatser.

Bare-Metal Provisioning för egen hand, eller automatisk förberedelse av servrar från grunden

Med firmware, tror jag att det är klart. Oftast levereras de som packade körbara filer. Den körbara filen kontrollerar processen för firmwareuppdatering och rapporterar en returkod.

BIOS och IPMI konfigureras vanligtvis via mallar. Om så behövs kan mallen redigeras före själva starten.

RAID-verktyg från vissa tillverkare kan också konfigureras via mallar. Om så inte är fallet måste ett konfigurationsskript skrivas.

Ordningen för RAID-konfiguration är oftast följande:

  • Begär nuvarande konfiguration.
  • Om logiska volymer redan finns - rensa dem.
  • Kontrollera vilka fysiska diskar som finns och hur många de är.
  • Skapa en ny logisk volym. Avbryt processen vid fel.

Hur får vi inställningar för en specifik server?

Anta att inställningarna för alla servrar kommer att lagras på installationsservern. I så fall, för att svara på vår fråga, måste vi först besluta: på vilket sätt vi ska överföra inställningarna till installationsservern.

I början kan textfiler räcka. (I framtiden kan en textfil användas som en reservmetod för att överföra inställningar).

Man kan "dela" textfilen på installationsservern. Och lägga till dess montering i skriptet mount.sh.

Raderna kommer till exempel att se ut så här:

Dessa rader kommer att överföras till en fil av ingenjören från hans arbetsdator. Vid serverinställningen kommer parametrarna för den specifika servern att läsas från filen.

Men på sikt är det bättre att använda en databas för att lagra inställningar, tillstånd och installationsloggar för servrar.

Naturligtvis räcker inte en databas, utan vi behöver skapa en klientdel som kommer att överföra inställningar till databasen. Att implementera detta är svårare jämfört med en textfil, men det är faktiskt inte så svårt som det verkar. En minimal version av klienten, som helt enkelt kommer att överföra data till databasen, kan man enkelt skriva själv. Och att förbättra klientprogrammet senare kan göras i fri takt (rapporter, utskrift av etiketter, skicka meddelanden och allt annat som dyker upp).

Genom att göra en viss fråga till databasen och ange serverns serienummer får vi nödvändiga parametrar för serverkonfiguration.

Dessutom behöver vi inte tänka på lås för samtidig åtkomst, som i fallet med textfilen.

Vi kan skriva installationsloggen i databasen i alla steg och kontrollera installationsprocessen via händelser och flaggor för förberedelsestegen.

Nu vet vi hur:

  • ladda servern via PXE;
  • överlämna kontrollen till vårt skript;
  • identifiera servern som ska förberedas med serienumret;
  • konfigurera servern med lämpliga verktyg;
  • överföra inställningar till installationsserverns databas med hjälp av klientdelen.

Vi har klargjort hur:

  • den installerade servern får nödvändiga inställningar från databasen;
  • alla framsteg i förberedelsen registreras i databasen (loggar, händelser, flaggor för stegen).

Vad gäller olika typer av installerad mjukvara? Hur installerar man hypervisorn, kopierar VM och konfigurerar allt detta?

Vid distribution av en filsystemavbildning (linux) på hårdvara är allt ganska enkelt:

  • Efter att ha konfigurerat alla serverkomponenter distribuerar vi avbildningen.
  • Vi installerar bootloader grub.
  • Vi gör chroot och konfigurerar allt som behövs.

Hur man överför kontrollen till OS-installatören (exempel med ESXi).

  • Vi organiserar överföringen av kontrollen från vårt skript till hypervisorinstallatören via en svarfil (kickstart):
  • Vi tar bort de nuvarande partitionerna på disken.
  • Vi skapar en partition som är 500 MB stor.
  • Vi markerar den som startpartition.
  • Vi formaterar den i FAT32.
  • Vi kopierar installationsfilerna för ESXi till roten av den.
  • Vi installerar syslinux.
  • Vi kopierar syslinux.cfg till /syslinux/

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

  • Vi kopierar mboot.c32 till /syslinux.
  • I boot.cfg ska kernelopt=ks=ftp:///ks_esxi.cfg
  • Starta om servern.

Efter omstart av servern kommer installationsprogrammet för ESXi att laddas från dess hårddisk. Alla nödvändiga installationsfiler laddas in i minnet och installationen av ESXi påbörjas enligt den angivna svarfilen.

Här är några rader från svarfilen ks_esxi.cfg:

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

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}')

# anslut NFS install-server

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

# kopiera temporära SSH-inställningar för att använda SSH-klienten

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

# kopiera ovftool för att distribuera VM nu, plus kan vara användbart senare

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

# distribuera 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å raden med inställningar för vår 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
...
# generera skript för nätverksinställningar

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

# ange parameter guestinfo.esxihost.id, ange det i seriellnummer

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

SYSNAME=$(esxcli hardware platform get | grep Product | sed 's/Product Name://;s/^ *//')
UUID=$(vim-cmd hostsvc/hostsummary | grep uuid | sed 's/ / /g;s/,$//;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 ...""

# återställ SSH-inställningar

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

# konfigurera nätverket och starta om

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

Vid detta steg har hypervisor installerats och konfigurerats, virtuella maskiner har kopierats.

Hur konfigurerar man nu de virtuella maskinerna?

Vi har lite fuskade: under installationen angav vi parametern guestinfo.esxihost.id = "$SYSSN" i filen VM1.vmx, och angav det fysiska serverns serienummer.

Nu kan den virtuella maskinen (med installerad vmware-tools-paket) få åtkomst till denna parameter:

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

Det vill säga, VM kommer att kunna identifiera sig själv (den känner till det fysiska värdets serienummer), göra en begäran till databasinstallationsservern och hämta de parametrar som behöver konfigureras. Detta hela formuleras i ett skript som ska köras automatiskt vid start av guestos vm (men endast en gång: RunOnce).

Nu vet vi hur:

  • ladda servern via PXE;
  • överlämna kontrollen till vårt skript;
  • identifiera servern som ska förberedas med serienumret;
  • konfigurera servern med lämpliga verktyg;
  • överföra inställningar till databasinstallationsservern med hjälp av klientdelen;
  • konfigurera olika typer av programvara, inklusive att distribuera hypervisor esxi och ställa in virtuella maskiner (och allt automatiskt).

Vi har klargjort hur:

  • den installerade servern får nödvändiga inställningar från databasen;
  • alla framsteg i förberedelsen registreras i databasen (loggar, händelser, flaggor för stegen).


Slutsats:

Jag tror att den unika egenskapen hos denna lösning ligger i dess flexibilitet, enkelhet, möjligheter och mångsidighet.

Skriv gärna i kommentarerna vad du tycker.

Källa: habr.com

Köp pålitlig webbhotell med DDoS-skydd, VPS VDS-servrar 🔥 Köp pålitlig webbhotell med DDoS-skydd, VPS VDS-servrar | ProHoster