Ce tutoriel vous explique comment déployer une base de données MySQL 5.6 surGoogle Cloud à l'aide de DRBD (Distributed Replicated Block Device : périphérique en mode bloc répliqué et distribué) et de Compute Engine. DRBD est un système de stockage répliqué distribué pour la plate-forme Linux.
Ce tutoriel est utile si vous êtes administrateur système, développeur, ingénieur, administrateur de base de données ou ingénieur DevOps. Vous voudrez peut-être gérer votre propre instance MySQL au lieu d'utiliser le service géré, et ce, pour différentes raisons. En voici quelques-unes :
- Vous utilisez des instances de MySQL interrégionales.
- Vous devez définir des paramètres qui ne sont pas disponibles dans la version gérée de MySQL.
- Vous souhaitez optimiser les performances d'une manière non configurable dans la version gérée.
DRBD assure la réplication au niveau du périphérique en mode bloc. Cela signifie que vous n'avez pas à configurer la réplication dans MySQL et que vous bénéficiez immédiatement des avantages de DRBD. Par exemple : compatibilité avec l'équilibrage de charge en lecture et connexions sécurisées.
Le tutoriel utilise les ressources suivantes :
Aucune connaissance avancée n'est requise pour utiliser ces ressources. Cependant, ce tutoriel fait référence à des fonctionnalités avancées telles que le clustering MySQL, la configuration DRBD et la gestion des ressources Linux.
Architecture
Pacemaker est un gestionnaire de ressources de cluster. Corosync est un package de communication et de participation de cluster, utilisé par Pacemaker. Dans ce tutoriel, vous utilisez DRBD pour répliquer le disque MySQL de l’instance principale sur l’instance de secours. Pour permettre aux clients de se connecter au cluster MySQL, vous devez également déployer un équilibreur de charge interne.
Vous déployez un cluster géré par Pacemaker de trois instances de calcul. Vous installez MySQL sur deux des instances, qui servent d’instances principale et de secours. La troisième instance sert de périphérique de quorum.
Dans un cluster, chaque nœud vote pour le nœud qui devrait être le nœud actif, c'est-à-dire celui qui exécute MySQL. Dans un cluster à deux nœuds, il suffit d'un seul vote pour déterminer le nœud actif. Dans ce cas, le comportement du cluster peut entraîner des problèmes de split-brain ou des temps d'arrêt. Les problèmes de split-brain surviennent lorsque les deux nœuds prennent le contrôle, car un seul vote est nécessaire dans un scénario à deux nœuds. Les temps d'arrêt surviennent lorsque le nœud qui s'arrête est celui configuré pour être le nœud principal en cas de perte de connectivité. Si les deux nœuds perdent la connectivité l'un avec l'autre, il est possible que plus d'un nœud de cluster se considère comme étant le nœud actif.
L'ajout d'un périphérique de quorum empêche cette situation. Un périphérique de quorum sert d'arbitre, sa seule tâche est de voter. De cette façon, dans une situation où les instances database1 et database2 ne peuvent pas communiquer, ce nœud de périphérique de quorum peut communiquer avec l'une des deux instances, et permettre ainsi d'obtenir une majorité.
Le diagramme suivant montre l'architecture du système décrit ici.
Configuration
Dans cette section, vous allez configurer un compte de service, créer des variables d'environnement et réserver des adresses IP.
Configurer un compte de service pour les instances de cluster
Ouvrez Cloud Shell.
Créez le compte de service :
gcloud iam service-accounts create mysql-instance \ --display-name "mysql-instance"Associez les rôles nécessaires pour réaliser ce tutoriel au compte de service :
gcloud projects add-iam-policy-binding ${DEVSHELL_PROJECT_ID} \ --member=serviceAccount:mysql-instance@${DEVSHELL_PROJECT_ID}.iam.gserviceaccount.com \ --role=roles/compute.instanceAdmin.v1 gcloud projects add-iam-policy-binding ${DEVSHELL_PROJECT_ID} \ --member=serviceAccount:mysql-instance@${DEVSHELL_PROJECT_ID}.iam.gserviceaccount.com \ --role=roles/compute.viewer gcloud projects add-iam-policy-binding ${DEVSHELL_PROJECT_ID} \ --member=serviceAccount:mysql-instance@${DEVSHELL_PROJECT_ID}.iam.gserviceaccount.com \ --role=roles/iam.serviceAccountUser
Créer des variables d'environnement Cloud Shell
Créez un fichier avec les variables d’environnement requises pour ce tutoriel :
cat <<EOF > ~/.mysqldrbdrc # Cluster instance names DATABASE1_INSTANCE_NAME=database1 DATABASE2_INSTANCE_NAME=database2 QUORUM_INSTANCE_NAME=qdevice CLIENT_INSTANCE_NAME=mysql-client # Cluster IP addresses DATABASE1_INSTANCE_IP="10.140.0.2" DATABASE2_INSTANCE_IP="10.140.0.3" QUORUM_INSTANCE_IP="10.140.0.4" ILB_IP="10.140.0.6" # Cluster zones and region DATABASE1_INSTANCE_ZONE="asia-east1-a" DATABASE2_INSTANCE_ZONE="asia-east1-b" QUORUM_INSTANCE_ZONE="asia-east1-c" CLIENT_INSTANCE_ZONE="asia-east1-c" CLUSTER_REGION="asia-east1" EOFChargez les variables d'environnement dans la session en cours, puis configurez Cloud Shell pour qu'il les charge automatiquement lors de futures connexions :
source ~/.mysqldrbdrc grep -q -F "source ~/.mysqldrbdrc" ~/.bashrc || echo "source ~/.mysqldrbdrc" >> ~/.bashrc
Réserver des adresses IP
Dans Cloud Shell, réservez une adresse IP interne pour chacun des trois nœuds de cluster :
gcloud compute addresses create ${DATABASE1_INSTANCE_NAME} ${DATABASE2_INSTANCE_NAME} ${QUORUM_INSTANCE_NAME} \ --region=${CLUSTER_REGION} \ --addresses "${DATABASE1_INSTANCE_IP},${DATABASE2_INSTANCE_IP},${QUORUM_INSTANCE_IP}" \ --subnet=default
Créer les instances Compute Engine
Dans les étapes suivantes, les instances de cluster utilisent Debian 9 et les instances clientes, Ubuntu 16.
Dans Cloud Shell, créez une instance MySQL nommée
database1dans la zoneasia-east1-a:gcloud compute instances create ${DATABASE1_INSTANCE_NAME} \ --zone=${DATABASE1_INSTANCE_ZONE} \ --machine-type=n1-standard-2 \ --network-tier=PREMIUM \ --maintenance-policy=MIGRATE \ --image-family=debian-9 \ --image-project=debian-cloud \ --boot-disk-size=50GB \ --boot-disk-type=pd-standard \ --boot-disk-device-name=${DATABASE1_INSTANCE_NAME} \ --create-disk=mode=rw,size=300,type=pd-standard,name=disk-1 \ --private-network-ip=${DATABASE1_INSTANCE_NAME} \ --tags=mysql --service-account=mysql-instance@${DEVSHELL_PROJECT_ID}.iam.gserviceaccount.com \ --scopes="https://www.googleapis.com/auth/compute,https://www.googleapis.com/auth/servicecontrol,https://www.googleapis.com/auth/service.management.readonly" \ --metadata="DATABASE1_INSTANCE_IP=${DATABASE1_INSTANCE_IP},DATABASE2_INSTANCE_IP=${DATABASE2_INSTANCE_IP},DATABASE1_INSTANCE_NAME=${DATABASE1_INSTANCE_NAME},DATABASE2_INSTANCE_NAME=${DATABASE2_INSTANCE_NAME},QUORUM_INSTANCE_NAME=${QUORUM_INSTANCE_NAME},DATABASE1_INSTANCE_ZONE=${DATABASE1_INSTANCE_ZONE},DATABASE2_INSTANCE_ZONE=${DATABASE2_INSTANCE_ZONE}"Créez une instance MySQL nommée
database2dans la zoneasia-east1-b:gcloud compute instances create ${DATABASE2_INSTANCE_NAME} \ --zone=${DATABASE2_INSTANCE_ZONE} \ --machine-type=n1-standard-2 \ --network-tier=PREMIUM \ --maintenance-policy=MIGRATE \ --image-family=debian-9 \ --image-project=debian-cloud \ --boot-disk-size=50GB \ --boot-disk-type=pd-standard \ --boot-disk-device-name=${DATABASE2_INSTANCE_NAME} \ --create-disk=mode=rw,size=300,type=pd-standard,name=disk-2 \ --private-network-ip=${DATABASE2_INSTANCE_NAME} \ --tags=mysql \ --service-account=mysql-instance@${DEVSHELL_PROJECT_ID}.iam.gserviceaccount.com \ --scopes="https://www.googleapis.com/auth/compute,https://www.googleapis.com/auth/servicecontrol,https://www.googleapis.com/auth/service.management.readonly" \ --metadata="DATABASE1_INSTANCE_IP=${DATABASE1_INSTANCE_IP},DATABASE2_INSTANCE_IP=${DATABASE2_INSTANCE_IP},DATABASE1_INSTANCE_NAME=${DATABASE1_INSTANCE_NAME},DATABASE2_INSTANCE_NAME=${DATABASE2_INSTANCE_NAME},QUORUM_INSTANCE_NAME=${QUORUM_INSTANCE_NAME},DATABASE1_INSTANCE_ZONE=${DATABASE1_INSTANCE_ZONE},DATABASE2_INSTANCE_ZONE=${DATABASE2_INSTANCE_ZONE}"Créez un nœud de quorum pour que Pacemaker puisse l'utiliser dans la zone
asia-east1-c:gcloud compute instances create ${QUORUM_INSTANCE_NAME} \ --zone=${QUORUM_INSTANCE_ZONE} \ --machine-type=n1-standard-1 \ --network-tier=PREMIUM \ --maintenance-policy=MIGRATE \ --image-family=debian-9 \ --image-project=debian-cloud \ --boot-disk-size=10GB \ --boot-disk-type=pd-standard \ --boot-disk-device-name=${QUORUM_INSTANCE_NAME} \ --private-network-ip=${QUORUM_INSTANCE_NAME}Créez une instance de client MySQL :
gcloud compute instances create ${CLIENT_INSTANCE_NAME} \ --image-family=ubuntu-1604-lts \ --image-project=ubuntu-os-cloud \ --tags=mysql-client \ --zone=${CLIENT_INSTANCE_ZONE} \ --boot-disk-size=10GB \ --metadata="ILB_IP=${ILB_IP}"
Installer et configurer DRBD
Dans cette section, vous allez installer et configurer les packages DRBD sur les instances database1 et database2, puis lancer la réplication DRBD depuis database1 vers database2.
Configurer DRBD sur database1
Dans la console Google Cloud , accédez à la page Instances de VM :
Sur la ligne de l'instance
database1, cliquez sur SSH pour vous connecter à l'instance.Créez un fichier pour récupérer et stocker les métadonnées d'instance dans des variables d'environnement :
sudo bash -c cat <<EOF > ~/.varsrc DATABASE1_INSTANCE_IP=$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/DATABASE1_INSTANCE_IP" -H "Metadata-Flavor: Google") DATABASE2_INSTANCE_IP=$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/DATABASE2_INSTANCE_IP" -H "Metadata-Flavor: Google") DATABASE1_INSTANCE_NAME=$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/DATABASE1_INSTANCE_NAME" -H "Metadata-Flavor: Google") DATABASE2_INSTANCE_NAME=$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/DATABASE2_INSTANCE_NAME" -H "Metadata-Flavor: Google") DATABASE2_INSTANCE_ZONE=$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/DATABASE2_INSTANCE_ZONE" -H "Metadata-Flavor: Google") DATABASE1_INSTANCE_ZONE=$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/DATABASE1_INSTANCE_ZONE" -H "Metadata-Flavor: Google") QUORUM_INSTANCE_NAME=$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/QUORUM_INSTANCE_NAME" -H "Metadata-Flavor: Google") EOFChargez les variables de métadonnées à partir du fichier :
source ~/.varsrcFormatez le disque de données :
sudo bash -c "mkfs.ext4 -m 0 -F -E \ lazy_itable_init=0,lazy_journal_init=0,discard /dev/sdb"Pour une description détaillée des options de
mkfs.ext4, consultez la page de manuel de la commande mkfs.ext4.Installez DRBD :
sudo apt -y install drbd8-utilsCréez le fichier de configuration DRBD :
sudo bash -c 'cat <<EOF > /etc/drbd.d/global_common.conf global { usage-count no; } common { protocol C; } EOF'Créez un fichier de ressources DRBD :
sudo bash -c "cat <<EOF > /etc/drbd.d/r0.res resource r0 { meta-disk internal; device /dev/drbd0; net { allow-two-primaries no; after-sb-0pri discard-zero-changes; after-sb-1pri discard-secondary; after-sb-2pri disconnect; rr-conflict disconnect; } on database1 { disk /dev/sdb; address 10.140.0.2:7789; } on database2 { disk /dev/sdb; address 10.140.0.3:7789; } } EOF"Chargez le module de noyau DRBD :
sudo modprobe drbdEffacez le contenu du disque
/dev/sdb:sudo dd if=/dev/zero of=/dev/sdb bs=1k count=1024Créez la ressource DRBD
r0:sudo drbdadm create-md r0Affichez DRBD :
sudo drbdadm up r0Désactivez DRBD au démarrage du système, en laissant le logiciel de gestion des ressources de cluster lancer tous les services nécessaires dans l'ordre :
sudo update-rc.d drbd disable
Configurer DRBD sur database2
Vous allez maintenant installer et configurer les packages DRBD sur l'instance database2.
- Connectez-vous à l'instance
database2via SSH. Créez un fichier
.varsrcpour récupérer et stocker les métadonnées d'instance dans des variables d'environnement :sudo bash -c cat <<EOF > ~/.varsrc DATABASE1_INSTANCE_IP=$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/DATABASE1_INSTANCE_IP" -H "Metadata-Flavor: Google") DATABASE2_INSTANCE_IP=$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/DATABASE2_INSTANCE_IP" -H "Metadata-Flavor: Google") DATABASE1_INSTANCE_NAME=$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/DATABASE1_INSTANCE_NAME" -H "Metadata-Flavor: Google") DATABASE2_INSTANCE_NAME=$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/DATABASE2_INSTANCE_NAME" -H "Metadata-Flavor: Google") DATABASE2_INSTANCE_ZONE=$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/DATABASE2_INSTANCE_ZONE" -H "Metadata-Flavor: Google") DATABASE1_INSTANCE_ZONE=$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/DATABASE1_INSTANCE_ZONE" -H "Metadata-Flavor: Google") QUORUM_INSTANCE_NAME=$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/QUORUM_INSTANCE_NAME" -H "Metadata-Flavor: Google") EOFChargez les variables de métadonnées à partir du fichier :
source ~/.varsrcFormatez le disque de données :
sudo bash -c "mkfs.ext4 -m 0 -F -E lazy_itable_init=0,lazy_journal_init=0,discard /dev/sdb"Installez les packages DRBD :
sudo apt -y install drbd8-utilsCréez le fichier de configuration DRBD :
sudo bash -c 'cat <<EOF > /etc/drbd.d/global_common.conf global { usage-count no; } common { protocol C; } EOF'Créez un fichier de ressources DRBD :
sudo bash -c "cat <<EOF > /etc/drbd.d/r0.res resource r0 { meta-disk internal; device /dev/drbd0; net { allow-two-primaries no; after-sb-0pri discard-zero-changes; after-sb-1pri discard-secondary; after-sb-2pri disconnect; rr-conflict disconnect; } on ${DATABASE1_INSTANCE_NAME} { disk /dev/sdb; address ${DATABASE1_INSTANCE_IP}:7789; } on ${DATABASE2_INSTANCE_NAME} { disk /dev/sdb; address ${DATABASE2_INSTANCE_IP}:7789; } } EOF"Chargez le module de noyau DRBD :
sudo modprobe drbdVidez le disque
/dev/sdb:sudo dd if=/dev/zero of=/dev/sdb bs=1k count=1024Créez la ressource DRBD
r0:sudo drbdadm create-md r0Affichez DRBD :
sudo drbdadm up r0Désactivez DRBD au démarrage du système, en laissant le logiciel de gestion des ressources de cluster lancer tous les services nécessaires dans l'ordre :
sudo update-rc.d drbd disable
Lancer la réplication DRBD depuis database1 vers database2
- Connectez-vous à l'instance
database1via SSH. Remplacez toutes les ressources
r0sur le nœud principal :sudo drbdadm -- --overwrite-data-of-peer primary r0 sudo mkfs.ext4 -m 0 -F -E lazy_itable_init=0,lazy_journal_init=0,discard /dev/drbd0Vérifiez le statut de DRBD :
sudo cat /proc/drbd | grep ============Le résultat ressemble à ceci :
[===================>] sync'ed:100.0% (208/307188)M
Installez
/dev/drbdsur/srv:sudo mount -o discard,defaults /dev/drbd0 /srv
Installer MySQL et Pacemaker
Dans cette section, vous installez MySQL et Pacemaker sur chaque instance.
Installer MySQL sur database1
- Connectez-vous à l'instance
database1via SSH. Mettez à jour le dépôt APT avec les définitions de package MySQL 5.6 :
sudo bash -c 'cat <<EOF > /etc/apt/sources.list.d/mysql.list deb http://repo.mysql.com/apt/debian/ stretch mysql-5.6\ndeb-src http://repo.mysql.com/apt/debian/ stretch mysql-5.6 EOF'Ajoutez les clés GPG au fichier APT
repository.srv:wget -O /tmp/RPM-GPG-KEY-mysql https://repo.mysql.com/RPM-GPG-KEY-mysql sudo apt-key add /tmp/RPM-GPG-KEY-mysqlMettez à jour la liste de packages :
sudo apt updateInstallez le serveur MySQL :
sudo apt -y install mysql-serverLorsque vous êtes invité à entrer un mot de passe, saisissez
DRBDha2.Arrêtez le serveur MySQL :
sudo /etc/init.d/mysql stopCréez le fichier de configuration MySQL :
sudo bash -c 'cat <<EOF > /etc/mysql/mysql.conf.d/my.cnf [mysqld] bind-address = 0.0.0.0 # You may want to listen at localhost at the beginning datadir = /var/lib/mysql tmpdir = /srv/tmp user = mysql EOF'Créez un répertoire temporaire pour le serveur MySQL (configuré dans
mysql.conf) :sudo mkdir /srv/tmp sudo chmod 1777 /srv/tmpDéplacez toutes les données MySQL dans le répertoire DRBD
/srv/mysql:sudo mv /var/lib/mysql /srv/mysqlLiez
/var/lib/mysqlà/srv/mysqlsous le volume de stockage répliqué DRBD :sudo ln -s /srv/mysql /var/lib/mysqlChangez le propriétaire de
/srv/mysqlpour le définir sur un processusmysql:sudo chown -R mysql:mysql /srv/mysqlSupprimez les données initiales
InnoDBpour vous assurer que le disque est aussi propre que possible :sudo bash -c "cd /srv/mysql && rm ibdata1 && rm ib_logfile*"InnoDB est un moteur de stockage pour le système de gestion de bases de données MySQL.
Démarrez MySQL :
sudo /etc/init.d/mysql startAccordez à l'utilisateur racine la permission de se connecter à distance afin qu'il puisse tester le déploiement ultérieurement :
mysql -uroot -pDRBDha2 -e "GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'DRBDha2' WITH GRANT OPTION;"Désactivez le démarrage automatique de MySQL, dont s'occupe la gestion des ressources du cluster :
sudo update-rc.d -f mysql disable
Installer Pacemaker sur database1
Chargez les variables de métadonnées à partir du fichier
.varsrcque vous avez créé précédemment :source ~/.varsrcArrêtez le serveur MySQL :
sudo /etc/init.d/mysql stopInstallez Pacemaker :
sudo apt -y install pcsActivez
pcsd,corosyncetpacemakerau démarrage du système sur l'instance principale :sudo update-rc.d -f pcsd enable sudo update-rc.d -f corosync enable sudo update-rc.d -f pacemaker enableConfigurez
corosyncpour qu'il démarre avantpacemaker:sudo update-rc.d corosync defaults 20 20 sudo update-rc.d pacemaker defaults 30 10Définissez le mot de passe de l'utilisateur du cluster sur
haCLUSTER3pour l'authentification :sudo bash -c "echo hacluster:haCLUSTER3 | chpasswd"Exécutez le script
corosync-keygenpour générer une clé d'autorisation de cluster de 128 bits et écrivez-la dans/etc/corosync/authkey:sudo corosync-keygen -lCopiez
authkeysur l'instancedatabase2. Lorsque vous êtes invité à entrer une phrase secrète, appuyez surEnter:sudo chmod 444 /etc/corosync/authkey gcloud beta compute scp /etc/corosync/authkey ${DATABASE2_INSTANCE_NAME}:~/authkey --zone=${DATABASE2_INSTANCE_ZONE} --internal-ip sudo chmod 400 /etc/corosync/authkeyCréez un fichier de configuration de cluster Corosync :
sudo bash -c "cat <<EOF > /etc/corosync/corosync.conf totem { version: 2 cluster_name: mysql_cluster transport: udpu interface { ringnumber: 0 Bindnetaddr: ${DATABASE1_INSTANCE_IP} broadcast: yes mcastport: 5405 } } quorum { provider: corosync_votequorum two_node: 1 } nodelist { node { ring0_addr: ${DATABASE1_INSTANCE_NAME} name: ${DATABASE1_INSTANCE_NAME} nodeid: 1 } node { ring0_addr: ${DATABASE2_INSTANCE_NAME} name: ${DATABASE2_INSTANCE_NAME} nodeid: 2 } } logging { to_logfile: yes logfile: /var/log/corosync/corosync.log timestamp: on } EOF"La section
totemconfigure le protocole Totem pour une communication fiable. Corosync utilise cette communication pour contrôler l’appartenance à un cluster et indique comment les membres du cluster doivent communiquer entre eux.Les paramètres importants de la configuration sont les suivants :
transport: spécifie le mode unicast (udpu).Bindnetaddr: spécifie l'adresse réseau à laquelle Corosync se lie.nodelist: définit les nœuds du cluster et la façon dont ils peuvent être atteints. Dans ce cas : nœudsdatabase1etdatabase2.quorum/two_node: par défaut, dans un cluster à deux nœuds, aucun nœud n'acquiert de quorum. Vous pouvez modifier ce comportement en spécifiant la valeur "1" pourtwo_nodedans la sectionquorum.
Cette configuration vous permet de configurer le cluster et de le préparer pour plus tard lorsque vous ajoutez un troisième nœud qui sera un périphérique de quorum.
Créez le répertoire de service pour
corosync:sudo mkdir -p /etc/corosync/service.dConfigurez
corosyncpour qu'il prenne en compte Pacemaker :sudo bash -c 'cat <<EOF > /etc/corosync/service.d/pcmk service { name: pacemaker ver: 1 } EOF'Activez le service
corosyncpar défaut :sudo bash -c 'cat <<EOF > /etc/default/corosync # Path to corosync.conf COROSYNC_MAIN_CONFIG_FILE=/etc/corosync/corosync.conf # Path to authfile COROSYNC_TOTEM_AUTHKEY_FILE=/etc/corosync/authkey # Enable service by default START=yes EOF'Redémarrez les services
corosyncetpacemaker:sudo service corosync restart sudo service pacemaker restartInstallez le package de périphérique de quorum Corosync :
sudo apt -y install corosync-qdeviceInstallez un script shell pour gérer les événements de défaillance DRBD :
sudo bash -c 'cat << 'EOF' > /var/lib/pacemaker/drbd_cleanup.sh #!/bin/sh if [ -z \$CRM_alert_version ]; then echo "\$0 must be run by Pacemaker version 1.1.15 or later" exit 0 fi tstamp="\$CRM_alert_timestamp: " case \$CRM_alert_kind in resource) if [ \${CRM_alert_interval} = "0" ]; then CRM_alert_interval="" else CRM_alert_interval=" (\${CRM_alert_interval})" fi if [ \${CRM_alert_target_rc} = "0" ]; then CRM_alert_target_rc="" else CRM_alert_target_rc=" (target: \${CRM_alert_target_rc})" fi case \${CRM_alert_desc} in Cancelled) ;; *) echo "\${tstamp}Resource operation "\${CRM_alert_task}\${CRM_alert_interval}" for "\${CRM_alert_rsc}" on "\${CRM_alert_node}": \${CRM_alert_desc}\${CRM_alert_target_rc}" >> "\${CRM_alert_recipient}" if [ "\${CRM_alert_task}" = "stop" ] && [ "\${CRM_alert_desc}" = "Timed Out" ]; then echo "Executing recovering..." >> "\${CRM_alert_recipient}" pcs resource cleanup \${CRM_alert_rsc} fi ;; esac ;; *) echo "\${tstamp}Unhandled \$CRM_alert_kind alert" >> "\${CRM_alert_recipient}" env | grep CRM_alert >> "\${CRM_alert_recipient}" ;; esac EOF' sudo chmod 0755 /var/lib/pacemaker/drbd_cleanup.sh sudo touch /var/log/pacemaker_drbd_file.log sudo chown hacluster:haclient /var/log/pacemaker_drbd_file.log
Installer MySQL sur database2
- Connectez-vous à l'instance
database2via SSH. Mettez à jour le dépôt APT avec le package MySQL 5.6 :
sudo bash -c 'cat <<EOF > /etc/apt/sources.list.d/mysql.list deb http://repo.mysql.com/apt/debian/ stretch mysql-5.6\ndeb-src http://repo.mysql.com/apt/debian/ stretch mysql-5.6 EOF'Ajoutez les clés GPG au dépôt APT :
wget -O /tmp/RPM-GPG-KEY-mysql https://repo.mysql.com/RPM-GPG-KEY-mysql sudo apt-key add /tmp/RPM-GPG-KEY-mysqlMettez à jour la liste de packages :
sudo apt updateInstallez le serveur MySQL :
sudo apt -y install mysql-serverLorsque vous êtes invité à entrer un mot de passe, saisissez
DRBDha2.Arrêtez le serveur MySQL :
sudo /etc/init.d/mysql stopCréez le fichier de configuration MySQL :
sudo bash -c 'cat <<EOF > /etc/mysql/mysql.conf.d/my.cnf [mysqld] bind-address = 0.0.0.0 # You may want to listen at localhost at the beginning datadir = /var/lib/mysql tmpdir = /srv/tmp user = mysql EOF'Supprimez les données sous
/var/lib/mysqlet ajoutez un lien symbolique à la cible du point d'installation du volume DRBD répliqué. Le volume DRBD (/dev/drbd0) ne sera installé sur/srvqu'en cas de basculement.sudo rm -rf /var/lib/mysql sudo ln -s /srv/mysql /var/lib/mysqlDésactivez le démarrage automatique de MySQL, dont s'occupe la gestion des ressources du cluster :
sudo update-rc.d -f mysql disable
Installer Pacemaker sur database2
Chargez les variables de métadonnées à partir du fichier
.varsrc:source ~/.varsrcInstallez Pacemaker :
sudo apt -y install pcsDéplacez le fichier Corosync
authkeyque vous avez précédemment copié dans/etc/corosync/:sudo mv ~/authkey /etc/corosync/ sudo chown root: /etc/corosync/authkey sudo chmod 400 /etc/corosync/authkeyActivez
pcsd,corosyncetpacemakerau démarrage du système sur l'instance de secours :sudo update-rc.d -f pcsd enable sudo update-rc.d -f corosync enable sudo update-rc.d -f pacemaker enableConfigurez
corosyncpour qu'il démarre avantpacemaker:sudo update-rc.d corosync defaults 20 20 sudo update-rc.d pacemaker defaults 30 10Définissez le mot de passe de l'utilisateur du cluster pour l'authentification. Le mot de passe est le même (
haCLUSTER3) que celui que vous avez utilisé pour l'instancedatabase1.sudo bash -c "echo hacluster:haCLUSTER3 | chpasswd"Créez le fichier de configuration
corosync:sudo bash -c "cat <<EOF > /etc/corosync/corosync.conf totem { version: 2 cluster_name: mysql_cluster transport: udpu interface { ringnumber: 0 Bindnetaddr: ${DATABASE2_INSTANCE_IP} broadcast: yes mcastport: 5405 } } quorum { provider: corosync_votequorum two_node: 1 } nodelist { node { ring0_addr: ${DATABASE1_INSTANCE_NAME} name: ${DATABASE1_INSTANCE_NAME} nodeid: 1 } node { ring0_addr: ${DATABASE2_INSTANCE_NAME} name: ${DATABASE2_INSTANCE_NAME} nodeid: 2 } } logging { to_logfile: yes logfile: /var/log/corosync/corosync.log timestamp: on } EOF"Créez le répertoire de service Corosync :
sudo mkdir /etc/corosync/service.dConfigurez
corosyncpour qu'il prenne en compte Pacemaker :sudo bash -c 'cat <<EOF > /etc/corosync/service.d/pcmk service { name: pacemaker ver: 1 } EOF'Activez le service
corosyncpar défaut :sudo bash -c 'cat <<EOF > /etc/default/corosync # Path to corosync.conf COROSYNC_MAIN_CONFIG_FILE=/etc/corosync/corosync.conf # Path to authfile COROSYNC_TOTEM_AUTHKEY_FILE=/etc/corosync/authkey # Enable service by default START=yes EOF'Redémarrez les services
corosyncetpacemaker:sudo service corosync restart sudo service pacemaker restartInstallez le package de périphérique de quorum Corosync :
sudo apt -y install corosync-qdeviceInstallez un script shell pour gérer les événements de défaillance DRBD :
sudo bash -c 'cat << 'EOF' > /var/lib/pacemaker/drbd_cleanup.sh #!/bin/sh if [ -z \$CRM_alert_version ]; then echo "\$0 must be run by Pacemaker version 1.1.15 or later" exit 0 fi tstamp="\$CRM_alert_timestamp: " case \$CRM_alert_kind in resource) if [ \${CRM_alert_interval} = "0" ]; then CRM_alert_interval="" else CRM_alert_interval=" (\${CRM_alert_interval})" fi if [ \${CRM_alert_target_rc} = "0" ]; then CRM_alert_target_rc="" else CRM_alert_target_rc=" (target: \${CRM_alert_target_rc})" fi case \${CRM_alert_desc} in Cancelled) ;; *) echo "\${tstamp}Resource operation "\${CRM_alert_task}\${CRM_alert_interval}" for "\${CRM_alert_rsc}" on "\${CRM_alert_node}": \${CRM_alert_desc}\${CRM_alert_target_rc}" >> "\${CRM_alert_recipient}" if [ "\${CRM_alert_task}" = "stop" ] && [ "\${CRM_alert_desc}" = "Timed Out" ]; then echo "Executing recovering..." >> "\${CRM_alert_recipient}" pcs resource cleanup \${CRM_alert_rsc} fi ;; esac ;; *) echo "\${tstamp}Unhandled \$CRM_alert_kind alert" >> "\${CRM_alert_recipient}" env | grep CRM_alert >> "\${CRM_alert_recipient}" ;; esac EOF' sudo chmod 0755 /var/lib/pacemaker/drbd_cleanup.sh sudo touch /var/log/pacemaker_drbd_file.log sudo chown hacluster:haclient /var/log/pacemaker_drbd_file.logVérifiez l'état du cluster Corosync :
sudo corosync-cmapctl | grep "members...ip"Le résultat est semblable à ce qui suit :
runtime.totem.pg.mrp.srp.members.1.ip (str) = r(0) ip(10.140.0.2) runtime.totem.pg.mrp.srp.members.2.ip (str) = r(0) ip(10.140.0.3)
Démarrer le cluster
- Connectez-vous à l'instance
database2via SSH. Chargez les variables de métadonnées à partir du fichier
.varsrc:source ~/.varsrcAuthentifiez-vous auprès des nœuds de cluster :
sudo pcs cluster auth --name mysql_cluster ${DATABASE1_INSTANCE_NAME} ${DATABASE2_INSTANCE_NAME} -u hacluster -p haCLUSTER3Démarrez le cluster :
sudo pcs cluster start --allVérifiez le statut du cluster :
sudo pcs statusLe résultat est semblable à ce qui suit :
Cluster name: mysql_cluster WARNING: no stonith devices and stonith-enabled is not false Stack: corosync Current DC: database2 (version 1.1.16-94ff4df) - partition with quorum Last updated: Sat Nov 3 07:24:53 2018 Last change: Sat Nov 3 07:17:17 2018 by hacluster via crmd on database2 2 nodes configured 0 resources configured Online: [ database1 database2 ] No resources Daemon Status: corosync: active/enabled pacemaker: active/enabled pcsd: active/enabled
Configurer Pacemaker pour gérer les ressources du cluster
Configurez Pacemaker avec les ressources DRBD, de disque, MySQL et quorum.
- Connectez-vous à l'instance
database1via SSH. Utilisez l'utilitaire Pacemaker
pcspour mettre plusieurs modifications en file d'attente dans un fichier et les appliquer ultérieurement à la base d'informations de cluster (CIB) de manière atomique :sudo pcs cluster cib clust_cfgDésactivez STONITH, car vous déploierez le périphérique de quorum ultérieurement :
sudo pcs -f clust_cfg property set stonith-enabled=falseDésactivez les paramètres liés au quorum. Vous configurerez ultérieurement le nœud du périphérique de quorum.
sudo pcs -f clust_cfg property set no-quorum-policy=stopEmpêchez Pacemaker de remettre les ressources à leur place après une récupération :
sudo pcs -f clust_cfg resource defaults resource-stickiness=200Créez la ressource DRBD dans le cluster :
sudo pcs -f clust_cfg resource create mysql_drbd ocf:linbit:drbd \ drbd_resource=r0 \ op monitor role=Master interval=110 timeout=30 \ op monitor role=Slave interval=120 timeout=30 \ op start timeout=120 \ op stop timeout=60Assurez-vous qu'un seul rôle principal est attribué à la ressource DRBD :
sudo pcs -f clust_cfg resource master primary_mysql mysql_drbd \ master-max=1 master-node-max=1 \ clone-max=2 clone-node-max=1 \ notify=trueCréez la ressource du système de fichiers pour installer le disque DRBD :
sudo pcs -f clust_cfg resource create mystore_FS Filesystem \ device="/dev/drbd0" \ directory="/srv" \ fstype="ext4"Configurez le cluster pour héberger la ressource DRBD en colocation avec la ressource de disque sur la même VM :
sudo pcs -f clust_cfg constraint colocation add mystore_FS with primary_mysql INFINITY with-rsc-role=MasterConfigurez le cluster pour afficher la ressource de disque uniquement après la promotion du DRBD principal :
sudo pcs -f clust_cfg constraint order promote primary_mysql then start mystore_FSCréez un service MySQL :
sudo pcs -f clust_cfg resource create mysql_service ocf:heartbeat:mysql \ binary="/usr/bin/mysqld_safe" \ config="/etc/mysql/my.cnf" \ datadir="/var/lib/mysql" \ pid="/var/run/mysqld/mysql.pid" \ socket="/var/run/mysqld/mysql.sock" \ additional_parameters="--bind-address=0.0.0.0" \ op start timeout=60s \ op stop timeout=60s \ op monitor interval=20s timeout=30sConfigurez le cluster pour héberger la ressource MySQL en colocation avec la ressource de disque sur la même VM :
sudo pcs -f clust_cfg constraint colocation add mysql_service with mystore_FS INFINITYAssurez-vous que le système de fichiers DRBD précède le service MySQL dans l'ordre de démarrage :
sudo pcs -f clust_cfg constraint order mystore_FS then mysql_serviceCréez l'agent d'alerte et ajoutez le correctif au fichier journal en tant que destinataire :
sudo pcs -f clust_cfg alert create id=drbd_cleanup_file description="Monitor DRBD events and perform post cleanup" path=/var/lib/pacemaker/drbd_cleanup.sh sudo pcs -f clust_cfg alert recipient add drbd_cleanup_file id=logfile value=/var/log/pacemaker_drbd_file.logValidez les modifications dans le cluster :
sudo pcs cluster cib-push clust_cfgVérifiez que toutes les ressources sont en ligne :
sudo pcs statusLe résultat est semblable à ce qui suit :
Online: [ database1 database2 ] Full list of resources: Master/Slave Set: primary_mysql [mysql_drbd] Masters: [ database1 ] Slaves: [ database2 ] mystore_FS (ocf::heartbeat:Filesystem): Started database1 mysql_service (ocf::heartbeat:mysql): Started database1
Configurer un périphérique de quorum
- Connectez-vous à l'instance
qdevicevia SSH. Installez
pcsetcorosync-qnetd:sudo apt update && sudo apt -y install pcs corosync-qnetdDémarrez le service daemon (
pcsd) du système de configuration Pacemaker ou Corosync et activez-le au démarrage du système :sudo service pcsd start sudo update-rc.d pcsd enableDéfinissez le mot de passe de l'utilisateur du cluster (
haCLUSTER3) pour l'authentification :sudo bash -c "echo hacluster:haCLUSTER3 | chpasswd"Vérifiez l'état du périphérique de quorum :
sudo pcs qdevice status net --fullLe résultat est semblable à ce qui suit :
QNetd address: *:5403 TLS: Supported (client certificate required) Connected clients: 0 Connected clusters: 0 Maximum send/receive size: 32768/32768 bytes
Configurer les paramètres du périphérique de quorum sur database1
- Connectez-vous au nœud
database1via SSH. Chargez les variables de métadonnées à partir du fichier
.varsrc:source ~/.varsrcAuthentifiez le nœud de périphérique de quorum pour le cluster :
sudo pcs cluster auth --name mysql_cluster ${QUORUM_INSTANCE_NAME} -u hacluster -p haCLUSTER3Ajoutez le périphérique de quorum au cluster. Utilisez l'algorithme
ffsplit, qui garantit que le nœud actif sera déterminé sur une base minimale de 50 % des votes :sudo pcs quorum device add model net host=${QUORUM_INSTANCE_NAME} algorithm=ffsplitAjoutez le paramètre de quorum à
corosync.conf:sudo bash -c "cat <<EOF > /etc/corosync/corosync.conf totem { version: 2 cluster_name: mysql_cluster transport: udpu interface { ringnumber: 0 Bindnetaddr: ${DATABASE1_INSTANCE_IP} broadcast: yes mcastport: 5405 } } quorum { provider: corosync_votequorum device { votes: 1 model: net net { tls: on host: ${QUORUM_INSTANCE_NAME} algorithm: ffsplit } } } nodelist { node { ring0_addr: ${DATABASE1_INSTANCE_NAME} name: ${DATABASE1_INSTANCE_NAME} nodeid: 1 } node { ring0_addr: ${DATABASE2_INSTANCE_NAME} name: ${DATABASE2_INSTANCE_NAME} nodeid: 2 } } logging { to_logfile: yes logfile: /var/log/corosync/corosync.log timestamp: on } EOF"Redémarrez le service
corosyncpour recharger le nouveau paramètre de périphérique de quorum :sudo service corosync restartDémarrez le daemon du périphérique de quorum
corosyncet affichez-le au démarrage du système :sudo service corosync-qdevice start sudo update-rc.d corosync-qdevice defaults
Configurer les paramètres du périphérique de quorum sur database2
- Connectez-vous au nœud
database2via SSH. Chargez les variables de métadonnées à partir du fichier
.varsrc:source ~/.varsrcAjoutez un paramètre de quorum à
corosync.conf:sudo bash -c "cat <<EOF > /etc/corosync/corosync.conf totem { version: 2 cluster_name: mysql_cluster transport: udpu interface { ringnumber: 0 Bindnetaddr: ${DATABASE2_INSTANCE_IP} broadcast: yes mcastport: 5405 } } quorum { provider: corosync_votequorum device { votes: 1 model: net net { tls: on host: ${QUORUM_INSTANCE_NAME} algorithm: ffsplit } } } nodelist { node { ring0_addr: ${DATABASE1_INSTANCE_NAME} name: ${DATABASE1_INSTANCE_NAME} nodeid: 1 } node { ring0_addr: ${DATABASE2_INSTANCE_NAME} name: ${DATABASE2_INSTANCE_NAME} nodeid: 2 } } logging { to_logfile: yes logfile: /var/log/corosync/corosync.log timestamp: on } EOF"Redémarrez le service
corosyncpour recharger le nouveau paramètre de périphérique de quorum :sudo service corosync restartDémarrez le daemon de périphérique de quorum Corosync et configurez-le pour qu'il apparaisse au démarrage du système :
sudo service corosync-qdevice start sudo update-rc.d corosync-qdevice defaults
Vérifier l'état du cluster
L'étape suivante consiste à vérifier que les ressources du cluster sont en ligne.
- Connectez-vous à l'instance
database1via SSH. Vérifiez le statut du cluster :
sudo pcs statusLe résultat est semblable à ce qui suit :
Cluster name: mysql_cluster Stack: corosync Current DC: database1 (version 1.1.16-94ff4df) - partition with quorum Last updated: Sun Nov 4 01:49:18 2018 Last change: Sat Nov 3 15:48:21 2018 by root via cibadmin on database1 2 nodes configured 4 resources configured Online: [ database1 database2 ] Full list of resources: Master/Slave Set: primary_mysql [mysql_drbd] Masters: [ database1 ] Slaves: [ database2 ] mystore_FS (ocf::heartbeat:Filesystem): Started database1 mysql_service (ocf::heartbeat:mysql): Started database1 Daemon Status: corosync: active/enabled pacemaker: active/enabled pcsd: active/enabledAffichez le statut du quorum :
sudo pcs quorum statusLe résultat est semblable à ce qui suit :
Quorum information ------------------ Date: Sun Nov 4 01:48:25 2018 Quorum provider: corosync_votequorum Nodes: 2 Node ID: 1 Ring ID: 1/24 Quorate: Yes Votequorum information ---------------------- Expected votes: 3 Highest expected: 3 Total votes: 3 Quorum: 2 Flags: Quorate Qdevice Membership information ---------------------- Nodeid Votes Qdevice Name 1 1 A,V,NMW database1 (local) 2 1 A,V,NMW database2 0 1 QdeviceAffichez l'état du périphérique de quorum :
sudo pcs quorum device statusLe résultat est semblable à ce qui suit :
Qdevice information ------------------- Model: Net Node ID: 1 Configured node list: 0 Node ID = 1 1 Node ID = 2 Membership node list: 1, 2 Qdevice-net information ---------------------- Cluster name: mysql_cluster QNetd host: qdevice:5403 Algorithm: Fifty-Fifty split Tie-breaker: Node with lowest node ID State: Connected
Configurer un équilibreur de charge interne en tant qu'adresse IP de cluster
Ouvrez Cloud Shell.
Créez un groupe d'instances non géré et ajoutez-y l'instance
database1:gcloud compute instance-groups unmanaged create ${DATABASE1_INSTANCE_NAME}-instance-group \ --zone=${DATABASE1_INSTANCE_ZONE} \ --description="${DATABASE1_INSTANCE_NAME} unmanaged instance group" gcloud compute instance-groups unmanaged add-instances ${DATABASE1_INSTANCE_NAME}-instance-group \ --zone=${DATABASE1_INSTANCE_ZONE} \ --instances=${DATABASE1_INSTANCE_NAME}Créez un groupe d'instances non géré et ajoutez-y l'instance
database2:gcloud compute instance-groups unmanaged create ${DATABASE2_INSTANCE_NAME}-instance-group \ --zone=${DATABASE2_INSTANCE_ZONE} \ --description="${DATABASE2_INSTANCE_NAME} unmanaged instance group" gcloud compute instance-groups unmanaged add-instances ${DATABASE2_INSTANCE_NAME}-instance-group \ --zone=${DATABASE2_INSTANCE_ZONE} \ --instances=${DATABASE2_INSTANCE_NAME}Créez une vérification de l'état pour le
port 3306:gcloud compute health-checks create tcp mysql-backend-healthcheck \ --port 3306Créez un service de backend interne régional :
gcloud compute backend-services create mysql-ilb \ --load-balancing-scheme internal \ --region ${CLUSTER_REGION} \ --health-checks mysql-backend-healthcheck \ --protocol tcpAjoutez les deux groupes d'instances en tant que backends au service de backend :
gcloud compute backend-services add-backend mysql-ilb \ --instance-group ${DATABASE1_INSTANCE_NAME}-instance-group \ --instance-group-zone ${DATABASE1_INSTANCE_ZONE} \ --region ${CLUSTER_REGION} gcloud compute backend-services add-backend mysql-ilb \ --instance-group ${DATABASE2_INSTANCE_NAME}-instance-group \ --instance-group-zone ${DATABASE2_INSTANCE_ZONE} \ --region ${CLUSTER_REGION}Créez une règle de transfert pour l'équilibreur de charge :
gcloud compute forwarding-rules create mysql-ilb-forwarding-rule \ --load-balancing-scheme internal \ --ports 3306 \ --network default \ --subnet default \ --region ${CLUSTER_REGION} \ --address ${ILB_IP} \ --backend-service mysql-ilbCréez une règle de pare-feu pour permettre une vérification interne de l'état de l'équilibreur de charge :
gcloud compute firewall-rules create allow-ilb-healthcheck \ --direction=INGRESS --network=default \ --action=ALLOW --rules=tcp:3306 \ --source-ranges=130.211.0.0/22,35.191.0.0/16 --target-tags=mysqlPour vérifier l'état de votre équilibreur de charge, accédez à la page Équilibrage de charge de la console Google Cloud .
Cliquez sur
mysql-ilb:
Étant donné que le cluster n'autorise qu'une seule instance à exécuter MySQL à la fois, une seule instance est opérationnelle du point de vue de l'équilibreur de charge interne.
Se connecter au cluster depuis le client MySQL
- Connectez-vous à l'instance
mysql-clientvia SSH. Mettez à jour les définitions de package :
sudo apt-get updateInstallez le client MySQL :
sudo apt-get install -y mysql-clientCréez un fichier de script qui crée et remplit une table avec des exemples de données :
cat <<EOF > db_creation.sql CREATE DATABASE source_db; use source_db; CREATE TABLE source_table ( id BIGINT NOT NULL AUTO_INCREMENT, timestamp timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, event_data float DEFAULT NULL, PRIMARY KEY (id) ); DELIMITER $$ CREATE PROCEDURE simulate_data() BEGIN DECLARE i INT DEFAULT 0; WHILE i < 100 DO INSERT INTO source_table (event_data) VALUES (ROUND(RAND()*15000,2)); SET i = i + 1; END WHILE; END$$ DELIMITER ; CALL simulate_data() EOFCréez la table :
ILB_IP=$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/ILB_IP" -H "Metadata-Flavor: Google") mysql -u root -pDRBDha2 "-h${ILB_IP}" < db_creation.sql
Tester le cluster
Pour tester la capacité haute disponibilité du cluster déployé, vous pouvez effectuer les tests suivants :
- Arrêtez l'instance
database1pour tester si la base de données principale peut basculer vers l'instancedatabase2. - Démarrez l'instance
database1pour voir sidatabase1peut rejoindre le cluster. - Arrêtez l'instance
database2pour tester si la base de données principale peut basculer vers l'instancedatabase1. - Démarrez l'instance
database2pour voir sidatabase2peut rejoindre le cluster et si l'instancedatabase1conserve toujours le rôle "primaire". - Créez une partition réseau entre
database1etdatabase2pour simuler un problème de split-brain.
Ouvrez Cloud Shell.
Arrêtez l'instance
database1:gcloud compute instances stop ${DATABASE1_INSTANCE_NAME} \ --zone=${DATABASE1_INSTANCE_ZONE}Vérifiez l'état du cluster :
gcloud compute ssh ${DATABASE2_INSTANCE_NAME} \ --zone=${DATABASE2_INSTANCE_ZONE} \ --command="sudo pcs status"Le résultat est semblable à ce qui suit. Vérifiez que les modifications de configuration que vous avez apportées ont bien eu lieu :
2 nodes configured 4 resources configured Online: [ database2 ] OFFLINE: [ database1 ] Full list of resources: Master/Slave Set: primary_mysql [mysql_drbd] Masters: [ database2 ] Stopped: [ database1 ] mystore_FS (ocf::heartbeat:Filesystem): Started database2 mysql_service (ocf::heartbeat:mysql): Started database2 Daemon Status: corosync: active/enabled pacemaker: active/enabled pcsd: active/enabledDémarrez l'instance
database1:gcloud compute instances start ${DATABASE1_INSTANCE_NAME} \ --zone=${DATABASE1_INSTANCE_ZONE}Vérifiez l'état du cluster :
gcloud compute ssh ${DATABASE1_INSTANCE_NAME} \ --zone=${DATABASE1_INSTANCE_ZONE} \ --command="sudo pcs status"Le résultat ressemble à ceci :
2 nodes configured 4 resources configured Online: [ database1 database2 ] Full list of resources: Master/Slave Set: primary_mysql [mysql_drbd] Masters: [ database2 ] Slaves: [ database1 ] mystore_FS (ocf::heartbeat:Filesystem): Started database2 mysql_service (ocf::heartbeat:mysql): Started database2 Daemon Status: corosync: active/enabled pacemaker: active/enabled pcsd: active/enabledArrêtez l'instance
database2:gcloud compute instances stop ${DATABASE2_INSTANCE_NAME} \ --zone=${DATABASE2_INSTANCE_ZONE}Vérifiez l'état du cluster :
gcloud compute ssh ${DATABASE1_INSTANCE_NAME} \ --zone=${DATABASE1_INSTANCE_ZONE} \ --command="sudo pcs status"Le résultat ressemble à ceci :
2 nodes configured 4 resources configured Online: [ database1 ] OFFLINE: [ database2 ] Full list of resources: Master/Slave Set: primary_mysql [mysql_drbd] Masters: [ database1 ] Stopped: [ database2 ] mystore_FS (ocf::heartbeat:Filesystem): Started database1 mysql_service (ocf::heartbeat:mysql): Started database1 Daemon Status: corosync: active/enabled pacemaker: active/enabled pcsd: active/enabledDémarrez l'instance
database2:gcloud compute instances start ${DATABASE2_INSTANCE_NAME} \ --zone=${DATABASE2_INSTANCE_ZONE}Vérifiez l'état du cluster :
gcloud compute ssh ${DATABASE1_INSTANCE_NAME} \ --zone=${DATABASE1_INSTANCE_ZONE} \ --command="sudo pcs status"Le résultat ressemble à ceci :
2 nodes configured 4 resources configured Online: [ database1 database2 ] Full list of resources: Master/Slave Set: primary_mysql [mysql_drbd] Masters: [ database1 ] Slaves: [ database2 ] mystore_FS (ocf::heartbeat:Filesystem): Started database1 mysql_service (ocf::heartbeat:mysql): Started database1 Daemon Status: corosync: active/enabled pacemaker: active/enabled pcsd: active/enabledCréez une partition réseau entre
database1etdatabase2:gcloud compute firewall-rules create block-comms \ --description="no MySQL communications" \ --action=DENY \ --rules=all \ --source-tags=mysql \ --target-tags=mysql \ --priority=800Après quelques minutes, vérifiez l'état du cluster. Notez que
database1conserve son rôle principal, car la règle de quorum privilégie l'ID de nœud le plus bas dans une situation de partition réseau. En attendant, le service MySQLdatabase2est arrêté. Ce mécanisme de quorum évite le problème de split-brain lorsque la partition réseau se produit.gcloud compute ssh ${DATABASE1_INSTANCE_NAME} \ --zone=${DATABASE1_INSTANCE_ZONE} \ --command="sudo pcs status"Le résultat est semblable à ce qui suit :
2 nodes configured 4 resources configured Online: [ database1 ] OFFLINE: [ database2 ] Full list of resources: Master/Slave Set: primary_mysql [mysql_drbd] Masters: [ database1 ] Stopped: [ database2 ] mystore_FS (ocf::heartbeat:Filesystem): Started database1 mysql_service (ocf::heartbeat:mysql): Started database1Supprimez la règle de pare-feu de réseau pour supprimer la partition réseau. (Appuyez sur
Ylorsque vous y êtes invité.)gcloud compute firewall-rules delete block-commsVérifiez que l'état du cluster est revenu à la normale :
gcloud compute ssh ${DATABASE1_INSTANCE_NAME} \ --zone=${DATABASE1_INSTANCE_ZONE} \ --command="sudo pcs status"Le résultat est semblable à ce qui suit :
2 nodes configured 4 resources configured Online: [ database1 database2 ] Full list of resources: Master/Slave Set: primary_mysql [mysql_drbd] Masters: [ database1 ] Slaves: [ database2 ] mystore_FS (ocf::heartbeat:Filesystem): Started database1 mysql_service (ocf::heartbeat:mysql): Started database1Connectez-vous à l'instance
mysql-clientvia SSH.Dans votre shell, interrogez la table que vous avez créée précédemment :
ILB_IP=$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/ILB_IP" -H "Metadata-Flavor: Google") mysql -uroot "-h${ILB_IP}" -pDRBDha2 -e "select * from source_db.source_table LIMIT 10"Le résultat doit répertorier 10 enregistrements de la forme suivante, vérifiant la cohérence des données dans le cluster :
+----+---------------------+------------+ | id | timestamp | event_data | +----+---------------------+------------+ | 1 | 2018-11-27 21:00:09 | 1279.06 | | 2 | 2018-11-27 21:00:09 | 4292.64 | | 3 | 2018-11-27 21:00:09 | 2626.01 | | 4 | 2018-11-27 21:00:09 | 252.13 | | 5 | 2018-11-27 21:00:09 | 8382.64 | | 6 | 2018-11-27 21:00:09 | 11156.8 | | 7 | 2018-11-27 21:00:09 | 636.1 | | 8 | 2018-11-27 21:00:09 | 14710.1 | | 9 | 2018-11-27 21:00:09 | 11642.1 | | 10 | 2018-11-27 21:00:09 | 14080.3 | +----+---------------------+------------+
Séquence de basculement
Si le nœud principal du cluster tombe en panne, la séquence de basculement se présente comme suit :
- Le périphérique de quorum et le nœud de secours perdent tous deux la connectivité avec le nœud principal.
- Le périphérique de quorum vote pour le nœud de secours et le nœud de secours vote pour lui-même.
- Le quorum est acquis par le nœud de secours.
- Le nœud de secours devient le nœud principal.
- Le nouveau nœud principal effectue les opérations suivantes :
- Promeut le DRBD en DRBD principal.
- Installe le disque de données MySQL à partir de DRBD.
- Démarre MySQL.
- Devient opérationnel pour l'équilibreur de charge.
- L'équilibreur de charge commence à envoyer du trafic au nouveau nœud principal.