Haute Disponibilité avec HAST et CARP et ZFS

Introduction

Soit 2 serveurs nX sous FreeBSD 14.0.
On considère la configuration réseau effective sur les serveurs :

10.10.10.10 n1
10.10.10.20 n2

Chaque serveur possède 2 supports de stockage :

Le second support fait la même taille sur les 2 serveurs.

Nous aurons besoin d'une IP libre sur le réseau 10.10.10.0/24 pour notre VIP
Décidons par exemple que la VIP aura pour IP : 10.10.10.50


Configuration de n1

Vérifier le nom de la carte réseau connectée :

ifconfig # prenons em0 pour exemple

Configurer le bon nom d'hôte, la bonne adresse IP et la route par défaut puis redémarrez :

sysrc hostname=n1

sysrc ifconfig_em0='inet 10.10.10.10 netmask 255.255.255.0'

sysrc defaultrouter='10.10.10.1'

reboot

Configuration de n2

Vérifier le nom de la carte réseau connectée :

ifconfig # prenons em0 pour exemple

Configurer le bon nom d'hôte, la bonne adresse IP et la route par défaut puis redémarrez :

sysrc hostname=n2

sysrc ifconfig_em0='inet 10.10.10.20 netmask 255.255.255.0'

sysrc defaultrouter='10.10.10.1'

reboot

Configuration HAST sur n1 ET n2

Ajouter le service pour un lancement au démarrage des serveurs :

sysrc hastd_enable='YES'

Renseigner le fichier /etc/hosts pour que chaque nX connaisse l'IP de l'autre :

10.10.10.10 n1
10.10.10.20 n2

Repérer les périphériques de stockage dévolus pour HAST :

camcontrol devlist

(on va dire que sur n1 j'ai ada1 et sur n2 ada1 aussi)

Créer le fichier de configuration /etc/hast.conf :

resource shared {
 on n1 {
 local /dev/ada1
 remote n2
 }
 on n2 {
 local /dev/ada1
 remote n1
 }
 replication memsync
}

Démarrer le service HAST :

service hastd start

Définir les rôles HAST

Sur n1 (serveur primaire)

hastctl role init shared

hastctl create shared

hastctl role primary shared

Sur n2 (serveur secondaire)

hastctl role init shared

hastctl create shared

hastctl role secondary shared

Sur n1 ET n2 - Vérification

hastctl status shared # il doit être 'completed' sur les n1 et n2

LA CONFIGURATION DE HAST EST TERMINEE.


Configuration du pool ZFS

Sur n1

Créer le pool ZFS sur le périphérique HAST :

zpool create hastpool /dev/hast/shared

Créer un système de fichiers ZFS :

zfs create hastpool/shared

LA CONFIGURATION ZFS EST TERMINEE.


Tester HAST manuellement (avant CARP)

Sur n1

Créer un fichier de test :

echo 'Hello from n1' > /hastpool/shared/testfile.txt

Changer le rôle de n1 à secondaire :

zpool export hastpool

hastctl role secondary shared

Sur n2

Changer le rôle de n2 à primaire :

hastctl role primary shared

zpool import hastpool

Regarder si le fichier y est :

cat /hastpool/shared/testfile.txt

LE TEST EST CONCLUANT
REFAIRE LE CHEMIN INVERSE POUR REMETTRE n1 EN PRIMARY


En cas de plantage et redémarrage des 2 serveurs

Sur n1 ET n2

service hastd start

Sur n1 (primaire)

hastctl role init shared

hastctl create shared

hastctl role primary shared

Sur n2 (secondaire)

hastctl role init shared

hastctl create shared

hastctl role secondary shared

Sur n1 - Remonter le pool

zpool import hastpool

Configuration de UCARP pour la Haute Disponibilité

Sur n1 ET n2

Installer ucarp :

pkg ins -y ucarp

Créer le script /usr/local/etc/ucarp-up.sh :

#!/bin/sh
/sbin/ifconfig $1 alias $2 netmask 255.255.255.255

Créer le script /usr/local/etc/ucarp-down.sh :

#!/bin/sh
/sbin/ifconfig $1 -alias $2 2>/dev/null

Ne pas oublier de les rendre exécutables :

chmod +x /usr/local/etc/ucarp-up.sh

chmod +x /usr/local/etc/ucarp-down.sh

Créer un script de démarrage personnalisé : /usr/local/etc/rc.d/ucarp_custom

#!/bin/sh
# PROVIDE: ucarp_custom
# REQUIRE: NETWORKING
# BEFORE: DAEMON
# KEYWORD: shutdown

. /etc/rc.subr

name="ucarp_custom"
rcvar="ucarp_custom_enable"
start_cmd="${name}_start"
stop_cmd="${name}_stop"

ucarp_custom_start() {
 /usr/local/sbin/ucarp -i ${ucarp_if} -s ${ucarp_src} -v ${ucarp_vhid} -p ${ucarp_pass} -a ${ucarp_addr} -b ${ucarp_advbase} -k ${ucarp_advskew} -P -u /usr/local/etc/ucarp-up.sh -d /usr/local/etc/ucarp-down.sh &
 echo $! > /var/run/ucarp_${ucarp_vhid}.pid
}

ucarp_custom_stop() {
 if [ -f /var/run/ucarp_${ucarp_vhid}.pid ]; then
 kill $(cat /var/run/ucarp_${ucarp_vhid}.pid)
 rm /var/run/ucarp_${ucarp_vhid}.pid
 fi
}

load_rc_config $name
run_rc_command "$1"

Ne pas oublier de le rendre exécutable :

chmod +x /usr/local/etc/rc.d/ucarp_custom

Sur n1 uniquement

sysrc ucarp_custom_enable="YES"
sysrc ucarp_if="em0"
sysrc ucarp_src="10.10.10.10"
sysrc ucarp_pass="testpass"
sysrc ucarp_vhid="1"
sysrc ucarp_addr="10.10.10.50"
sysrc ucarp_advbase="1"
sysrc ucarp_advskew="1"

Sur n2 uniquement

sysrc ucarp_custom_enable="YES"
sysrc ucarp_if="em0"
sysrc ucarp_src="10.10.10.20"
sysrc ucarp_pass="testpass"
sysrc ucarp_vhid="1"
sysrc ucarp_addr="10.10.10.50"
sysrc ucarp_advbase="1"
sysrc ucarp_advskew="100"

Sur n1 PUIS n2

service ucarp_custom start

LE SYSTEME DE HA EST EN PLACE


Test final de la HA

Sur n1

ifconfig em0

(vous devez voir l'attribution de la VIP sur em0)

A présent, c'est le grand test ! Eteignez n1 et regardez ce qui se passe sur le prompt de n2 :

poweroff

Sur n2

ifconfig em0

LE TEST EST CONCLUANT

Sur n1

Rallumer n1 à présent et regarder si la VIP revient sur n1

ifconfig em0

(oui, la VIP est revenue sur n1)


Importation forcée du pool - Problème connu

Nous avons un problème.
Si n1 tombe, n2 prend le relais de la VIP. Cela fonctionne !
Mais, le pool hastpool ne se réimporte pas automatiquement... Il faut le remonter manuellement pour l'instant (je vous laisse scripter ça !)



↑ Haut de page