Tag Archives: ha

DRS rules PART II: How to create VM-VM affinity rules using vSphere API.

In my last post we learned how to create VM-Host DRS affinity rules using vSphere API. Now today in PART II, we will see how to create VM-VM affinity rules using vSphere API. Before jumping on API coding, I would like to list out what VM-VM affinity rules are there and when we should use these rules.

What are the DRS VM-VM rules we can create on ESXi host cluster.

1. VM-VM affinity rule: This rule will keep the 1 or more VMs together on a host. i.e. DRS will make sure these VMs are running together on the same host all the time. Note that, this rule is soft rule, it is mean that, DRS can violate this rule if required in order to balance the cpu/memory load on the cluster. However, DRS will try its best to resolve this rule violation in next DRS invocation(Default DRS invocation is 5 mins).

Use cases:
1. If there is a group of VMs in DRS cluster those communicate frequently with each other, it would make sense to keep these VMs together on the same host to save some network bandwidth & increase the performance. If we keep such VMs on separate hosts, network traffic should exit from external physical network & will impact network latency.
2. If there is group of VMs in DRS cluster with same GuestOS, Apps or user data, we can keep these VMs together on same host to take advantage of Transparent Page Sharing (TPS) memory reclamation technique, so that host memory will be efficiently shared wherever there is opportunity.
Both of above use-cases can be satisfied by using VM-VM affinity rule

2. VM-VM anti-affinity rule: This rule is exactly opposite to above rule. Here this rule will keep 2 or more VMs away from each other. As per this rule, all the VMs involved in this rule should run on separate hosts. Again this rule is soft rule and DRS can violate this rule if required.
Use case:
If you want to make 2 critical VMs highly available, it makes sense to configure VM-VM anti-affinity rule on these 2 critical VMs. If one host goes down, second VM will be still running.

I strongly suggest you to read my blog post is HA aware of DRS rules in order to understand impact of above DRS rules on vSphere HA.

Note: All DRS rules are very popular among VMware admin but it is important to note that, if there are multiple rules configured on DRS cluster, it can impose constraint on DRS load balancing ability as DRS has to think on satisfying configured rules on cluster. It reduces DRS migration options. Hence please make use of these rules if absolutely required.

Creating these rules using vSphere API
Now with above basic fundamentals on DRS rules, we are ready to deal with creating these rules using vSphere APIs. I assume now you are familiar with vSphere API reference, go through below pointed data-object in detail so that you will understand code yourself. (Click on image to enlarge)
VMVMrules Dataobject
Refer: ClusterRuleInfo data object API reference

Below program creates both VM-VM affinity rule and VM-VM anti-affinity rule

package com.vmware.vijava;
import java.net.MalformedURLException;
import java.net.URL;
import java.rmi.RemoteException;
import com.vmware.vim25.ArrayUpdateOperation;
import com.vmware.vim25.ClusterAffinityRuleSpec;
import com.vmware.vim25.ClusterAntiAffinityRuleSpec;
import com.vmware.vim25.ClusterConfigSpec;
import com.vmware.vim25.ClusterRuleSpec;
import com.vmware.vim25.InvalidProperty;
import com.vmware.vim25.ManagedObjectReference;
import com.vmware.vim25.RuntimeFault;
import com.vmware.vim25.mo.ClusterComputeResource;
import com.vmware.vim25.mo.Folder;
import com.vmware.vim25.mo.InventoryNavigator;
import com.vmware.vim25.mo.ServiceInstance;
import com.vmware.vim25.mo.VirtualMachine;
import com.vmware.vim25.mo.util.MorUtil;

public class DRSVMVMRules {

	public static void main(String[] args) throws InvalidProperty,
			RuntimeFault, RemoteException, MalformedURLException {
		ServiceInstance si = new ServiceInstance(new URL(args[0]), args[1],
				args[2], true); // Pass 3 argument as vCenterIP/username/password
                String ClusterName = "BLR-NTP"; // Cluster Name
		String affineVM1 = "CentOS6_x64_2GB_1"; // First VM for affinity rule
		String affineVM2 = "CentOS6_x64_2GB_2"; // Second VM for affinity rule
		String anti_affineVM1 = "CentOS6_x64_2GB_3"; // First VM for anti-affinity rule
		String anti_affineVM2 = "CentOS6_x64_2GB_4"; // Second VM for anti-affinity rule
                Folder rootFolder = si.getRootFolder();

		ClusterComputeResource cluster = null;
		cluster = (ClusterComputeResource) new InventoryNavigator(rootFolder)
				.searchManagedEntity("ClusterComputeResource", ClusterName);
                ManagedObjectReference ClusterMor = cluster.getMOR();
		ClusterComputeResource ccr = (ClusterComputeResource) MorUtil
				.createExactManagedEntity(si.getServerConnection(), ClusterMor);

		// VM-VM affinity rule configuration
		ClusterConfigSpec ccs = new ClusterConfigSpec();
		ClusterAffinityRuleSpec cars = null;
		VirtualMachine vm1 = (VirtualMachine) new InventoryNavigator(rootFolder)
				.searchManagedEntity("VirtualMachine", affineVM1);
		VirtualMachine vm2 = (VirtualMachine) new InventoryNavigator(rootFolder)
				.searchManagedEntity("VirtualMachine", affineVM2);
		ManagedObjectReference vmMor1 = vm1.getMOR();
		ManagedObjectReference vmMor2 = vm2.getMOR();
		ManagedObjectReference[] vmMors1 = new ManagedObjectReference[] {
				vmMor1, vmMor2 };
		cars = new ClusterAffinityRuleSpec();
		cars.setName("VM-VM Affinity Rule");
		ClusterRuleSpec crs1 = new ClusterRuleSpec();

		// VM-VM Anti-affinity rule configuration
		ClusterAntiAffinityRuleSpec caars = null;
		VirtualMachine vm3 = (VirtualMachine) new InventoryNavigator(rootFolder)
				.searchManagedEntity("VirtualMachine", anti_affineVM1);
		VirtualMachine vm4 = (VirtualMachine) new InventoryNavigator(rootFolder)
				.searchManagedEntity("VirtualMachine", anti_affineVM2);
		ManagedObjectReference vmMor3 = vm3.getMOR();
		ManagedObjectReference vmMor4 = vm4.getMOR();
		ManagedObjectReference[] vmMors2 = new ManagedObjectReference[] {
				vmMor3, vmMor4 };
		caars = new ClusterAntiAffinityRuleSpec();
		caars.setName("VM-VM Anti-Affinity Rule");
		ClusterRuleSpec crs2 = new ClusterRuleSpec();

		// Passing the rule spec
		ccs.setRulesSpec(new ClusterRuleSpec[] { crs1, crs2 });
		// Reconfigure the cluster
		ccr.reconfigureCluster_Task(ccs, true);
		System.out.println("Rules are created with no issues:");


Code itself is self explanatory, just map the code with data-objects in vSphere API reference. Note that for the sake of simplicity, I have hard-coded VM/Cluster name , do make changes according to your environment. Please do leave the comment if you have any doubt.

Below is the VI client view of created VM-VM DRS rules using above code.
VM-VM Rules

If you have still not setup your VI JAVA Eclipse environment:Getting started tutorial
Important tutorials to start with: Part I & Part II

is vSphere HA aware of DRS affinity rules?

Recently I was exploring vSphere HA interop with DRS affinity rules. It is quite interesting to know that as of vCenter server 5.5, how vSphere HA deals with various DRS affinity rules.

Here are the current DRS rules we can configure on the DRS cluster:
1. VM-VM affinity rule: This rule is intended to keep group of VMs together on single host.

2. VM-VM anti-affinity rule: This rule is intended to keep group of VMs away from each other all the time.

3. VM-Host affinity rule: This rule restricts to run a group of VMs on a group of Host. It is mean that, VMs in VM group should/must always be running on hosts in Host Group. This rule can be hard/must or soft/should rule.

4. VM-Host anti affinity rule: This rule is exactly opposite to above VM-Host Affinity rule. This rule does not allow  to  run a group of VMs on a group of Host. This rule can be hard/must or soft/should rule.

Now question is : whether vSphere HA aware of DRS affinity rules? Answer is “Yes”, as of vSphere 5.5, vSphere HA is aware of 2 DRS rules. Here are the rules those are honored by vSphere HA.

1 . VM-Host must affinity/anti-affinity rule

2.  VM-VM anti-affinity rule.

vSphere HA honors these rules, it is mean that, in case of host failure, if re-starting VMs on available host  leads to rule violation, vSphere HA will not re-start VMs those were on the failed host. vSphere HA will raise the error instead.

Example: Say , you have a HA-DRS enabled cluster of 2 hosts (H1, H2) & with 2 VMs (VM1-H1, VM2-H2) one on each host in powered on state. Now you configured VM-Host must affinity rule :HostGroup:H1 & VMGroup:VM1. It is mean that VM1 must always run on H1. Once you configure this rule, say, H1 host got failed. Now vSphere HA will try to restart the VM on H2 but as HA knows that VM-Host rule is configured, it will not restart the VM1 on H2.

It is important to note that, by default, VM-Host must affinity/anti-affinity is honored by vSphere HA. You just need to configure VM-host must affinity/anti-affinity rule but in order to make VM-VM anti-affinity rule vSphere HA aware, you will have to configure one HA advanced option “das.respectVmVmAntiAffinityRules” to true. (default value of this advanced option is false). I repeat this is a HA advanced option, not the DRS advanced option. You can configure this option from web client through this workflow (Cluster>>Manage>>vSphere HA>>Advanced option). However, you can configure this option from Desktop client as well.

It is also important to note that, even when DRS is disabled on cluster, HA continues to honor them. As per the current design, we can not disable these rules when DRS is disabled. Hence care must be taken while disabling DRS, you can disable these rule when you disable DRS or when you want to disable these rules, enable DRS for a while in conservative migration threshold mode & disable these rules.

As I specified earlier, in case of host failure, HA will not restart VMs if that is going to violate the configured rule. Hence, admin need be to very cautious while configuring these rules as these rule can have availability impact. These rules should be configured when it is absolutely required.