Requisitos#
- Máquina Linux (estou usando o WSL rodando Ubuntu 24.04 neste exemplo)
- ISO do ESXi 8.0U3 (deve funcionar em versões mais antigas, mas alguns parâmetros podem ser diferentes)
Objetivos principais#
- Subir um servidor HTTP temporário que você possa usar em campo para implantar ESXi em massa
- Criar uma ISO personalizada do ESXi, com o boot.cfg editado para ler o ks.cfg de um servidor HTTP
- Explicar a lógica por trás dos meus scripts
A ISO personalizada#
Editar o BOOT.CFG#
Baixe a ISO mais recente do ESXi no portal da Broadcom aqui
Monte essa ISO no seu sistema e copie o conteúdo dela para um diretório dentro da sua máquina Linux (no meu caso, /home/novello/ESXi8/)
Com esses arquivos em um diretório, é hora de editar o arquivo BOOT.CFG, responsável por indicar onde está o arquivo kickstart
vi /home/novello/ESXi8/EFI/BOOT/BOOT.CFGe
vi /home/novello/ESXi8/BOOT.CFG- Linhas editadas:
timeout: Removi o tempo de espera da tela de abertura para pular a tela de “carregando”.kernelopt: Adicionei o caminho do arquivoks.cfghospedado no servidor web.
bootstate=0
title=Loading ESXi installer
timeout=0 # Here I removed the timeout to not show the "loading" screen
prefix=
kernel=/b.b00
kernelopt=runweasel ks=http://192.168.100.32:8000/ks.cfg # Here I added the ks.cfg file to the boot options, loaded from a web server
modules=/jumpstrt.gz --- /useropts.gz --- /features.gz --- /k.b00 --- /uc_intel.b00 --- /uc_amd.b00 --- /uc_hygon.b00 --- /procfs.b00 --- /vmx.v00 --- /vim.v00 --- /tpm.v00 --- /sb.v00 --- /s.v00 --- /atlantic.v00 --- /bcm_mpi3.v00 --- /bnxtnet.v00 --- /bnxtroce.v00 --- /brcmfcoe.v00 --- /cndi_igc.v00 --- /dwi2c.v00 --- /elxiscsi.v00 --- /elxnet.v00 --- /i40en.v00 --- /iavmd.v00 --- /icen.v00 --- /igbn.v00 --- /intelgpi.v00 --- /ionic_cl.v00 --- /ionic_en.v00 --- /irdman.v00 --- /iser.v00 --- /ixgben.v00 --- /lpfc.v00 --- /lpnic.v00 --- /lsi_mr3.v00 --- /lsi_msgp.v00 --- /lsi_msgp.v01 --- /lsi_msgp.v02 --- /mtip32xx.v00 --- /ne1000.v00 --- /nenic.v00 --- /nfnic.v00 --- /nhpsa.v00 --- /nipmi.v00 --- /nmlx5_cc.v00 --- /nmlx5_co.v00 --- /nmlx5_rd.v00 --- /ntg3.v00 --- /nvme_pci.v00 --- /nvmerdma.v00 --- /nvmetcp.v00 --- /nvmxnet3.v00 --- /nvmxnet3.v01 --- /pvscsi.v00 --- /qcnic.v00 --- /qedentv.v00 --- /qedrntv.v00 --- /qfle3.v00 --- /qfle3f.v00 --- /qfle3i.v00 --- /qflge.v00 --- /rdmahl.v00 --- /rste.v00 --- /sfvmk.v00 --- /smartpqi.v00 --- /vmkata.v00 --- /vmksdhci.v00 --- /vmkusb.v00 --- /vmw_ahci.v00 --- /bmcal.v00 --- /clusters.v00 --- /crx.v00 --- /drivervm.v00 --- /elx_esx_.v00 --- /btldr.v00 --- /dvfilter.v00 --- /esx_ui.v00 --- /esxupdt.v00 --- /tpmesxup.v00 --- /weaselin.v00 --- /esxio_co.v00 --- /infravis.v00 --- /loadesx.v00 --- /lsuv2_hp.v00 --- /lsuv2_in.v00 --- /lsuv2_ls.v00 --- /lsuv2_nv.v00 --- /lsuv2_oe.v00 --- /lsuv2_oe.v01 --- /lsuv2_sm.v00 --- /native_m.v00 --- /qlnative.v00 --- /trx.v00 --- /vcls_pod.v00 --- /vdfs.v00 --- /vds_vsip.v00 --- /vmware_e.v00 --- /hbrsrv.v00 --- /vsan.v00 --- /vsanheal.v00 --- /vsanmgmt.v00 --- /tools.t00 --- /xorg.v00 --- /gc.v00 --- /imgdb.tgz --- /basemisc.tgz --- /resvibs.tgz --- /esxiodpt.tgz --- /imgpayld.tgz
build=8.0.3-0.0.24022510
updated=0Compilar os novos arquivos em uma nova ISO personalizada#
É aqui que a mágica acontece: como compilamos todos aqueles arquivos extraídos em uma nova .ISO personalizada? Simples!
Parâmetros que você precisa alterar:
-o: Caminho/nome do arquivo que você quer salvar. Neste exemplo,/home/novello/ESXi8U3_custom.iso- O caminho onde a ISO foi extraída, no meu caso
/home/novello/ESXi8
genisoimage -relaxed-filenames -J -R -o /home/novello/ESXi8U3_custom.iso -b ISOLINUX.BIN -c BOOT.CAT -no-emul-boot -boot-load-size 4 -boot-info-table -eltorito-alt-boot -e EFIBOOT.IMG -no-emul-boot /home/novello/ESXi8ks.cfg (onde a mágica realmente acontece)#
- Ok, então no BOOT.CFG eu informei que, quando o host iniciar, ele deve ler um arquivo kickstart e usar a lógica dele para começar a configurar o ESXi.
Objetivos principais do ks.cfg#
- Carregar a instalação do ESXi e aceitar o EULA
- Definir a senha do root
- Obter o IP inicial usando a vmnic0 e DHCP
- Habilitar o SSH e o shell Bash
- Executar um script Python que vai configurar o IP definitivo e o hostname no host
vmaccepteula
rootpw VMware123!
install --firstdisk --overwritevmfs
network --bootproto=dhcp --device=vmnic0
reboot
%firstboot --interpreter=busybox
# Wait for the network to start
sleep 5
# Enable SSH and ESXi Shell
vim-cmd hostsvc/enable_ssh
vim-cmd hostsvc/start_ssh
vim-cmd hostsvc/enable_esx_shell
vim-cmd hostsvc/start_esx_shell
# Suppress ESXi Shell warning
esxcli system settings advanced set -o /UserVars/SuppressShellWarning -i 1
# Adjust the time zone
cp /usr/share/zoneinfo/America/Sao_Paulo /etc/localtime
# Download the host_config.py script and macs.csv file
wget http://192.168.100.32:8000/host_config.py -O /tmp/host_config.py
wget http://192.168.100.32:8000/macs.csv -O /tmp/macs.csv
# Make the script executable
# (Note: The script is already executable in the original code, but this is a good practice)
chmod u+x /tmp/host_config.py
# Run the host_config.py script
/bin/python3 /tmp/host_config.pyObjetivos principais do host_config.py#
- O Python lê o macs.csv
- Com base no endereço MAC da vmnic0, ele determina qual IP/máscara/gateway/VLAN/hostname será configurado no vmk0 (gerenciamento)
import os
import csv
import subprocess
CSVPATH = "/tmp/macs.csv" # Path to the CSV file
# Get the MAC address of the host interfaces
MAC = subprocess.check_output(
"esxcli network ip interface list | grep 'MAC Address' | awk '{print $3}'",
shell=True
)
MACADDR = MAC.split()
print("MACs found:")
print(MACADDR)
# Read the CSV file and find the matching MAC address
with open(CSVPATH, 'r') as csvFile:
csvReader = csv.reader(csvFile)
next(csvReader) # Skip the header row
for csvRow in csvReader:
# csvRow format: hostname,mac,ip,netmask,gateway,vlan
if MACADDR[0].decode('utf-8').lower() == csvRow[1].lower():
hostname = csvRow[0]
ip = csvRow[2]
netmask = csvRow[3]
gateway = csvRow[4]
vlan = csvRow[5]
print(f"Configuring host {hostname} with IP {ip}")
os.system(f"esxcli system hostname set --fqdn={hostname}")
os.system(f"esxcli network ip interface ipv4 set --interface-name=vmk0 --ipv4={ip} --netmask={netmask} --type=static")
os.system(f"esxcfg-route {gateway}")
os.system(f"esxcfg-vswitch -p 'Management Network' -v {vlan} vSwitch0")Como é o macs.csv
hostname,mac,ip,netmask,gateway,vlan esxi01,00:50:56:11:22:33,10.1.99.101,255.255.255.0,10.1.99.1,99 esxi02,00:50:56:44:55:66,10.1.99.102,255.255.255.0,10.1.99.1,99
Subir o servidor HTTP#
- Vou usar a mesma instância do WSL que usei para compilar a ISO como servidor HTTP
- Criei uma pasta separada que vai conter
ks.cfg,macs.csvehost_config.py
python3 -m http.server -d /home/novello/http- No seu navegador, acesse
http://<IP_da_instância_WSL>:8000; você deve ver algo parecido com

E é só isso: estamos prontos para iniciar a instalação do ESXi, que deve configurar o básico para nós automaticamente.
Instalado#
- Para fins de teste, criei uma VM no VMware Workstation e personalizei o endereço MAC para corresponder ao
esxi02do nossomacs.csv

Referências#
Documentação da VMware sobre o ks.cfg

