Studenten Net Twente making the net wiki work

Hoe zet je de fileservers op?

Er zijn twee fileservers: de primaire en de backup-fileserver. Deze twee moeten identiek ingericht worden.

Hoe werken de fileservers?

Als eerste een korte uitleg over de principes die gebruikt worden op de fileservers. De fileservers hebben drie functies:

  • Data van de webservers centraal opslaan via NFS
  • De webservers toegang geven tot de database via MySQL
  • Webmasters de gelegenheid geven om bestanden te uploaden via FTP

Om te zorgen dat de data altijd beschikbaar is is er een backup-fileserver die alle taken van de primaire fileserver kan overnemen als deze uitvalt. De fileservers zijn kevy en knagertje; de actieve server is altijd ook te benaderen als ftp.scouting.nl of fileserver.intern. Om te zorgen dat de backup-fileserver altijd de beschikking heeft over alle data gebruiken we DRBD, dit kan je zien als raid-1 over TCP/IP.

Ook de MySQL-data wordt via DRBD gerepliceerd en niet via MySQL-replication. We hebben getest met MySQL-replication maar hierbij bleken sommige queries niet op allebei de servers uitgevoerd te worden. Wat natuurlijk niet de bedoeling is. Door de MySQL-data op een DRBD-disk te zetten blijft deze wel consistent op beide servers.

Tot slot wordt op de fileservers, net als op de loadbalancers, Heartbeat gebruikt om in de gaten te houden wanneer een server stuk is en de andere het over moet nemen.

Partities indelen

Als eerste moeten de partities goed ingedeeld worden. Mocht je de partities ooit goed moeten zetten, hier is de dump van “sfdisk -d”:

# partition table of /dev/sda
unit: sectors

/dev/sda1 : start=        1, size=  4000184, Id=83, bootable
/dev/sda2 : start=  4000185, size= 16000740, Id=82
/dev/sda3 : start= 20000925, size= 31455270, Id=83
/dev/sda4 : start= 51456195, size=234757845, Id= 5
/dev/sda5 : start= 51456258, size=  9992367, Id=83
/dev/sda6 : start= 61448688, size= 20000862, Id=83
/dev/sda7 : start= 81449613, size= 20000862, Id=83
/dev/sda8 : start=101450538, size= 29993292, Id=83
/dev/sda9 : start=131443893, size= 20000862, Id=83
/dev/sda10: start=151444818, size=130110372, Id=83
/dev/sda11: start=281555253, size=  4658787, Id=83

Deze partities worden als volgt gebruikt:

Partitie Grootte DRBD-disk Mountpoint
/dev/sda1 2 GB /
/dev/sda2 8 GB swap
/dev/sda3 15 GB /dev/drbd0 /home
/dev/sda4 extended
/dev/sda5 5 GB /dev/drbd1 /var/lib/mysql
/dev/sda6 10 GB /dev/drbd2 /var/data
/dev/sda7 10 GB /usr
/dev/sda8 15 GB /dev/drbd3 /usr/local
/dev/sda9 10 GB /var
/dev/sda10 61 GB /dev/drbd4 /var/www

Het makkelijkst is het om de partities meteen bij het installeren goed te zetten. Dit kan bijvoorbeeld door de bovenstaande sfdisk-dump als volgt te gebruiken:

sfdisk /dev/sda < dumpfile

Wil je het toch later nog veranderen dan kan je twee dingen doen:

  1. Gebruik maken van parted om de partities te veranderen met behoud van data
  2. Alle data backuppen, de dump inlezen in sfdisk, nieuwe filesystems maken en alle data terugzetten.



Je hoeft op dit punt nog geen filesystems te maken op de partities die DRBD straks gaat gebruiken, dit kan pas als DRBD eenmaal draait!

DRBD installeren

DRBD bestaat uit twee gedeeltes: kernel-modules en een aantal tooltjes om die kernel-modules te kunnen gebruiken. Om de kernel-modules te kunnen compilen moet je de beschikking hebben over de “kernel-compile-tree”, dit zijn de directories waarin de huidige kernel gecompiled is.

Als eerste moeten de tools geinstalleerd worden:

apt-get install drbd0.7-utils module-assistant

Kernel-modules

Vervolgens moeten de kernel-modules een keer geinstalleerd worden zodat die directory-structuur in /lib/modules gemaakt wordt:

cd /usr/src/linux-2.6.15.1
make modules_install


Nu kunnen de drbd-modules gecompiled worden. Dit gaat met module-assistant, kortweg m-a:

m-a a-i drbd0.7-module-source

Dit geeft een wizzard die de modules compiled. Het kan zijn dat deze wizzard een error geeft maar dat is meestal geen probleem. Als alles klaar is staat er in /usr/src een .deb-pakketje met de modules er in, deze kunnen geinstalleerd worden met:

dpkg -i /usr/src/drbd0.7-module-2.6.15.1snti004_0.7.10-4_i386.deb

Let hierbij even op de filename, het exacte versienummer kan iets verschillen.

Nu kunnen de modules toegevoegd worden met modconf; ze zijn te vinden onder kernel/drivers/block. Modconf vraagt naar command-line opties voor de modules, hier moet komen te staan:

minor-count=10

Standaard is dit 2 en dan kunnen er maar 2 drbd-disks gebruikt worden. We gebruiken er hier echter 5. Om voorlopig veilig te zitten is het de beste optie om hier 10 in te vullen.

Als de modules geinstalleerd zijn kan je even in het syslog kijken of de drbd-modules inderdaad geladen zijn.

DRBD configureren

Nu alles ingesteld is begint het echte werk pas. In /etc/drbd.conf moet per DRBD-partitie iets ingesteld worden:

resource home {
  protocol C;
  incon-degr-cmd "killall heartbeat";

  startup {
    degr-wfc-timeout 120;
  }

  disk {
    on-io-error pass_on;
  }

  syncer {
    rate 100M; # Note: 'M' is MegaBytes, not MegaBits
    group 1;
    al-extents 257;
  }

  on ando {
    device    /dev/drbd0;
    disk      /dev/sda3;
    address   10.0.6.22:7789;
    meta-disk  internal;
  }

  on filius {
    device    /dev/drbd0;
    disk      /dev/sda3;
    address   10.0.6.24:7789;
    meta-disk  internal;
  }
}

Dit moet per “resource” gebeuren. Een resource is een DRBD-disk en dus ook een partitie op de schijf.

Hier een uitleg van de opties:

  • resource home {: Hiermee begin je een resource-block. Elke resource moet een unieke naam hebben, we gebruiken hier gewoon de namen van de mountpoints
  • protocol C: Welk protocol er gebruikt wordt. C is op het moment van schrijven het nieuwste.
  • incon-degr-cmd: Welk commando moet er uitgevoerd worden als DRBD in paniek raakt? Heartbeat stoppen is een goede omdat de andere server het dan over kan nemen. We hopen dat de andere server het op dit punt nog wel snapt.
  • startup { degr-wfc-timeout: Bij het opstarten van DRBD (wat gebeurt bij het opstarten van de server) wordt er een bepaald aantal seconden gewacht tot de andere server ook online komt. 120 seconden is misschien wat veel, maar het geeft de andere server in ieder geval wat tijd om verbinding te maken. In de praktijk kan deze fase soms wel een halve minuut duren.
  • disk { on-io-error pass_on: Als er een I/O-error optreedt op de fysieke schijf, wat moet er dan gebeuren? pass_on wil zeggen dat de I/O-error wordt doorgegeven aan het programma wat aan het lezen/schrijven is. Dat programma moet het dan maar afhandelen.
  • syncer { rate 100M: De maximale snelheid waarmee gegevens gesynchroniseerd worden over het netwerk. 100 MegaByte per seconde is een mooie snelheid omdat we toch gigabit hebben. En zo blijft er nog wat bandbreedte over voor de applicaties.
  • group 1: Het is mogelijk om een aantal DRBD-disks tegelijk te syncen. Bij ons staan ze echter allemaal op de zelfde fysieke schijf/raid-array, dus willen we niet dat ze tegelijk worden gesynct. Door alle resources in group 1 te stoppen worden ze niet tegelijk gesynct.
  • al-extents 257: Dit heeft iets te maken met het synchronisatie-protocol. Om het efficient te laten werken moet dit zeker geen 2-macht zijn. Een priemgetal werkt het beste.
  • on ando {: Per server staat er zo'n block met daarin de server-specifieke config. Deze config moet wel op allebei de machines staan!
  • device /dev/drbd0: Aan welk device moet deze DRBD-disk komen te hangen?
  • disk /dev/sda3: Op welke partitie moet de data komen te staan?
  • address 10.0.6.22:7789: Welk IP heeft deze machine? Let op dat het poortnummer bij elke DRBD-disk anders moet zijn, je kan een poort maar voor 1 DRBD-disk gebruiken! :!: Let er ook op dat deze poorten open moeten zijn in de firewall.
  • meta-disk internal: De meta-disk is waar DRBD z'n meta-data opslaat. Dit is bijvoorbeeld de drive-bitmap van welke stukken nog gesynchroniseerd moeten worden. Internal wil zeggen dat de meta-data op de partitie zelf wordt opgeslagen
  • on filius {: De config voor de andere server. Hier is deze toevallig identiek aan die van Ando, maar dat hoeft natuurlijk niet. Als de partities maar even groot zijn.

Per resource maak je nu zo'n blok aan, denk er aan dat je steeds een andere naam, /dev/drbdX, /dev/sdaX en poortnummer gebruikt. Vervolgens kopieer je de configfile ook naar de andere server zodat ze een identieke config hebben.

DRBD voor het eerst starten

Nu kan je DRBD starten met:

/etc/init.d/drbd start

In het syslog kan je vervolgens kijken of het werkt.

Als de twee machines verbinding hebben met elkaar moet je DRBD vertellen dat een van de twee primary is. Alleen op het systeem wat primary is kan je bij de data, op het andere systeem (dat is dan “secondary”) kan dat niet! Omdat het nu de eerste keer is weet DRBD nog niet welke van de twee machines de correcte data bevat. Omdat er nog helemaal geen data op staat maakt het niks uit op welke machine je het doet:

drbdsetup /dev/drbd0 primary --do-what-I-say

Dit doe je voor elke DRBD-disk die je aangemaakt hebt, dus ook voor drbd1, drbd2 etc. DRBD gaat nu de (lege) partities synchroniseren. De voortgang hiervan kan je volgen met:

watch cat /proc/drbd

Als het syncen van de eerste partitie klaar is kan je die gaan voorzien van een filesystem en daarna ergens mounten. Dit is allemaal standaard en hoeft alleen op de primary server te gebeuren:

mkfs.ext3 /dev/drbd0
mount /dev/drbd0 /home

Dit filesystem kan je, zoals al gezegd, alleen mounten op de machine die primary is! Ook moet je deze mount niet in fstab zetten, straks gaat heartbeat zorgen voor het mounten van de filesystems.

Nu de partitie gemount is kan je de data er weer op kopieren (mocht dat nodig zijn, bijvoorbeeld bij /home). Denk er wel aan dat er ergens op een partitie een directory moet komen waar de NFS-locks moeten komen te staan. In de huidige setup is dit op /var/data.

NFS opzetten

De volgende stappen moeten weer op beide servers worden uitgevoerd: NFS opzetten is vrij simpel. Als eerste moeten de goede packages geinstalleerd worden. Omdat de NFS-server al meteen gestart wordt na installatie moet je 'm meteen weer stoppen:

apt-get install nfs-kernel-server
/etc/init.d/nfs-kernel-server stop

Om te zorgen dat de NFS-clients niet in de war raken na een serverwissel moet de naam van de server even worden vastgelegd. Zet hiervoor in /etc/default/nfs-kernel-server het volgende neer:

STATDOPTS="-n fileserver.intern"

Op de primary server moet nu de NFS-management-data (op andere plekken in dit document ook wel de NFS-locks genoemd) verplaatst worden naar de DRBD-disk:

mv /var/lib/nfs/* /var/data/nfs_locks/

Op beide servers kan de nfs-dir nu gesymlinkt worden aan de drbd-disk:

rmdir /var/lib/nfs
ln /var/data/nfs_locks /var/lib/nfs -s

Ook kunnen nu de exports aangemaakt worden in /etc/exports:

/home        roetsjie.intern(ro,no_root_squash,sync) wamsie.intern(ro,no_root_squash,sync)
/var/data    roetsjie.intern(ro,no_root_squash,sync) wamsie.intern(rw,root_squash,sync)
/var/www     roetsjie.intern(ro,no_root_squash,sync) wamsie.intern(ro,root_squash,sync)
/usr/local   roetsjie.intern(ro,no_root_squash,sync) wamsie.intern(ro,no_root_squash,sync)

Voor de leesbaarheid zijn hier de exports naar woemsie en doortje weggelaten, woemsie.intern en doortje.intern moeten de zelfde export krijgen als wamsie.

MySQL installeren

Als het goed is heb je een DRBD-disk voor MySQL aangemaakt en deze gemount op /var/lib/mysql. Als deze disk al bestaat en gemount is voldoet het om MySQL gewoon te installeren met

apt-get install mysql-server

Nadat MySQL geinstalleerd is moet je 'm weer stoppen, heartbeat gaat straks zorgen dat MySQL gestart wordt. Op de secondary server kan je 'm ook gewoon installeren en stoppen, en daarna de data-dir leegmaken omdat die niet nodig is:

rm -rf /var/lib/mysql/*

Wat je wel moet doen is het volgende: Het wachtwoord van de Debian-system-user kopieren van de primary naar de secondary server. Dit wachtwoord is te vinden in /etc/mysql/debian.cnf.

Proftpd installeren

Dit gaat net zoals anders:

apt-get install proftpd
/etc/init.d/proftpd stop

Heartbeat installeren

Om te beginnen installeren we het pakketje:

apt-get install heartbeat

Nu maken we een file /etc/heartbeat/authkeys met daar in:

auth 2
2 sha1 TikJeKeyHier

Omdat de key in deze file staat is het belangrijk dat niemand anders 'm kan lezen:

chown root:root /etc/heartbeat/authkeys
chmod 600 /etc/heartbeat/authkeys

Vervolgens maken we de heartbeat-configfile /etc/heartbeat/ha.cf met daar in:

logfacility local0
keepalive 1
deadtime 5
warntime 3
initdead 60
udpport 694
ucast eth1 10.0.6.22  # = ando.intern
auto_failback off
node filius
node ando

Dit is de configfile van Filius. Die van Ando is iets verschillend: daar moet het IP van filius.intern komen te staan in plaats van dat van Ando. Hier nog een korte uitleg van de opties en hun betekenis:

  • logfacility local0: Dit wil zeggen dat heartbeat logt naar het syslog
  • keepalive 1: Elke seconde wordt er een heartbeat-pakketje naar de andere server gestuurd
  • deadtime 5: Als er 5 seconden lang niks van de andere server is ontvangen dan is die dood
  • warntime 3: Als er 3 seconden lang niks van de andere server is ontvangen komt er een waarschuwing in de logs. Als dit vaak gebeurt moet je er eens over denken om de warntime en deadtime wat hoger te maken
  • initdead 60: Bij het opstarten van heartbeat (als het goed is tegelijk met het starten van de machine) wordt er de eerste 60 seconden niks gedaan, dit om het netwerk de kans te geven in de lucht te komen etc.
  • udpport 694: Dit is de poort waarover de heartbeat-pakketjes worden verstuurd. Let er op dat deze open moet zijn in de firewall!
  • ucast eth1 10.0.6.22: Waar moeten de heartbeat-pakketjes heen worden gestuurd? Hier moet je het ip van de andere server vermelden. Verder gaat dit over eth1, dus over het interne netwerk.
  • auto_failback off: Als een uitgevallen server weer terug online komt moet er niet automatisch overgeschakeld worden naar die server. Dit moet handmatig zodat je even kan controleren of de data nog consistent is.
  • node filius: Voor elke machine moet er een node-regel worden neergezet zodat heartbeat weet welke machines er zouden moeten zijn.

Heartbeat resources

De volgende stap is het instellen van de heartbeat-resources. Als eerste moeten er een aantal scriptjes worden gemaakt:

echo 'sleep $1' > /etc/heartbeat/resource.d/sleep && chmod 755 /etc/heartbeat/resource.d/sleep
echo 'killall -9 nfsd' > /etc/heartbeat/resource.d/killnfsd && chmod 755 /etc/heartbeat/resource.d/killnfsd

Ook moet er een scriptje gemaakt worden dat er voor zorgt dat altijd de goede cronjobs actief zijn. Hierover later meer.

We gaan nu de resources definieren, deze moeten in /etc/heartbeat/haresources komen te staan. Het is belangrijk dat deze file op beide machines identiek is!

filius  MailTo::systeemkabouter@scouting.nl::Fileserver \
    drbddisk::home \
    Filesystem::/dev/drbd0::/home::ext3::usrquota,grpquota \
    drbddisk::varlibmysql \
    Filesystem::/dev/drbd1::/var/lib/mysql::ext3 \
    drbddisk::vardata \
    Filesystem::/dev/drbd2::/var/data::ext3 \
    drbddisk::usrlocal \
    Filesystem::/dev/drbd3::/usr/local::ext3 \
    drbddisk::varwww \
    Filesystem::/dev/drbd4::/var/www::ext3::usrquota,grpquota \
    killnfsd \
    nfs-common \
    nfs-kernel-server \
    quota \
    sleep::3 \
    IPaddr::83.98.194.120/24/eth0 \
    IPaddr::10.0.6.120/24/eth1 \
    proftpd \
    mysql \
    Crontabs

Deze items worden van boven naar beneden uitgevoerd zodra een server actief worden, en in omgekeerde volgorde uitgevoerd zodra een machine op 'standby' gaat. In dit geval zorgt het er voor dat als eerste de filesystems primary worden gemaakt en daarna gemount worden. Vervolgens wordt de NFS-server gestart en worden de quota's aangezet. Na eventjes wachten worden dan de fileserver-IP's gekaapt en daarna worden de FTP- en MySQL-server gestart.

Crontabs

Tot slot de crontabs. Er zijn een aantal crontabs die alleen op de actieve fileserver moeten draaien. Het heartbeat-scriptje Crontabs zorgt hier voor en ziet er zo uit:

#!/bin/sh

# geschreven door cbo @ 9-apr-2006
#
# Script wat de crontabs goedzet bij een resource takeover

ARGV="$@"

case $ARGV in
start)
    cp /etc/heartbeat/crontabs/crontab.run-always /etc/heartbeat/crontabs/crontab.temp
    cat /var/data/crontabs/crontab.only-when-primary >> /etc/heartbeat/crontabs/crontab.temp
    echo Running > /etc/heartbeat/crontabs/status
    crontab -u root /etc/heartbeat/crontabs/crontab.temp
    ;;
stop)
    cp /etc/heartbeat/crontabs/crontab.run-always /etc/heartbeat/crontabs/crontab.temp
    echo Stopped > /etc/heartbeat/crontabs/status
    crontab -u root /etc/heartbeat/crontabs/crontab.temp
    ;;
status)
    cat /etc/heartbeat/crontabs/status
    ;;
esac

exit 0

Dit script moet je neerzetten als /etc/heartbeat/resource.d/Crontabs en daarna chmod 755 maken.

Nu moeten er twee crontab-files worden gemaakt. Als eerste moet je de directory /etc/heartbeat/crontabs aanmaken, met daarin de file crontab.run-always . In die file moet de inhoud van de crontab van root komen te staan die altijd uitgevoerd moet worden, zoals bijvoorbeeld MRTG:

# Filius's crontab for root
# Don't use 'crontab -e' to edit it but edit it in /etc/heartbeat/crontab

*/5 * * * *   mrtg /etc/mrtg/filius.conf --logging /var/log/mrtg.log

0 * * * * /etc/systraq/make_filetraq.conf.sh > /dev/null

Daarnaast moet er een crontab-file gemaakt worden die alleen op de actieve fileserver draait. Deze staat in /var/data/crontabs/crontab.only-when-primary:

# Alles hier onder draait alleen op de primaire server

#######################################################################
##########################  BELANGRIJK ################################
# Wijzigingen in dit gedeelte alleen aanbrengen in /var/data/crontabs #
#                                                                     #
# Wijzigingen voorvoeren via /etc/heartbeat/resource.d/Crontabs start #
#######################################################################

#backups naar eigen FS
21 03 * * *     /usr/local/sbin/run_backup.sh > /dev/null
...

Niet alles automatisch opstarten

Een aantal dingen moeten niet automatisch gestart worden bij het starten van de server. Heartbeat zorgt er later voor dat deze dingen gestart worden dus kunnen ze uit rcX.d verwijderd worden:

update-rc.d -f mysql remove
update-rc.d -f proftpd remove
update-rc.d -f nfs-kernel-server remove
update-rc.d -f quota remove

Heartbeat starten

Nu kan je heartbeat starten en via het syslog in de gaten houden of alles goed gaat:

/etc/init.d/heartbeat start

Manual Failover

Als je handmatig wilt overschakelen van de ene naar de andere server moet je even dit documentje lezen.

Upgrade naar DRBD 8

De stappen om te upgraden naar drbd8 waren:

  • kernel bouwen waar drbd8 mee samenwerkt (SNTI007, 2.6.23.9)
  • op beide servers heartbeat en drbd uitzetten
  • rebooten naar die kernel. drbd wil nu niet starten
  • apt-get install drbd8-utils
  • m-a a-i drbd8-module-source

Dit gaat de eerste keer mis, de drbd8 die in debian backports zit is nog voor kernel 2.6.22. Er is een patch (TODO: link terugvinden). Er is vast een mooiere manier maar wat ik gedaan heb is: patch toepassen, en /usr/src/modules/drbd opnieuw inpakken in /usr/src/drbd8.tar.gz en dan m-a opnieuw runnen. Hoe dan ook, dit resulteert in een .deb pakketje met de module

  • een paar configuratie wijzigingen in /etc/drbd.conf. Optie group bestaat niet meer, als je zou willen dat disks in bepaalde volgorde behandeld worden (waar de groepen voor waren), dan werkt dat nu met andere opties, maar we gebruikten dit niet, dus group opties uitgezet. En er is een nieuwe sectie handlers waarin je commando's specificeert voor wat te doen in geval van ellende. Komt in de plaats van het incon-degr-cmd, want er zijn nu diverse vormen van degradatie te detecteren. Moet nog verder uitgezocht worden, maar hier is wat er nu staat:
handlers {
  #drbd 0.7: incon-degr-cmd "killall heartbeat";
  pri-on-incon-degr  "killall heartbeat";
  pri-lost-after-sb  "killall heartbeat";
}
  • modprobe drbd (en bv testen door in /proc/drbd te kijken, nog geen disks, wel versie nummer zodat je weet dat het goed zit)
  • Volgens de documentatie moet je nu de metadata kunnen upgraden: drbdadm create-md home (etc ook voor de andere resources). Wilde niet, hij herjkende de oude metadata niet. Dus maar yes geantwoord om nieuwe metadata te maken, wat risico oplevert dat data weg is, maar maakte bij deze upgrade toch niet echt uit.
  • Volgens de documentatie moet je nu met drbdadm up all de resources handmatig up kunnen brengen. Wilde nog niet, vermoedelijk omdat de metadata informatie had moeten bevatten over de status van de disk. Dan maar forceren: drbdsetup /dev/drbd0 primary -o (-o = –overwrite-data-of-peer dus we kiezen zelf wel wiens data we behouden). Idem voor de andere disks, en dan alsnog ze up brengen en de inhoud bekijken.
  • als dit allemaal goed gaat, zou je de disks weer aan heartbeat moeten kunnen toevertrouwen.
projecten/storage/scoutingnederlandnas.txt · Last modified: 2009/03/23 21:19 by robin