Page tree
Skip to end of metadata
Go to start of metadata

Ziel

Das Ziel dieses Tutorials ist die Grundlage eines performanten und ausfallsicheren Clusters in der Amazon Elasic Computing Cloud. Dabei wird ein Volume mit DRBD als Primary/Primary gespiegelt und mit dem Cluster Dateisystem OCFS2 auf zwei Instanzen zur Verfügung gestellt.

Auf diesem Cluster lassen sich beliebige verteilte Dienste wie z.B. Mail-, Web-, Datenbank-Server betreiben, welche die Daten auf einem gemeinsamen Dateisystem verwalten.

Dazu muss lediglich noch die gewünschte Anwendung aufgesetzt und ein Load Balancer (z.B. nginx) vorgeschaltet werden.

Cloud

Für die Amazon Elastic Cloud muss ein Account und KeyPair vorhanden sein, oder eingerichtet werden. Für dieses Tutorial wird als Region eu-west-1 gewählt, da diese Instanzen in Irland und damit noch in der EU gestartet werden. Hier hat man weniger Probleme mit europäischen Datenschutzbestimmungen.

Damit Zugangsdaten und Region nicht für jeden Befehl eingegeben werden müssen, sollte man sich folgende Konfiguration der Bash anlegen:

$ vi .bashrc
export EC2_PRIVATE_KEY=$HOME/aws/pk-Q7DP2MJWDDEXRUXXXXXXXXX.pem
export EC2_CERT=$HOME/aws/cert-Q7DP2MJWDDEXRUWFCIZXXXXXXXXX.pem
export EC2_URL="https://eu-west-1.ec2.amazonaws.com"

Danach installiert man die API Tools:

$ sudo aptitude install ec2-ami-tools ec2-api-tools

Sicherheitsgruppe

Damit die Instanzen später auch erreichbar sind und untereinander kommunizieren können, legt man eine Sicherheitsgruppe an:

$ ec2-add-group cluster -d "Cluster"
GROUP	cluster Cluster

Hier legt man die gewünschten Regeln an:

# SSH nur von einer Office IP erlauben
$ ec2-authorize cluster -P tcp -p 22 -s xx.xx.xx.xx/32

# DRBD Replikation innerhalb der Gruppe erlauben
$ ec2-authorize cluster -P tcp -p 7789 -o cluster -u 1234567890

# OCFS2 Cluster innerhalb der Gruppe erlauben
$ ec2-authorize cluster -P tcp -p 7777 -o cluster -u 1234567890

Damit sieht die Sicherheitsgruppe wie folgt aus:

$ ec2-describe-group
GROUP	1234567890	cluster	Cluster
PERMISSION	1234567890	cluster	ALLOWS	tcp	7789	7789	FROM	USER	1234567890	GRPNAME	cluster
PERMISSION	1234567890	cluster	ALLOWS	tcp	7777	7777	FROM	USER	1234567890	GRPNAME	cluster
PERMISSION	1234567890	cluster	ALLOWS	tcp	22	22	FROM	CIDR	xx.xx.xx.xx/32

Instanzen

Als Instanztyp kommt t1.micro zum Einsatz. Hier sind die Kosten (~$60/Monat) überschaubar. Da der Typ auch 64 Bit unterstützt, können die Instanzen später ohne Probleme auf mehr Ressourcen vegrößert werden. Bei t1.micro gibt Amazon die I/O Leistung auch nur mit Mittel an. Erst ab m1.large steigt die I/O Leistung auf Hoch:

Der Typ m1.small kann nich genutzt werden, da hier nur 32 Bit Instanzen möglich sind.

Vor dem Start einer Instanz muss man sich für ein AMI (Amazon Machine Image) entscheiden. Natürlich können auch eigene angelegt werden, dieser Prozess würde den Artikel aber sprengen. In diesem Tutorial wird ein aktuelles Ubuntu Lucid Image auf EBS verwendet:

$ EC2_AMI=`ec2-describe-images -a|grep ubuntu-lucid-daily-amd64-server|grep ebs|tail -n1|cut -f2`
$ echo $EC2_AMI
ami-a9aa9fdd

Eine Instanz kann dann wie folgt gestartet werden:

$ EC2_INSTANCE=`ec2-run-instances $EC2_AMI -k Gathars_KeyPair -g cluster -t t1.micro|grep INSTANCE|cut -f2`
$ echo $EC2_INSTANCE

Der Startvorgang der Instanz kann einige Minuten dauern. Sobald die Instanz gestartet wurde, ermittelt man den öffentlichen Hostnamen:

$ ec2-describe-instances|grep $EC2_INSTANCE|cut -f4
ec2-46-137-5-168.eu-west-1.compute.amazonaws.com

Auf diesen Hostname kann man sich per SSH verbinden:

$ ssh -i aws/id-Gathars_KeyPair ubuntu@ec2-46-137-5-168.eu-west-1.compute.amazonaws.com

Diesen Vorgang wiederholt man, damit 2 Instanzen zur Verfügung stehen!

Möchte man Befehle auf allen Instanzen ausführen, hilft folgende Schleife:

$ for I in `ec2-describe-instances|grep INSTANCE|cut -f4`; do \
  ssh -i aws/id-Gathars_KeyPair ubuntu@$I "sudo uname -a"; \
  done

Volumes

Die Volumes mit Daten sollten unabhängig der Instanzen auf EBS eingerichtet werden.

Ein Volume muss immer in der selben Verfügbarkeitszone wie die Instanz angelegt werden. Welche das ist, kann wie folgt ermittelt werden:

$ ec2-describe-instances|grep $EC2_INSTANCE|cut -f12

Jetzt legt man ein Volume an (10 GB):

$ VOLUME_ID=`ec2-create-volume -s 10 -z eu-west-1b|cut -f2`
$ echo $VOLUME_ID

Dieses Volume fügt man der Instanz hinzu:

$ ec2-attach-volume $VOLUME_ID -i $EC2_INSTANCE -d /dev/sdb1

Dieses Volume könnte in der Instanz jetzt formatiert und eingebunden werden:

$ sudo mkfs.ext3 /dev/sdb1
$ sudo mount /dev/sdb1 /mnt/
$ df -h|grep sdb1
/dev/sdb1             9.9G  151M  9.2G   2% /mnt

Das ist aber NICHT notwendig, da es später eh mit DRBD und OCFS2 überschrieben wird!

Storage Cluster

Ein wichtiger Teil des Clusters ist ein zentrales Storage. Da in der Amazon Cloud ein Volume jeweils nur einer Instanz hinzugefügt werden kann, müssen die Volumes live repliziert werden. Dazu kommt DRBD zum Einsatz. Damit die Volumes auch gleichzeitig gemountet werden können, bedarf es eines Cluster Dateisystems wie z.B. OCFS2. Sollten mehr als 2 Nodes notwendig werden, oder die I/O Last der DRBD Replikation nicht ausreichend sein, muss man in der Amazon Cloud auf alternative Dienste wie z.B. S3 ausweichen. Welche I/O Leistung möglich ist, wird im Abschnitt Performance behandelt.

DRBD

Zuerst installiert man die Kernel Headers und legt einen Link an, damit DRBD auch durch kompiliert:

$ sudo aptitude install gawk linux-headers-`uname -r`
$ sudo ln -nsf /usr/src/linux-headers-`uname -r`/include/asm-x86 /usr/src/linux-headers-`uname -r`/include/asm

Jetzt installiert man DRBD:

$ sudo aptitude install drbd8-utils

Danach legt man die Konfigurationsdatei an und startet die Software:

$ sudo vi /etc/drbd.d/res1.res
resource res1 {
        syncer {
                rate 100M;
        }
        net {
                allow-two-primaries;
        }
        on ip-10-224-109-154 {
                device /dev/drbd1;
                disk    /dev/sdb1;
                address 10.224.109.154:7789;
                meta-disk internal;
        }
        on ip-10-224-109-155 {
                device /dev/drbd1;
                disk    /dev/sdb1;
                address 10.224.109.155:7789;
                meta-disk internal;
}

$ sudo drbdadm create-md res1
$ sudo /etc/init.d/drbd start

Der erste Node wird dann als Primary konfiguriert:

$ sudo drbdadm -- --overwrite-data-of-peer primary res1

$ cat /proc/drbd
[>...................] sync'ed:  7.5% (9480/10236)M

Wenn der initiale Sync abgeschlossen ist, kann auch der zweite Node auf Primary geschaltet werden:

$ sudo drbdadm primary res1

OCFS2

Im nächsten Schritt wird die DRBD Replikation mit einem Cluster Dateisystem auf beiden Nodes gemountet. Dazu installiert man erstmal die Software:

$ sudo aptitude install ocfs2-tools

Legt dann die Konfiguration an:

$ sudo vi /etc/ocfs2/cluster.conf
node:
	ip_port = 7777
	ip_address = 10.235.42.182
	number = 0
	name = ip-10-235-42-182
	cluster = ocfs2
node:
	ip_port = 7777
	ip_address = 10.224.77.101
	number = 1
	name = ip-10-224-77-101
	cluster = ocfs2
cluster:
	node_count = 2
	name = ocfs2

Jetzt wird OCFS2 auf beiden Nodes gestartet:

$ sudo dpkg-reconfigure ocfs2-tools
$ sudo /etc/init.d/o2cb restart
$ sudo /etc/init.d/ocfs2 restart

Auf einem Node wird dann das Dateisystem erstellt:

$ sudo mkfs.ocfs2 /dev/drbd1

Danach kann es auf beiden Nodes gemountet werden:

$ sudo mkdir /mnt/cluster
$ sudo mount /dev/drbd1 /mnt/cluster/

Performance

I/O

Das Ergebnis der I/O Performance ist eindeutig. Erst ab dem Instanz Typ m1.large kommt man auf zirka 35 MB/s und damit auf einen akzeptablen Wert. Die hohe Latenz ist für ein Netzwerkstorage üblich. Diese Konfiguration eigenet sich damit hervoragend für z.B. Mail- und Web-Server. Datenbanken sollten wegen der hohen Latenz vermieden werden. Hier ist z.B. eine MySQL Replikation besser.

t1.micro

$ sudo aptitude install bonnie++
$ sudo bonnie++ -u root -s 4000 -d /mnt/cluster/

Version  1.96       ------Sequential Output------ --Sequential Input- --Random-
Concurrency   1     -Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--
Machine        Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP  /sec %CP
ip-10-235-42- 4000M    43  98  8248   2  8068   2   718  99 81431   8  3091  45
Latency              3489ms   12329ms     513ms   41255us   60630us   10541us
Version  1.96       ------Sequential Create------ --------Random Create--------
ip-10-235-42-182    -Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
              files  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP
                 16   271  12 +++++ +++   584   4   286  11 +++++ +++  1864  18
Latency              1663ms      56us   13177ms     965ms     159us    1856ms
1.96,1.96,ip-10-235-42-182,1,1293212790,4000M,,43,98,8248,2,8068,2,718,99,81431,8,3091
$ sudo dd if=/dev/zero of=/mnt/cluster/dd.img bs=512k count=1000
1000+0 records in
1000+0 records out
524288000 bytes (524 MB) copied, 63.8069 s, 8.2 MB/s

m1.large

$ sudo bonnie++ -u root -r 4000 -s 8000 -d /mnt/cluster/
Version  1.96       ------Sequential Output------ --Sequential Input- --Random-
Concurrency   1     -Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--
Machine        Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP  /sec %CP
ip-10-235-10- 8000M   144  99 34273  11 31637  10   507  99 112539  10  5889  50
Latency               109ms     545ms     486ms   35951us     107ms   21121us
Version  1.96       ------Sequential Create------ --------Random Create--------
ip-10-235-10-112    -Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
              files  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP
                 16   311  14 +++++ +++  3329  16   693  31 +++++ +++  1739  21
Latency               378ms   16873us     833ms     721ms      52us    1774ms
1.96,1.96,ip-10-235-10-112,1,1293363888,8000M,,144,99,34273,11,31637,10,507,99,112539
$ sudo dd if=/dev/zero of=/mnt/cluster/dd.img bs=512k count=10000
10000+0 records in
10000+0 records out
5242880000 bytes (5.2 GB) copied, 144.672 s, 36.2 MB/s

Ausbaustufen

Instanz Typ anpassen

Dabei ändern sich private und ggf. öffentliche IP's und DRBD/OCFS2 Konfigurationen müssen angepasst werden!

Der Instanz Typ kann angepasst werden, wenn die Instanz gestoppt wurde:

$ ec2-stop-instances $EC2_INSTANCE
$ ec2-modify-instance-attribute -t m1.large $EC2_INSTANCE
$ ec2-start-instances $EC2_INSTANCE

Verschlüsselung

Alle Daten der Replikation werden in dieser Konfiguration unverschlüsselt über das Amazon Netzwerk übertragen. Handelt es sich hier um sensible Daten, sollte ein VPN (z.B. OpenVPN) für die Replikation eingerichtet werden. Es ist auch empfehlenswert, zwischen DRBD und OCFS2 nochmal eine Verschlüsselung des Volumes zu etablieren, damit die Daten später nicht in die falschen Hände geraten können. Wer diese Konfiguration nur nutzt, um weniger sensible Daten auszuliefern, kann auf die Verschlüsselung verzichten, da die Performance natürlich darunter leidet.

Vergrößerung des Volumes

Um ein bestehendes Volume zu vergrößern, ist es unumgänglich, das Cluster für wenige Minuten offline zu nehmen, oder zumindest das Dateisystem auf Read Only zu stellen. Entscheidet man sich für Read Only, können die Instanzen nach und nach auf das größere Volume umgestellt werden. Das ganze sollte dann aber über ein Script automatisiert werden, um die Umstellung so kurz wie möglich zu halten.

Hier ein kleines Beispiel, wie ein bestehendes Volume vergrößert werden kann.

Zuerst nimmt man einen Node aus dem Cluster und mountet auf dem anderen Node das Dateisystem mit Read Only

$ sudo mount -r -o remount /mnt/cluster/
$ touch /mnt/cluster/test
touch: cannot touch `/mnt/cluster/test': Read-only file system

Danach muss aus dem Read Only Volume ein Snapshot erstellt werden:

$ SNAPSHOT_ID=`ec2-create-snapshot $VOLUME_ID`

Sobald der Snapshot fertig erzeugt wurde, kann ein größeres Volume daraus erstellt werden:

$ ec2-describe-snapshots
$ VOLUME_ID_NEW=`ec2-create-volume -s 20 --snapshot $SNAPSHOT_ID -z eu-west-1b`

Auf dem zweiten Node stoppt man jetzt DRBD und OCFS2 und attached das neue Volume (vorher natürlich das alte Volume detachen):

$ ec2-detach-volume $VOLUME_ID -i $EC2_INSTANCE -d /dev/sdb1
$ ec2-attach-volume $VOLUME_ID_NEW -i $EC2_INSTANCE -d /dev/sdb1

Bevor das neue Volume auf Node 2 mit DRBD gestartet werden kann, sollte sicherheitshalber die Firewall Regel die Verbindung zu Node 1 unterbinden. Dann startet man DRBD wieder und setzt Node 2 auf Primary.

Jetzt kann das Dateisystem erweitert werden:

$ sudo umount /mnt/cluster/
$ sudo tunefs.ocfs2 -S /dev/drbd1
$ sudo mount /dev/drbd1 /mnt/cluster/

Danach steht die neue Kapazität zur Verfügung:

$ df -h|grep sdb1
/dev/drbd1              20G  331M   20G   2% /mnt/cluster

Im nächsten Schritt nimmt man Node 2 ins Cluster und Node 1 offline. Danach kann die selbe Konfiguration mit Node 1 durchgeführt werden. Hier müssen die aktuellen Daten der Replikation natürlich wieder von Node 2 geholt werden.

Nach ein paar Tagen empfiehlt es sich, die alten Volumes und Snapshots wieder zu löschen.