PowerShell, Office 365, Azure and automation
Azure Linux VM performance tuning

Azure Linux VM performance tuning

I was looking for options, what I can do in Azure to speed up (optimize) a stack of servers for one business application. They were built approximately 2 years ago, and some features were not available at that time.

Good that machines running on quite fresh version of Linux that has a kernel version good enough. Otherwise, I would had to upgrade Linux to the latest supported version.

Azure Virtual Machine OS disk optimisation

First this is to convert OS disk from Standard HDD to Premium SSD. The cost change is not that big while data access difference is serious. This functionality is not supported for unmanaged disks. But you can easily convert an unmanaged disk to a managed disk to be able to switch between disk types.

To do that, I created a PowerShell function so it could be used on a few different machines I had to deal with.

Just be aware to use latest AZ module and to execute that function you must be connected to a proper subscription in Azure. OS disk conversion is also requires a VM to be deallocated.

function Convert-VMOSDisk {
    param (
        [Parameter (Mandatory = $true)]
        [string]$ResourceGroupName,
        [Parameter(Mandatory = $true)]
        [string]$VmName
    )
    $storageType = 'Premium_LRS'
    Import-Module Az.Accounts
    Import-Module Az.Compute
    $vm = Get-AzVM -ResourceGroupName $ResourceGroupName -Name $VmName
    If (!$vm) {
        Write-Error -Message "$VmName not found"
        Break
    }
    if ($vm.PowerState -notlike '*deallocated') {
        Write-Host "VM needs to be deallocated before we start converting OS disk"
        Stop-AzVM -Name $vm.Name -ResourceGroupName $vm.ResourceGroupName
    }
    $disk = Get-AzDisk -ResourceGroupName $resourcegroup -DiskName ($vm.StorageProfile.OsDisk.Name)
    If ($disk) {
        $disk.Sku = [Microsoft.Azure.Management.Compute.Models.DiskSku]::new($storageType)
        $disk.sku
        $disk | Update-AzDisk   
    }
    else {
        Write-Error -Message "Azure Disk $DiskName not found"
    }
}

Azure Virtual Machine DataDisk optimisation

You can also adjust this script to convert all the data disks or one disk only, because $vm.StorageProfile.DataDisks object is an array of DataDisks attached to a VM. That allow you to use the following method:

Foreach ($datadisk in $vm.StorageProfile.DataDisks) {
    $disk = Get-AzDisk -ResourceGroupName $resourcegroup -DiskName $datadisk.Name
    If ($disk) {
        $disk.Sku = [Microsoft.Azure.Management.Compute.Models.DiskSku]::new($storageType)
        $disk.sku
        $disk | Update-AzDisk   
    }
}

Enable network acceleration for Azure Virtual Machine

Next thing to do, if your Azure VM size is allowed to do so is enable network acceleration.  It is removing virtual switch from connection so should decrease latency. More information is available there.

The following distributions are supported out of the box from the Azure Gallery:

  • Ubuntu 14.04 with the linux-azure kernel
  • Ubuntu 16.04 or later
  • SLES12 SP3 or later
  • RHEL 7.4 or later
  • CentOS 7.4 or later
  • CoreOS Linux
  • Debian “Stretch” with backports kernel
  • Oracle Linux 7.4 and later with Red Hat Compatible Kernel (RHCK)
  • Oracle Linux 7.5 and later with UEK version 5
  • FreeBSD 10.4, 11.1 & 12.0

The up-to-date list of supported Operation Systems is available by the link.

Accelerated Networking is supported on most general purpose and compute-optimized instance sizes with 2 or more vCPUs. The supported series these days are: D/DSv2 and F/Fs.

On instances that support hyperthreading, Accelerated Networking is supported on Virtual Machine instances with 4 or more vCPUs. The supported series are: D/Dsv3, E/Esv3, Fsv2, Lsv2, Ms/Mms and Ms/Mmsv2.

More details and latest updates at MS Docs

Please see the function:

function Enable-NetworkAcceleration {
    param (
        [Parameter (Mandatory = $true)]
        [string]$ResourceGroupName,
       # [Parameter(Mandatory = $true)]
       # [string]$NICName,
        [Parameter(Mandatory = $true)]
        [string]$VmName
    ) 
        $vm = Get-AzVM -ResourceGroupName $ResourceGroupName -Name $VmName
        If (!$vm) {
            Write-Error -Message "$VmName not found"
            Break
        }
        $nic = Get-AzNetworkInterface -ResourceId $vm.NetworkProfile.NetworkInterfaces.id
        Write-Host $nic.Name
        start-sleep -Seconds 5
        # $nic = Get-AzNetworkInterface -ResourceGroupName $ResourceGroupName  -Name $NICName
        $nic.EnableAcceleratedNetworking = $true
        $nic | Set-AzNetworkInterface   
}

Place Azure Virtual Machine to Proximity Placement group

And the last part, because all the VMs I had are a part of one application stack, it is good to place them at one Proximity Placement group. That will place Virtual Machines close to each other and speed up communications between them.

That may not work well if you have HA. In this case you need to re-design and create multiple Proximity Placement groups for different shoulders of your application stack.

There is also a limitation that you can’t add a VM to Proximity Placement group if it is a part of Availability Set. The best practice is available on MS Docs.

function Add-VMtoProximityGroup {
    param (
        [Parameter (Mandatory = $true)]
        [string]$ResourceGroupName,
        [Parameter(Mandatory = $true)]
        [string]$ProximityPlacementGroupName,
        [Parameter(Mandatory = $true)]
        [string]$VmName
    )
    # Query proximity group
    $ppg = Get-AzProximityPlacementGroup -ResourceGroupName $ResourceGroupName -Name $ProximityPlacementGroupName
    # Query VM
    $vm = Get-AzVM -ResourceGroupName $ResourceGroupName -Name $VmName -Status
    # Check that VM is deallocated
    if ($vm.PowerState -notlike '*deallocated') {
        Stop-AzVM -Name $vm.Name -ResourceGroupName $vm.ResourceGroupName
    }
    #Add Vm to proximity group
    Update-AzVM -VM $vm -ResourceGroupName $vm.ResourceGroupName -ProximityPlacementGroupId $ppg.Id
}

Conclusion

Hope that helps you with optimisation for your Azure Linux VMs and you can get better performance for the same or lower price. Unfortunately, not all the options might be available for some VM sizes, but it could change in future so please don’t hesitate to check for latest updates on MS Docs site.

There are more things what you can do to tune your Linux VM, but it is inside the Linux: kernel tweaks by “sysctl”, filesystem, network stack and service parameters. I don’t want to go that way because it is a long topic and it is not Azure related, so you can find answers in Linux books.

More Azure related articles

Leave a Reply

Your email address will not be published. Required fields are marked *