DNS Loadbalancing

Die meisten Administratoren kennen Network Load Balancing (NLB), Hardware Load-Balancer, DNS Cache und TTL und DNS Round Robin. Jede Variante hat ihre individuellen Vorteile und Nachteile. Siehe auch WebCast LB und HA. Es gibt aber noch eine Zwischenform. bei der DNS-Antworten optimiert werden. Stellen Sie sich vor ein DNS-Server liefert immer nur die IP-Adressen der Server in einer Farm, die funktionieren.

Funktion und Abgrenzung

Verfügbarkeit beginnt immer damit, dass zwei oder mehr Systeme die gleiche Arbeit tun können und die Nutzer, also meistens Clients, bei einem Ausfall nichts oder wenig merken und Ressourcen geschont werden. Ein alter klassischer Aktiv/Passiv-Cluster, wie Exchange 2007 - Cluster Continuous Replication war schon besser verfügbar aber die Ressourcen des passiven Servers waren unterfordert. Hier konnte aber auch die IP-Adresse für den Service einfach mit schwenken. Seit dem es die DAG - Database Availability Groups gibt, können bis zu 16 Exchange Server in einem Verbund laufen und jeder hat eine Teilmenge der Datenbanken aktiv. Es gibt aber keine gemeinsame IP-Adresse mehr, so dass quasi "davor" eine Verteilung stattfinden muss. Allerdings kann ein Client jeden Exchange Frontend Service ansprechen. Der FE leitet die Anfrage entweder transparent zum Backend Server weiter oder macht einen Redirect des Clients zu einem anderen Pool-Namen.

Funktionsweise

Die Bereitstellung von Diensten über DNS Loadbalancing ähnelt sehr stark dem Verfahren DNS Round Robin. Während aber bei DNS Round Robin ein Client immer unterschiedliche und mehrere Adressen geliefert bekommt und dann die Systeme anspricht, nutzt man sich bei DNS Loadbalancing die Möglichkeit, dass ein entsprechend präparierter DNS-Service nur genau die IP-Adressen zurück gibt, die funktionieren. Er kann sogar genau eine IP-Adresse zurück geben und damit den Client gezielt auf einen Server lenken.

Um im Fehlerfall möglichst flexibel zu reagieren, wird die Antwort mit einer eher kurzen Verfallszeit (TTL) versehen, so dass ein Client diese Daten nicht allzu lange im Cache vorhält, sondern immer mal wieder neu nachfragt. So kann der Betreiber auch einfach die Clients auf andere Server verlagern oder im Fehlerfall den defekten Server aus der Liste streichen.

Anders als DNS-Round Robin, bei dem quasi immer alle Server zurück gegeben werden, kann diese Verteilung auch die Verfügbarkeit der Dienste mit einbeziehen. Dazu benötigen wir aber einen Service, der die Verfügbarkeit der Dienste prüft und abhängig davon dann die Antwort realisiert.

In den meisten Fällen ist der Dienst selbst ein Name in einer Domäne, wie z:B. "outlook.office365.com". ein normaler DNS-Eintrag sieht daher wie folgt aus:

uclabor.de. 1800     IN  SOA  ns1.uclabor.de. admin.uclabor.de (
                                     2019011301   ; Seriennummer
                                            300   ; Refresh Time
                                            100   ; Retry Time
                                            6000  ; Expire Time
                                            600   ; negative Caching Zeit
                                               )
uclabor.de.    1800  IN  NS   ns1.uclabor.de.
ns1                  IN  A    192.168.1.2
outlook              IN  A    192.168.1.3
outlook              IN  A    192.168.1.4

Das wäre dann ein Beispiel für DNS Round Robin mit zwei Einträgen. Die Domäne uclabor.de wird vom DNS alleine angehängt, wenn der Eintrag keinen "." am Ende hat

Der normale DNS-Server prüft natürlich nicht, ob ein Server erreichbar ist oder nicht, ehe er eine Anfrage beantwortet. Aber es ist im DNS-System über eine Delegierung möglich, eine Zone abzutrennen. Genau das mache ich nun, indem ich eine eigene Zonendatei für outlook.uclabor.de anlege. Hier erst mal als statische Zone aber mit einem kürzeren TTL von 60 Sekunden.

outlook.uclabor.de. 1800           IN  SOA  ns1.outlook.uclabor.de. admin.uclabor.de (
                                     2019011301   ; Seriennummer
                                            300   ; Refresh Time
                                            10   ; Retry Time
                                            60    ; Expire Time
                                            60    ; negative Caching Zeit
                                               )
outlook.uclabor.de.    1800  IN  NS ns.outlook.uclabor.de.
ns.outlook.uclabor.de        IN  A    <IP-Adresse des Loadbalancers oder optimierten DNS-Servers>
@                            IN  A    192.168.1.3
@                            IN  A    192.168.1.4

Zudem muss ich in der darüber liegenden Zone eine Delegierung auf outlook.uclabor.de einrichten. Die oben exemplarisch angegebene Zone wird also geändert

uclabor.de. 1800     IN  SOA  ns1.uclabor.de. admin.uclabor.de (
                                     2019011301   ; Seriennummer
                                            300   ; Refresh Time
                                            100   ; Retry Time
                                            6000  ; Expire Time
                                            600   ; negative Caching Zeit
                                               )
uclabor.de.    1800  IN  NS   ns1.uclabor.de.
ns1                  IN  A    192.168.1.2
outlook              IN  NS   <IP-Adresse des Loadbalancers oder optimierten DNS-Servers1>
outlook              IN  NS   <IP-Adresse des Loadbalancers oder optimierten DNS-Servers2>

Die Hauptdomäne verweist also Anfragen nach "outlook.uclabor.de" auf die hinterlegte IP-Adresse. Nun brauchen wir nur noch einen DNS-Service, der diese Anfragen bekommt und anhand einer Statustabelle die entsprechende Antwort liefert. Wenn im DNS durchgängig eine Delegierung und keine Weiterleitung zum Einsatz kommt, stellt der Client selbst die Anfrage an den Loadbalancer. Der Loadbalancer kann somit sogar Affinitäten beibehalten. Wenn der Loadbalancer nicht nur den Verfügbarkeitsstatus der Dienste sondern auch deren Last ermittelt, dann kann sogar eine Verteilung nach der Last erfolgen.

Diese Funktion wird im Internet sogar recht häufig eingesetzt um z.B. per GeoDNS bestimmte Anfragen nach einer Adresse zu einem System zu leiten, welches nahe am Client steht. Insofern ist GeoDNS auch über die gleiche Funktion umgesetzt.

Andere Loadbalancer kennen das Feature natürlich auch.

Praktische Umsetzung

Nicht jeder hat einen Loadbalancer zuhause und ich habe mir überlegt, wie man diese Funktion vielleicht auch einfach mit Bordmitteln erreichen kann.

Eine andere "Selbstbaulösung" für eine bessere Verfügbarkeit habe ich auf MiniSFT beschrieben.

Folgendes System habe ich mir ausgedacht:

  • Es gibt zwei Webserver, die beide die gleiche Information bereit stellen
  • Auf den Servern läuft zusätzlich ein DNS-Server
  • Der DNS-Server hat genau die Child-Zone mit dem Namen des Servers
    Diese Zone darf natürlich nicht repliziert werden und ist daher als Primary-Zone auf jedem Server angelegt. Sie sieht auf den beiden Server dann wie folgt aus. Beachten Sie einfach den Unterschied in der IP-Adresse
    • Root-Zone uclabor.de auf dem normalen DNS-Servern als Delegierung auf die beiden Server

      In der delegierten Zone gibt es nur den Verweis auf die beiden DNS-Server, die mit auf den WebServern installiert sind. Der entsprechende A-Record ist in der uclabor.de-Zone und hier nicht zu sehen
    • Zone outlook.uclabor.de auf Server 1
    • Zone outlook.uclabor.de auf Server 2
  • WebServer auf Server 1 und Server 2
    In der ersten Stufe reicht mit ein Webserver, der eine Seite ausliefert.

Wenn einer der Server quasi "Down" ist, dann antwortet auch der DNS-Server nicht. Ich erhoffe mir dabei, dass der Client daher sehr schnell den nächsten Server nutzt, der per Delegation mit angeboten wird.

Ob das auch funktioniert, habe ich natürlich per WireShark nachgeschaut. Allein für die Namensauflösung reicht ja auch ein "PING". Leider hat mein Windows Client eine ganz andere Reaktion gezeigt. Der Client hat den DNS-Serer gefragt und von diesem auch die Antwort bekommen.

Erst ein Mitschnitt auf dem DNS-Server hat gezeigt, dass dort die Delegation erfolgt ist.

Das Bild sieht also eher so aus:

Aber schlussendlich bleibt das Ergebnis gleich. Ich habe einen Dauertest gemacht:

# Abfrage des Namens. Gut zu sehen, dass nur eine Adresse kommt aber der TTL=0 ist
Resolve-DnsName outlook.uclabor.de

Name               Type TTL Section IPAddress
----               ---- --- ------- ---------
outlook.uclabor.de A    0   Answer  192.168.1.3

# Nun das ganze als Dauertest
while ($true) {
   (Resolve-DnsName outlook.uclabor.de -Server nawdc003).ipaddress;
   start-sleep -Seconds 1
}

Die Anfragen wurden sehr schnell beantwortet und die Antworten wechselten zwischen der 192.168.1.3 und 192.168.1.4. Als ich dann einen Server "offline" genommen habe, indem ich einfach den DNS-Dienst auf dem Server gestoppt habe, wurde dessen IP-Adresse auch nicht mehr zurück gegeben. Der andere Server hat weiter die Daten geliefert und der Windows DNS-Server, der vom Client gefragt wird, findet ja noch den zweiten Server. Wenn ich dann beide DNS-Server beende, dann bekommt der Client auch keine IP-Adresse mehr.

Allerdings ist hier immer das Thema "Cache" im Boot. Sie müssen schon genau hinschauen, dass an jeder Stelle sichergestellt ist, dass nicht eine Komponenten auf dem Weg die Daten doch im Cache hält und damit Ausfälle erst verzögert beim Client zu einem Wechsel der IP-Adresse führen.

In der Konfiguration überprüft der DNS-Server selbst natürlich nicht, wie "gesund" es dem Dienst geht. Aber es ist technisch sehr einfach den DNS-Server mit dem eigentlichen Server zu verbinden. Ich kann z.B. relativ einfach über die Windows Dienste eine Abhängigkeit dergestalt einbauen, dass der DNS-Server erst startet, wenn der WWW-Dienst gestartet wurde. Ich kann den DNS-Server auch als "Delayed Autostart" eintragen, so dass alle anderen Dienste schon vorab sich warmlaufen können. Natürlich kann ich auch eine Monitoring-Lösung einsetzen, die immer wieder die "Gesundheit" des eigentlichen Dienstes überprüft und ggfls. den DNS-Server beendet. Damit wäre auch die Integration in ein Enterprise Monitoring sehr einfach möglich: Wenn der DNS-Server auf dem Dienstserver nicht läuft, dann hat auch der Dienst ein Problem. Wenngleich das natürlich keine professionelle Alternative zu einer richtigen Überwachung ist.

Eine intelligente Lastverteilung kommt so natürlich auch nicht zum Tragen. Bei genügend Abfragen dürfte es auf eine Gleichverteilung hinauslaufen, wie dies auch DNS Round Robin und Network Load Balancing (NLB) machen. Es kostet halt nichts.

Eine andere Option ist natürlich direkt die DNS-Zone per WMI- PowerShell oder DNSCMD zu verändern. Dann können Sie sich diese Subzonen und zusätzlichen DNS-Server auch sparen und direkt die Hauptzone bearbeiten.

Windows 2016 DNS Policies

Bei der Recherche zu dem Artikel bin ich über eine interessante Funktion gestoßen, die wohl seit Windows 2016 DNS verfügbar ist

Leider ist hier nicht die Verfügbarkeit das Ziel sondern unterschiedliche Ansichten auf eine Zone je nach Zeit oder Source-IP. So lassen sich Client geografisch zu einem naheliegenden Server leiten.

Weitere Links