Einen hoch-verfügbaren NFS Server aufsetzen

Setting Up A Highly Available NFS Server

Version 1.0
Author: Falko Timme <ft [at] falkotimme [dot] com>
Last edited: 03/07/2006

Diese Anleitung veranschaulicht, wie man einen hoch-verfügbaren NFS server aufsetzt, der als Speicherlösung für andere hoch-verfügbare Dienste wie zum Beispiel einem Cluster von Web Servern verwendet werden kann. Wenn Du ein Web Server Cluster bestehend aus zwei oder mehreren Systemen hast, die die gleiche(n) Webseite(n) bedienen, dann müssen diese Systeme auf den gleichen Datenpool zugreifen, so dass jedes System die gleichen Daten bedient, egal ob der Loadbalancer den Benutzer  auf System 1 oder n verweist. Das kann mit einer NFS Freigabe auf einem NFS Server, auf den alle Web Server Systeme (die NFS Clients) zugreifen können, erreicht werden.

Da wir nicht möchten, dass der NFS Server zu einer weiteren Schwachstelle wird, müssen wir ihn hoch-verfügbar machen. Tatsächlich werde ich in dieser Anleitung zwei NFS Server erstellen, die ihre Daten in Echtzeit unter Verwendung von DRBD spiegeln und sich mittels heartbeat gegenseitig überwachen. Wenn ein NFS Server ausfällt, übernimmt der andere. Nach außen werden diese beiden NFS Server den Anschein erwecken, als sei es nur ein NFS Server.

In diesem Setup werde ich Debian Sarge (3.1) für die beiden NFS Server sowie für den NFS Client (der ein System des Web Server Clusters repräsentiert) verwenden.

Ich möchte an dieser Stelle darauf hinweisen, dass dies nicht der einzige Weg ist, ein solches System aufzusetzen. Es gibt viele Möglichkeiten dieses Ziel zu erreichen – dies ist der Weg, den ich gewählt habe. Ich übernehme keine Garantie, dass dies auch bei Dir funktioniert!

1 Mein Setup

In dieser Anleitung verwende ich folgende Systeme:

  • NFS Server 1: server1.example.com, IP Adresse: 192.168.0.172; ich werde mich als server1 auf ihn beziehen.
  • NFS Server 2: server2.example.com, IP Adresse: 192.168.0.173; ich werde mich als server2 auf ihn beziehen.
  • Virtuelle IP Adresse: ich verwende 192.168.0.174 als die virtuelle IP Adresse, die das NFS Cluster nach Außen repräsentiert.
  • NFS Client (z.B. ein System des Web Server Clusters): client.example.com, IP Adresse: 192.168.0.100; ich werde mich client auf den NFS Client beziehen.
  • Das /data Verzeichnis wird von DRBD zwischen server1 und server2 gespiegelt. Es wird die NFS Freigabe /data/export beinhalten.

2 Basis-Installation von server1 und server2

Zuerst richten wir zwei Debian Basissysteme für server1 und server2 ein. Dies nimmst Du wie auf den ersten beiden Seiten folgender Anleitung beschrieben wird vor: https://www.howtoforge.com/perfect_setup_debian_sarge. Als Hostnamen gibst Du an gegebener Stelle server1 und server2 ein und example.com als Domain.

Was die Partitionierung betrifft, verwende ich folgendes Partitionsschema:

/dev/sda1 — 100 MB /boot (primary, ext3, Bootable flag: on)
/dev/sda5 — 5000 MB / (logical, ext3)
/dev/sda6 — 1000 MB swap (logical)
/dev/sda7 — 150 MB unmounted (logical, ext3)
(wird DRBDs Meta Daten enthalten)
/dev/sda8 — 26 GB unmounted (logical, ext3)
(wird das /data Verzeichnis enthalten)

Du kannst die Größe der Partitionen entsprechend der Größe Deiner Festplatte ändern. Die Bezeichnung Deiner Partition können ebenfalls variieren, das hängt von Deiner Hardware ab (z.B. hast Du vielleicht /dev/hda1 anstelle von /dev/sda1 und so weiter). Es ist jedoch wichtig, dass /dev/sda7 etwas mehr als 128 MB aufweist, da wir diese Partition für DRBDs Meta Daten verwenden, was 128 MB verwendet. Pass auf, dass /dev/sda7 sowie /dev/sda8 die gleiche Größe auf server1 und server2 aufweisen und bitte mounte sie nicht (wenn Dich der Installer fragt:

No mount point is assigned for the ext3 file system in partition #7 of SCSI1 (0,0,0) (sda).
Do you want to return to the partitioning menu?

antworte bitte No)! /dev/sda8 wird unsere Daten-Partition sein (d.h. unsere NFS Freigabe).

Stelle nach der Basis-Installation sicher, dass Du server1 und server2 statische IP Adressen (server1: 192.168.0.172, server2: 192.168.0.173) zuweist, was am Anfang von https://www.howtoforge.com/perfect_setup_debian_sarge_p3) beschrieben wird.

Danach solltest Du /etc/fstab auf beiden Systemen überprüfen. Meine sieht auf beiden Systemen wie folgt aus:

# /etc/fstab: static file system information.
#
#              

proc            /proc           proc    defaults        0       0
/dev/sda5       /               ext3    defaults,errors=remount-ro 0       1
/dev/sda1       /boot           ext3    defaults        0       2
/dev/sda6       none            swap    sw              0       0
/dev/hdc        /media/cdrom0   iso9660 ro,user,noauto  0       0
/dev/fd0        /media/floppy0  auto    rw,user,noauto  0       0

Wenn Deine zum Beispiel wie diese aussieht:

# /etc/fstab: static file system information.
#
#              

proc            /proc           proc    defaults        0       0
/dev/hda5       /               ext3    defaults,errors=remount-ro 0       1
/dev/hda1       /boot           ext3    defaults        0       2
/dev/hda6       none            swap    sw              0       0
/dev/hdc        /media/cdrom0   iso9660 ro,user,noauto  0       0
/dev/fd0        /media/floppy0  auto    rw,user,noauto  0       0

dann pass bitte auf, dass Du /dev/hda anstelle von /dev/sda in den folgenden Konfigurationsdateien verwendest. Pass ebenfalls auf, dass /dev/sda7 (oder /dev/hda7) und /dev/sda8 (oder /dev/hda8…) nicht in /etc/fstab aufgelistet sind!

3 Synchronisation der System-Zeit

Es ist wichtig, dass server1 und server2 die gleiche System-Zeit haben. Daher installieren wir einen NTP Client auf beiden Servern:

server1/server2:

apt-get install ntp ntpdate

Danach kannst Du überprüfen, ob beide die gleiche Zeit haben, indem Du dies ausführst

server1/server2:

date

4 Installation des NFS Servers

Als Nächstes installieren wir den NFS Server auf server1 und server2:

server1/server2:

apt-get install nfs-kernel-server

Dann entfernen wir die System Bootup Links für NFS, da NFS in unserem Setup von heartbeat gestartet und kontrolliert wird:

server1/server2:

update-rc.d -f nfs-kernel-server remove
update-rc.d -f nfs-common remove

Wir möchten das Verzeichnis /data/export (d.h. dies wird unsere NFS Freigabe sein, die unsere Web Server Cluster Systeme verwenden werden, um Web Inhalt zu bedienen) exportieren, also bearbeiten wir /etc/exports auf server1 und server2. Es sollte nur die folgende Zeile enthalten:

server1/server2:

/etc/exports:

/data/export/ 192.168.0.0/255.255.255.0(rw,no_root_squash,no_all_squash,sync)

Das bedeutet, dass auf /data/export von allen Systemen aus dem 192.168.0.x Subnetz zugegriffen werden kann. Du kannst den Zugriff auf ein einziges System beschränken, indem Du 192.168.0.100/255.255.255.255 anstelle von 192.168.0.0/255.255.255.0 verwendest. Sieh Dir zum Beispiel

man 5 exports

an um mehr darüber zu erfahren.

Zu einem späteren Zeitpunkt werden wir  /data/exports auf unserer leeren (und immer noch nicht gemounteten!) Partition /dev/sda8 erstellen.

5 Installation von DRBD

Als Nächstes installieren wir DRBD auf server1 und server2:

server1/server2:

apt-get install kernel-headers-2.6.8-2-386 drbd0.7-module-source drbd0.7-utils
cd /usr/src/
tar xvfz drbd0.7.tar.gz
cd modules/drbd/drbd
make
make install

Bearbeite dann /etc/drbd.conf auf server1 und server2. Es muss auf beiden Systemen identisch sein und wie folgt aussehen:

server1/server2:

/etc/drbd.conf:

resource r0 {

 protocol C;
 incon-degr-cmd "halt -f";

 startup {
    degr-wfc-timeout 120;    # 2 minutes.
  }

  disk {
    on-io-error   detach;
  }

  net {

  }

  syncer {

    rate 10M;

    group 1;

    al-extents 257;
  }

 on server1 {                # ** EDIT ** the hostname of server 1 (uname -n)
   device     /dev/drbd0;        #
   disk       /dev/sda8;         # ** EDIT ** data partition on server 1
   address    192.168.0.172:7788; # ** EDIT ** IP address on server 1
   meta-disk  /dev/sda7[0];      # ** EDIT ** 128MB partition for DRBD on server 1
  }

 on server2 {                # ** EDIT ** the hostname of server 2 (uname -n)
   device    /dev/drbd0;         #
   disk      /dev/sda8;          # ** EDIT ** data partition on server 2
   address   192.168.0.173:7788;  # ** EDIT ** IP address on server 2
   meta-disk /dev/sda7[0];       # ** EDIT ** 128MB partition for DRBD on server 2
  }

}

Als Resource Namen kannst Du nehmen was immer Du willst. Hier ist es r0. Bitte pass auf, dass Du die korrekten Hostnamen von server1 und server2 in /etc/drbd.conf einsetzt. DRBD erwartet dass die Hostnamen so sind wie sie von folgendem Befehl angezeigt werden

uname -n

Wenn Du server1 und server2 als Hostnamen während der Basis-Installation von Debian gewählt hast, dann sollte die Ausgabe von uname -n  server1 und server2 sein.

Pass außerdem auf, dass Du die IP Adressen und Festplatten entsprechend ersetzt. Wenn Du /dev/hda anstelle von /dev/sda verwendest, bitte setze /dev/hda8 anstelle von /dev/sda8 in /etc/drbd.conf (das Gleiche gilt für die meta-disk auf der DRBD seine Meta Daten speichert). /dev/sda8 (oder /dev/hda8…) wird später als unsere NFS Freigabe verwendet.

6 Konfiguration von DRBD

Nun laden wir das DRBD Kernel Modul auf server1 und server2. Das müssen wir nur dieses eine Mal ausführen, da es danach vom DRBD Init Skript geladen wird.

server1/server2:

modprobe drbd

Lass uns DRBD konfigurieren:

server1/server2:

drbdadm up all
cat /proc/drbd

Der letzte Befehl sollte etwas in der Art anzeigen (auf server1 und server2):

version: 0.7.10 (api:77/proto:74)
SVN Revision: 1743 build by phil@mescal, 2005-01-31 12:22:07
 0: cs:Connected st:Secondary/Secondary ld:Inconsistent
    ns:0 nr:0 dw:0 dr:0 al:0 bm:1548 lo:0 pe:0 ua:0 ap:0
 1: cs:Unconfigured

Wie Du siehst, geben beide NFS Server an, dass sie zweitrangig und die Daten inkonsistent sind. Das liegt daran, dass bisher noch kein Initial Sync ausgeführt wurde.

server1 soll der erste NFS Server und server2 der „hot-standby“ sein. Wenn server1 ausfällt, übernimmt server2 und wenn server1 wieder funktionsfähig ist, werden alle Daten, die sich in der Zwischenzeit geändert haben, von server2 auf server1 zurück gespiegelt, damit die Daten immer konsistent sind.

Der nächste Schritt wird nur auf server1 durchgeführt!

server1:

drbdadm — –do-what-I-say primary all

Nun starten wir das Initial Sync zwischen server1 und server2 damit die Daten auf beiden Servern konsistent werden. Auf server1 führen wir dies aus:

server1:

drbdadm — connect all

Das Initial Sync wird ein paar Stunden dauern (das hängt von der Größe von  /dev/sda8 (/dev/hda8…) ab), sei also bitte geduldig.

So siehst Du den Fortschritt des Initial Sync auf server1 oder server2:

server1/server2:

cat /proc/drbd

Die Ausgabe sollte wie folgt aussehen:

version: 0.7.10 (api:77/proto:74)
SVN Revision: 1743 build by phil@mescal, 2005-01-31 12:22:07
 0: cs:SyncSource st:Primary/Secondary ld:Consistent
    ns:13441632 nr:0 dw:0 dr:13467108 al:0 bm:2369 lo:0 pe:23 ua:226 ap:0
        [==========>.........] sync'ed: 53.1% (11606/24733)M
        finish: 1:14:16 speed: 2,644 (2,204) K/sec
 1: cs:Unconfigured

Wenn das Initial Sync abgeschlossen ist, sollte die Ausgabe wie folgt aussehen:

SVN Revision: 1743 build by phil@mescal, 2005-01-31 12:22:07
 0: cs:Connected st:Primary/Secondary ld:Consistent
    ns:37139 nr:0 dw:0 dr:49035 al:0 bm:6 lo:0 pe:0 ua:0 ap:0
 1: cs:Unconfigured

7 Eine weitere NFS Konfiguration

NFS speichert einige wichtige Informationen (z.B. Informationen über die Datei Locks, etc.) in /var/lib/nfs. Was passiert nun wenn server1 ausfällt? server2 übernimmt, aber seine Information in /var/lib/nfs wird von der Information im server1s /var/lib/nfs Verzeichnis abweichen. Dazu nehmen wir eine Optimierung vor, so dass diese Angaben auf unserer  /data Partition (/dev/sda8 oder /dev/hda8…) gespeichert werden, die von DRBD zwischen server1 und server2 gespiegelt wird. Wenn server1 also ausfällt, kann server2 die NFS Angaben von server1 verwenden.

server1/server2:

mkdir /data

server1:

mount -t ext3 /dev/drbd0 /data
mv /var/lib/nfs/ /data/
ln -s /data/nfs/ /var/lib/nfs
mkdir /data/export
umount /data

server2:

rm -fr /var/lib/nfs/
ln -s /data/nfs/ /var/lib/nfs

8 Installation und Konfiguration von heartbeat

heartbeat ist die Kontrollinstanz des ganzen Setups. Es wird auf server1 und server2 installiert und überwacht den anderen Server. Wenn server1 zum Beispiel ausfällt, bemerkt heartbeat das auf server2 und sorgt dafür, dass server2 übernimmt. Außerdem startet und stoppt heartbeat den NFS Server auf server1 und server2. Es bietet NFS außerdem als virtuellen Dienst via der IP Adresse 192.168.0.174 an, so dass die Web Server Cluster Systeme nur einen NFS server sehen.

Zuerst installieren wir heartbeat:

server1/server2:

apt-get install heartbeat

Nun müssen wir drei Konfigurationsdateien für heartbeat erstellen. Sie müssen auf server1 und server2 identisch sein!

server1/server2:

/etc/heartbeat/ha.cf:

logfacility     local0
keepalive 2
#deadtime 30 # USE THIS!!!
deadtime 10
bcast   eth0
node server1 server2

Als Systemnamen müssen wir die Ausgabe von uname -n auf server1 und server2 verwenden.

server1/server2:

/etc/heartbeat/haresources:

server1  IPaddr::192.168.0.174/24/eth0 drbddisk::r0 Filesystem::/dev/drbd0::/data::ext3 nfs-kernel-server

Das erste Wort ist die Ausgabe von uname -n auf server1, egal ob Du die Datei auf server1 oder server2 erstellst! Nach IPaddr setzen wir unsere virtuelle IP Adresse 192.168.0.174 ein und nach drbddisk verwenden wir den Resource Namen unserer DRBD Resource, was hier r0 ist (denke daran, das ist der Resource Name, den wir /etc/drbd.conf  verwenden – wenn Du einen anderen verwendest, musst Du ihn auch hier verwenden).

server1/server2:

/etc/heartbeat/authkeys:

auth 3
3 md5 somerandomstring

somerandomstring ist ein Password, den die beiden heartbeat Daemons auf server1 und server2 verwenden, um sich gegenseitig zu authentifizieren. Verwende hier Deine eigenen Zeichenfolge. Du hast die Wahl zwischen drei Authentifizierungsmechanismen. Ich verwende md5, da es der sicherste ist.

/etc/heartbeat/authkeys sollte nur von Root gelesen werden können, daher führen wir dies aus:

server1/server2:

chmod 600 /etc/heartbeat/authkeys

Schließlich starten wir DRBD und heartbeat auf server1 und server2:

server1/server2:

/etc/init.d/drbd start
/etc/init.d/heartbeat start

9 Erste Tests

Jetzt können wir unsere ersten Tests durchführen. Führe auf server1 dies aus

server1:

ifconfig

In der Ausgabe sollte die virtuelle IP Adresse 192.168.0.174 auftauchen:

eth0      Link encap:Ethernet  HWaddr 00:0C:29:A1:C5:9B
          inet addr:192.168.0.172  Bcast:192.168.0.255  Mask:255.255.255.0
          inet6 addr: fe80::20c:29ff:fea1:c59b/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:18992 errors:0 dropped:0 overruns:0 frame:0
          TX packets:24816 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:2735887 (2.6 MiB)  TX bytes:28119087 (26.8 MiB)
          Interrupt:177 Base address:0x1400

eth0:0    Link encap:Ethernet  HWaddr 00:0C:29:A1:C5:9B
          inet addr:192.168.0.174  Bcast:192.168.0.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          Interrupt:177 Base address:0x1400

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:71 errors:0 dropped:0 overruns:0 frame:0
          TX packets:71 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:5178 (5.0 KiB)  TX bytes:5178 (5.0 KiB)

Führe auch dies

server1:

df -h

auf server1 aus. Du müsstest dort nun /data aufgelistet sehen:

Filesystem            Size  Used Avail Use% Mounted on
/dev/sda5             4.6G  430M  4.0G  10% /
tmpfs                 126M     0  126M   0% /dev/shm
/dev/sda1              89M   11M   74M  13% /boot
/dev/drbd0             24G   33M   23G   1% /data

Wenn Du das Gleiche

server2:

ifconfig
df -h

auf server2 ausführst, solltest Du 192.168.0.174 und /data nicht sehen können.

Nun erstellen wir eine Testdatei in /data/export auf server1 und simulieren dann das Ausfallen von server1 (indem wir heartbeat stoppen):

server1:

touch /data/export/test1
/etc/init.d/heartbeat stop

Wenn Du nun ifconfig und df -h auf server2 ausführst, solltest Du die IP Adresse 192.168.0.174 und die /data Partition sehen, und

server2:

ls -l /data/export

sollte die Datei test1 auflisten, die Du zuvor auf server1 erstellt hast. Sie wurde also auf server2 gespiegelt!

Nun erstellen wir eine andere Testdatei auf server2 und überprüfen, ob sie auf server1 gespiegelt wird, wenn er wieder funktionstüchtig ist:

server2:

touch /data/export/test2

server1:

/etc/init.d/heartbeat start

(Wait a few seconds.)

ifconfig
df -h
ls -l /data/export

Du müsstest 192.168.0.174 und /data wieder auf server1 sehen, was bedeutet, dass er wieder übernommen hat (da wir ihn als ersten Server definiert haben). Außerdem solltest Du die Datei  /data/export/test2 sehen!

10 Konfiguration des NFS Clients

Nun installieren wir NFS auf unserem Client (192.168.0.100):

apt-get install nfs-common

Als Nächstes erstellen wir das  /data Verzeichnis und mounten unsere NFS Freigabe darin:

mkdir /data
mount 192.168.0.174:/data/export /data

192.168.0.174 ist die virtuelle IP Adresse, die wir zuvor konfiguriert haben. Du musst sicher gehen, dass der Forward und der Reverse DNS Record für client.example.com übereinstimmen, sonst erhältst Du eine „Permission denied“ Fehlermeldung auf dem Client und auf dem Server findest Du dies in /var/log/syslog:

#Mar  2 04:19:09 localhost rpc.mountd: Fake hostname localhost for 192.168.0.100 - forward lookup doesn't match reverse

Wenn Du keine entsprechenden DNS Records hast (oder für Dein lokales Netzwerk keinen DNS Server hast), musst Du dies nun ändern, sonst kannst Du die NFS Freigabe nicht mounten!

Wenn es funktioniert kannst Du nun weitere Testdateien in /data auf dem Client erstellen, dann den Ausfall von server1 und server2 simulieren (aber nicht beide zur gleichen Zeit!) und überprüfen, ob die Testdateien repliziert werden. Auf dem Client solltest Du überhaupt nicht bemerken, dass server1 oder server2 ausgefallen ist – die Daten im  /data Verzeichnis sollten immer verfügbar sein (es sei denn server1 und server2 fallen zur gleichen Zeit aus…).

Um das  /data Verzeichnis zu unmounten, führe dies aus

umount /data

Wenn die NFS Freigabe beim Hochfahren automatisch gemounted werden soll, setze folgend Zeile in /etc/fstab:

192.168.0.174:/data/export  /data    nfs          rw            0    0

Links

Das könnte Dich auch interessieren …