Er zijn twee fileservers: de primaire en de backup-fileserver. Deze twee moeten identiek ingericht worden.
Als eerste een korte uitleg over de principes die gebruikt worden op de fileservers. De fileservers hebben drie functies:
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.
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:
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 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
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.
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:
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.
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.
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.
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.
Dit gaat net zoals anders:
apt-get install proftpd /etc/init.d/proftpd stop
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:
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.
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 ...
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
Nu kan je heartbeat starten en via het syslog in de gaten houden of alles goed gaat:
/etc/init.d/heartbeat start
Als je handmatig wilt overschakelen van de ene naar de andere server moet je even dit documentje lezen.
De stappen om te upgraden naar drbd8 waren:
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
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"; }
/proc/drbd
te kijken, nog geen disks, wel versie nummer zodat je weet dat het goed zit)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.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.