Showing posts with label loadbalancer. Show all posts
Showing posts with label loadbalancer. Show all posts

Sunday, January 29, 2017

F5 management through PowerShell

I've mentioned in my vCPU upgrade article that one of the requirements of me being allowed to shut down the VM was to be sure that there were no connections on the F5 loadbalancer for the webserver.

So I needed to script against the F5 loadbalancer. The first thing you need to do, is to get the F5 PowerShell Snapin from the F5 site. An account can be made for free, then you can login and download the plugin and follow the instructions to get it installed.

Once installed, you can add the snapin with:

Add-PSSnapIn iControlSnapIn

Now you have commands to manage the F5. Great, now it's time to login. First you need to add some credentials to a variable, and I've mentioned this in a previous article too. After that, you can set up the connection to the loadbalancer:

$creds = Import-CliXml -Path "D:\akos\LB01.Cred"
Initialize-F5.iControl -HostName "192.168.1.10" -Credentials $creds

Great, now you have the power to enable and disable nodes within the loadbalancer pool with actions like:

Disable-F5.LTMNodeAddress -Node "10.0.20.3"

and

Enable-F5.LTMNodeAddress -Node "10.0.20.3"

Now disabling and enabling is fine, but knowing if there's really no connections left is what you want to have. Luckily the Internet is a great place for info, and someone on Stackoverflow created the following excellent code, which I adapted a little to suit my needs. These two excellent functions do exactly what I want it to do, namely wait around for connections to drop (with a max time, don't want to spend waiting forever), and a supporting function to get the number of connections:

function WaitForConnectionsToDrop(
    [int]$MaxWaitTime = 300,
    [string]$Node
)
{
    $connections = GetCurrentConnections -Node $Node

    $elapsed = [System.Diagnostics.Stopwatch]::StartNew();
    while($connections -gt 0 -and $elapsed.ElapsedMilliseconds -lt ($MaxWaitTime * 1000)){        

        Start-Sleep -Seconds 10

        $connections = GetCurrentConnections -Node $Node
    }
}

function GetCurrentConnections(
    [string]$Node
)
{
    $ic=Get-F5.iControl
    $connections = $ic.LocalLBNodeAddress.get_statistics($Node) | foreach{$_.statistics.statistics | where {$_.type -eq "STATISTIC_SERVER_SIDE_CURRENT_CONNECTIONS"} | foreach{$_.value.low} }
    Write-Host "$Node has $connections Connections"
    return $connections
}

(note, that last few lines are broken up due to the format of the blog, it should be one line)
The great thing is, now you can easily do the following:

foreach ($node in $serverlist){
    Disable-F5.LTMNodeAddress -Node "$node"
    WaitForConnectionsToDrop -Node "$node" -MaxWaitTime 300
    #insert whatever code you want to do, like, say upgrade vCPU's, or patch the host
    Enable-F5.LTMNodeAddress -Node "$node"
}

As you can tell, it is easy to create a script with this info that will easily disable and enable nodes. Yeay, PowerShell!

Wednesday, January 25, 2017

Automatically upgrade vCPU's

I am lazy. Well, not lazy, I just don't like working at ungodly hours. Here's the story: I got this request to upgrade 2 customer VM's from 3 vCPU's to 4 vcpu's. No biggy, I thought. But he wanted it done after 1 AM.. Wait, that's not during office hours!

OK, I could fix that with my trusty Powershell toolkit, and a scheduled task. But then I talked to the customer who went like: "Sure that's fine with me to script it, but make sure the sessions are drained from the webserver".. Hmm, F5 loadbalancers. I've not worked too much with those before, really. I get the general ideas within loadbalancing, but let's try and script against it.

So I had a number of things I wanted to happen:
  • Log in to the F5 loadbalancer, preferably not with a script filled with credentials hardcoded into it. 
  • Wait an X amount of time for connections to drop from the specific pool
  • Shut down the machine, and wait for it to be properly turned off.
  • Set the number of CPU's and memory. This had an extra challenge, namely that the person who built the VM put in 1 vCPU with 3 cores, instead of 3 vCPU's.
  • Send an email with the results, so I can see what happened from my phone.
I'll spend a few posts on those different things.

Firstly the vCPU upgrade, which is the basis of this entire story:

Normally, you can turn off a VM, upgrade vCPU's, then start a VM again, through this simple set of commands:

$VM=Get-VM -Name 'WEB01'

Stop-VMGuest –VM $VM –Confirm:$False
do {
        $status = (get-VM $VM).PowerState
    }until($status -eq "PoweredOff")

$VM | Set-VM -NumpCPU 4 –Confirm:$False | Start-VM

However, since someone used 1 vCPU with multiple cores instead of multiple vCPU sockets, things work a little differently. If you would try this command, the VM would be shut down, but no upgrade would happen, and start back up with the same amount as before.

Fortunately there's another trick for that:

$VMSpec = New-Object -Type VMware.Vim.VirtualMachineConfigSpec -Property @{"NumCoresPerSocket" = 4;"numCPUs" = 4}
$VM.ExtensionData.ReconfigVM_Task($VMSpec)

(That first line shouldn't be cut off like that, should be 1 line, but alas: blog template gets in the way)

Now the VM gets upgraded to 4 vCPU's, although you would think it'd be 4x4 cpu's looking at the syntax.

So now the final complete code would be:

Add-PSsnapin VMware.VimAutomation.Core
Connect-VIServer myVcenter -ErrorAction Stop


$VM=Get-VM -Name 'WEB01'


Stop-VMGuest –VM $VM –Confirm:$False
do {
        $status = (get-VM $VM).PowerState
    }until($status -eq "PoweredOff")


$VMSpec = New-Object -Type VMware.Vim.VirtualMachineConfigSpec -Property @{"NumCoresPerSocket" = 4;"numCPUs" = 4}


Start-VM $VM


Yeay, success! Now on to the next bit...