MySQL/MariaDB: Ausfallsicheren Galera-Cluster erstellen

Eine eigene MySQL-Datenbank zu erstellen ist kein Problem. Aber der Stress beginnt dann, wenn Aliens auf das Rechenzentrum ballern und der Server ausfällt.

Während sich also die Welt darum kümmert, nicht von grünköpfigen Glubschaugen unterjocht zu werden, kämpft der Administrator an seiner eigenen Front: Den Datenbankserver wieder in die Gänge zu bekommen, damit die interstellare Abwehrarmee der Menschen ihre Dosenrationen online überwachen kann.

Das sind die wahren Helden!

Besser wäre es aber im vorhinein gewesen, wenn der Server ein Cluster gewesen wäre, also ein Netzwerk bestehend aus mindestens drei Servern. Fällt einer aus, sind mindestens zwei noch im Einsatz.

Doch Stop! MySQL kann das nicht von Haus aus. Stattdessen kann man hier das Pendant MariaDB einsetzen. Und das geht unter Ubuntu 18.0 so…

Zunächst mein Dank an howtoforge, deren Artikel die Grundlage für diesen hier bildet.

Los geht’s! Erstmal in der Linux-Shell das Paket installieren:

sudo apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xF1656F24C74CD1D8
sudo add-apt-repository 'deb [arch=amd64,i386,ppc64el] http://ftp.utexas.edu/mariadb/repo/10.4/ubuntu xenial main'
sudo apt update
sudo apt install mariadb-server rsync -y

Als nächstes: Den Server konfigurieren und installieren. Das geht am Besten über das mitgelieferte Tool.

sudo mysql_secure_installation

Easy Peasy! Nächster Schritt: Die Kommunikation zwischen den Servern im Cluster absichern. Je nachdem, wie diese verteilt sind, sollte die interne Absprache verschlüsselt sein. Das geht natürlich über SSL – die Abkürzung für SuperSichereVerschLüsselung.

Also als nächstes ein paar Verzeichnisse anlegen, in denen die Zertifikate abgelegt werden. Die werden später an die richtige Stelle kopiert.

cd ~
mkdir ssl
cd ssl

Dann werden die Zertifikate generiert; ich höre jetzt schon einen Aufschrei. Seit Anbeginn der Menschheit versuchen Administratoren, die Generierung von SSL-Zertifikaten zu deuten und zu verstehen. Viele sind beim Versuch gestorben. Insofern: Einfach die Schritte ausführen und hoffen, das es schon so passt.

Achtung: Unbedingt bei der Abfrage auf den angegebenen “Common Name” achten! Die anderen Felder müssen nicht ausgefüllt werden.

# "Common Name" = 'db'
openssl genrsa 2048 > ca-key.pem
openssl req -new -x509 -nodes -days 21900 -key ca-key.pem > ca-cert.pem

# "Common Name" = 'server'
openssl req -newkey rsa:2048 -days 21900 -nodes -keyout server-key-pkcs8.pem > server-req.pem
openssl rsa -in server-key-pkcs8.pem -out server-key.pem
openssl x509 -req -in server-req.pem -days 21900 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 > server-cert.pem

# "Common Name" = "client"
openssl req -newkey rsa:2048 -days 10000 -nodes -keyout client-key-pkcs8.pem > client-req.pem
openssl rsa -in client-key-pkcs8.pem -out client-key.pem
openssl x509 -req -in client-req.pem -days 21900 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 > client-cert.pem

Die Zertifikatsdateien sind jetzt verfügbar. Aber nicht lesbar und für den falschen Nutzer – das müssen wir ändern.

chmod 777 *.pem
sudo cp *.pem /etc/mysql
cd /etc/mysql
sudo chown mysql:mysql *.pem

Fertig. Jetzt müssen wir noch der Konfiguration von MariaDB mitteilen, dass wir SSL nutzen wollen.

Dafür wird die Datei /etc/mysql/conf.d/galera.cnf editiert. Achtung: Hier sollten später die IPs der anderen Server eingetragen werden, die im Cluster aktiv sind. Momentan reicht die des ersten Servers.

Achtung: Unter bind-address wird eingestellt, dass der Server von außen erreichbar ist. Wenn du das nicht möchtest, kannst du die IP anpassen. Generell kann man den Zugriff aber dann auch über eine Firewall regeln.

[mysql]
# Using mysql in case this is used
ssl=true
ssl-ca=/etc/mysql/ca-cert.pem
ssl-cert=/etc/mysql/client-cert.pem
ssl-key=/etc/mysql/client-key.pem

[client]
# Also client to be sure
ssl=true
ssl-ca=/etc/mysql/ca-cert.pem
ssl-cert=/etc/mysql/client-cert.pem
ssl-key=/etc/mysql/client-key.pem

[mysqld]
ssl=true
ssl-ca=/etc/mysql/ca-cert.pem
ssl-cert=/etc/mysql/server-cert.pem
ssl-key=/etc/mysql/server-key.pem

binlog_format=ROW
default-storage-engine=innodb
innodb_autoinc_lock_mode=2
bind-address=0.0.0.0

# Galera Provider Configuration
wsrep_on=ON
wsrep_provider=/usr/lib/galera/libgalera_smm.so
wsrep_cluster_name="galera_cluster"

# Achtung: Hier IP ersetzen!
wsrep_cluster_address="gcomm://<SERVERIP 1>"

wsrep_sst_method=rsync
wsrep_provider_options="socket.ssl_key=/etc/mysql/server-key.pem;socket.ssl_cert=/etc/mysql/server-cert.pem;socket.ssl_ca=/etc/mysql/ca-cert.pem"

# Galera Node Configuration

# Achtung: Hier IP ersetzen!
wsrep_node_address="<SERVERIP 1>"

wsrep_node_name="MariaDB1"

Jetzt wieder in die Shell wechseln und den neuen Galera Cluster starten. Zunächst muss aber der Service gestoppt werden.

sudo systemctl stop mysqld
sudo galera_new_cluster

Gespannt ob es geklappt hat? Mal schnell über die Shell in die Datenbank schauen:

mysql -u root -p -e "show status like 'wsrep_cluster_size'"

Als Antwort sollte jetzt “1” erscheinen.

Das war’s auch schon. Du hast jetzt einen Server-Cluster mit einem Server. Das ungefähr so sinnvoll wie eine 1-Mann-Armee. Aber dazu gleich mehr – erstmal versuchen wir, auf den Server zu connecten. Dazu musst du sicherstellen, dass die Config auf bind-address = 0.0.0.0 gesetzt ist.

Wenn du einen Client wie Workbench oder Navicat benutzt, achte darauf, dass “SSL” aktiviert ist. Die Zertifikate musst du nicht einfügen.

Solltes du komische Fehlermeldungen wie mariadb system error: 0 "Internal error/check" erhalten, bedeutet das, dass dein MySQL root User falsch konfiguriert ist. Um das zu beheben, wird diesem Zugriff von außen ermöglicht:

# Auf MySQL Client wechseln
mysql -u root -p

# Rechte für Root vergeben
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '<PASSWORT>' WITH GRANT OPTION;
FLUSH PRIVILEGES;

Wenn du jetzt den Server auf Reboot-Sicherheit testen möchtest, muss ich dich enttäuschen: Da dies der einzige Server im Cluster ist, muss er wieder mit galera_new_cluster gestartet werden. Das ist natürlich nicht nötig, wenn es mehrere gibt!

Um einen Cluster zu starten, sollte der Server noch zweimal geklont werden. Dann nicht vergessen, bei allen Servern die Datei /etc/mysql/conf.d/galera.cnf anzupassen. Dadurch, dass die Server geklont werden, sind die SSL-Keys bereits an Ort und Stelle.

# Achtung: Hier IPs aller Server ersetzen!
wsrep_cluster_address="gcomm://<SERVERIP 1>,<SERVERIP 2>,<SERVERIP 3>"

# Achtung: Hier IP ersetzen!
wsrep_node_address="<SERVERIP>"

wsrep_node_name="MariaDB<ServerNummer>"

Anschließend die MySQL-Services auf allen Servern ausschalten:

sudo systemctl stop mysqld

Einmal ein Stoßgebet zum Servergott senden und auf dem ersten Server den Cluster starten:

sudo galera_new_cluster

Wenn das geklappt hat, die Services auf den anderen Servern starten:

sudo systemctl start mysqld

Fertig!

Björn Falszewski
31. Januar 2020
Disclaimer
Alle meine Artikel entstehen mit bestem Wissen und Gewissen, sind aber nicht perfekt und sollten immer nur als Ausgangspunkt für deine eigenen Recherchen bilden.

Sollte dir etwas Fehlerhaftes auffallen, freue ich mich über deine Nachricht!