Advertisement

news | articles | utilities | resources | about

News

DRS and anti-affinity rules

An anti-affinity DRS rule is used when you want to keep 2 virtual machines on seperate hosts, usually because they provide a redundant service and locating them on the same host would eliminate that redundancy. Unfortunately an anti-affinity DRS rule can only be created for exactly 2 VMs. As you can see from the table below, once you get to creating anti-affinity rules for sets of VMs larger than 4, the creation of the rules becomes daunting.

Given VMs [1..X] where 1/2 denotes a rule specifying an anti-affinity rule for VMs 1 and 2.
2 VMs = 1 Rule ( 1/2 )
3 VMs = 3 Rules ( 1/2, 1/3, 2/3 )
4 VMs = 6 Rules ( 1/2, 1/3, 1/4, 2/3, 2/4, 3/4 )
5 VMs = 10 Rules ( 1/2, 1/3, 1/4, 1/5, 2/3, 2/4, 2/5, 3/4, 3/5, 4/5 )
6 VMs = 15 Rules ( 1/2, 1/3, 1/4, 1/5, 1/6, 2/3, 2/4, 2/5, 2/6, 3/4, 3/5, 3/6, 4/5, 4/6, 5/6 )
7 VMs = 21 Rules ...etc
8 VMs = 28 Rules ...etc
9 VMs = 36 Rules ...etc
10 VMs = 45 Rules ...etc


So realistically, 5 or 6 VMs is probably as far as you'd want to go with this without some sort of automation. First, let's take a look at some scripts written by VMTN forum member LucD that are written in powershell:


This first script will export a list of all the DRS rules for cluster
[drs_export.ps1]

$outfile = "C:\rules.txt"
Remove-Item $outfile
$clusterName =
$rules = get-cluster -Name $clusterName | Get-DrsRule

foreach($rule in $rules){
$line = (Get-View -Id $rule.ClusterId).Name
$line += ("," + $rule.Name + "," + $rule.Enabled + "," + $rule.KeepTogether)
foreach($vmId in $rule.VMIds){
$line += ("," + (Get-View -Id $vmId).Name)
}
$line | Out-File -Append $outfile
}


If we modify that script just a tad, it will get all the DRS rules for all the clusters in the vCenter(s) that we connect to:
[drs_export.ps1 (modified)]

$outfile = "C:\rules.txt"
$rules = get-cluster | Get-DrsRule

foreach($rule in $rules){
$line = (Get-View -Id $rule.ClusterId).Name
$line += ("," + $rule.Name + "," + $rule.Enabled + "," + $rule.KeepTogether)
foreach($vmId in $rule.VMIds){
$line += ("," + (Get-View -Id $vmId).Name)
}
$line | Out-File -Append $outfile
}


That's a quick and accurate way of documenting all of your DRS rules. If have a large enviornment and work extensively with DRS rules, you can run this on the vCenter server on a scheduled basis and have them dumped out in case you ever need to remove/readd a cluster object ( I can think of 2 scenarios off the top of my head this would apply to ). Then you can use the following script ( Also written by LucD ) to re-import rules:

[drs_import.ps1]

$file = "C:\rules.txt"
$rules = Get-Content $file

foreach($rule in $rules){
$ruleArr = $rule.Split(",")
if($ruleArr[2] -eq "True"){$rEnabled = $true} else {$rEnabled = $false}
if($ruleArr[3] -eq "True"){$rTogether = $true} else {$rTogether = $false}
get-cluster $ruleArr[0] | `
New-DrsRule -Name $ruleArr[1] -Enabled $rEnabled -KeepTogether $rTogether\
-VM (Get-VM -Name ($ruleArr[4..($ruleArr.Count - 1)]))
}


What's more, it's pretty trivial to make an engine to build the powershell that will generate the rules, and them insert those rules right into your vCenter. Here is an example script that I wrote earlier today:
[drs_rules.pl]

[root@vmprofessional scripts]# more drs_rules.pl
#!/usr/bin/perl -w

my @servers;
print "Cluster: ";
chomp ( my $cluster = );
print "Rule Name: ";
chomp ( my $rule_name = );

my $rule_number = 1;
while (scalar @ARGV > 0 ){
my $server = shift(@ARGV);
foreach ( @ARGV ){
print "New-DrsRule -RunAsync -Cluster $cluster -Name \"$rule_name #$rule_number\"\
-Enabled \$true -KeepTogether \$false -VM $server,$_\n";
$rule_number++;
}
}



Running this util would generate output like the following ( where a, b, c and d are the VM names that need anti affinity rules ):

[root@vmprofessional scripts]# ./drs_rules.pl a b c d
Cluster: test
Rule Name: dominic test
New-DrsRule -RunAsync -Cluster test -Name "dominic test #1" -Enabled $true -KeepTogether $false -VM a,b
New-DrsRule -RunAsync -Cluster test -Name "dominic test #2" -Enabled $true -KeepTogether $false -VM a,c
New-DrsRule -RunAsync -Cluster test -Name "dominic test #3" -Enabled $true -KeepTogether $false -VM a,d
New-DrsRule -RunAsync -Cluster test -Name "dominic test #4" -Enabled $true -KeepTogether $false -VM b,c
New-DrsRule -RunAsync -Cluster test -Name "dominic test #5" -Enabled $true -KeepTogether $false -VM b,d
New-DrsRule -RunAsync -Cluster test -Name "dominic test #6" -Enabled $true -KeepTogether $false -VM c,d

You can then take that output, and put it into a vSphere PowerCLI window, and it will inject all the DRS rules. My script it written in perl, but could just as well be written in powershell if you're so inclined.

Labels: drs anti affinity powershell

Posted by Dominic Rivera at Wednesday, June 10, 2009.


Archives

10/01/2006 - 11/01/2006 | 03/01/2007 - 04/01/2007 | 04/01/2007 - 05/01/2007 | 05/01/2007 - 06/01/2007 | 06/01/2007 - 07/01/2007 | 07/01/2007 - 08/01/2007 | 09/01/2007 - 10/01/2007 | 10/01/2007 - 11/01/2007 | 11/01/2007 - 12/01/2007 | 12/01/2007 - 01/01/2008 | 01/01/2008 - 02/01/2008 | 02/01/2008 - 03/01/2008 | 03/01/2008 - 04/01/2008 | 04/01/2008 - 05/01/2008 | 05/01/2008 - 06/01/2008 | 06/01/2008 - 07/01/2008 | 08/01/2008 - 09/01/2008 | 09/01/2008 - 10/01/2008 | 10/01/2008 - 11/01/2008 | 03/01/2009 - 04/01/2009 | 06/01/2009 - 07/01/2009 |

 
Copyright © 2007 - vmprofessional. All rights reserved.