Gjør-det-selv Bare-Metal Provisioning, eller Automatisk klargjøring av servere fra bunnen av

Hei, jeg heter Denis og et av mine aktivitetsområder er utvikling av infrastrukturløsninger hos X5. I dag vil jeg dele med deg hvordan du kan distribuere et automatisk serverforberedelsessystem basert på offentlig tilgjengelige verktøy. Etter min mening er dette en interessant, enkel og fleksibel løsning.

Gjør-det-selv Bare-Metal Provisioning, eller Automatisk klargjøring av servere fra bunnen av

Med forberedelse mener vi: gjør en ny server ut av esken til en fullt konfigurert server med OS. Linux eller med ESXi hypervisor (distribusjon av Windows-servere er ikke diskutert i denne artikkelen).

Vilkår:

  • servere – servere som må konfigureres.
  • installasjonsserveren er hovedserveren som sørger for hele forberedelsesprosessen over nettverket.

Hvorfor trengs automatisering?

La oss si at det er en oppgave: å forberede servere massivt fra bunnen av, på en topp – 30 per dag. Servere fra forskjellige produsenter og modeller, forskjellige operativsystemer kan være installert på dem, og kan ha en hypervisor eller ikke.

Hvilke operasjoner er inkludert i oppsettprosessen (uten automatisering):

  • koble et tastatur, mus, skjerm til serveren;
  • konfigurer BIOS, RAID, IPMI;
  • oppdatere komponentfastvare;
  • distribuere et filsystembilde (eller installer en hypervisor og kopier virtuelle maskiner);

Merk. Alternativt er OS-distribusjon mulig gjennom installasjon med en autosvarfil. Men dette vil ikke bli diskutert i artikkelen. Selv om du vil se nedenfor at det ikke er vanskelig å legge til denne funksjonaliteten.

  • konfigurere OS-parametere (vertsnavn, IP, etc.).

Med denne tilnærmingen utføres de samme innstillingene sekvensielt på hver server. Effektiviteten til slikt arbeid er svært lav.

Essensen av automatisering er å eliminere menneskelig deltakelse fra serverforberedelsesprosessen. Så mye som mulig.

Automatisering reduserer nedetid mellom operasjoner og gjør det mulig å klargjøre flere servere samtidig. Sannsynligheten for feil på grunn av menneskelige faktorer er også sterkt redusert.

Gjør-det-selv Bare-Metal Provisioning, eller Automatisk klargjøring av servere fra bunnen av

Hvordan konfigureres servere automatisk?

La oss analysere alle stadiene i detalj.

Du har en Linux-server som du bruker som PXE-installasjonsserver. Tjenester er installert og konfigurert på den: DHCP, TFTP.

Så vi starter opp serveren (som må konfigureres) via PXE. La oss huske hvordan det fungerer:

  • Nettverksoppstart er valgt på serveren.
  • Serveren laster PXE-ROM-en til nettverkskortet og kontakter installasjonsserveren via DHCP for å få en nettverksadresse.
  • DHCP-installasjonsserveren utsteder en adresse, samt instruksjoner for videre nedlasting via PXE.
  • Serveren laster nettverksoppstartslasteren fra installasjonsserveren via PXE, videre lasting skjer i henhold til PXE-konfigurasjonsfilen.
  • Oppstarten skjer basert på de mottatte parameterne (kjerne, initramfs, monteringspunkter, squashfs-bilde, etc.).

Merk. Artikkelen beskriver oppstart via PXE via BIOS-modus. For tiden implementerer produsenter aktivt UEFI-oppstartsmodus. For PXE vil forskjellen være i konfigurasjonen av DHCP-serveren og tilstedeværelsen av en ekstra oppstartslaster.

La oss se på et eksempel på en PXE-serverkonfigurasjon (pxelinux-menyen).

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 // меню по умолчанию
	MENU LABEL Linux Scripting Toolkits
	MENU default
	KERNEL menu.c32
	APPEND pxelinux.cfg/toolkit // переход на следующее меню

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 // по умолчанию — автоматический режим
        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=”…”

Kjernen og initramfs på dette stadiet er et mellomliggende Linux-bilde, ved hjelp av hvilket hovedforberedelsen og konfigurasjonen av serveren vil finne sted.

Som du kan se, sender bootloaderen mange parametere til kjernen. Noen av disse parameterne brukes av selve kjernen. Og vi kan bruke noen til våre egne formål. Dette vil bli diskutert senere, men foreløpig kan du bare huske at alle beståtte parametere vil være tilgjengelige i det mellomliggende Linux-bildet via /proc/cmdline.

Hvor kan jeg få tak i dem, kernel og initramfs?
Som grunnlag kan du velge hvilken som helst Linux-distribusjon. Hva vi legger merke til når vi velger:

  • oppstartsbildet må være universelt (tilgjengelighet av drivere, mulighet til å installere tilleggsverktøy);
  • Mest sannsynlig må du tilpasse initramfs.

Hvordan gjøres dette i vår løsning for X5? CentOS 7 ble valgt som grunnlag. La oss prøve følgende triks: klargjør den fremtidige bildestrukturen, pakk den inn i et arkiv og lag en initramfs, der det vil være vårt filsystemarkiv. Når du laster bildet, vil arkivet utvides til den opprettede tmpfs-partisjonen. På denne måten vil vi få et minimalt, men likevel fullverdig live linux-bilde med alle nødvendige verktøy, bestående av bare 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 spesifisert kjernen og initramfs som skal lastes. Som et resultat, på dette stadiet, ved å laste det mellomliggende linux-bildet via PXE, vil vi motta OS-konsollen.

Flott, men nå må vi overføre kontrollen til vår "automatisering".

Det kan gjøres slik.

La oss anta at etter å ha lastet bildet planlegger vi å overføre kontrollen til mount.sh-skriptet.
La oss inkludere mount.sh-skriptet i autorun. For å gjøre dette må du endre initramfs:

  • pakk ut initramfs (hvis vi bruker initramfs-alternativet ovenfor, er dette ikke nødvendig)
  • inkludere kode i oppstart som vil analysere parameterne som sendes gjennom /proc/cmdline og overføre kontrollen videre;
  • pakke initramfs.

Merk. Når det gjelder X5-verktøysettet, overføres innlastingskontrollen til skriptet /opt/x5/toolkit/bin/hook.sh с помощью override.conf в getty tty1 (ExecStart=…)

Så bildet er lastet, der mount.sh-skriptet starter ved autorun. Deretter analyserer mount.sh-skriptet de beståtte parameterne (script_cmd=) under kjøring og starter det nødvendige programmet/skriptet.

etikettverktøysett-auto
kjerne...
legg til... nfs_toolkit_script=scripts/mount.sh script_cmd=master-install.sh

etikettverktøysett-shell
kjerne...
legg til... nfs_toolkit_script=scripts/mount.sh script_cmd=/bin/bash

Gjør-det-selv Bare-Metal Provisioning, eller Automatisk klargjøring av servere fra bunnen av

Her til venstre er PXE-menyen, til høyre er kontrolloverføringsdiagrammet.

Vi fant ut overføringen av kontroll. Avhengig av valget av PXE-menyen, startes enten autokonfigurasjonsskriptet eller feilsøkingskonsollen.

Ved automatisk konfigurasjon monteres de nødvendige katalogene fra installasjonsserveren, som inneholder:

  • skript;
  • lagrede BIOS/UEFI-maler for ulike servere;
  • fastvare;
  • serververktøy;
  • tømmerstokker

Deretter overfører mount.sh-skriptet kontrollen til master-install.sh-skriptet fra skriptkatalogen.

Skripttreet (rekkefølgen de lanseres i) ser omtrent slik ut:

  • master-installere
  • delefunksjoner (delte funksjoner)
  • info (informasjonsutgang)
  • modeller (innstilling av installasjonsparametere basert på servermodellen)
  • prepare_utils (installasjon av nødvendige verktøy)
  • fwupdate (fastvareoppdatering)
  • diag (elementær diagnostikk)
  • biosconf (BIOS/UEFI-innstillinger)
  • clockfix (stiller inn tiden på hovedkortet)
  • srmconf (konfigurasjon av eksternt grensesnitt)
  • raidconf (konfigurere logiske volumer)

en av:

  • forhåndsinstallasjon (overfører kontrollen til operativsystemet eller hypervisorinstallasjonsprogrammet, for eksempel ESXi)
  • merged-install (umiddelbar start på utpakking av bildet)

Nå vet vi:

  • hvordan starte en server via PXE;
  • hvordan overføre kontrollen til ditt eget skript.


La oss fortsette. Følgende spørsmål ble aktuelle:

  • Hvordan identifisere serveren vi forbereder?
  • Hvilke verktøy og hvordan konfigurere serveren?
  • Hvordan få innstillinger for en bestemt server?

Hvordan identifisere serveren vi forbereder?

Det er enkelt - DMI:

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

Alt du trenger er her: leverandør, modell, serienummer. Hvis du ikke er sikker på at denne informasjonen finnes på alle servere, kan du identifisere dem ved deres MAC-adresse. Eller på begge måter samtidig, hvis serverleverandørene er forskjellige og på noen modeller er det rett og slett ingen informasjon om serienummeret.

Basert på informasjonen som mottas, monteres nettverksmapper fra installasjonsserveren og alt nødvendig lastes inn (verktøy, fastvare, etc.).

Hvilke verktøy og hvordan konfigurere serveren?

Jeg vil tilby verktøy for Linux for noen produsenter. Alle verktøy er tilgjengelige på de offisielle nettstedene til leverandører.

Gjør-det-selv Bare-Metal Provisioning, eller Automatisk klargjøring av servere fra bunnen av

Med fastvaren tror jeg alt er klart. De kommer vanligvis i form av pakkede kjørbare filer. Den kjørbare filen kontrollerer fastvareoppdateringsprosessen og rapporterer returkoden.

BIOS og IPMI konfigureres vanligvis gjennom maler. Om nødvendig kan malen redigeres før nedlasting.

RAID-verktøy fra enkelte leverandører kan også konfigureres ved hjelp av en mal. Hvis dette ikke er tilfelle, må du skrive et konfigurasjonsskript.

Prosedyren for å sette opp RAID er oftest som følger:

  • Vi ber om gjeldende konfigurasjon.
  • Hvis det allerede er logiske matriser, sletter vi dem.
  • La oss se på hvilke fysiske disker som finnes og hvor mange det er.
  • Opprett en ny logisk matrise. Vi avbryter prosessen ved feil.

Hvordan få innstillinger for en bestemt server?

La oss anta at innstillingene til alle servere vil bli lagret på installasjonsserveren. I dette tilfellet, for å svare på spørsmålet vårt, må vi først bestemme hvordan vi skal overføre innstillingene til installasjonsserveren.

Til å begynne med kan du klare deg med tekstfiler. (I fremtiden vil du kanskje bruke en tekstfil som en reservemetode for å overføre innstillinger.)

Du kan "dele" en tekstfil på installasjonsserveren. Og legg til monteringen til mount.sh-skriptet.

Linjene vil for eksempel se slik ut:

<serienummer> <vertsnavn> <undernett>

Disse linjene vil bli overført til filen av ingeniøren fra hans arbeidsmaskin. Og så, når du setter opp en server, vil parametrene for en spesifikk server bli lest fra filen.

Men på lang sikt er det bedre å bruke en database til å lagre innstillinger, tilstander og logger for serverinstallasjoner.

En database alene er selvfølgelig ikke nok, og du må lage en klientdel ved hjelp av hvilke innstillinger som skal overføres til databasen. Dette er vanskeligere å implementere sammenlignet med en tekstfil, men faktisk er ikke alt så vanskelig som det ser ut til. Det er fullt mulig å skrive en minimal versjon av en klient som ganske enkelt overfører data til databasen selv. Og i fremtiden vil det være mulig å forbedre klientprogrammet i fri modus (rapporter, skrive ut etiketter, sende varsler osv. som du tenker på).

Ved å gjøre en spesifikk forespørsel til databasen og spesifisere serverens serienummer, vil vi motta de nødvendige parameterne for å konfigurere serveren.

I tillegg trenger vi ikke å komme opp med låser for samtidig tilgang, slik tilfellet er med en tekstfil.

Vi kan skrive konfigurasjonsloggen til databasen på alle stadier og kontrollere installasjonsprosessen gjennom hendelser og flagg fra forberedelsesstadiene.

Nå vet vi hvordan:

  • boot serveren via PXE;
  • overføre kontrollen til skriptet vårt;
  • identifisere serveren som må klargjøres ved serienummeret;
  • konfigurere serveren ved å bruke de riktige verktøyene;
  • overføre innstillinger til installasjonsserverdatabasen ved hjelp av klientdelen.

Vi fant ut hvordan:

  • den installerte serveren mottar de nødvendige innstillingene fra databasen;
  • all forberedelsesfremgang registreres i databasen (logger, hendelser, sceneflagg).

Hva med de forskjellige typer programvare du installerer? Hvordan installere en hypervisor, kopiere en VM og konfigurere alt?

Når det gjelder å distribuere et filsystembilde (linux) til maskinvare, er alt ganske enkelt:

  • Etter å ha satt opp alle serverkomponentene, distribuerer vi bildet.
  • Installer grub bootloader.
  • Vi chroot og konfigurerer alt som trengs.

Hvordan overføre kontrollen til OS-installasjonsprogrammet (med ESXi som eksempel).

  • Vi organiserer overføringen av kontroll fra skriptet vårt til hypervisorinstallasjonsprogrammet ved å bruke den automatiske svarfilen (kickstart):
  • Vi sletter gjeldende partisjoner på disken.
  • Lag en partisjon med en størrelse på 500MB.
  • Vi merker den som oppstartbar.
  • Formater til FAT32.
  • Vi kopierer ESXi-installasjonsfilene til roten.
  • Installerer syslinux.
  • Kopier syslinux.cfg til /syslinux/

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

  • Kopier mboot.c32 til /syslinux.
  • Boot.cfg skal ha kernelopt=ks=ftp:// /ks_esxi.cfg
  • Vi starter serveren på nytt.

Etter at serveren har startet på nytt, vil ESXi-installasjonsprogrammet lastes ned fra serverens harddisk. Alle nødvendige installasjonsfiler vil bli lastet inn i minnet og deretter vil ESXi-installasjonen begynne, i henhold til den spesifiserte autosvar-filen.

Her er noen linjer fra autosvar-filen 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

På dette stadiet er hypervisoren installert og konfigurert, og virtuelle maskiner kopieres.

Hvordan konfigurere virtuelle maskiner nå?

Vi jukset litt: under installasjonen satte vi parameteren guestinfo.esxihost.id = "$SYSSN" i VM1.vmx-filen og indikerte serienummeret til den fysiske serveren i den.

Nå, etter oppstart, kan den virtuelle maskinen (med vmware-tools-pakken installert) få tilgang til denne parameteren:

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

Det vil si at VM-en vil kunne identifisere seg selv (den kjenner serienummeret til den fysiske verten), sende en forespørsel til installasjonsserverdatabasen og motta parametrene som må konfigureres. Alt dette er kompilert til et skript, som skal startes automatisk når guestos vm starter (men én gang: RunOnce).

Nå vet vi hvordan:

  • boot serveren via PXE;
  • overføre kontrollen til skriptet vårt;
  • identifisere serveren som må klargjøres ved serienummeret;
  • konfigurere serveren ved å bruke de riktige verktøyene;
  • overføre innstillinger til installasjonsserverdatabasen ved å bruke klientdelen;
  • konfigurere ulike typer programvare, inkludert distribusjon av esxi hypervisor og konfigurering av virtuelle maskiner (alt automatisk).

Vi fant ut hvordan:

  • den installerte serveren mottar de nødvendige innstillingene fra databasen;
  • all forberedelsesfremgang registreres i databasen (logger, hendelser, sceneflagg).


Den nederste linjen:

Jeg tror at det unike med denne løsningen ligger i dens fleksibilitet, enkelhet, muligheter og allsidighet.

Skriv gjerne i kommentarfeltet hva du synes.

Kilde: www.habr.com

Legg til en kommentar