Wednesday, February 16, 2011

Creating the VM Role in an Azure Service

A VM Role is configured as a Role within a larger Hosted Service.  This is no different from a Web or Worker role except for the additional steps of creating and uploading the base VHD that the Role instances will be provisioned from.

The following example uses Visual Studio 2010 with the Azure SDK Installed to define and publish the service. It is important that the latest Azure SDK is installed, the VM Role capability is enabled, and Visual Studio is already configured to manage your subscription.

Create the VM Image
  1. Begin by creating a VM using Hyper-V

    1. The VHD size cannot exceed 15 Gb for an Extra Small VM, 30 GB for a Small VM, or 64 GB for a Medium to Extra Large VM.

    2. http://msdn.microsoft.com/en-us/library/gg465391.aspx

  2. Install Server 2008 R2

    1. Apply Windows Updates

    2. Add .Net Framework 3.5.1

  3. Install and configure your application(s)

    1. Be aware that the image will be prepared with sysprep. When provisioned, the VM will be unique and will complete mini setup.  Therefore the application must be in a state that is compatible with sysprep.  Any additional configuration that must be performed after mini-setup is complete should be scripted using a custom service, or defining Syncronous Commands in the unattend.xml created by step 4.

  4. Install the Azure VM Integration Components.

    1. http://msdn.microsoft.com/en-us/library/gg465409.aspx

    2. This generates an unattend.xml at the root of the system drive (with the Administrator password prompted for).  This unattend.xml is very specific to the VM successfully provisioning on Azure.  Sections can be added to the XML file, but not deleted.

  5. Install Azure Connect endpoint agent if it will be used.

  6. Apply any modifications to the unattend.xml to support installing or configuring your application.

    1. A combination of scripts or commands and the FirstLogonCommands and SynchronousCommand keys can be combined with the AutoLogon to orchestrate the actions.

  7. Run sysprep to generalize the image

    1. http://msdn.microsoft.com/en-us/library/gg465407.aspx

    2. sysprep /generalize /oobe /shutdown /unattend:"C:\unattend.xml"

Upload the VM (vhd) image
  1. Upload the VHD using the csupload tool that is included with the SDK.  This is accessed by launching the SDK Command prompt using "Run As Administrator".

    1. http://msdn.microsoft.com/en-us/library/gg465385.aspx

Author and Deploy an Azure Service
  1. http://msdn.microsoft.com/en-us/library/gg465379.aspx

    1. External endpoints are ports that are available publically in front of the load balancers and mapped to a particular role.

    2. Internal endpoints are available behind the load balancers and can be used to define specific endpoints (open TCP ports) for machine to machine communication. 

    3. Be aware that you cannot use FQDNs or DNS or the like – the intercommunication involves enumeration of role instances using Azure Service Runtime components combined with proper configuration using IP addresses.

    Tuesday, February 15, 2011

    Unable to start additional virtual machines when Hyper-V has plenty of resources

    Ben Armstrong from the Hyper-V team just published a really interesting blog article about CPU Reserves.

    The thing that you really need to think about here is how tweaking these settings impacts your virtualization environment as a whole – and Ben spends some time trying to relate that concept.

    http://blogs.msdn.com/b/virtual_pc_guy/archive/2011/02/14/hyper-v-cpu-scheduling-part-1.aspx

    In the forums I frequently advise folks to leave the knobs and buttons alone unless you have a really good reason for modifying them.  Why?  Because the system is designed to self manage and it does a really good job of it.

    The place where you get into problems is not from tweaking a single VM on a single hypervisor.  This usually works.  The problems come when that VM is moved to another hypervisor, for any number of reasons.

    After moving to another hypervisor the environment changes, how that VM interacts changes, the settings on the other VMs are different, and so on.

    The big take away from Ben’s article is – if you change the settings, understand what you are doing and how it impacts the entire environment, not just this VM.

    The little take aways: don’t change the settings unless you really need to, if you do change the settings be sure to document what and most importantly WHY, and tweak as few as absolutely possible.

    Think on that a bit, and if you like play around a bit – it will all come clear once you create a conflict caused by a setting that the environment should be able to support.

    Wednesday, February 2, 2011

    Tuning SCVMM for VDI deployments - Vishwa Kumbalimutt's blog

     

    Tuning SCVMM for VDI deployments - Vishwa Kumbalimutt's blog - Site Home - TechNet Blogs

    I have only re-blogged articles a very, very few times – but this is one that I feel is really important to any folks who are using SCVMM in a VDI scenario.

    Many of these tweaks I have know about for a few years but have been asked to not share them.  Now that a MSFT person has spilled the beans you all can benefit.

    I am not going to go into the details, but all of the tweaks are highly useful.  The one I have found most useful in my work (when moving into scales of over 400 VMs) is the tune for Windows Communication Framework.

    Don’t get me wrong, all of these tweaks are golden to any deployment of XenDesktop that uses SCVMM.

    Saturday, January 29, 2011

    Creating disk fragmentation in virtual disks

    Yes, you read that right. I WANT to fragment a hard drive. I want to do it well. I want it relatively quickly (one day vs. three years). And, you know what, it isn't as easy as you might expect.

    I mean, I could install a Windows XP virtual machine, and then update it. But, it is use over time that causes fragmentation. The writing and deleting of files. The intermix of small and large files. Unless you have an old server sitting around you don't have it.

    Oh, and I want to do this in a virtual machine. Hmm...So that means I can only go backward about six years at the very most. And who has had a single virtual machine running for six years? (at least that I can get my hands on..)

    Needless to say, I have been busy the past couple days with PowerShell.

    My theory is this: Write a bunch of little files. Randomly delete them. Write some big files. Randomly delete them and check the result.

    My results have been promising.  I may need to tweak it a bit to be sure to break near non-standard disk sizing increments.  But for a first try it was not too bad.  On a side note.  Nothing can simulate fragmentation like a PC that has been running in continuous service for many years, without a good 3rd party defragmentation.

    Here is my PowerShell script:

    # This is a script designed to highly fragment a system disk in one pass.
    # The theory is to nearly fill the disk with 128kb files, then to delete
    # one-half of those files, then populate the disk with 2Mb files, then remove a portion of those.
    #
    # I am going to use randomization in the delete functions, therefore it is unknown exactly
    # how many files might be deleted, because an empty array location might be chosen.
    # Initiate the random number function
    $Random=New-Object System.Random (get-date).millisecond
    # Get the System Disk
    $systemDisk = get-wmiObject win32_LogicalDisk | where {$_.DeviceId -eq $Env:SystemDrive}
    # determine 10%
    $tenPercent = $systemDisk.Size / 10
    # Move to to the system Temp folder where we will do the workset-Location $Env:Temp
    ################################################################################ Write lots of 128kb files
    ###############################################################################
    write-host "Write lots of 128kb files"
    # An array for the names
    $128kNames = @()
    #Create the sample 128k file
    $fileToCopy = "128kSample.txt"
    for ( $i = 0; $i -lt 21843; $i++) { "1" | Out-File $fileToCopy -append }
    While ($systemDisk.FreeSpace -gt $tenPercent) { Clear-Host Write-Host "Writing small files" Write-Host "Remaining free space is: " $systemDisk.FreeSpace Write-Host "Cycle: " $128kNames.Count

    # Set the file name
    $file = [string]$systemDisk.FreeSpace +".txt" copy $fileToCopy $file
    # Write the file name to the array
    $128kNames = $128kNames + $file


    # Requery the disk $systemDisk = get-wmiObject win32_LogicalDisk | where {$_.DeviceId -eq $Env:SystemDrive} }
    ################################################################################ Delete half of the 128kb files
    ###############################################################################
    write-host "Delete half of the 128kb files"
    # 1/2 of names in the array
    $half = $128kNames.Count / 2
    While ($half -gt 0) {
    Clear-Host Write-Host "Deleting small files" Write-Host "Remaining free space is: " $systemDisk.FreeSpace Write-Host "Countdown: " $half
    $rndName = $128kNames[$Random.Next(0, $128kNames.Count)]
    Remove-Item $rndName $half-- }

    # Requery the disk
    $systemDisk = get-wmiObject win32_LogicalDisk | where {$_.DeviceId -eq $Env:SystemDrive}
    # Clear the small name array
    $128kNames = 0
    ################################################################################ Write lots of 2Mb files
    ###############################################################################
    write-host "Write lots of 2Mb files"
    # An array for the names
    $2mbNames = @()
    #Create the sample 2Mb file
    $fileToCopy = "2MbSample.txt"
    for ( $i = 0; $i -lt 349512; $i++) { "0" | Out-File $fileToCopy -append }
    While ($systemDisk.FreeSpace -gt $tenPercent) {
    Clear-Host Write-Host "Writing large files" Write-Host "Remaining free space is: " $systemDisk.FreeSpace Write-Host "Cycle: " $2MbNames.Count

    # Set the file name
    $file = [string]$systemDisk.FreeSpace +"2mb.txt" copy $fileToCopy $file
    # Write the file name to the array
    $2mbNames = $2mbNames + $file
    # Requery the disk
    $systemDisk = get-wmiObject win32_LogicalDisk | where {$_.DeviceId -eq $Env:SystemDrive} }
    ################################################################################ Delete half of the 2Mb files
    ###############################################################################
    write-host "Delete half of the 2Mb files"
    # 1/2 of names in the array
    $half = $2mbNames.Count / 2
    While ($half -gt 0) {
    Clear-Host Write-Host "Deleting large files" Write-Host "Remaining free space is: " $systemDisk.FreeSpace Write-Host "Countdown: " $half
    $rndName = $2mbNames[$Random.Next(0, $2mbNames.Count)]
    Remove-Item $rndName $half-- }
    Clear-HostWrite-Host "Finally done"

    # What is the damage?
    # THIS DOES NOT WORK ON WIN XP AND EARLIER - THIS CLASS IS NOT AVAILABLE
    # $sysVolume = get-wmiObject win32_volume | where {$_.DriveLetter -eq $Env:SystemDrive}

    # $sysVolume.DefragAnalysis

    Tuesday, January 4, 2011

    The Azure VM Role reboot reset – understanding the pale blue cloud

    1/5/2011 update:
    Only one day has gone by since I originally posted this – and I must say that this has been a very interesting adventure.  The detiled discussion is in the comments.  However, this is a real and valid scenario that a developer should plan for.

    Here is a bit more insight into the behavior of VMs in Azure – and one more point that VM Role is NOT a solution for Infrastructure as a Service.
    Lest begin with a very simple, one VM scenario:
    With a VM Role VM – you (the developer, the person that wants to run your VM on Azure) uploads a VHD into what is now VHD specific storage, in a specific datacenter.
    You then create an application in the tool of your choice and define the VHD with the service settings – this links your VHD to a VM definition, firewall configuration, load balancer configuration, etc.
    You deploy your VM Role centric service and sit back and wait – then test and voila! it works.
    You do stuff with your VM, the VM life changes and all is happy – or is it.
    Now, you – being a curious individual – click the “Reboot” button in the Azure portal.  You think, cool, I am rebooting my VM – but you aren’t you are actually resetting your service deployment.  You return to your VM Role VM to find changes missing.
    This takes us into behaviors of the Azure Fabric.  On a quick note – if you wanted some type of persistence, you need to use Azure storage for that.  Back to the issue at had – your rolled back VM.  Lets explore a possibility for why this is.
    BTW - This behavior is the same for Web Roles, and Worker Roles as well – but it is the Azure base OS image, not yours.
    Basically what happened was no different than a revert to a previous snapshot using Hyper-V, or the old VirtualPC rollback mode.  When a VM is deployed there is a base VHD (this can be a base image – or your VM Role VHD) and there is a new differencing disk that is spawned off.
    You selecting reboot actually tossed out the differencing disk which contains your latest changes and created a new one, thus reverting your VM Role VM.  This is all fine and dandy, however my biggest question is:  What are the implications upon authentication mechanism such as Active Directory – AD does not deal with rollbacks of itself or of domain joined machines very well at all.
    My scenario is that you are using Azure Connect Services connecting back to a domain controller in your environment – you join the domain, someone clicks reboot and your machine is no longer domain joined or you have a mess of authentication errors.  Again, this is not the Azure model.
    The Azure model I in this case is that your VM reboots at the fabric layer back to the base image (they recommend that you prepare with sysprep) and it re-joins your domain as a new machine – with all of the pre-installed software.
    This is all about persistence and where that persistence resides.  In the VMs of your service there is no persistence, the persistence resides within your application and its interaction with Azure storage or writing back to some element within the enterprise.
    This is important to understand, especially if you think of Azure as IaaS  - which you need to stop doing.  It is a platform.  It is similar to a hypervisor but it is not a hypervisor in your interaction with it as a developer or ITPro. 
    In a nutshell what happened is that during the reboot of my VM the Azure Fabric considered the VM unhealthy and thus provisioned a new one.  It could be that the differencing disk could not be written back to the root VHD, it could be that “something” in my VM is not as the fabric wants it so it considered it bad and provisioned a new one.
    Regardless – this is valid behavior – it is behavior to understand and plan for – and again emphasizes that if you want persistence you must design it in by writing your application state out to Azure Storage (or enterprise storage using Azure Connect) in some way in order to guarantee persistence.
    All very interesting.