Mini automatyzacja mini klastra vSAN.

Zenon Matuszyk
22. kwietnia 2021
Reading time: 2 min
Mini automatyzacja mini klastra vSAN.
Automatyzacja jest wszechobecna, jak okiem sięgnąć. Chcemy sobie ułatwić życie, aby nie wykonywać jak małpa powtarzalnych dla nas czynności. Cały czas mówimy tutaj o automatyzacji w IT, rzecz jasna. Pozostałe elementy, takie jak jedzenie czy spanie możemy już wykonywać sami, ponieważ należą do bardziej przyjemnych czynności, które się powtarzają. Przynajmniej, jeżeli chodzi o mnie. Wracając do IT i wszechobecnej automatyzacji… Podjąłem się automatyzacji klastra VMware vSAN. Czemu, w jakim celu i co z tego wynikło? Przeczytajcie.

Wiemy, dlaczego automatyzujemy, chociaż czasem nie wiemy „czym” automatyzować. Mamy tak dużo możliwości, że czujemy się zagubieni. Chyba najczęstsze rozterki to te, czy wybrać płatne czy darmowe rozwiązania. Zainwestować czas, czy też pieniądze i niech ktoś inny się martwi, aby wszystko działało. Oba rozwiązania są dobre, wszystko zależy od naszych możliwości. Czasem niestety gotowe rozwiązania nie dają nam możliwości wykonania automatyzacji w taki sposób, jak tego oczekujemy. W takiej sytuacji musimy szyć sobie na miarę rozwiązanie, które nas będzie satysfakcjonowało.

Automatyzując uruchomienie klastrów VMware vSAN, napotkałem właśnie na kilka rzeczy, których nie mogłem przeskoczyć gotowymi skryptami czy rozwiązaniami.

 class=

Dlatego postanowiłem wziąć sprawy we własne ręce i napisać własny skrypt.

Tak… ja i skrypt… to dwa słowa, które nie występują w jednym zdaniu czy sformułowaniu. Pewnie dlatego, że uważam, iż producent oprogramowania powinien przewidzieć różne zastosowania danego produktu, a nie tylko jeden czy dwa scenariusze, które od siebie różnią się ilością dysków twardych. Ta naturalna potrzeba wynika z różnorodności naszych środowisk i to jest oczywiste. Ale jak wspomniałem wcześniej – nie wszystko jest takie różowe.

Pewnie ktoś może zapytać po co ta automatyzacja przy vSAN? Przecież można to wszystko „przeklikać”.

W pełni się zgodzę, ale gdy mamy do uruchomienia 40 małych klastrów vSAN to ustawienie wszystkiego może być wyzwaniem. Dodatkowo mogą pojawić się błędy podczas konfiguracji wynikające z czynnika ludzkiego. Wyzwaniem też staje się taka konfiguracja, gdy inny dział w firmie odpowiada za wdrożenie serwerów. W takiej sytuacji należy przygotować odpowiednio długą instrukcję, aby inne osoby były w stanie to zrobić.

Krok 1. Przygotowanie hostów ESXi.

Do tego możemy wykorzystać instalacje nienadzorowaną. Można to zrobić co najmniej na dwa sposoby, czyli przez uruchomienie odpowiedniego zasobu, gdzie będzie znajdował się plik Kickstart i podczas wystartowania serwera z ISO podania mu ścieżki do niego. Drugi to zmodyfikowanie pliku startowego w samym obrazie ISO. Wadą tego rozwiązania jest to, że przy 40 klastrach, gdzie są po 2 hosty musimy utworzyć sporo obrazów ISO.

Poniżej przedstawiam przykładowy plik, który działa z ESXi 7.

# Sample scripted installation file
#
# Accept the VMware End User License Agreement
vmaccepteula
# Set the root password for the DCUI and Tech Support Mode
rootpw Haslo@123
# Install on the first local disk available on machine
install --firstdisk=usb
# Set the network to static on the first network adapter
network --bootproto=static --device=vmnic0 --ip=192.168.1.10 --netmask=255.255.255.0 --gateway=192.168.1.1 --nameserver=192.168.1.51 --hostname=esxi-1.lab.inleo.pl
reboot --noeject
%firstboot --interpreter=busybox
esxcli network ip dns search add --domain=lab.inleo.pl
esxcli network vswitch standard uplink add --uplink-name=vmnic1 --vswitch-name=vSwitch0
esxcli network vswitch standard portgroup remove --portgroup-name="VM Network" --vswitch-name=vSwitch0
esxcli network ip set --ipv6-enabled=false
esxcli system module parameters set -m tcpip4 -p ipv6=0
echo "server 192.168.1.51" >> /etc/ntp.conf;
esxcfg-firewall -e ntpClient
/sbin/chkconfig ntpd on;
esxcli system settings advanced set -o /UserVars/HostClientCEIPOptIn -i 2
esxcli system maintenanceMode set -e false
esxcli system shutdown reboot -d 15 -r "rebooting after ESXi host configuration"

 

Przygotowanie tego pliku jest, jak widać proste, a konfiguracja czytelna. Oczywiście na tym etapie możemy dodać odpowiednie grupy na potrzeby maszyn wirtualnych czy konfiguracji fizycznych portów np. jak poniżej.

esxcli network vswitch standard add --vswitch-name=vSwitch1 --ports=24
esxcli network vswitch standard uplink add --uplink-name=vmnic4 --vswitch-name=vSwitch1
esxcli network vswitch standard uplink add --uplink-name=vmnic5 --vswitch-name=vSwitch1
esxcli network vswitch standard portgroup add --portgroup-name=ADMIN --vswitch-name=vSwitch1
esxcli network vswitch standard portgroup set -p ADMIN --vlan-id 213
esxcli network vswitch standard policy failover set --active-uplinks=vmnic4 --standby-uplinks=vmnic5 --vswitch-name=vSwitch1

 

Tutaj też konfiguracja jest bardzo prosta i intuicyjna. Plusem takiej konfiguracji hostów jest to, że po instalacji host jest gotowy do podłączenia do vCenter, konfiguracja jest powtarzalna. Minusem jest pomyłka. Jeżeli pomylimy się w jednym miejscu, to pomylimy się w konfiguracji na każdym z przygotowanych tak hostów.

Krok 2. VMware – vCenter Server.

Mając tak przygotowane hosty potrzebujemy jeszcze jednego rozwiązania VMware, jakim jest vCenter Server. Ten produkt też posiada plik, gdzie możemy wprowadzić konfiguracje i jednym poleceniem uruchomić instalacje. Przykład poniżej:

{
    "__version": "2.13.0",
    "__comments": "Sample template to deploy a vCenter Server Appliance with an embedded Platform Services Controller on an ESXi host.",
    "new_vcsa": {
        "esxi": {
            "hostname": "esxi-1.lab.inleo.pl",
            "username": "root",
            "password": "Haslo@123",
            "deployment_network": "ADMIN",
            "datastore": "esxi-1-datastore1 "
        },
        "appliance": {
            "__comments": [
                "You must provide the 'deployment_option' key with a value, which will affect the VCSA's configuration parameters, such as the VCSA's number of vCPUs, the memory size, the storage size, and the maximum numbers of ESXi hosts and VMs which can be managed. For a list of acceptable values, run the supported deployment sizes help, i.e. vcsa-deploy --supported-deployment-sizes"
            ],
            "thin_disk_mode": true,
            "deployment_option": "medium",
            "name": "vCenter Server"
        },
        "network": {
            "ip_family": "ipv4",
            "mode": "static",
            "system_name": "vcsa.lab.inleo.pl",
            "ip": "192.168.1.20",
            "prefix": "24",
            "gateway": "192.168.1.1",
            "dns_servers": [
                "192.168.1.51"
            ]
        },
        "os": {
            "password": "Haslo@123",
            "ntp_servers": "192.168.1.51",
            "ssh_enable": false
        },
        "sso": {
            "password": "Password@123",
            "domain_name": "vsphere.local"
        }
    }

Oczywiście wszystkie inne elementy, takie jak konfiguracja DNS i NTP powinny zostać przygotowane wcześniej. Tutaj się nic nie zmienia , a vcsa-deploy.exe znajduje się w ISO vCenter Server. Poniżej przykład wykorzystania.

Uruchamiamy i idziemy na kawę.

vcsa-deploy.exe install --accept-eula --acknowledge-ceip --no-esx-ssl-verify C:embedded_vCSA_on_ESXi-config.json 

 

Krok 3. Gwóźdź programu, czyli konfiguracja sieci i vSAN.

W bardzo uproszczonej wersji przygotowałem skrypt w PowerShellu. Oczywiście nieuniknione było wykorzystanie PowerCLI. Funkcjonalnie podzieliłem skrypt na 3 bloki. Pierwszy blok to oczywiście część ze zmiennymi oraz podłączeniem hostów do vCenter i konfiguracji klastrów. Drugi blok to konfiguracja sieci i ostatni to konfiguracja samego vSANu.

Pierwszy blok mógłby wyglądać jak poniżej. Deklaracja zmiennych, utworzenie data center czy klastra to jedna linia. Dodanie jednej prostej pętli może zmniejszyć objętość skryptu i uprościć go.  Można pokusić się również o pobieranie zmiennych z pliku csv lub o to, aby wszystko wpisywać z palca. Możliwości jest sporo.

$VCNode = ''
$host1 = ''
$host2 = ''
$wintess = ''
 
$VCUserName = 'administrator@vsphere.local'
$ESXiUserName = 'root'
$VCPassword = ''
$ESXPassword = 'Haslo@123'
$DCName = 'INLEO-LAB'
$CluName = 'PODMIEJSKA'
$VDSName = 'PODMIEJSKA-NODE-vDS'
$pgname_vmotion = 'PODMIEJSKA-Node-vMotion'
$pgname_vSAN = 'PODMIEJSKA-Node-vSAN-Traffic'
$pgname_vmadmin = 'PODMIEJSKA-Node-ADMIN'
$pgname_vmdmz = 'PODMIEJSKA-Node-DMZ'
$pgname_vmbackup = 'PODMIEJSKA-Node-BACKUP'
$pgname_vmdb = 'PODMIEJSKA-Node-DB'
 
.
.
.
.
 
 
Connect-VIServer $VCNode -User $VCUserName -Password $VCPassword -WarningAction SilentlyContinue
 
$DC = New-Datacenter -Name $DCName -Location (Get-Folder Datacenters)
 
$CLU = New-Cluster -Name $CluName -Location ($DC)
 
 
Add-VMHost -Name $host1 -Location $CLU -User $ESXiUserName -Password $ESXPassword -Force | Out-Null
Add-VMHost -Name $host2 -Location $CLU -User $ESXiUserName -Password $ESXPassword -Force | Out-Null

 

Krok 4. Konfiguracja sieci.

Tutaj też można pokusić się o kilka pętli dla ułatwienia sprawy. Ten etap jest, według mnie najbardziej skomplikowany. Duża ilość zmiennych i sporo linii kodu może trochę przerażać, ale zawsze można skorzystać z funkcji nagrywania w vCenter. Chociaż to ułatwienie może wprowadzić sporo zamieszania, bo kod z „nagrania” jest już mniej zrozumiały. Przynajmniej dla bardziej początkujących. Część odpowiedzialna za konfigurację sieci mogłaby wyglądać jak poniżej:

New-VDSwitch -Name $VDSName -Location $DCName -NumUplinkPorts 6 -Version 7.0.0 -Mtu 9000
 
New-VDPortgroup -VDSwitch $VDSname -Name $pgname_vmotion -NumPorts 2 -PortBinding Static
New-VDPortgroup -VDSwitch $VDSname -Name $pgname_vSAN -NumPorts 2 -PortBinding Static
New-VDPortgroup -VDSwitch $VDSname -Name $pgname_vmdmz -NumPorts 2 -PortBinding Static -VlanId 5
New-VDPortgroup -VDSwitch $VDSname -Name $pgname_vmadmin -NumPorts 2 -PortBinding Static -VlanId 2
New-VDPortgroup -VDSwitch $VDSname -Name $pgname_vmbackend -NumPorts 2 -PortBinding Static -VlanId 4
New-VDPortgroup -VDSwitch $VDSname -Name $pgname_vmbackup -NumPorts 2 -PortBinding Static -VlanId 6
Add-VDSwitchVMHost -VDSwitch $VDSName -VMHost $host1, $host2
 
 
 
$vhost = Get-VMHost $host1
$uplinks = $vhost | Get-VDSwitch | Get-VDPort -Uplink | where {$_.ProxyHost -like $vhost.Name}
$vds = Get-VDSwitch $VDSName
$_this.QueryNetworkHint($null)
$config = New-Object VMware.Vim.HostNetworkConfig
$config.proxySwitch = New-Object VMware.Vim.HostProxySwitchConfig[] (1)
$config.proxySwitch[0] = New-Object VMware.Vim.HostProxySwitchConfig
$config.proxySwitch[0].changeOperation = "edit"
$config.proxySwitch[0].uuid = $vds.Key
$config.ProxySwitch[0].Spec = New-Object VMware.Vim.HostProxySwitchSpec
$config.ProxySwitch[0].Spec.Backing = New-Object VMware.Vim.DistributedVirtualSwitchHostMemberPnicBacking
$config.ProxySwitch[0].Spec.Backing.PnicSpec = New-Object VMware.Vim.DistributedVirtualSwitchHostMemberPnicSpec[] (6)
 
$config.ProxySwitch[0].Spec.Backing.PnicSpec[0] = New-Object VMware.Vim.DistributedVirtualSwitchHostMemberPnicSpec
$config.ProxySwitch[0].Spec.Backing.PnicSpec[0].PnicDevice = 'vmnic4'
$config.ProxySwitch[0].Spec.Backing.PnicSpec[0].UplinkPortKey = ($uplinks | where {$_.Name -eq "dvUplink1"}).key
 
$config.ProxySwitch[0].Spec.Backing.PnicSpec[1] = New-Object VMware.Vim.DistributedVirtualSwitchHostMemberPnicSpec
$config.ProxySwitch[0].Spec.Backing.PnicSpec[1].PnicDevice = 'vmnic5'
$config.ProxySwitch[0].Spec.Backing.PnicSpec[1].UplinkPortKey = ($uplinks | where {$_.Name -eq "dvUplink2"}).key
 
$config.ProxySwitch[0].Spec.Backing.PnicSpec[2] = New-Object VMware.Vim.DistributedVirtualSwitchHostMemberPnicSpec
$config.ProxySwitch[0].Spec.Backing.PnicSpec[2].PnicDevice = 'vmnic6'
$config.ProxySwitch[0].Spec.Backing.PnicSpec[2].UplinkPortKey = ($uplinks | where {$_.Name -eq "dvUplink3"}).key
 
$config.ProxySwitch[0].Spec.Backing.PnicSpec[3] = New-Object VMware.Vim.DistributedVirtualSwitchHostMemberPnicSpec
$config.ProxySwitch[0].Spec.Backing.PnicSpec[3].PnicDevice = 'vmnic7'
$config.ProxySwitch[0].Spec.Backing.PnicSpec[3].UplinkPortKey = ($uplinks | where {$_.Name -eq "dvUplink4"}).key
 
$config.ProxySwitch[0].Spec.Backing.PnicSpec[4] = New-Object VMware.Vim.DistributedVirtualSwitchHostMemberPnicSpec
$config.ProxySwitch[0].Spec.Backing.PnicSpec[4].PnicDevice = 'vmnic2'
$config.ProxySwitch[0].Spec.Backing.PnicSpec[4].UplinkPortKey = ($uplinks | where {$_.Name -eq "dvUplink5"}).key
 
$config.ProxySwitch[0].Spec.Backing.PnicSpec[5] = New-Object VMware.Vim.DistributedVirtualSwitchHostMemberPnicSpec
$config.ProxySwitch[0].Spec.Backing.PnicSpec[5].PnicDevice = 'vmnic3'
$config.ProxySwitch[0].Spec.Backing.PnicSpec[5].UplinkPortKey = ($uplinks | where {$_.Name -eq "dvUplink6"}).key

 

Krok 5 i ostatni. Wisienka na torcie, czyli Konfiguracja klastra VMware vSAN.

Element konfiguracyjny jest niezwykle prostą sprawą. Istotne jest, aby sprawdzić dyski twarde i ich identyfikatory, aby odpowiednio były przydzielone do grup. Widzimy to idealnie na poniższym przykładzie:

Set-Cluster -Cluster $CluName -VsanEnabled:$true  -DrsEnabled:$true -DrsAutomationLevel FullyAutomated -HAEnabled:$true -Confirm:$false
 
New-VsanFaultDomain -Name FD1 -VMHost $host1
New-VsanFaultDomain -Name FD2 -VMHost $host2
New-VsanFaultDomain -Name FD3 -VMHost $host3
 
New-VsanDiskGroup -DataDiskCanonicalName mpx.vmhba0:C0:T65:L0, mpx.vmhba0:C0:T66:L0, mpx.vmhba0:C0:T67:L0, mpx.vmhba0:C0:T68:L0 -SsdCanonicalName mpx.vmhba0:C0:T64:L0 -Confirm:$false -VMHost $host1
New-VsanDiskGroup -DataDiskCanonicalName mpx.vmhba0:C0:T65:L0, mpx.vmhba0:C0:T66:L0, mpx.vmhba0:C0:T67:L0, mpx.vmhba0:C0:T68:L0 -SsdCanonicalName mpx.vmhba0:C0:T64:L0 -Confirm:$false -VMHost $host2
New-VsanDiskGroup -DataDiskCanonicalName mpx.vmhba0:C0:T65:L0, mpx.vmhba0:C0:T66:L0, mpx.vmhba0:C0:T67:L0, mpx.vmhba0:C0:T68:L0 -SsdCanonicalName mpx.vmhba0:C0:T64:L0 -Confirm:$false -VMHost $host3
 
 
Get-Datastore -Name 'vsanDatastore' | Set-Datastore -Name $CluName
Get-VsanClusterConfiguration -Cluster $CluName | Set-VsanClusterConfiguration -PerformanceServiceEnabled $true
Disconnect-VIServer -Server $session -Confirm:$false

 

Zakładając, że skrypt działa poprawnie, konfiguracja klastra wykonuje się w ciągu 20-30 sekund. Można to oczywiście zrobić szybciej, kwestia dopracowania skryptu. Na pewno sporo osób powie, że zrobienie takiego skryptu jest bardzo czasochłonne. Nic bardziej mylnego!

Jako osoba, która nie zajmuje się na co dzień tego typu skryptami i automatyzacją, przygotowanie skryptu zajęło mi niewiele czasu.

  • Oczywiście można wykorzystać już istniejące, ale przeglądając internet w poszukiwaniu czegoś uszytego na miarę, napotkałem na sporo problemów.
  • Modyfikacja skryptów innych osób też nie jest łatwa, bo zdarza się, że natrafimy na elementy, gdzie zastanawiamy się co autor miał na myśli. Zajmuje to nasz cenny czas, a często nie przynosi oczekiwanych efektów.
  • Części skryptów, które przedstawiłem są dość “krnąbrne”. Brakuje funkcji, przejrzystości i wielu innych rzeczy, ale najważniejsze, że działa! Przyspiesza moją pracę i może przyspieszyć Waszą.

Epilog.

Dodatkowo chciałbym Was zainspirować do działania i opracowywania własnej prostej lub bardziej zaawansowanej automatyzacji, dzięki której świat IT będzie prosty i przyjemny. Doskonale wiemy, że taki nie jest, albo nie jest we wszystkich jego aspektach.

Artykuł powstał przy współpracy z dostawcą usługi VMware vSAN <klik>