This repository has been archived by the owner on Oct 28, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 89
/
Copy pathNSXLBAustoScale-v1.0.ps1
204 lines (171 loc) · 9.1 KB
/
NSXLBAustoScale-v1.0.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
## NSX LB AutoScale
## Author: Dimitri Desmidt
## version 1.0
## August 2017
###
# This PowerShell script offers Auto Scaling of your application.
# Your application is running on servers ($VM_PrefixName + $VM_Clone_PrefixName)
# When those servers are heavily loaded ($CPU_Max or $RAM_Max) and are less than $VM_Max
# The script deploys one new VM from vCenter template ($VM_Template)
# and adds that new VM in NSX LB Pool ($Edge_Name, $LB_Pool_Name)
# When those servers are lightly loaded ($CPU_Min or $RAM_Min) and more than $VM_Min,
# The script removes one VM from NSX LB Pool ($Edge_Name, $LB_Pool_Name)
# and removes that VM from vCenter
#
# Go to section "Define Variables for NSX LB AutoScale script" and enter your environment settings
#
###
# To allow the launch of that script in Windows Tasks "powershell.exe -file C:\NSXLBAustoScale-v1.0.ps1"
<#
Copyright © 2017 VMware, Inc. All Rights Reserved.
This program is free software: you can redistribute it and/or modify it under
the terms of the GNU General Public License version 2, as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTIBILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License version 2 for more details.
You should have received a copy of the General Public License version 2 along with this program.
If not, see https://www.gnu.org/licenses/gpl-2.0.html.
The full text of the General Public License 2.0 is provided in the COPYING file.
Some files may be comprised of various open source software components, each of which
has its own license that is located in the source code of the respective component.”
#>
###
# Define Variables for NSX LB AutoScale script
###
# vCenter IP / User / Password
$vCenter_IP = "192.168.10.4"
$vCenter_User = "[email protected]"
$vCenter_Pwd = "VMware1!"
# vCenter Cluster where new Clone_VM will be deployed
$Cluster_Compute_Name = "Cluster-CompA"
# NSX_Mgr IP / User / Password
# No need thanks to the Single-Sign-On
# Name of the VM template to clone + Prefix Name of the VM Names of LB Pool + Name of Clone VM
$VM_Template = "Web-Template"
$VM_PrefixName = "Web0"
$VM_Clone_PrefixName = "Web_Clone"
# LB information
# How many pool members Minimum / Maximum
$VM_Min = 2
$VM_Max = 3
# Edge Name / Pool Name
$Edge_Name = "LB1"
$Edge_VIP = "VIP1"
$LB_Pool_Name = "NSXLBAutoScale-Pool"
$LB_Pool_Port = 80
# CPU_Max, RAM_Max, CPU_Min, RAM_Min that will trigger AutoScale (create VM / delete VM)
$CPU_Max = 80
$RAM_Max = 80
$CPU_Min = 50
$RAM_Min = 50
# When load decrease, do you want to drain connections before deleting Pool Member and for how long in minute (only available for L4-VIP).
$VM_Drain = $true
$VM_Drain_Timer = 1
# File to write the log output
$Output_File = "C:\NSXLBAutoScale.log"
# Note: To "tail -f" in PowerShell "Get-Content .\NSXLBAutoScale.log -Wait"
###
# Do Not modify below this line! :)
###
# Set variables
$allvms = @()
$clone_vm = $false
$vm_not_hot = 0
# Connect to vCenter + NSX
#Connect-NsxServer -Server $NSX_IP -Username $NSX_User -Password $NSX_Pwd -VIUserName $vCenter_User -VIPassword $vCenter_Pwd -ViWarningAction "Ignore"
Connect-NsxServer -vCenterServer $vCenter_IP -Username $vCenter_User -Password $vCenter_Pwd
# Print the date in the file
"##############################################" >> $Output_File
Get-Date >> $Output_File
# Get all Pool_VMs powered on
$vms_base = Get-Vm -Name "$VM_PrefixName*" |Where-object {$_.powerstate -eq "PoweredOn"}
$vms_clone = Get-Vm -Name "$VM_Clone_PrefixName*" |Where-object {$_.powerstate -eq "PoweredOn"}
$vms_total = $vms_base + $vms_clone
# Count all Pool_VMs powered on
$number_vms = ($vms_total | Measure-Object).count
# For each Pool_VM powered on, check its CPU + RAM
foreach($vm in $vms_total) {
$vmstat = "" | Select VmName, CPUAvg, MemAvg
$vmstat.VmName = $vm.name
$statcpu = Get-Stat -Entity ($vm) -IntervalMins 1 -MaxSamples 5 -stat cpu.usage.average
$statmem = Get-Stat -Entity ($vm) -IntervalMins 1 -MaxSamples 5 -stat mem.usage.average
$cpu = $statcpu | Measure-Object -Property value -Average
$mem = $statmem | Measure-Object -Property value -Average
$vmstat.CPUAvg = $cpu.Average
$vmstat.MemAvg = $mem.Average
# If CPU or RAM above $CPU_Max/$RAM_Max, ask to create a new Pool_VM
if (($vmstat.CPUAvg -gt $CPU_Max) -or ($vmstat.MemAvg -gt $RAM_Max)) {
$clone_vm = $true
}
# If CPU and RAM below $CPU_Min/$RAM_Min, +1 $vm_not_hot
if (($vmstat.CPUAvg -lt $CPU_Min) -and ($vmstat.MemAvg -lt $RAM_Min)) {
$vm_not_hot += 1
}
$allvms += $vmstat
}
write-host -foregroundcolor "Green" "List of Pool_VM Servers: $($allvms | Format-Table | Out-String)"
"List of Pool_VM Servers: $($allvms | Format-Table | Out-String)" >> $Output_File
# If less than $VM_Min Pool_VMs AND asked to Clone_VM, THEN Create new Clone_VM + Add to LB_Pool
if (($number_vms -lt $VM_Max) -and ($clone_vm -eq $true)) {
# Get Pool_VM Template
$vm_template = Get-Template -Name $VM_Template
# vCenter Cluster where new Pool_VM will be deployed
$cluster_compute = get-cluster $Cluster_Compute_Name
# Create new Pool_VM
$new_vm = "$VM_Clone_PrefixName$($number_vms-$VM_Min+1)"
write-host -foregroundcolor "Green" "Adding new Clone_VM $new_vm..."
"Adding new Clone_VM $new_vm..." >> $Output_File
$vmhost = $cluster_compute | Get-vmhost | Sort-Object MemoryUsageGB | Select -first 1
New-VM -Name $new_vm -Template $vm_template -vmhost $vmhost
Start-VM -VM $new_vm
# Add Clone_VM to NSX Edge LB Pool
# Wait for the VMTools to get the IP@ of the Clone_VM
write-host -foregroundcolor "Green" "Waiting for VMTools to get new Pool VM $new_vm IP@..."
"Waiting for VMTools to get new Pool VM $new_vm IP@" >> $Output_File
$timeout = new-timespan -Minutes 10
$sw = [diagnostics.stopwatch]::StartNew()
while (($sw.elapsed -lt $timeout) -and !((Get-VM -Name $new_vm).guest.ipaddress)){
Start-Sleep -s 1
}
if ((Get-VM -Name $new_vm).guest.ipaddress) {
# Get the IP-v4 of the Clone_VM
$new_vm_ipv4_address = (Get-VM -Name $new_vm).Guest.IPAddress | where {([IPAddress]$_).AddressFamily -eq [System.Net.Sockets.AddressFamily]::InterNetwork}
if (!$new_vm_ipv4_address) {
write-host -foregroundcolor "Red" "The new Clone_VM $new_vm does not have an IPv4 address..."
"The new Clone_VM $new_vm does not have an IPv4 address..." >> $Output_File
} else {
write-host -foregroundcolor "Green" "Adding new Clone_VM $new_vm in NSX Edge $Edge_Name Pool $LB_Pool_Name..."
"Adding new Clone_VM $new_vm in NSX Edge $Edge_Name Pool $LB_Pool_Name..." >> $Output_File
# Add the Clone_VM in the NSX LB Pool
# Note: Adding VM with option IP@ (-IpAddress) and not Name (-Name) because Name not allowed with Pools in transparent mode when VM has both IPv4 and IPv6.
$lb_pool = Get-NsxEdge $Edge_Name | Get-NsxLoadBalancer | Get-NsxLoadBalancerPool -name $LB_Pool_Name
$lb_pool = $lb_pool | Add-NsxLoadBalancerPoolMember -name $new_vm -IpAddress $new_vm_ipv4_address -Port $LB_Pool_Port
}
}
}
#If "not request to clone" + "# of VM greater than $VM_Min Pool_VMs" + "All VMs are not hot", THEN delete one Clone_VM
if (($clone_vm -eq $false) -and ($number_vms -gt $VM_Min) -and ($number_vms -eq $vm_not_hot)) {
$remove_vm = "$VM_Clone_PrefixName$($number_vms-$VM_Min)"
# Check if option VM_Drain enabled, and if so Drain Pool_VM for $VM_Drain_Timer
if ($VM_Drain) {
if ((Get-NsxEdge $Edge_Name | Get-NsxLoadBalancer | Get-NsxLoadBalancerVIP -name $Edge_VIP).accelerationEnabled) {
write-host -foregroundcolor "Green" "Moving the Clone_VM $remove_vm in NSX Edge $Edge_Name Pool $LB_Pool_Name in Drain mode for $VM_Drain_Timer minute(s)..."
"Moving the Clone_VM $remove_vm in NSX Edge $Edge_Name Pool $LB_Pool_Name in Drain mode for $VM_Drain_Timer minute(s)..." >> $Output_File
Get-NsxEdge $Edge_Name | Get-NsxLoadBalancer | Get-NsxLoadBalancerPool -name $LB_Pool_Name | Get-NsxLoadBalancerPoolMember $remove_vm | Set-NsxLoadBalancerPoolMember -state drain
Start-Sleep -s (60*$VM_Drain_Timer)
} else {
write-host -foregroundcolor "Green" "Did NOT move the Clone_VM $remove_vm to Drain State before removing it from pool, because the VIP is with acceleration enabled."
"Did NOT move the Clone_VM $remove_vm to Drain State before removing it from pool, because the VIP is with acceleration enabled." >> $Output_File
}
}
# Delete the Clone_VM in the NSX LB Pool
write-host -foregroundcolor "Green" "Removing Clone_VM $remove_vm in NSX Edge $Edge_Name Pool $LB_Pool_Name..."
"Removing Clone_VM $remove_vm in NSX Edge $Edge_Name Pool $LB_Pool_Name..." >> $Output_File
$lb_pool = Get-NsxEdge $Edge_Name | Get-NsxLoadBalancer | Get-NsxLoadBalancerPool -name $LB_Pool_Name
$lb_pool = $lb_pool | Get-NsxLoadBalancerPoolMember $remove_vm | remove-nsxLoadbalancerPoolMember -confirm:$false
# Delete the Clone_VM in the NSX LB Pool
write-host -foregroundcolor "Green" "Deleting Clone_VM $remove_vm..."
"Deleting Clone_VM $remove_vm ..." >> $Output_File
Stop-VM -VM $remove_vm -Confirm:$false
Remove-VM -VM $remove_vm -DeletePermanently -Confirm:$false
}