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");
		cars.setEnabled(true);
		cars.setVm(vmMors1);
		ClusterRuleSpec crs1 = new ClusterRuleSpec();
		crs1.setOperation(ArrayUpdateOperation.add);
		crs1.setInfo(cars);

		// 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");
		caars.setEnabled(true);
		caars.setVm(vmMors2);
		ClusterRuleSpec crs2 = new ClusterRuleSpec();
		crs2.setOperation(ArrayUpdateOperation.add);
		crs2.setInfo(caars);

		// 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