Approvisionnement Bare-Metal à faire soi-même ou préparation automatique des serveurs à partir de zéro

Bonjour, je m'appelle Denis et un de mes domaines d'activité est le développement de solutions d'infrastructure chez X5. Aujourd'hui, j'aimerais partager avec vous comment déployer un système de préparation automatique de serveur basé sur des outils accessibles au public. C'est à mon avis une solution intéressante, simple et flexible.

Approvisionnement Bare-Metal à faire soi-même ou préparation automatique des serveurs à partir de zéro

Par préparation, nous entendons : transformer un nouveau serveur prêt à l'emploi en un serveur entièrement configuré avec système d'exploitation. Linux ou avec l'hyperviseur ESXi (le déploiement de serveurs Windows n'est pas abordé dans cet article).

Termes:

  • serveurs – serveurs qui doivent être configurés.
  • Le serveur d'installation est le serveur principal qui assure l'ensemble du processus de préparation sur le réseau.

Pourquoi l’automatisation est-elle nécessaire ?

Disons qu’il y a une tâche : préparer massivement les serveurs à partir de zéro, au maximum – 30 par jour. Des serveurs de différents fabricants et modèles, différents systèmes d'exploitation peuvent y être installés et peuvent ou non disposer d'un hyperviseur.

Quelles opérations sont incluses dans le processus de configuration (sans automatisation) :

  • connectez un clavier, une souris, un moniteur au serveur ;
  • configurer le BIOS, RAID, IPMI ;
  • mettre à jour le micrologiciel des composants ;
  • déployer une image du système de fichiers (ou installer un hyperviseur et copier des machines virtuelles) ;

Note. Alternativement, le déploiement du système d'exploitation est possible via l'installation avec un fichier de réponse automatique. Mais cela ne sera pas abordé dans l'article. Même si vous verrez ci-dessous que l’ajout de cette fonctionnalité n’est pas difficile.

  • configurer les paramètres du système d'exploitation (nom d'hôte, IP, etc.).

Avec cette approche, les mêmes paramètres sont effectués séquentiellement sur chaque serveur. L'efficacité d'un tel travail est très faible.

L’essence de l’automatisation est d’éliminer la participation humaine du processus de préparation du serveur. Autant que possible.

L'automatisation réduit les temps d'arrêt entre les opérations et permet de provisionner plusieurs serveurs simultanément. La probabilité d’erreurs dues à des facteurs humains est également considérablement réduite.

Approvisionnement Bare-Metal à faire soi-même ou préparation automatique des serveurs à partir de zéro

Comment les serveurs sont-ils automatiquement configurés ?

Analysons toutes les étapes en détail.

Vous disposez d'un serveur Linux que vous utilisez comme serveur d'installation PXE. Des services y sont installés et configurés : DHCP, TFTP.

Nous démarrons donc le serveur (qui doit être configuré) via PXE. Rappelons comment cela fonctionne :

  • Le démarrage réseau est sélectionné sur le serveur.
  • Le serveur charge le PXE-ROM de la carte réseau et contacte le serveur d'installation via DHCP pour obtenir une adresse réseau.
  • Le serveur d'installation DHCP délivre une adresse, ainsi que des instructions pour un téléchargement ultérieur via PXE.
  • Le serveur charge le chargeur de démarrage réseau à partir du serveur d'installation via PXE, le chargement ultérieur s'effectue conformément au fichier de configuration PXE.
  • Le démarrage s'effectue en fonction des paramètres reçus (noyau, initramfs, points de montage, image squashfs, etc.).

Note. L'article décrit le démarrage via PXE via le mode BIOS. Actuellement, les fabricants implémentent activement le mode de démarrage UEFI. Pour le PXE, la différence se fera dans la configuration du serveur DHCP et la présence d'un bootloader supplémentaire.

Regardons un exemple de configuration de serveur PXE (menu pxelinux).

Fichier 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 // переход на следующее меню

Fichier 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=”…”

Le noyau et initramfs à ce stade sont une image Linux intermédiaire, à l'aide de laquelle la préparation et la configuration principales du serveur auront lieu.

Comme vous pouvez le constater, le chargeur de démarrage transmet de nombreux paramètres au noyau. Certains de ces paramètres sont utilisés par le noyau lui-même. Et nous pouvons en utiliser pour nos propres besoins. Cela sera discuté plus tard, mais pour l'instant, vous pouvez simplement vous rappeler que tous les paramètres transmis seront disponibles dans l'image Linux intermédiaire via /proc/cmdline.

Où puis-je les obtenir, noyau et initramfs ?
Comme base, vous pouvez choisir n'importe quelle distribution Linux. Ce à quoi nous prêtons attention lors du choix :

  • l'image de démarrage doit être universelle (disponibilité des pilotes, possibilité d'installer des utilitaires supplémentaires) ;
  • Très probablement, vous devrez personnaliser les initramfs.

Comment cela se fait-il dans notre solution pour X5 ? Comme base, nous avons choisi CentOS 7. Essayons l'astuce suivante : préparez la future structure de l'image, placez-la dans une archive et créez un initramfs, à l'intérieur duquel se trouvera notre archive de système de fichiers. Lors du chargement de l'image, l'archive sera développée dans la partition tmpfs créée. De cette façon, nous obtiendrons une image Linux live minimale mais complète avec tous les utilitaires nécessaires, composée de seulement deux fichiers : vmkernel et 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

Nous avons donc spécifié le noyau et les initramfs qui doivent être chargés. Du coup, à ce stade, en chargeant l'image Linux intermédiaire via PXE, nous recevrons la console de l'OS.

Génial, mais nous devons maintenant transférer le contrôle à notre « automatisation ».

Cela peut être fait comme ça.

Supposons qu'après avoir chargé l'image, nous prévoyons de transférer le contrôle au script mount.sh.
Incluons le script mount.sh dans l'exécution automatique. Pour ce faire, vous devrez modifier les initramfs :

  • décompressez initramfs (si nous utilisons l'option initramfs ci-dessus, cela n'est pas obligatoire)
  • inclure du code au démarrage qui analysera les paramètres transmis via /proc/cmdline et transférera davantage le contrôle ;
  • emballer les initramfs.

Note. Dans le cas du toolkit X5, le contrôle du chargement est transféré au script /opt/x5/toolkit/bin/hook.sh с помощью override.conf в getty tty1 (ExecStart=…)

Ainsi, l'image est chargée, dans laquelle le script mount.sh démarre lors de l'exécution automatique. Ensuite, le script mount.sh analyse les paramètres transmis (script_cmd=) lors de l'exécution et lance le programme/script nécessaire.

boîte à outils d'étiquetage-auto
noyau...
ajouter...nfs_toolkit_script=scripts/mount.sh script_cmd=master-install.sh

boîte à outils d'étiquetage-coquille
noyau...
ajouter...nfs_toolkit_script=scripts/mount.sh script_cmd=/bin/bash

Approvisionnement Bare-Metal à faire soi-même ou préparation automatique des serveurs à partir de zéro

Ici à gauche se trouve le menu PXE, à droite le schéma de transfert de contrôle.

Nous avons compris le transfert de contrôle. Selon le choix du menu PXE, soit le script d'auto-configuration, soit la console de débogage est lancé.

Dans le cas d'une configuration automatique, les répertoires nécessaires sont montés depuis le serveur d'installation, qui contiennent :

  • des scénarios ;
  • modèles BIOS/UEFI enregistrés pour divers serveurs ;
  • micrologiciel ;
  • utilitaires de serveur ;
  • journaux

Ensuite, le script mount.sh transfère le contrôle au script master-install.sh depuis le répertoire du script.

L'arborescence des scripts (l'ordre dans lequel ils sont lancés) ressemble à ceci :

  • installation principale
  • sharefunctions (fonctions partagées)
  • info (sortie d'informations)
  • modèles (définition des paramètres d'installation en fonction du modèle de serveur)
  • prepare_utils (installation des utilitaires nécessaires)
  • fwupdate (mise à jour du micrologiciel)
  • diag (diagnostic élémentaire)
  • biosconf (paramètres BIOS/UEFI)
  • clockfix (réglage de l'heure sur la carte mère)
  • srmconf (configuration de l'interface de l'interface distante)
  • raidconf (configuration des volumes logiques)

un des:

  • préinstallation (transfert du contrôle au programme d'installation du système d'exploitation ou de l'hyperviseur, tel qu'ESXi)
  • installation fusionnée (démarrage immédiat du déballage de l'image)

Maintenant nous savons :

  • comment démarrer un serveur via PXE ;
  • comment transférer le contrôle à votre propre script.


Nous allons continuer. Les questions suivantes sont devenues pertinentes :

  • Comment identifier le serveur que nous préparons ?
  • Quels utilitaires et comment configurer le serveur ?
  • Comment obtenir les paramètres d'un serveur spécifique ?

Comment identifier le serveur que nous préparons ?

C'est simple - DMI :

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

Tout ce dont vous avez besoin se trouve ici : fournisseur, modèle, numéro de série. Si vous n'êtes pas sûr que ces informations soient présentes sur tous les serveurs, vous pouvez les identifier grâce à leur adresse MAC. Ou dans les deux sens en même temps, si les fournisseurs de serveurs sont différents et que sur certains modèles, il n'y a tout simplement aucune information sur le numéro de série.

Sur la base des informations reçues, les dossiers réseau sont montés depuis le serveur d'installation et tout le nécessaire est chargé (utilitaires, firmware, etc.).

Quels utilitaires et comment configurer le serveur ?

Je fournirai des utilitaires pour Linux pour certains fabricants. Tous les utilitaires sont disponibles sur les sites officiels des fournisseurs.

Approvisionnement Bare-Metal à faire soi-même ou préparation automatique des serveurs à partir de zéro

Avec le firmware, je pense que tout est clair. Ils se présentent généralement sous la forme de fichiers exécutables packagés. Le fichier exécutable contrôle le processus de mise à jour du micrologiciel et signale le code retour.

Le BIOS et l'IPMI sont généralement configurés via des modèles. Si nécessaire, le modèle peut être modifié avant le téléchargement.

Les utilitaires RAID de certains fournisseurs peuvent également être configurés à l'aide d'un modèle. Si ce n’est pas le cas, vous devrez alors écrire un script de configuration.

La procédure de mise en place du RAID est le plus souvent la suivante :

  • Nous demandons la configuration actuelle.
  • S'il existe déjà des tableaux logiques, nous les effaçons.
  • Regardons quels disques physiques sont présents et combien il y en a.
  • Créez un nouveau tableau logique. Nous interrompons le processus en cas d'erreur.

Comment obtenir les paramètres d'un serveur spécifique ?

Supposons que les paramètres de tous les serveurs seront stockés sur le serveur d'installation. Dans ce cas, pour répondre à notre question, nous devons d'abord décider comment transférer les paramètres vers le serveur d'installation.

Au début, vous pouvez vous débrouiller avec des fichiers texte. (À l'avenir, vous souhaiterez peut-être utiliser un fichier texte comme méthode de secours pour transférer les paramètres.)

Vous pouvez « partager » un fichier texte sur le serveur d'installation. Et ajoutez son montage au script mount.sh.

Les lignes ressembleront par exemple à ceci :

<numéro de série> <nom d'hôte> <sous-réseau>

Ces lignes seront transférées au dossier par l'ingénieur depuis sa machine de travail. Et puis, lors de la configuration d'un serveur, les paramètres d'un serveur spécifique seront lus à partir du fichier.

Mais, à long terme, il est préférable d'utiliser une base de données pour stocker les paramètres, les états et les journaux des installations du serveur.

Bien entendu, une base de données à elle seule ne suffit pas et vous devrez créer une partie client à l'aide de laquelle les paramètres seront transférés vers la base de données. C'est plus difficile à mettre en œuvre qu'un fichier texte, mais en réalité, tout n'est pas aussi difficile qu'il y paraît. Il est tout à fait possible d’écrire une version minimale d’un client qui transférera simplement vous-même les données vers la base de données. Et à l'avenir, il sera possible d'améliorer le programme client en mode libre (rapports, impression d'étiquettes, envoi de notifications, etc. qui me viennent à l'esprit).

En faisant une requête spécifique à la base de données et en précisant le numéro de série du serveur, nous recevrons les paramètres nécessaires à la configuration du serveur.

De plus, nous n'aurons pas besoin de prévoir des verrous pour un accès simultané, comme c'est le cas avec un fichier texte.

Nous pouvons écrire le journal de configuration dans la base de données à toutes les étapes et contrôler le processus d'installation via des événements et des indicateurs des étapes de préparation.

Nous savons maintenant comment :

  • démarrer le serveur via PXE ;
  • transférer le contrôle à notre script ;
  • identifier le serveur qui doit être préparé par son numéro de série ;
  • configurer le serveur à l'aide des utilitaires appropriés ;
  • transférer les paramètres vers la base de données du serveur d'installation à l'aide de la partie client.

Nous avons découvert comment :

  • le serveur installé reçoit les paramètres nécessaires de la base de données ;
  • tous les progrès de la préparation sont enregistrés dans la base de données (logs, événements, drapeaux d'étape).

Qu’en est-il des différents types de logiciels que vous installez ? Comment installer un hyperviseur, copier une VM et tout configurer ?

Dans le cas du déploiement d'une image de système de fichiers (linux) sur du matériel, tout est assez simple :

  • Après avoir configuré tous les composants du serveur, nous déployons l'image.
  • Installez le chargeur de démarrage grub.
  • Nous chrootons et configurons tout ce qui est nécessaire.

Comment transférer le contrôle au programme d'installation du système d'exploitation (en utilisant ESXi comme exemple).

  • Nous organisons le transfert de contrôle de notre script vers l'installateur de l'hyperviseur à l'aide du fichier de réponse automatique (kickstart) :
  • Nous supprimons les partitions actuelles sur le disque.
  • Créez une partition d'une taille de 500 Mo.
  • Nous le marquons comme bootable.
  • Formatez en FAT32.
  • Nous copions les fichiers d'installation d'ESXi à la racine.
  • Installation de Syslinux.
  • Copiez syslinux.cfg dans /syslinux/

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

  • Copiez mboot.c32 dans /syslinux.
  • Boot.cfg devrait avoir kernelopt=ks=ftp:// /ks_esxi.cfg
  • Nous redémarrons le serveur.

Après le redémarrage du serveur, le programme d'installation d'ESXi sera téléchargé à partir du disque dur du serveur. Tous les fichiers d'installation nécessaires seront chargés en mémoire, puis l'installation d'ESXi commencera, selon le fichier de réponse automatique spécifié.

Voici quelques lignes du fichier de réponse automatique 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

A ce stade, l'hyperviseur est installé et configuré, et les machines virtuelles sont copiées.

Comment configurer les machines virtuelles maintenant ?

Nous avons un peu triché : lors de l'installation, nous avons défini le paramètre guestinfo.esxihost.id = "$SYSSN" dans le fichier VM1.vmx et y avons indiqué le numéro de série du serveur physique.

Désormais, après le démarrage, la machine virtuelle (avec le package vmware-tools installé) peut accéder à ce paramètre :

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

Autrement dit, la VM pourra s'identifier (elle connaît le numéro de série de l'hôte physique), faire une requête à la base de données du serveur d'installation et recevoir les paramètres à configurer. Tout cela est compilé dans un script, qui devrait être lancé automatiquement au démarrage de guestos vm (mais une fois : RunOnce).

Nous savons maintenant comment :

  • démarrer le serveur via PXE ;
  • transférer le contrôle à notre script ;
  • identifier le serveur qui doit être préparé par son numéro de série ;
  • configurer le serveur à l'aide des utilitaires appropriés ;
  • transférer les paramètres vers la base de données du serveur d'installation à l'aide de la partie client ;
  • configurer différents types de logiciels, notamment le déploiement de l'hyperviseur esxi et la configuration des machines virtuelles (le tout automatiquement).

Nous avons découvert comment :

  • le serveur installé reçoit les paramètres nécessaires de la base de données ;
  • tous les progrès de la préparation sont enregistrés dans la base de données (logs, événements, drapeaux d'étape).


The bottom line:

Je crois que le caractère unique de cette solution réside dans sa flexibilité, sa simplicité, ses capacités et sa polyvalence.

Veuillez écrire dans les commentaires ce que vous en pensez.

Source: habr.com

Ajouter un commentaire