自己動手裸機配置,或從頭開始自動準備伺服器

您好,我是 Denis,我的活動領域之一是 X5 基礎設施解決方案的開發。 今天我想和大家分享如何基於公開的工具部署自動伺服器準備系統。 在我看來,這是一個有趣、簡單且靈活的解決方案。

自己動手裸機配置,或從頭開始自動準備伺服器

我們所說的準備是指:將開箱即用的新伺服器變成帶有作業系統的完全配置的伺服器。 Linux 或使用 ESXi 管理程式(本文不討論 Windows 伺服器的部署)。

條款:

  • 伺服器 – 需要設定的伺服器。
  • 安裝伺服器是透過網路提供整個準備過程的主伺服器。

為什麼需要自動化?

假設有一項任務:從頭開始大規模準備伺服器,最多時為每天 30 台。 不同製造商和型號的伺服器,可能安裝不同的作業系統,並且可能有或沒有虛擬機器管理程式。

設定過程中包含哪些操作(無自動化):

  • 將鍵盤、滑鼠、顯示器連接到伺服器;
  • 配置BIOS、RAID、IPMI;
  • 更新組件韌體;
  • 部署檔案系統映像(或安裝虛擬機器管理程式並複製虛擬機器);

筆記。 或者,可以透過使用自動回應檔案進行安裝來部署作業系統。 但本文不會討論這一點。 儘管您將在下面看到添加此功能並不困難。

  • 配置作業系統參數(主機名稱、IP 等)。

透過這種方法,在每台伺服器上順序執行相同的設定。 這樣的工作效率是很低的。

自動化的本質是在伺服器準備過程中消除人工參與。 越多越好。

自動化減少了操作之間的停機時間,並使同時配置多個伺服器成為可能。 由於人為因素造成錯誤的可能性也大大降低。

自己動手裸機配置,或從頭開始自動準備伺服器

伺服器如何自動配置?

我們來詳細分析一下各個階段。

您有一台用作 PXE 安裝伺服器的 Linux 伺服器。 在其上安裝和設定服務:DHCP、TFTP。

因此,我們透過 PXE 啟動伺服器(需要設定)。 讓我們記住它是如何運作的:

  • 伺服器上選擇網路啟動。
  • 伺服器載入網卡的PXE-ROM,並透過DHCP聯絡安裝伺服器取得網路位址。
  • DHCP 安裝伺服器發出位址以及透過 PXE 進一步下載的說明。
  • 伺服器透過 PXE 從安裝伺服器載入網路引導程序,並根據 PXE 設定檔進行進一步載入。
  • 引導根據接收到的參數(核心、initramfs、掛載點、squashfs 映像等)進行。

筆記。 本文介紹了透過 BIOS 模式透過 PXE 啟動。 目前,廠商正積極實施UEFI啟動模式。 對於 PXE,差異在於 DHCP 伺服器的配置和附加引導程式的存在。

讓我們來看看 PXE 伺服器配置的範例(pxelinux 選單)。

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

檔案 pxelinux.cfg/工具包:

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

此階段的核心和 initramfs 是中間 Linux 映像,伺服器的主要準備和配置將在其幫助下進行。

正如您所看到的,引導程式將許多參數傳遞給核心。 其中一些參數由核心本身使用。 我們可以將一些用於我們自己的目的。 這將在稍後討論,但現在您只需記住所有傳遞的參數都將透過 /proc/cmdline 在中間 Linux 映像中可用。

我在哪裡可以獲得內核和 initramfs?
作為基礎,您可以選擇任何 Linux 發行版。 我們在選擇時要注意什麼:

  • 啟動映像必須是通用的(驅動程式的可用性、安裝其他實用程式的能力);
  • 最有可能的是,您需要自訂 initramfs。

我們的 X5 解決方案是如何做到這一點的? 選擇CentOS 7作為基礎,讓我們嘗試以下技巧:準備未來的映像結構,將其打包成存檔並建立一個initramfs,其中將包含我們的檔案系統存檔。 載入映像時,存檔將擴展到建立的 tmpfs 分割區。 這樣,我們將獲得一個最小但功能齊全的實時 Linux 映像,其中包含所有必需的實用程序,僅包含兩個檔案:vmkernel 和 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

所以我們已經指定了應該載入的核心和initramfs。 因此,在這個階段,透過 PXE 載入中間 Linux 映像,我們將收到作業系統控制台。

太好了,但現在我們需要將控制權轉移給我們的「自動化」。

可以這樣做。

假設載入映像後,我們計劃將控制權轉移到 mount.sh 腳本。
讓我們將 mount.sh 腳本包含在自動運行中。 為此,您需要修改 initramfs:

  • 解壓縮 initramfs(如果我們使用上面的 initramfs 選項,則不需要)
  • 在啟動中包含程式碼,該程式碼將分析透過 /proc/cmdline 傳遞的參數並進一步轉移控制;
  • 打包 initramfs。

筆記。 對於 X5 工具包,載入控制權轉移到腳本 /opt/x5/toolkit/bin/hook.sh с помощью override.conf в getty tty1 (ExecStart=…)

因此,圖像已加載,其中 mount.sh 腳本在自動運行時啟動。 接下來,mount.sh 腳本在執行過程中分析傳遞的參數 (script_cmd=) 並啟動必要的程式/腳本。

標籤工具包-汽車
核心...
附加... nfs_toolkit_script=scripts/mount.sh script_cmd=master-install.sh

標籤工具包-
核心...
附加... nfs_toolkit_script=scripts/mount.sh script_cmd=/bin/bash

自己動手裸機配置,或從頭開始自動準備伺服器

這裡左邊是PXE選單,右邊是控制傳輸圖。

我們弄清楚了控制權的轉移。 根據 PXE 選單的選擇,啟動自動配置腳本或偵錯控制台。

在自動配置的情況下,將從安裝伺服器安裝必要的目錄,其中包含:

  • 腳本;
  • 保存各種伺服器的BIOS/UEFI範本;
  • 韌體;
  • 伺服器實用程式;
  • 紀錄

接下來,mount.sh 腳本將控制權從腳本目錄轉移到 master-install.sh 腳本。

腳本樹(它們啟動的順序)看起來像這樣:

  • 主安裝
  • sharefunctions(共享函數)
  • info(資訊輸出)
  • models(根據伺服器型號設定安裝參數)
  • prepare_utils(安裝必要的實用程式)
  • fwupdate(韌體更新)
  • diag(基本診斷)
  • biosconf(BIOS/UEFI 設定)
  • ClockFix(設定主機板上的時間)
  • srmconf(遠端介面介面配置)
  • raidconf(配置邏輯磁碟區)

之一:

  • 預先安裝(將控制權轉移給作業系統或虛擬機器管理程式安裝程序,例如 ESXi)
  • 合併安裝(立即開始解壓縮映像)

現在我們知道:

  • 如何透過 PXE 啟動伺服器;
  • 如何將控制權轉移到您自己的腳本。


我們繼續吧。 以下問題變得相關:

  • 如何識別我們準備的伺服器呢?
  • 有哪些實用程式以及如何配置伺服器?
  • 如何取得特定伺服器的設定?

如何識別我們準備的伺服器呢?

很簡單 - DMI:

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

您需要的一切都在這裡:供應商、型號、序號。 如果您不確定所有伺服器中是否都存在此訊息,您可以透過 MAC 位址來識別它們。 或者同時採用兩種方式,如果伺服器供應商不同且在某些型號上根本沒有有關序號的資訊。

根據收到的訊息,從安裝伺服器安裝網路資料夾並載入所需的所有內容(實用程式、韌體等)。

有哪些實用程式以及如何配置伺服器?

我將為一些製造商提供適用於 Linux 的實用程式。 所有實用程式都可以在供應商的官方網站上找到。

自己動手裸機配置,或從頭開始自動準備伺服器

有了固件,我想一切都清楚了。 它們通常以已打包的可執行檔的形式出現。 可執行檔案控制韌體更新過程並報告回傳代碼。

BIOS和IPMI通常透過模板進行配置。 如有必要,可以在下載之前對模板進行編輯。

某些供應商的 RAID 實用程式也可以使用範本進行設定。 如果不是這種情況,那麼您將必須編寫配置腳本。

設定 RAID 的過程通常如下:

  • 我們請求當前配置。
  • 如果已經存在邏輯數組,我們將其刪除。
  • 讓我們看看存在哪些實體磁碟以及有多少個。
  • 建立一個新的邏輯數組。 如果出現錯誤,我們會中斷該過程。

如何取得特定伺服器的設定?

假設所有伺服器的設定都將儲存在安裝伺服器上。 在這種情況下,要回答我們的問題,我們必須先決定如何將設定傳輸到安裝伺服器。

首先,您可以使用文字檔案。 (將來,您可能希望使用文字檔案作為傳輸設定的後備方法。)

您可以在安裝伺服器上「共用」文字檔案。 並將其掛載加入到 mount.sh 腳本中。

例如,這些行將如下所示:

<序號> <主機名稱> <子網路>

這些行將由工程師從他的工作機器傳輸到文件中。 然後,在設定伺服器時,將從檔案中讀取特定伺服器的參數。

但是,從長遠來看,最好使用資料庫來儲存伺服器安裝的設定、狀態和日誌。

當然,僅有資料庫是不夠的,您需要建立一個客戶端部分,借助該部分將設定傳輸到資料庫。 與文字檔案相比,這更難實現,但事實上,一切都不像看起來那麼困難。 很有可能編寫一個最小版本的客戶端,只需自己將資料傳輸到資料庫。 並且將來可以在免費模式下改進客戶端程式(想到的報告、列印標籤、發送通知等)。

透過向資料庫發出特定請求並指定伺服器序號,我們將收到配置伺服器所需的參數。

另外,我們不需要像文字檔案那樣為同時存取提供鎖。

我們可以將各個階段的設定日誌寫入資料庫,並透過準備階段的事件和標誌來控制安裝過程。

現在我們知道如何:

  • 透過 PXE 啟動伺服器;
  • 將控制權轉移給我們的腳本;
  • 透過序號識別需要準備的伺服器;
  • 使用適當的實用程式配置伺服器;
  • 使用客戶端部分將設定傳輸到安裝伺服器資料庫。

我們發現如何:

  • 安裝的伺服器從資料庫接收必要的設定;
  • 所有準備進度都記錄在資料庫中(日誌、事件、階段標誌)。

您安裝的不同類型的軟體怎麼樣? 如何安裝虛擬機器管理程式、複製虛擬機器並進行設定?

在將檔案系統映像(linux)部署到硬體的情況下,一切都非常簡單:

  • 設定完所有伺服器元件後,我們部署映像。
  • 安裝 grub 引導程式。
  • 我們 chroot 並配置所需的一切。

如何將控制權轉移給作業系統安裝程式(以 ESXi 為例)。

  • 我們使用自動回應檔案(kickstart)組織控制從腳本到虛擬機器管理程式安裝程式的轉移:
  • 我們刪除磁​​碟上的目前分割區。
  • 建立一個大小為 500MB 的分割區。
  • 我們將其標記為可啟動。
  • 格式化為 FAT32。
  • 我們將 ESXi 安裝檔複製到根目錄。
  • 安裝 syslinux。
  • 將 syslinux.cfg 複製到 /syslinux/

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

  • 將 mboot.c32 複製到 /syslinux。
  • Boot.cfg 應該有 kernelopt=ks=ftp:// /ks_esxi.cfg
  • 重新啟動伺服器。

伺服器重新啟動後,ESXi 安裝程式將從伺服器的硬碟下載。 所有必需的安裝程式檔案都會載入到記憶體中,然後根據指定的自動回應檔案開始 ESXi 安裝。

以下是自動回應文件 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

在此階段,將安裝和設定虛擬機器管理程序,並複製虛擬機器。

現在如何設定虛擬機器?

我們做了一點小作弊:在安裝過程中,我們在 VM1.vmx 檔案中設定了參數 guestinfo.esxihost.id = "$SYSSN" 並在其中指示了實體伺服器的序號。

現在,啟動後,虛擬機器(安裝了vmware-tools套件)就可以存取這個參數了:

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

也就是說,VM 將能夠識別自身(它知道實體主機的序號),向安裝伺服器資料庫發出請求並接收需要配置的參數。 這一切都被編譯成一個腳本,該腳本應該在 guestos vm 啟動時自動啟動(但一次:RunOnce)。

現在我們知道如何:

  • 透過 PXE 啟動伺服器;
  • 將控制權轉移給我們的腳本;
  • 透過序號識別需要準備的伺服器;
  • 使用適當的實用程式配置伺服器;
  • 使用客戶端部分將設定傳輸到安裝伺服器資料庫;
  • 配置各種類型的軟體,包括部署 esxi 管理程式和設定虛擬機器(全部自動)。

我們發現如何:

  • 安裝的伺服器從資料庫接收必要的設定;
  • 所有準備進度都記錄在資料庫中(日誌、事件、階段標誌)。


底線:

我相信這個解決方案的獨特之處在於它的靈活性、簡單性、功能和多功能性。

請在評論中寫下你的想法。

來源: www.habr.com

添加評論