Ahoj, já jsem Denis a jedním z mých zaměření je vývoj infrastrukturních řešení ve společnosti X5. Dnes bych se s vámi chtěl podělit o to, jak lze na základě veřejně dostupných nástrojů vybudovat automatický systém přípravy serverů. Podle mě je to zajímavé, jednoduché a flexibilní řešení.

Pod přípravou se rozumí: udělat z nového serveru přímo z krabice, plně nakonfigurovaný server s operačním systémem Linux nebo s hypervizorem ESXi (Windows v tomto článku není diskutován). servery Termíny
servery – servery, které je potřeba nakonfigurovat.:
- instalující server – hlavní server, který zajišťuje celý proces přípravy po síti.
- Proč je potřebná automatizace?
Představte si úkol: hromadně připravovat servery od základu, v maximálním objemu – 30 za den. Servery různých výrobců a modelů, na kterých mohou být instalovány různé OS, mohou mít nebo nemít hypervizor.
Jaké operace jsou součástí procesu konfigurace (bez automatizace):
připojit klávesnici, myš, monitor k serveru;
- nastavit BIOS, RAID, IPMI;
- aktualizovat firmware komponent;
- nasadit obraz souborového systému (buď nainstalovat hypervizor a zkopírovat virtuální stroje);
- Poznámka. Jako možnost lze nasadit OS prostřednictvím instalace s odpovědním souborem. Ale to nebude v článku diskutováno. I když níže uvidíte, že přidání této funkčnosti není složité.
nastavit parametry OS (název hostitele, IP, ostatní).
- Při tomto přístupu se provádějí stejné nastavení postupně na každém serveru. Efektivita takové práce je velmi nízká.
Podstata automatizace – vyloučit účast člověka z procesu přípravy serveru. Co nejvíce, jak je to možné.
Díky automatizaci se zkracuje doba nečinnosti mezi operacemi a vzniká možnost připravit několik serverů současně. Také se výrazně snižuje pravděpodobnost vzniku chyb v důsledku lidského faktoru.
Jak probíhá automatická konfigurace serverů?

Prozkoumáme všechny etapy podrobně.
Máte linuxový server, který používáte jako PXE instalační server. Na něm jsou nainstalovány a nastaveny služby: DHCP, TFTP.
Máte linuxový server, který používáte jako PXE instalační server. Na něm jsou nainstalovány a nakonfigurovány služby: DHCP, TFTP.
Nyní načítáme server (který je třeba nastavit) přes PXE. Připomeňme si, jak to funguje:
- Na serveru je vybráno bootování přes síť.
- Server načítá PXE-ROM síťové karty a obrací se na instalační server pomocí DHCP pro získání síťové adresy.
- DHCP instalačního serveru dává adresu a také pokyn o dalším bootování přes PXE.
- Server načítá síťový zaváděč z instalačního serveru přes PXE, další bootování probíhá podle konfiguračního souboru PXE.
- Probíhá bootování na základě získaných parametrů (jádro, initramfs, body připojení, obraz squashfs a další).
Poznámka. V článku je popsáno bootování přes PXE pomocí režimu BIOS. V současnosti výrobci aktivně implementují UEFI bootmode. Pro PXE bude rozdíl v konfiguraci DHCP serveru a dostupnosti dalšího zaváděče.
Podíváme se na příklad konfigurace PXE serveru (menu pxelinux).
Soubor 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 // výchozí menu
MENU LABEL Linux Scripting Toolkits
MENU default
KERNEL menu.c32
APPEND pxelinux.cfg/toolkit // přechod na další menuSoubor pxelinux.cfg/toolkit:
prompt 0
timeout 100
menu title X5 PXE Boot Menu
label mainmenu
menu label ^Vrátit se do hlavního menu
kernel menu.c32
append pxelinux.cfg/default
label x5toolkit-auto // výchozí - automatický režim
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 // pro debug - konzole
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="…"Jádro a initramfs v této fázi jsou mezilehlým linuxovým obrazem, pomocí kterého bude probíhat hlavní příprava a konfigurace serveru.
Jak vidíte, zaváděč předává mnoho parametrů jádru. Některé z těchto parametrů používá samotné jádro. A některé můžeme využít pro naše účely. O tom bude řeč později, ale zatím si můžete zapamatovat, že všechny předané parametry budou dostupné v mezilehlém linuxovém obraze přes /proc/cmdline.
Kde je získat, jádro a initramfs?
Za základ si můžete zvolit jakýkoliv linuxový distribuci. Na co se zaměřit při výběru:
- Zaváděcí obraz by měl být univerzální (přítomnost ovladačů, možnosti instalace dodatečných utilit);
- Pravděpodobně bude potřeba přizpůsobit initramfs.
Jak je to provedeno v našem řešení pro X5? Jako základ byl vybrán CentOS 7. Provedeme následující trik: připravíme budoucí strukturu obrazu, zabalíme ji do archivu a vytvoříme initramfs, ve kterém bude náš archiv souborového systému. Při zavádění obrazu se archiv rozbalí do vytvářeného oddílu tmpfs. Tímto způsobem získáme minimální, přitom plnohodnotný live obraz linuxu se všemi potřebnými utilitami, skládající se pouze ze dvou souborů: vmkernel a 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.gzTakže jsme určili jádro a initramfs, které mají být zavedeny. V důsledku toho v této fázi, po zavedení mezilehlého obrazu linuxu přes PXE, získáme konzoli OS.
Skvělé, ale nyní je potřeba předat řízení naší „automatizaci“.
To lze provést takto.
Předpokládejme, že po zavedení obrazu plánujeme předat řízení do skriptu mount.sh.
Začleníme skript mount.sh do automatického spuštění. K tomu bude třeba upravit initramfs:
- rozbalit initramfs (pokud používáme výše uvedenou variantu initramfs, to není třeba)
- včetně kódu do automatického spuštění, který prozkoumá předávané parametry přes /proc/cmdline a předá řízení dále;
- zabalit initramfs.
Poznámka. V případě X5 toolkit se řízení zavádění předává do skriptu /opt/x5/toolkit/bin/hook.sh с помощью override.conf в getty tty1 (ExecStart=…)
Takže se zavádí obraz, ve kterém se ve spuštění automaticky spouští skript mount.sh. Dále skript mount.sh v průběhu provádění analyzuje předané parametry (script_cmd=) a spouští potřebný program/skript.
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

Zde na levé straně – menu PXE, na pravé – schéma předávání řízení.
S předáváním řízení jsme se vypořádali. V závislosti na výběru PXE-menu se spouští buď skript automatické konfigurace, nebo konzole pro ladění.
V případě automatické konfigurace se montují potřebné adresáře z instalačního serveru, v nichž se nachází:
- skripty;
- uložené šablony BIOS/UEFI různých serverů;
- firmware;
- utility pro servery;
- logy.
Dále skript mount.sh předává řízení skriptu master-install.sh z adresáře se skripty.
Strom skriptů (pořadí jejich spuštění) vypadá přibližně takto:
- master-install
- sharefunctions (společné funkce)
- info (výstup informací)
- models (nastavení parametrů instalace na základě modelu serveru)
- prepare_utils (instalace potřebných utilit)
- fwupdate (aktualizace firmwaru)
- diag (základní diagnostika)
- biosconf (nastavení BIOSu/UEFI)
- clockfix (nastavení času na základní desce)
- srmconf (nastavení rozhraní vzdáleného přístupu)
- raidconf (nastavení logických svazků)
jeden z:
- preinstall (předání řízení instalátoru OS nebo hypervizoru, např. ESXi)
- merged-install (okamžitý start rozbalení obrazu)
Nyní víme:
- jak zavést server přes PXE;
- jak předat řízení do vlastního skriptu.
Pokračujeme. Aktuální otázky jsou:
- Jak identifikovat server, který připravujeme?
- Jaké utility a jak konfigurovat server?
- Jak získat nastavení pro konkrétní server?
Jak identifikovat server, který připravujeme?
To je jednoduché – DMI:
dmidecode –s system-product-name
dmidecode –s system-manufacturer
dmidecode –s system-serial-numberZde je vše, co potřebujete: dodavatel, model, sériové číslo. Pokud si nejste jisti, že tyto informace jsou k dispozici na všech serverech, můžete je identifikovat podle MAC adresy. Nebo oběma způsoby najednou, pokud jsou dodavatelé serverů různí a na některých modelech chybí informace o sériovém čísle.
Na základě získaných informací se namontují síťové složky z instalačního serveru a načte se vše potřebné (utility, firmwary a další).
Jaké utility a jak konfigurovat server?
Uvedu utility pro Linux pro některé výrobce. Všechny utility jsou k dispozici na oficiálních stránkách dodavatelů.

S firmwary, myslím, je vše jasné. Obvykle jsou dodávány ve formě zabalených spustitelných souborů. Spustitelný soubor řídí proces aktualizace firmwaru a hlásí kód návratu.
BIOS a IPMI se obvykle konfigurují prostřednictvím šablon. Pokud je to nutné, lze šablonu upravit před samotným načtením.
RAID utility některých dodavatelů mohou také nastavovat podle šablony. Pokud tomu tak není, budete muset napsat skript pro nastavení.
Postup nastavení RAID je většinou následující:
- Žádáme o aktuální konfiguraci.
- Pokud již existují logické svazky – odstraníme je.
- Podíváme se, jaké fyzické disky jsou přítomny a kolik jich je.
- Vytvoříme nový logický svazek. Přerušíme proces v případě chyby.
Jak získat nastavení pro konkrétní server?
Předpokládejme, že nastavení všech serverů bude uloženo na instalačním serveru. V takovém případě, abychom odpověděli na naši otázku, musíme nejprve vyřešit, jakým způsobem předávat nastavení na instalační server.
Na začátku lze bez problémů použít textové soubory. (V budoucnu lze použít textový soubor jako záložní způsob předávání nastavení).
Můžeme sdílet textový soubor na instalačním serveru. A přidat jeho připojení do skriptu mount.sh.
Řádky budou například tohoto typu:
Tyto řádky budou předávány v souboru inženýrem z jeho pracovního stroje. A dále při nastavení serveru budou parametry pro konkrétní server přečteny ze souboru.
Ale v budoucnu bychom měli používat databázi pro ukládání nastavení, stavů a záznamů o instalacích serverů.
Samozřejmě, nebude možné obejít se bez databáze, a bude třeba vytvořit klientskou část, pomocí které budou předávány nastavení do databáze. Realizace je složitější ve srovnání s textovým souborem, ale ve skutečnosti to není tak těžké, jak se zdá. Minimální verzi klienta, který bude jednoduše předávat data do databáze, je možné napsat na vlastní pěst. A v budoucnu lze klientskou aplikaci dále vylepšovat ve volném režimu (reporty, tisk štítků, odesílání oznámení a další, co nás napadne).
Při určitém dotazu do databáze a uvedení sériového čísla serveru získáme potřebné parametry pro nastavení serveru.
Navíc nebudeme muset vymýšlet zámky pro současný přístup, jako je tomu v případě textového souboru.
Žurnál nastavení můžeme zapisovat ve všech fázích do databáze a proces instalace řídit prostřednictvím událostí a vlajek fází přípravy.
Nyní víme, jak:
- načíst server přes PXE;
- předat řízení našemu skriptu;
- identifikovat server, který má být připraven, podle sériového čísla;
- konfigurovat server pomocí odpovídajících utilit;
- předávat nastavení do databáze instalačního serveru pomocí klientské části.
Zjistili jsme, jakým způsobem:
- instalovaný server získává potřebná nastavení z databáze;
- celý pokrok přípravy je zaznamenáván v databázi (logy, události, vlajky fází).
Jaké jsou různé typy instalovatelného softwaru? Jak nainstalovat hypervisor, zkopírovat VM a všechno to nastavit?
V případě nasazení obrazu souborového systému (linux) na hardware je to celkem jednoduché:
- Po nastavení všech komponentů serveru nasadíme obraz.
- Nainstalujeme bootloader grub.
- Provádíme chroot a nastavujeme vše potřebné.
Jak předat řízení instalátoru OS (na příkladu ESXi).
- Organizujeme předání řízení z našeho skriptu instalátoru hypervisoru pomocí souboru odpovědí (kickstart):
- Odstraňujeme aktuální oddíly na disku.
- Vytváříme oddíl o velikosti 500MB.
- Oz označujeme jako spouštěcí.
- Formátujeme na FAT32.
- Kopírujeme na něj do kořene instalační soubory ESXi.
- Instalujeme syslinux.
- Kopírujeme syslinux.cfg do /syslinux/
default esxi
prompt 1
timeout 50
label esxi
kernel mboot.c32
append -c boot.cfg- Kopírujeme mboot.c32 do /syslinux.
- V boot.cfg by mělo být kernelopt=ks=ftp:///ks_esxi.cfg
- Restartujeme server.
Po restartování serveru se z jeho pevného disku spustí instalátor ESXi. Všechny potřebné instalační soubory se načtou do paměti a poté začne instalace ESXi podle uvedeného souboru odpovědí.
Zde uvedu několik řádků ze souboru odpovědí ks_esxi.cfg:
%firstboot --interpreter=busybox
…
# získejte sériové číslo
SYSSN=$(esxcli hardware platform get | grep Serial | awk -F " " '{print $3}')
# získejte IP
IPADDRT=$(esxcli network ip interface ipv4 get | grep vmk0 | awk -F " " '{print $2}')
LAST_OCTET=$(echo $IPADDRT | awk -F'.' '{print $4}')
# připojte NFS instalační server
esxcli storage nfs add -H is -s /srv/nfs_share -v nfsshare1
# kopírujte dočasné nastavovací soubory ssh pro použití ssh klienta
mv /etc/ssh /etc/ssh.tmp
cp -R /vmfs/volumes/nfsshare1/ssh /etc/
chmod go-r /etc/ssh/ssh_host_rsa_key
# kopírujte ovftool pro nasazení VM nyní, může se hodit i později
cp -R /vmfs/volumes/nfsshare1/ovftool /vmfs/volumes/datastore1/
# nasazení 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
# získat řádek s nastavením našeho serveru
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
...
# generujeme skript pro nastavení sítě
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
# nastavíme parametr guestinfo.esxihost.id, uvedeme do něj sériové číslo
echo "guestinfo.esxihost.id = "$SYSSN"" >> /vmfs/volumes/datastore1/VM1/VM1.vmx
echo "guestinfo.esxihost.id = "$SYSSN"" >> /vmfs/volumes/datastore1/VM2/VM2.vmx
...
# aktualizujeme informace v databázi
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 ...""
# vrátíme nastavení SSH
rm -rf /etc/ssh
mv /etc/ssh.tmp /etc/ssh
# nastavujeme síť a restartujeme
esxcli system hostname set --fqdn=esx-${G_NICK}.x5.ru
/vmfs/volumes/datastore1/netconf.sh
reboot
V této fázi je hypervizor nainstalován a nakonfigurován, virtuální stroje byly zkopírovány.
Jak nyní nakonfigurovat virtuální stroje?
Trochu jsme podváděli: během instalace jsme nastavili parametr guestinfo.esxihost.id = "$SYSSN" v souboru VM1.vmx, uvedli jsme v něm sériové číslo fyzického serveru.
Nyní po spuštění může virtuální stroj (s nainstalovaným balíčkem vmware-tools) přistupovat k tomuto parametru:
ESXI_SN=$(vmtoolsd --cmd "info-get guestinfo.esxihost.id")To znamená, že VM se dokáže identifikovat (zná sériové číslo fyzického hostitele), provede dotaz do databáze instalačního serveru a získá potřebné parametry pro konfiguraci. To vše je zabaleno do skriptu, který by měl být automaticky spuštěn při startu guestos vm (ale pouze jednou: RunOnce).
Nyní víme, jak:
- načíst server přes PXE;
- předat řízení našemu skriptu;
- identifikovat server, který má být připraven, podle sériového čísla;
- konfigurovat server pomocí příslušných nástrojů;
- předávat nastavení do databáze instalačního serveru prostřednictvím klientské části;
- nastavovat různé typy softwaru, včetně nasazení hypervizoru ESXi a konfigurace virtuálních strojů (a to vše automaticky).
Zjistili jsme, jakým způsobem:
- instalovaný server získává potřebná nastavení z databáze;
- celý pokrok přípravy je zaznamenáván v databázi (logy, události, vlajky fází).
Výsledek:
Domnívám se, že jedinečnost tohoto řešení spočívá v flexibilitě, jednoduchosti, možnostech a univerzálnosti.
Prosím, napište do komentářů, co si myslíte.
Zdroj: habr.com
