您好,我是 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