Blog
Thursday, 07. September 2023

Automatisierte Installation einer MS SQL AlwaysOn Gruppe auf Ubuntu

Attila
IT–Consultant

Es gibt viele gute Dokumentationen darüber, wie ein Ubuntu Cluster mit einer MSSQL AlwaysOn Gruppe erstellt werden kann. Das Mühsame hierbei ist, dass sämtliche Befehle rund um das Erstellen des Clusters auf allen Nodes separat ausgeführt werden müssen und sich hierbei schnell der ein oder andere Fehler einschleichen kann. Die anschließende Fehlerbehebung kann sich hier als echte Herausforderung entpuppen. In diesem Artikel stellen wir ein Skript vor, welches diese Befehle um einige Funktionen erweitert. Es automatisiert die Konfiguration des gesamten Clusters von der Primären Node aus.

Vorkonfiguration

Das Skript muss in der Lage sein, Befehle ohne Prompts auszuführen. Hierzu werden sowohl sudo Rechte als auch ein Identifizierungsschlüssel benötigt, um so ssh-Befehle auf Remote Knoten ausführen zu können.

Als Erstes fügen wir also unseren Benutzer auf allen Nodes zu den sudoers hinzu, damit wir Befehle ausführen können ohne nach einem Passwort gefragt zu werden. Dies erfolgt über folgenden Befehl:

echo "administrator ALL=(ALL) NOPASSWD:ALL" | sudo tee -a /etc/sudoers

Um anschließend auch SSH ohne die Aufforderung zur Passworteingabe nutzen zu können, generieren wir einen Authentifizierungsschlüssel auf Node 1.

ssh-keygen -t rsa

Dieser Befehl wird uns nun noch einmal nach einem Passwort fragen. Nachdem wir dieses eingegeben und mit Enter bestätigt haben, kopieren wir den generierten Authentifizierungsschlüssel auf alle weiteren Nodes, die wir unserem Cluster hinzufügen möchten. Wir kopieren den Schlüssel auch noch einmal auf die primäre Node, da sich unser Skript über diesen identifiziert.

ssh-copy-id administrator@oplin4sql2201-d
ssh-copy-id administrator@oplin4sql2202-d
ssh-copy-id administrator@oplin4sql2203-d

Jetzt sollten wir keine lästigen Prompts mehr bekommen und das Skript kann gestartet werden.

Skript Aufbau

Im folgenden Abschnitt wollen wir einmal genauer auf den Aufbau unseres Skriptes eingehen um zu verstehen, wie dieses im Detail funktioniert.

Variablen
Als Erstes definieren wir eine Logdatei (Zeile 4). Anschließend legen wir die Variablen für die DNS-Namen und IP-Adressen unserer Hosts, des Listeners und des Cluster Objektes an. Weiterhin erstellen wir Variablen zur Konfiguration von SQL Server, Pacemaker und VSphere:

#!/bin/bash

#Log file path
logFile="aogcluster.log"

#Variables
hostIp1="172.17.6.153"
hostname1="oplin4sql2201-d"
hostIp2="172.17.6.171"
hostname2="oplin4sql2202-d"
hostIp3="172.17.6.173"
hostname3="oplin4sql2203-d"
listenerIP="172.17.6.186"
listener="oplin4sql22li-d"
cluster="oplin4sql22cl-d"
VSPHERE_LOGIN="administrator@vsphere.local"
VSPHERE_PASSWORD="vsphere_password"

#MSSQL_Config variables
MSSQL_SA_PASSWORD="mssql_sa_password"
MSSQL_PID="developer"
SQL_ENABLE_AGENT="y"
MKEYENC_PASSWORD="master_key_encription_password"
PACEMAKER_PASSWORD="pacemaker_password"

Funktionen

Das Skript selbst, ist in 3 Hauptfunktionen unterteilt:

  • Eine Funktion für das Logging,
  • Eine Funktion zum Ausführen eines Befehls auf einer Node
  • Eine Funktion zum Ausführen eines Befehls auf allen Nodes
#Function to write log messages

function writeLog {
    timestamp=$(date +"%Y-%m-%d %T")
    message="$timestamp - $1"
    echo "$message" >> "$logFile"
    echo "$message"
}

#Function to execute commands on a remote node

function executeCommandOnRemoteNode {
    host=$1
    command=$2
    writeLog "Executing command on $host: $command"
    ssh -o "StrictHostKeyChecking no" "$host" "$command" >> "$logFile" 2>&1
}

#Function to execute commands on all Nodes

function executeCommandOnAllNodes {
    command=$1
    executeCommandOnRemoteNode "$hostname1" "$command"
    executeCommandOnRemoteNode "$hostname2" "$command"
    executeCommandOnRemoteNode "$hostname3" "$command"
}

Nachdem wir nun Variablen und Funktionen definiert haben, können wir mit den eigentlichen Konfigurationsschritten fortfahren.

Schritt 1 - Hostdatei

Im ersten Schritt wird die Hostdatei um alle Nodes mit ihren DNS-Namen und IP-Adressen ergänzt:

#Step 1 - Edit Hosts file on all Nodes

writeLog "Step 1 - Edit Hosts file on all Nodes"
executeCommandOnAllNodes "echo '$hostIp1 $hostname1' | sudo tee -a /etc/hosts"
executeCommandOnAllNodes "echo '$hostIp2 $hostname2' | sudo tee -a /etc/hosts"
executeCommandOnAllNodes "echo '$hostIp3 $hostname3' | sudo tee -a /etc/hosts"
executeCommandOnAllNodes "echo '$listenerIP $listener' | sudo tee -a /etc/hosts"

Schritt 2 - Clusterpakete

Im nächsten Schritt werden nötige Cluster Pakete wie pacemaker, crmsh und fencing installiert:

#Step 2 - Install required packages on all Nodes

writeLog "Step 2 - Install required packages on all Nodes"
executeCommandOnAllNodes "sudo apt-get install -y pacemaker pacemaker-cli-utils crmsh resource-agents fence-agents csync2"

Pacemaker ist ein hochverfügbarer Cluster-Ressourcenmanager. Dieser erreicht maximale Verfügbarkeit für Cluster-Dienste oder Ressourcen, indem Ausfälle auf Knoten- und Ressourcenebene erkannt und behoben werden. Hierfür werden die von Corosync bereitgestellten Messaging- und Mitgliedschaftsfunktionen genutzt.

Fencing software: Unter Fencing versteht man den Vorgang, einem Knoten die Möglichkeit zu entziehen, Ressourcen auszuführen, selbst wenn dieser Knoten auf Clusterbefehle reagiert. Dies ist auch unter dem Begriff STONITH bekannt, ein Akronym für „Shoot The Other Node In The Head“, was auf die gebräuchlichste Fencingmethode zurückzuführen ist, welche daraus besteht, die Stromversorgung des Knotes zu unterbrechen. Eine andere Methode ist das „Fabric-Fencing“, bei dem der Zugriff des Knotens auf einige Funktionen eingeschränkt wird, die zum Ausführen von Ressourcen erforderlich sind (z. B. Netzwerkzugriff oder eine gemeinsam genutzte Festplatte).

Schritt 3 - SQL Server und High Availability Paket

Der dritte Schritt umfasst die Installation und Konfiguration von SQL Sever, weshalb dieser deutlich mehr Zeit in Anspruch nimmt als alle anderen Schritte.

In diesem Schritt werden alle Repositories um die Microsoft Repositories ergänzt sowie MSSQL Server mitsamt dem High Availability Paket installiert und konfiguriert. Die betroffenen Dienste werden anschließend neugestartet.

Alle Installationsschritte werden hier in einer Ladung an alle Nodes geschickt, so müssen die Umgebungsvariablen nicht neu gesetzt werden.

#Step 3 - Installing SQL Server on all Nodes

writeLog "Step 3 - Installing SQL Server on all Nodes"
sqlautoinstall="
MSSQL_SA_PASSWORD='$MSSQL_SA_PASSWORD'
MSSQL_PID='developer'
sudo curl https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add -
repoargs=\"\$(curl https://packages.microsoft.com/config/ubuntu/20.04/mssql-server-2019.list)\\"
sudo add-apt-repository \"\${repoargs}\"
sudo apt-get update -y
sudo apt-get install -y mssql-server
sudo MSSQL_SA_PASSWORD=$MSSQL_SA_PASSWORD MSSQL_PID=$MSSQL_PID /opt/mssql/bin/mssql-conf -n setup accept-eula
sudo ACCEPT_EULA=Y apt-get install -y mssql-tools unixodbc-dev
echo PATH=\"\$PATH:/opt/mssql-tools/bin\" >> \~/.bash_profile
echo 'export PATH=\"\$PATH:/opt/mssql-tools/bin\"' >> \~/.bashrc
source \~/.bashrc
sudo /opt/mssql/bin/mssql-conf set sqlagent.enabled true
sudo apt-get install -y mssql-server-fts
echo Configuring UFW to allow traffic on port 1433...
sudo ufw allow 1433/tcp
sudo ufw reload
sudo systemctl restart mssql-server
sleep 3s
/opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P $MSSQL_SA_PASSWORD -Q \"SELECT @@VERSION\" 2>/dev/null
echo Done!
"
executeCommandOnAllNodes "$sqlautoinstall"
executeCommandOnAllNodes "sudo /opt/mssql/bin/mssql-conf set sqlagent.enabled true"
executeCommandOnAllNodes "sudo /opt/mssql/bin/mssql-conf set hadr.hadrenabled 1"
executeCommandOnAllNodes "sudo apt-get install -y mssql-server-ha"
executeCommandOnAllNodes "sudo systemctl restart mssql-server"

Schritt 4 - Corosync

Nachdem wir nun SQL Server und das Availability Paket installiert und konfiguriert haben, müssen wir die Cluster Messaging Software, Coroysnc, anpassen. Hierfür müssen wir ebenfalls eine Config Datei sowie einen Identifizierungsschlüssel erstellen und diese auf alle Nodes kopieren.

Da diese Datei nun nur vom root Benutzer lesbar ist, können wir sie nicht ohne weiteres automatisiert Kopieren, da wir für das Ausführen des Kopierbefehls sudo scp immer eine Aufforderung zur Passworteingabe erhalten. Aus diesem Grund müssen wir diese Berechtigung für den Kopiervorgang temporär ändern, und anschließend wieder zurückstellen.

Abschließend wird Pacemaker einmal neugestartet und das Cluster ist erstellt.

#Step 4 Corosync config

writeLog "Step 4 - Corosync config"
writeLog "Generating corosync key"
executeCommandOnRemoteNode "$hostname1" "sudo corosync-keygen"
writeLog "Copying key to remote Nodes"
executeCommandOnRemoteNode "$hostname1" "sudo chmod 404 /etc/corosync/authkey"
executeCommandOnRemoteNode "$hostname1" "scp /etc/corosync/authkey administrator@oplin4sql2202-d:~"
executeCommandOnRemoteNode "$hostname1" "scp /etc/corosync/authkey administrator@oplin4sql2203-d:~"
writeLog "Moving key to /etc on remote Nodes"
executeCommandOnRemoteNode "$hostname2" "sudo mv authkey /etc/corosync/"
executeCommandOnRemoteNode "$hostname3" "sudo mv authkey /etc/corosync/"
executeCommandOnAllNodes "sudo chmod 400 /etc/corosync/authkey"
executeCommandOnAllNodes "sudo chown root:root /etc/corosync/authkey"
executeCommandOnAllNodes "sudo tee /etc/corosync/corosync.conf > /dev/null <<EOF
totem {
  version: 2
  cluster_name: $cluster
  transport: udpu
  crypto_cipher: none
  crypto_hash: none
}
logging {
  fileline: off
  to_stderr: yes
  to_logfile: yes
  logfile: /var/log/corosync/corosync.log
  to_syslog: yes
  debug: off
  logger_subsys {
    subsys: QUORUM
    debug: off
  }
}
quorum {
  provider: corosync_votequorum
}
nodelist {
  node {
    name: $hostname1
    nodeid: 1
    ring0_addr: $hostIp1
  }
  node {
    name: $hostname2
    nodeid: 2
    ring0_addr: $hostIp2
  }
  node {
    name: $hostname3
    nodeid: 3
    ring0_addr: $hostIp3
  }
}
EOF"
executeCommandOnAllNodes "sudo cp /etc/corosync/corosync.conf /etc/corosync/corosync.conf.bak"
executeCommandOnAllNodes "sudo systemctl restart pacemaker corosync"
sleep 10s
executeCommandOnAllNodes "sudo crm status"

Schritt 5 - Zertifikate und Encription

Da der Sicherheitsaspekt auch nicht zu kurz kommen darf, aktivieren wir nun im fünften Schritt die Master Encription auf der primären Node. Die zugehörigen Zertifikate werden anschließend auf die weiteren Nodes kopiert und nachträglich ein High Availability and Disaster Recovery (HADR) Endpoint erstellt.

Um ein Verfügbarkeitsreplikat für eine Verfügbarkeitsgruppe zu hosten, muss eine Serverinstanz über einen Endpoint verfügen. Die Serverinstanz verwendet diesen Endpunkt, um auf Always On-Verfügbarkeitsgruppennachrichten von Verfügbarkeitsreplikaten zu warten, die von anderen Serverinstanzen gehostet werden.

#Step 5 Creating master key encription on primary and copying certificates to remote Nodes
writeLog "Step 5 - Creating master key encription"
writeLog "Creating master key on primary"

executeCommandOnAllNodes "tee create_master_enc.sql > /dev/null <<EOF
USE master;
CREATE MASTER KEY ENCRYPTION BY PASSWORD = '$MKEYENC_PASSWORD';
CREATE CERTIFICATE dbm_certificate WITH SUBJECT = 'dbm';
BACKUP CERTIFICATE dbm_certificate TO FILE = '/var/opt/mssql/data/dbm_certificate.cer' WITH PRIVATE KEY (FILE = '/var/opt/mssql/data/dbm_certificate.pvk', ENCRYPTION BY PASSWORD = '$MKEYENC_PASSWORD');
EOF"
executeCommandOnRemoteNode "$hostname1" "sudo /opt/mssql-tools/bin/sqlcmd -S $hostname1 -U sa -P $MSSQL_SA_PASSWORD -i create_master_enc.sql"

executeCommandOnRemoteNode "$hostname1" "sudo -H -u mssql bash -c 'cp /var/opt/mssql/data/dbm_certificate* /tmp/'"
executeCommandOnRemoteNode "$hostname1" "sudo -H -u mssql bash -c 'chmod 664 /tmp/dbm_certificate*'"
executeCommandOnRemoteNode "$hostname1" "scp /tmp/dbm_certificate* administrator@oplin4sql2202-d:~"
executeCommandOnRemoteNode "$hostname1" "scp /tmp/dbm_certificate* administrator@oplin4sql2203-d:~"
executeCommandOnRemoteNode "$hostname2" "sudo -H -u mssql bash -c 'cp dbm* /var/opt/mssql/data/'"
executeCommandOnRemoteNode "$hostname3" "sudo -H -u mssql bash -c 'cp dbm* /var/opt/mssql/data/'"
executeCommandOnRemoteNode "$hostname2" "sudo -H -u mssql bash -c 'chmod 660 /var/opt/mssql/data/dbm_certificate*'"
executeCommandOnRemoteNode "$hostname3" "sudo -H -u mssql bash -c 'chmod 660 /var/opt/mssql/data/dbm_certificate*'"

executeCommandOnAllNodes "tee create_master_enc_remote.sql > /dev/null <<EOF
CREATE MASTER KEY ENCRYPTION BY PASSWORD = '$MKEYENC_PASSWORD';
CREATE CERTIFICATE dbm_certificate FROM FILE = '/var/opt/mssql/data/dbm_certificate.cer' WITH PRIVATE KEY (FILE = '/var/opt/mssql/data/dbm_certificate.pvk',DECRYPTION BY PASSWORD = '$MKEYENC_PASSWORD');
EOF"

executeCommandOnRemoteNode "$hostname2" "/opt/mssql-tools/bin/sqlcmd -S $hostname2 -U sa -P $MSSQL_SA_PASSWORD -i create_master_enc_remote.sql"
executeCommandOnRemoteNode "$hostname3" "/opt/mssql-tools/bin/sqlcmd -S $hostname3 -U sa -P $MSSQL_SA_PASSWORD -i create_master_enc_remote.sql"

executeCommandOnAllNodes "tee create_hadr_endpoint.sql > /dev/null <<EOF
CREATE ENDPOINT [Hadr_endpoint] AS TCP (LISTENER_PORT = 5022) FOR DATABASE_MIRRORING (ROLE = ALL, AUTHENTICATION = CERTIFICATE dbm_certificate, ENCRYPTION = REQUIRED ALGORITHM AES);
ALTER ENDPOINT [Hadr_endpoint] STATE = STARTED;
USE master;
CREATE LOGIN [pacemakerLogin] with PASSWORD= N'$PACEMAKER_PASSWORD';
ALTER SERVER ROLE [sysadmin] ADD MEMBER [pacemakerLogin];
EOF"

executeCommandOnAllNodes "/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P $MSSQL_SA_PASSWORD -i create_hadr_endpoint.sql"

Schritt 6 - Pacemaker Login

Im sechsten Schritt erstellen wir einen Pacemaker Login und eine Datei zum hinterlegen des Passworts.

#Step 6 - Creating Pacemaker passwd file
executeCommandOnAllNodes "echo 'pacemakerLogin' >> ~/pacemaker-passwd"
executeCommandOnAllNodes "echo '$PACEMAKER_PASSWORD' >> ~/pacemaker-passwd"
executeCommandOnAllNodes "sudo mv ~/pacemaker-passwd /var/opt/mssql/secrets/passwd"
executeCommandOnAllNodes "sudo chown root:root /var/opt/mssql/secrets/passwd"
executeCommandOnAllNodes "sudo chmod 400 /var/opt/mssql/secrets/passwd"

Schritt 7 - AlwaysOn

Nachdem wir nun in den vorherigen Schritten alle Vorbereitungen getroffen haben, können wir nun die AlwaysOn Gruppe erstellen:

#Step 7 - Creating the availability group
writeLog "Step 7 - Creating the availability group"

#create the availability group
executeCommandOnRemoteNode "$hostname1" "tee create_av_group.sql > /dev/null <<EOF
CREATE AVAILABILITY GROUP [oplin4sql22ag-d]
WITH (CLUSTER_TYPE = EXTERNAL)
FOR REPLICA ON
N'oplin4sql2201-d'
WITH (
ENDPOINT_URL = N'tcp://oplin4sql2201-d:5022',
AVAILABILITY_MODE = SYNCHRONOUS_COMMIT,
FAILOVER_MODE = EXTERNAL,
SEEDING_MODE = AUTOMATIC
),
N'oplin4sql2202-d'
WITH (
ENDPOINT_URL = N'tcp://oplin4sql2202-d:5022',
AVAILABILITY_MODE = SYNCHRONOUS_COMMIT,
FAILOVER_MODE = EXTERNAL,
SEEDING_MODE = AUTOMATIC
),
N'oplin4sql2203-d'
WITH(
ENDPOINT_URL = N'tcp://oplin4sql2203-d:5022',
AVAILABILITY_MODE = SYNCHRONOUS_COMMIT,
FAILOVER_MODE = EXTERNAL,
SEEDING_MODE = AUTOMATIC
);
ALTER AVAILABILITY GROUP [oplin4sql22ag-d] GRANT CREATE ANY DATABASE;
EOF"

executeCommandOnRemoteNode "$hostname1" "/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P $MSSQL_SA_PASSWORD -i create_av_group.sql"

#join other Nodes to the availability group
writeLog "Step 7 - Joining remote Nodes to ag"
executeCommandOnRemoteNode "$hostname2" "tee join_av_group.sql > /dev/null <<EOF
ALTER AVAILABILITY GROUP [oplin4sql22ag-d] JOIN WITH (CLUSTER_TYPE = EXTERNAL);
ALTER AVAILABILITY GROUP [oplin4sql22ag-d] GRANT CREATE ANY DATABASE;
EOF"
executeCommandOnRemoteNode "$hostname3" "tee join_av_group.sql > /dev/null <<EOF
ALTER AVAILABILITY GROUP [oplin4sql22ag-d] JOIN WITH (CLUSTER_TYPE = EXTERNAL);
ALTER AVAILABILITY GROUP [oplin4sql22ag-d] GRANT CREATE ANY DATABASE;
EOF"
executeCommandOnRemoteNode "$hostname2" "/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P $MSSQL_SA_PASSWORD -i join_av_group.sql"
executeCommandOnRemoteNode "$hostname3" "/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P $MSSQL_SA_PASSWORD -i join_av_group.sql"

Schritt 8 - Pacemaker Berechtigungen

Nach dem Erstellen der AlwaysOn Gruppe setzen wir nun die korrekten Berechtigungen für Pacemaker.

#Step 8 - Grant permissions to pacemaker login
writeLog "Step 8 - Grant permissions to pacemaker login"
executeCommandOnAllNodes "tee pacemaker_permissions.sql > /dev/null <<EOF
GRANT ALTER, CONTROL, VIEW DEFINITION ON AVAILABILITY GROUP::[oplin4sql22ag-d] TO [pacemakerLogin];
GRANT VIEW SERVER STATE TO [pacemakerLogin];
EOF"

executeCommandOnAllNodes "/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P $MSSQL_SA_PASSWORD -i pacemaker_permissions.sql"

Schritt 9 - Clusterkonfiguration

Als nächstes wird das Cluster konfiguriert:

#Step 9 - CRM Cluster configuration
writeLog "Step 9 - CRM Cluster configuration"
executeCommandOnRemoteNode "$hostname1" "tee crm_cluster_config.txt > /dev/null <<EOF
configure
primitive oplin4sql22cl-d \
ocf:mssql:ag \
params ag_name="oplin4sql22ag-d" \
meta failure-timeout=60s \
op start timeout=60s \
op stop timeout=60s \
op promote timeout=60s \
op demote timeout=10s \
op monitor timeout=60s interval=10s \
op monitor timeout=60s on-fail=demote interval=11s role="Master" \
op monitor timeout=60s interval=12s role="Slave" \
op notify timeout=60s
ms ms-oplin4sql22a oplin4sql22cl-d \
meta master-max="1" master-node-max="1" clone-max="3" \
clone-node-max="1" notify="true"

commit
EOF"

executeCommandOnRemoteNode "$hostname1" "sudo crm configure property stonith-enabled=false"
executeCommandOnRemoteNode "$hostname1" "sudo crm -f crm_cluster_config.txt"
sleep 5s
executeCommandOnRemoteNode "$hostname1" "sudo crm resource status ms-oplin4sql22a"

Schritt 10

Nun benötigen wir noch einen Listener für Pacemaker sowie Ordering Constraints für die Nodes. Diese konfigurieren wir im zehnten Schritt:

#Step 10 - create listener resource in pacemaker

executeCommandOnRemoteNode "$hostname1" "sudo crm configure primitive virtualip ocf:heartbeat:IPaddr2 params ip=172.17.6.186"
sleep 5s
executeCommandOnRemoteNode "$hostname1" "sudo crm status"
executeCommandOnRemoteNode "$hostname1" "tee add_listener_to_ag.sql > /dev/null <<EOF
ALTER AVAILABILITY GROUP [oplin4sql22ag-d] ADD LISTENER N'oplin4sql22li-d' (
WITH IP
((N'172.17.6.186', N'255.255.255.0')), PORT=1433);
EOF"
executeCommandOnRemoteNode "$hostname1" "/opt/mssql-tools/bin/sqlcmd -S $hostname1 -U sa -P $MSSQL_SA_PASSWORD -i add_listener_to_ag.sql"

#configure colocation and ordering constraints

executeCommandOnRemoteNode "$hostname1" "sudo crm configure colocation ag-with-listener INFINITY: virtualip ms-oplin4sql22a:Master"
executeCommandOnRemoteNode "$hostname1" "sudo crm configure order ag-before-listener Mandatory: ms-oplin4sql22a:promote virtualip:start"

#create fence_vmware_rest stonith resource
executeCommandOnRemoteNode "$hostname1" "tee crm_fence_vmware_stonith.txt > /dev/null <<EOF
configure
primitive fence_vmware stonith:fence_vmware_rest \
params \
ipaddr='172.17.6.91' \
action=reboot \
login='VSPHERE_LOGIN' \
passwd='$VSPHERE_PASSWORD' \
ssl=1 ssl_insecure=1 \
pcmk_reboot_timeout=900 \
power_timeout=60 \
op monitor \
interval=3600 \
timeout=120
EOF"
executeCommandOnRemoteNode "$hostname1" "sudo crm -f crm_fence_vmware_stonith.txt"

Schritt 11 - STONITH

Als finalen Schritt Konfigurieren wir noch die STONITH Ressource. In unserem Beispiel befinden sich alle Nodes in VSphere und werden dementsprechend ausgeschaltet, sollte es zu Problemen kommen.

#Step 11 - configure stonith properties

executeCommandOnRemoteNode "$hostname1" "sudo crm configure property cluster-recheck-interval=2min"
executeCommandOnRemoteNode "$hostname1" "sudo crm configure property start-failure-is-fatal=true"
executeCommandOnRemoteNode "$hostname1" "sudo crm configure property stonith-timeout=900"
executeCommandOnRemoteNode "$hostname1" "sudo crm configure property concurrent-fencing=true"
executeCommandOnRemoteNode "$hostname1" "sudo crm configure property stonith-enabled=true"

Test Datenbank - Optional
Um unsere AlwaysOn Gruppe zu Testen, können wir nun eine Testdatenbank Einspielen. Diese heißt in unserem Falle testdatabase1.

USE master;
CREATE DATABASE [testdatabase1];
BACKUP DATABASE [testdatabase1] TO DISK = N'/var/opt/mssql/data/testdatabase1.bak';
BACKUP LOG [testdatabase1] TO DISK = N'/var/opt/mssql/data/testdatabase1.trn';
ALTER AVAILABILITY GROUP [oplin4sql22ag-d] ADD DATABASE [testdatabase1];

Fazit

Mit den oben gezeigten, automatisierten Schritten, ist es mit fast nur einem Klick möglich, ein 3 Node Ubuntu Cluster mit einer SQL Server AlwaysOn Gruppe zu erstellen. Das Risiko auf manuelle Fehler während des Erstellprozesses ist hiermit auf ein Minimum reduziert.
Wenn Sie weitere Fragen zu dem Thema haben, stehen Ihnen unsere Expert:innen mit Rat und Tat zur Seite. Kontaktieren Sie uns dafür gerne über unser Kontaktformular.

Interesse geweckt?

Unsere Expert:innen stehen Ihnen bei allen Fragen rund um Ihre IT Infrastruktur zur Seite.

Kontaktieren Sie uns gerne über das Kontaktformular und vereinbaren ein unverbindliches Beratungsgespräch mit unseren Berater:innen zur Bedarfsevaluierung. Gemeinsam optimieren wir Ihre Umgebung und steigern Ihre Performance!
Wir freuen uns auf Ihre Kontaktaufnahme!

Taunusstraße 72
55118 Mainz
info@madafa.de
+49 6131 3331612
Bürozeiten
Montag bis Donnerstag:
9:00 - 17:00 Uhr MEZ

Freitags:
9:30 - 14:00 Uhr MEZ
Wir sind Ihre SQL Expert:innen!
Noch Fragen? - Wir haben immer die passende Antwort für Sie!