Aprovisionamiento bare-metal hágalo usted mismo o preparación automática de servidores desde cero

Hola, soy Denis y una de mis áreas de actividad es el desarrollo de soluciones de infraestructura en X5. Hoy me gustaría compartir con ustedes cómo se puede implementar un sistema de preparación automática de servidores basado en herramientas disponibles públicamente. En mi opinión, esta es una solución interesante, sencilla y flexible.

Aprovisionamiento bare-metal hágalo usted mismo o preparación automática de servidores desde cero

Por preparación queremos decir: convertir un servidor nuevo listo para usar en un servidor completamente configurado con sistema operativo. Linux o con el hipervisor ESXi (la implementación de servidores Windows no se analiza en este artículo).

Condiciones:

  • servidores: servidores que deben configurarse.
  • El servidor de instalación es el servidor principal que proporciona todo el proceso de preparación a través de la red.

¿Por qué es necesaria la automatización?

Digamos que hay una tarea: preparar servidores masivamente desde cero, como máximo: 30 por día. Servidores de diferentes fabricantes y modelos, en ellos se pueden instalar diferentes sistemas operativos y pueden tener o no hipervisor.

Qué operaciones se incluyen en el proceso de configuración (sin automatización):

  • conecte un teclado, mouse, monitor al servidor;
  • configurar BIOS, RAID, IPMI;
  • actualizar el firmware de los componentes;
  • implementar una imagen del sistema de archivos (o instalar un hipervisor y copiar máquinas virtuales);

Nota. Alternativamente, la implementación del sistema operativo es posible mediante la instalación con un archivo de respuesta automática. Pero esto no se discutirá en el artículo. Aunque verás a continuación que añadir esta funcionalidad no es complicado.

  • configurar los parámetros del sistema operativo (nombre de host, IP, etc.).

Con este enfoque, las mismas configuraciones se realizan secuencialmente en cada servidor. La eficiencia de este trabajo es muy baja.

La esencia de la automatización es eliminar la participación humana del proceso de preparación del servidor. Cuanto más se pueda.

La automatización reduce el tiempo de inactividad entre operaciones y permite aprovisionar varios servidores simultáneamente. También se reduce considerablemente la probabilidad de errores debidos a factores humanos.

Aprovisionamiento bare-metal hágalo usted mismo o preparación automática de servidores desde cero

¿Cómo se configuran los servidores automáticamente?

Analicemos todas las etapas en detalle.

Tiene un servidor Linux que utiliza como servidor de instalación PXE. En él se instalan y configuran los servicios: DHCP, TFTP.

Entonces, iniciamos el servidor (que debe configurarse) a través de PXE. Recordemos cómo funciona:

  • El arranque de red está seleccionado en el servidor.
  • El servidor carga el PXE-ROM de la tarjeta de red y contacta con el servidor de instalación vía DHCP para obtener una dirección de red.
  • El servidor de instalación DHCP emite una dirección, así como instrucciones para realizar más descargas a través de PXE.
  • El servidor carga el gestor de arranque de red desde el servidor de instalación a través de PXE; la carga adicional se produce de acuerdo con el archivo de configuración de PXE.
  • El arranque se produce en función de los parámetros recibidos (kernel, initramfs, puntos de montaje, imagen de squashfs, etc.).

Nota. El artículo describe el arranque a través de PXE a través del modo BIOS. Actualmente, los fabricantes están implementando activamente el modo de arranque UEFI. Para PXE, la diferencia estará en la configuración del servidor DHCP y la presencia de un gestor de arranque adicional.

Veamos un ejemplo de configuración de un servidor PXE (menú pxelinux).

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

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

El kernel y initramfs en esta etapa son una imagen intermedia de Linux, con la ayuda de la cual se llevará a cabo la preparación y configuración principal del servidor.

Como puede ver, el gestor de arranque pasa muchos parámetros al kernel. Algunos de estos parámetros son utilizados por el propio núcleo. Y podemos usar algunos para nuestros propios fines. Esto se discutirá más adelante, pero por ahora puede recordar que todos los parámetros pasados ​​estarán disponibles en la imagen intermedia de Linux a través de /proc/cmdline.

¿Dónde puedo conseguirlos, kernel e initramfs?
Como base, puedes elegir cualquier distribución de Linux. A qué prestamos atención al elegir:

  • la imagen de arranque debe ser universal (disponibilidad de controladores, posibilidad de instalar utilidades adicionales);
  • Lo más probable es que necesites personalizar el archivo initramfs.

¿Cómo se hace esto en nuestra solución para X5? Se eligió como base CentOS 7. Probemos el siguiente truco: preparar la futura estructura de la imagen, empaquetarla en un archivo y crear un initramfs, dentro del cual estará nuestro archivo del sistema de archivos. Al cargar la imagen, el archivo se expandirá a la partición tmpfs creada. De esta manera obtendremos una imagen de Linux en vivo mínima pero completa con todas las utilidades necesarias, que consta de solo dos archivos: vmkernel e 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

Entonces hemos especificado el kernel y el initramfs que deben cargarse. Como resultado, en esta etapa, al cargar la imagen intermedia de Linux a través de PXE, recibiremos la consola del sistema operativo.

Genial, pero ahora necesitamos transferir el control a nuestra "automatización".

Se puede hacer así.

Supongamos que después de cargar la imagen planeamos transferir el control al script mount.sh.
Incluyamos el script mount.sh en ejecución automática. Para hacer esto necesitarás modificar initramfs:

  • descomprimir initramfs (si usamos la opción initramfs anterior, esto no es necesario)
  • incluir código en el inicio que analizará los parámetros pasados ​​a través de /proc/cmdline y transferirá el control aún más;
  • empaquetar initramfs.

Nota. En el caso del kit de herramientas X5, el control de carga se transfiere al script /opt/x5/toolkit/bin/hook.sh с помощью override.conf в getty tty1 (ExecStart=…)

Entonces, se carga la imagen, en la que el script mount.sh comienza en la ejecución automática. A continuación, el script mount.sh analiza los parámetros pasados ​​(script_cmd=) durante la ejecución y lanza el programa/script necesario.

kit de herramientas de etiquetas-auto
núcleo...
agregar...nfs_toolkit_script=scripts/mount.sh script_cmd=master-install.sh

kit de herramientas de etiquetas-shell
núcleo...
agregar...nfs_toolkit_script=scripts/mount.sh script_cmd=/bin/bash

Aprovisionamiento bare-metal hágalo usted mismo o preparación automática de servidores desde cero

Aquí a la izquierda está el menú PXE, a la derecha está el diagrama de transferencia de control.

Descubrimos la transferencia de control. Dependiendo de la elección del menú PXE, se inicia el script de configuración automática o la consola de depuración.

En el caso de configuración automática, desde el servidor de instalación se montan los directorios necesarios que contienen:

  • guiones;
  • plantillas BIOS/UEFI guardadas para varios servidores;
  • firmware;
  • utilidades de servidor;
  • registros

A continuación, el script mount.sh transfiere el control al script master-install.sh desde el directorio del script.

El árbol de secuencias de comandos (el orden en que se inician) se parece a esto:

  • instalación maestra
  • funciones compartidas (funciones compartidas)
  • info (salida de información)
  • modelos (configuración de parámetros de instalación según el modelo del servidor)
  • prepare_utils (instalación de utilidades necesarias)
  • fwupdate (actualización de firmware)
  • diag (diagnóstico elemental)
  • biosconf (configuración BIOS/UEFI)
  • clockfix (configurar la hora en la placa base)
  • srmconf (configuración de interfaz de interfaz remota)
  • raidconf (configuración de volúmenes lógicos)

uno de:

  • preinstalación (transfiriendo el control al sistema operativo o al instalador del hipervisor, como ESXi)
  • instalación fusionada (inicio inmediato de descomprimir la imagen)

Ahora sabemos:

  • cómo iniciar un servidor mediante PXE;
  • cómo transferir el control a su propio script.


Continuemos. Las siguientes preguntas se volvieron relevantes:

  • ¿Cómo identificar el servidor que estamos preparando?
  • ¿Qué utilidades y cómo configurar el servidor?
  • ¿Cómo obtener la configuración para un servidor específico?

¿Cómo identificar el servidor que estamos preparando?

Es simple - DMI:

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

Todo lo que necesita está aquí: proveedor, modelo, número de serie. Si no está seguro de que esta información esté presente en todos los servidores, puede identificarlos por su dirección MAC. O en ambos sentidos al mismo tiempo, si los proveedores del servidor son diferentes y en algunos modelos simplemente no hay información sobre el número de serie.

A partir de la información recibida se montan carpetas de red desde el servidor de instalación y se carga todo lo necesario (utilidades, firmware, etc.).

¿Qué utilidades y cómo configurar el servidor?

Proporcionaré utilidades para Linux para algunos fabricantes. Todas las utilidades están disponibles en los sitios web oficiales de los proveedores.

Aprovisionamiento bare-metal hágalo usted mismo o preparación automática de servidores desde cero

Con el firmware creo que todo está claro. Generalmente vienen en forma de archivos ejecutables empaquetados. El archivo ejecutable controla el proceso de actualización del firmware e informa el código de retorno.

BIOS e IPMI generalmente se configuran mediante plantillas. Si es necesario, la plantilla se puede editar antes de descargarla.

Las utilidades RAID de algunos proveedores también se pueden configurar mediante una plantilla. Si este no es el caso, deberá escribir un script de configuración.

El procedimiento para configurar RAID suele ser el siguiente:

  • Solicitamos la configuración actual.
  • Si ya existen matrices lógicas, las borramos.
  • Veamos qué discos físicos hay presentes y cuántos hay.
  • Cree una nueva matriz lógica. Interrumpimos el proceso en caso de error.

¿Cómo obtener la configuración para un servidor específico?

Supongamos que la configuración de todos los servidores se almacenará en el servidor de instalación. En este caso, para responder a nuestra pregunta, primero debemos decidir cómo transferir la configuración al servidor de instalación.

Al principio, puedes arreglártelas con archivos de texto. (En el futuro, es posible que desee utilizar un archivo de texto como método alternativo para transferir configuraciones).

Puede "compartir" un archivo de texto en el servidor de instalación. Y agregue su montaje al script mount.sh.

Las líneas, por ejemplo, se verán así:

<número de serie> <nombre de host> <subred>

Estas líneas serán trasladadas al fichero por el ingeniero desde su máquina de trabajo. Y luego, al configurar un servidor, los parámetros de un servidor específico se leerán del archivo.

Pero, a largo plazo, es mejor utilizar una base de datos para almacenar configuraciones, estados y registros de instalaciones del servidor.

Por supuesto, una base de datos por sí sola no es suficiente y será necesario crear una parte del cliente con la ayuda de la cual se transferirán las configuraciones a la base de datos. Esto es más difícil de implementar en comparación con un archivo de texto, pero en realidad no todo es tan complicado como parece. Es muy posible escribir una versión mínima de un cliente que simplemente transfiera datos a la base de datos usted mismo. Y en un futuro se podrá mejorar el programa cliente en modo gratuito (informes, impresión de etiquetas, envío de notificaciones, etc. que se nos ocurra).

Al realizar una solicitud específica a la base de datos y especificar el número de serie del servidor, recibiremos los parámetros necesarios para configurar el servidor.

Además, no necesitaremos crear bloqueos para el acceso simultáneo, como es el caso de un archivo de texto.

Podemos escribir el registro de configuración en la base de datos en todas las etapas y controlar el proceso de instalación a través de eventos e indicadores de las etapas de preparación.

Ahora sabemos cómo:

  • iniciar el servidor a través de PXE;
  • transferir el control a nuestro script;
  • identificar el servidor que necesita ser preparado por su número de serie;
  • configurar el servidor utilizando las utilidades adecuadas;
  • transfiera la configuración a la base de datos del servidor de instalación utilizando la parte del cliente.

Descubrimos cómo:

  • el servidor instalado recibe la configuración necesaria de la base de datos;
  • Todo el progreso de la preparación se registra en la base de datos (registros, eventos, indicadores de etapa).

¿Qué pasa con los diferentes tipos de software que instala? ¿Cómo instalar un hipervisor, copiar una VM y configurarlo todo?

En el caso de implementar una imagen del sistema de archivos (linux) en el hardware, todo es bastante sencillo:

  • Después de configurar todos los componentes del servidor, implementamos la imagen.
  • Instale el gestor de arranque grub.
  • Hacemos chroot y configuramos todo lo que sea necesario.

Cómo transferir el control al instalador del sistema operativo (usando ESXi como ejemplo).

  • Organizamos la transferencia de control desde nuestro script al instalador del hipervisor utilizando el archivo de respuesta automática (kickstart):
  • Eliminamos las particiones actuales del disco.
  • Cree una partición con un tamaño de 500 MB.
  • Lo marcamos como de arranque.
  • Formatee a FAT32.
  • Copiamos los archivos de instalación de ESXi a la raíz.
  • Instalando syslinux.
  • Copie syslinux.cfg a /syslinux/

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

  • Copie mboot.c32 a /syslinux.
  • Boot.cfg debería tener kernelopt=ks=ftp:// /ks_esxi.cfg
  • Reinicie el servidor.

Después de que el servidor se reinicie, el instalador de ESXi se descargará desde el disco duro del servidor. Todos los archivos de instalación necesarios se cargarán en la memoria y luego comenzará la instalación de ESXi, de acuerdo con el archivo de respuesta automática especificado.

Aquí hay algunas líneas del archivo de respuesta automática 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

En esta etapa, se instala y configura el hipervisor y se copian las máquinas virtuales.

¿Cómo configurar máquinas virtuales ahora?

Hicimos un poco de trampa: durante la instalación configuramos el parámetro guestinfo.esxihost.id = "$SYSSN" en el archivo VM1.vmx e indicamos en él el número de serie del servidor físico.

Ahora, después de iniciar, la máquina virtual (con el paquete vmware-tools instalado) puede acceder a este parámetro:

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

Es decir, la VM podrá identificarse (conoce el número de serie del host físico), realizar una solicitud a la base de datos del servidor de instalación y recibir los parámetros que deben configurarse. Todo esto está compilado en un script, que debería iniciarse automáticamente cuando se inicia guestos vm (pero una vez: RunOnce).

Ahora sabemos cómo:

  • iniciar el servidor a través de PXE;
  • transferir el control a nuestro script;
  • identificar el servidor que necesita ser preparado por su número de serie;
  • configurar el servidor utilizando las utilidades adecuadas;
  • transferir la configuración a la base de datos del servidor de instalación utilizando la parte del cliente;
  • Configure varios tipos de software, incluida la implementación del hipervisor esxi y la configuración de máquinas virtuales (todo automáticamente).

Descubrimos cómo:

  • el servidor instalado recibe la configuración necesaria de la base de datos;
  • Todo el progreso de la preparación se registra en la base de datos (registros, eventos, indicadores de etapa).


El resultado final:

Creo que la singularidad de esta solución radica en su flexibilidad, simplicidad, capacidades y versatilidad.

Por favor escribe en los comentarios lo que piensas.

Fuente: habr.com

Añadir un comentario