Load balancing DNS servers using DHCP Server Policies

This blog is authored by Ken Johnson, Senior Premier Field Engineer, Microsoft.

DNS is one of the critical services needed for accessing network resources.  Response time of the DNS server is critical to the speed and performance of relying services.  These two blogs have the timeout information and DNS client behavior explained in detail (DNS Clients and Timeouts (Part 1)  and DNS Clients and Timeouts (part 2)).  The important aspect of this to note is that the DNS server has a full second to respond to queries.  As long as all clients receive a response within this timeframe everything operates from a single DNS server.  The functionality to query additional DNS servers in the event that it does not respond in time is described in the above blogs.  During high usage times I’ve seen varied response times, but under load the primary DNS server will respond slower than other DNS servers available to a site.  Normally, the DNS configuration is done through DHCP and options to load balance the preferred DNS servers are limited.   One option could be to split your scopes and individually assign a random DNS server order for each half of the scope.  This is inefficient and will lead to an increase in management overhead to keep up.  This may be fine if you are only maintaining a few scopes.  But, maintaining this across multiple scopes would require unique settings on each scope and any changes to the DNS infrastructure would need to be changed individually as well.

Now with Windows Server 2012 R2 we have the availability of Policy Based Assignment to configure options for the server or the scope.  One possibility to load balance these DNS server settings is to use the MAC address of the requesting client.  The Policy Based Assignment gives us the option to use the MAC address as a condition to specify DHCP options to use for our clients.  The MAC address is made up of two parts. The first half is the Organizationally Unique Identifier (OUI) and the second half is the Network Interface Controller (NIC) specific section.  Because in many acquisitions of new hardware we end up with the same manufacturer focusing on the second half of the MAC address would result in a much higher probability of getting an equal distribution of requests to the corresponding DNS servers.  If we were to focus on the first half of the MAC address we would end up assigning large blocks of clients to the same DNS server, this would not be the intended outcome.  If we used the entire MAC address we would end up having to distribute 281,474,976,710,656 possibilities into each of our policies, too many to put in.  That being said in this case we chose to simply use the last two digits with only 256 possibilities to distribute between the policies. 

Using PowerShell we can easily randomize the DNS servers utilized by focusing in on the last two digits of the MAC address and prefixing the rest with a wildcard(*).  In the script below, we create all 256 possibilities from 00 to FF in an array of conditions for each policy to meet.  Then assign the MAC address to each policy in a sequenced order to ensure a pseudo random assignment throughout the policies.  The following function will configure one policy per DNS server specified.  Each policy will specify a different DNS server as the preferred primary DNS server.  Additionally, each policy will get a distribution of the MAC addresses to match to facilitate the ‘load balancing’.

function Add-CustomDHCPServerv4LoadBalancedDNSPolicy

{

    param (

        [string]

        $PolicyPrefix,

         [ipaddress[]]

        $DNSServers,

        [string[]]

        $ComputerName

    )

    for($i=0;$i-lt$DNSServers.Count;$i++)

    {

        Set-Variable -Name $i -Value @('EQ')

     }

    for([int]$i=0;$i-lt256;$i++)

    {

        $cv = Get-Variable -Name ($i%$DNSServers.Count) -ValueOnly

        $v = $i | % { $_.ToString("X") } | % { if($_.length -lt 2){ "0"+$_ }else{ $_ } }

        Set-Variable -Name ($i%$DNSServers.Count) -Value ($cv + ("*$v"))

    }

    for($i=0;$i-lt$DNSServers.Count;$i++)

    {

        $ips = @()

        "$policyPrefix-$($i+1) - $((Get-Variable -Name $i -ValueOnly).Count - 1)"

        for($f=0;$f-lt$DNSServers.Count;$f++)

        {

            $ips += $DNSServers[$(($i+$f)%($DNSServers.Count))]

        }

        foreach($computer in $ComputerName)

        {

            Add-DhcpServerv4Policy -Name "$PolicyPrefix-$($i+1)" -Condition OR -MacAddress (Get-Variable -Name $i -ValueOnly) -ComputerName $computer

            Set-DhcpServerv4OptionValue -PolicyName "$PolicyPrefix-$($i+1)" -OptionId 006 -Value $ips -ComputerName $computer

        }        

     }  

}

Let’s look at an example where we have 3 DNS servers to specify:

Server1 = 10.0.0.253

Server2 = 10.0.0.252

Server3 = 10.0.0.249 

To run the command we would need to specify three parameters. 
$PolicyPrefix = The name of the policy

$DNSServers = An array of possible DNS servers in your environment

$ComputerName = An array of DHCP servers that you want to configure these policies on

Add-CustomDHCPServerv4LoadBalancedDNSPolicy DNS '10.0.0.254','10.0.0.253','10.0.0.249' 'DC-01','DC-02'

There are two DHCP servers in a failover partnership in this example DC-01 and DC-02.  This command will run on both and configure three policies.  The output of the command lets you know how the distribution of MAC addresses were placed into your policies.  In this case, DNS-1 policy has 1 more criteria (86 in total) to match than policies DNS-2 and DNS-3 (85 in total).

 

  

Hope this helps the DHCP Administrators out there to administer the DNS server options in their environment!