Wednesday, February 17, 2016

How to identify from the guest OS on which vCenter is virtual machine registered?

One my customer asked me how to identify - from the VM guest operating system - in which vCenter server is that particular virtual machine registered.

They use VM deployment from VM Templates with Customization Specifications and they would like to use vCenter locality information for additional tasks during VM deployment process.

I was thinking about several possibilities. Considered options are listed below.

Considered options:

  • OPTION 1: Define specific customization profile for each vCenter and have a special guest OS specific command in Customization Specification to run after sysprep and save vCenter identification somewhere to the guest file system.
  • OPTION 2: Use VM mac address for identification of vCenter Server Instance.
  • OPTION 3: leverage PowerCLI or vCLI running in guest os to communicate with vCenter.
  • OPTION 4: leverage custom VM guestinfo properties which can be read inside Guest OS.

Option 3 is not good option at all because you would need to have network connectivity from production VMs to vCenter (management network) and therefore it has negative impact on overall security.

Option 4 is described by William Lam here. It would need special VM templates having custom VM property like guestinfo.vcenter=VC01 which is visible in the guest info through vmtools. The command in the guest would look like
vmtoolsd --cmd "info-get guestinfo.vcenter"
Option 1 is relatively easy and it is leveraging the fact that Customization Specification for deployment of VM templates can run some script in guest after template deployment. I think that Option 1 is relatively good option. The only drawback is that vSphere admin would need to manage more customization specification and specific scripts to store vCenter identification somewhere in guest os filesystem which introduces some additional management overhead but it is acceptable if you ask me.

Option 2 intrigued me technically so let's elaborate on this option. Option 2 is leveraging the fact that "vCenter Server instance ID" is used for generating virtual machine MAC addresses and MAC address is well known digital identifier which can be relatively simply identified in any operating system.  So what this "vCenter Server instance ID" is? Each vCenter Server system has a vCenter Server instance ID. This ID is a number between 0 and 63 which is randomly generated at installation time, but can be reconfigured after installation. Here in vSphere 6.0 documentation is written that ... According to this scheme, a MAC address has the following format:
00:50:56:XX:YY:ZZ
where 00:50:56 represents the VMware OUI,
XX is calculated as (80 + vCenter Server Instance ID),
and YY:ZZ is a random number.
Note 1:
The formula above (80 + vCenter Server Instance ID) is in hexadecimal format therefore in decimal format it is 128 + vCenter Server Instance ID.
Note 2:
vCenter Server unique ID is generated randomly during vCenter installation. It can be changed after installation in the Runtime Settings section from the General settings of the vCenter Server instance and restart it. Please be aware, that existing Virtual Machines MAC addresses are not changed automatically after ID reconfiguration therefore it is good idea to change vCenter Server unique ID immediately after vCenter Server installation. There are methods how to regenerate VM mac addresses but it requires VM downtime. For more information look at VMware KB 1024025
Below is PowerShell script example of in-guest calculation of vCenter Server Instance ID.
$mac_str = Get-CimInstance win32_networkadapterconfiguration | where {$_.ServiceName -eq "vmxnet3ndis6"} | select macaddress | Out-String
$mac_arr = $mac_str.split(':')
$XX_hex = $mac_arr[3];
$XX_dec = [Convert]::ToInt32($XX, 16)
$VC_instance_ID = $XX_dec - 128
$VC_instance_ID
The script above is just an example written for Windows OS (Win2012R2) and PowerShell (4.0) to show how to automate the trick described in this blog post. Similar scripts can be prepared for other guest operating systems.

Disclaimer:
The script above is just an example and it works in my lab environment. You should carefully test if your script inspired by this blog post works correctly in your particular environment. I don't take any responsibility for the script and you use it in your own risk. I have spent just few minutes to write this script and I would definitely recommend to invest some more time on development and test if you want to use such script in production environment.
Know caveats of option 2 (vCenter identification based on VM MAC address) :

  • This solution will only work for dynamically assigned MAC addresses by vCenter and not for statically configured MAC addresses by administrator
  • This solution will not work correctly for cross vCenter vMotioned VMs because they are keeping the MAC address from original vCenter
  • I didn't test how behaves VM's recovered by VMware SRM (Site Recovery Manager). If recovered VM's keep original MAC address then this solution will not work for these recovered VMs. Unfortunately, I don't have access to SRM lab to verify SRM behavior. 

I would recommend to my customer to consider between options (1) and (2).

Hope this helps to broader IT community and as always ... your feedback is very welcome so don't hesitate to use comments, twitter or e-mail to share your opinions and other solution alternatives.