Déployer un cluster MySQL 5.6 hautement disponible avec DRBD sur Compute Engine

Last reviewed 2019-05-10 UTC

Ce tutoriel vous explique comment déployer une base de données MySQL 5.6 sur Google Cloud à l'aide du système DRBD (Distributed Replicated Block Device, ou 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 de l'appareil de stockage 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.

Architecture montrant une base de données MySQL 5.6 déployée sur Google Cloud à l'aide de DRBD et Compute Engine

Objectifs

  • Créer des instances de cluster
  • Installer MySQL et DRBD sur deux des instances
  • Configurer la réplication DRBD
  • Installer Pacemaker sur les instances
  • Configurer le clustering Pacemaker sur les instances
  • Créer une instance et la configurer en tant que périphérique de quorum
  • Tester le basculement

Coûts

Utilisez le Simulateur de coût pour générer une estimation des coûts en fonction de votre utilisation prévue.

Avant de commencer

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. Make sure that billing is enabled for your Google Cloud project.

  4. Enable the Compute Engine API.

    Enable the API

  5. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  6. Make sure that billing is enabled for your Google Cloud project.

  7. Enable the Compute Engine API.

    Enable the API

Dans ce tutoriel, vous entrez des commandes à l'aide de Cloud Shell, sauf indication contraire.

Une fois que vous avez terminé les tâches décrites dans ce document, vous pouvez éviter de continuer à payer des frais en supprimant les ressources que vous avez créées. Pour en savoir plus, consultez la section Effectuer un nettoyage.

Procédure de 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

  1. Ouvrez Cloud Shell.

    Ouvrir Cloud Shell

  2. Créez le compte de service :

    gcloud iam service-accounts create mysql-instance \
        --display-name "mysql-instance"
    
  3. 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

  1. 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"
    EOF
    
  2. Chargez 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.

  1. Dans Cloud Shell, créez une instance MySQL nommée database1 dans la zone asia-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}"
    
  2. Créez une instance MySQL nommée database2 dans la zone asia-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}"
    
  3. 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}
    
  4. 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

  1. Dans la console Google Cloud, accédez à la page Instances de VM :

    PAGE "INSTANCES DE VM"

  2. Sur la ligne de l'instance database1, cliquez sur SSH pour vous connecter à l'instance.

  3. 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")
    
    EOF
    
  4. Chargez les variables de métadonnées à partir du fichier :

    source ~/.varsrc
    
  5. Formatez 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.

  6. Installez DRBD :

    sudo apt -y install drbd8-utils
    
  7. Cré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'
    
  8. 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"
    
  9. Chargez le kernel module DRBD :

    sudo modprobe drbd
    
  10. Effacez le contenu du disque /dev/sdb :

    sudo dd if=/dev/zero of=/dev/sdb bs=1k count=1024
    
  11. Créez la ressource DRBD r0 :

    sudo drbdadm create-md r0
    
  12. Affichez DRBD :

    sudo drbdadm up r0
    
  13. Dé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.

  1. Connectez-vous à l'instance database2 via SSH.
  2. Créez un fichier .varsrc 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")
    EOF
    
  3. Chargez les variables de métadonnées à partir du fichier :

    source ~/.varsrc
    
  4. Formatez 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"
    
  5. Installez les packages DRBD :

    sudo apt -y install drbd8-utils
    
  6. Cré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'
    
  7. 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"
    
  8. Chargez le kernel module DRBD :

    sudo modprobe drbd
    
  9. Videz le disque /dev/sdb :

    sudo dd if=/dev/zero of=/dev/sdb bs=1k count=1024
    
  10. Créez la ressource DRBD r0 :

    sudo drbdadm create-md r0
    
  11. Affichez DRBD :

    sudo drbdadm up r0
    
  12. Dé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

  1. Connectez-vous à l'instance database1 via SSH.
  2. Remplacez toutes les ressources r0 sur 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/drbd0
    
  3. Vérifiez le statut de DRBD :

    sudo cat /proc/drbd | grep ============
    

    Le résultat ressemble à ceci :

    [===================>] sync'ed:100.0% (208/307188)M
    
  4. Installez /dev/drbd sur /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

  1. Connectez-vous à l'instance database1 via SSH.
  2. 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'
    
  3. 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-mysql
    
  4. Mettez à jour la liste de packages :

    sudo apt update
    
  5. Installez le serveur MySQL :

    sudo apt -y install mysql-server
    

    Lorsque vous êtes invité à entrer un mot de passe, saisissez DRBDha2.

  6. Arrêtez le serveur MySQL :

    sudo /etc/init.d/mysql stop
    
  7. Cré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'
    
  8. Créez un répertoire temporaire pour le serveur MySQL (configuré dans mysql.conf) :

    sudo mkdir /srv/tmp
    sudo chmod 1777 /srv/tmp
    
  9. Déplacez toutes les données MySQL dans le répertoire DRBD /srv/mysql :

    sudo mv /var/lib/mysql /srv/mysql
    
  10. Liez /var/lib/mysql à /srv/mysql sous le volume de stockage répliqué DRBD :

    sudo ln -s /srv/mysql /var/lib/mysql
    
  11. Changez le propriétaire de /srv/mysql pour le définir sur un processus mysql :

    sudo chown -R mysql:mysql /srv/mysql
    
  12. Supprimez les données initiales InnoDB pour 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.

  13. Démarrez MySQL :

    sudo /etc/init.d/mysql start
    
  14. Accordez à 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;"
    
  15. 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

  1. Chargez les variables de métadonnées à partir du fichier .varsrc que vous avez créé précédemment :

    source ~/.varsrc
    
  2. Arrêtez le serveur MySQL :

    sudo /etc/init.d/mysql stop
    
  3. Installez Pacemaker :

    sudo apt -y install pcs
    
  4. Activez pcsd, corosync et pacemaker au 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 enable
    
  5. Configurez corosync pour qu'il démarre avant pacemaker :

    sudo update-rc.d corosync defaults 20 20
    sudo update-rc.d pacemaker defaults 30 10
    
  6. Définissez le mot de passe de l'utilisateur du cluster sur haCLUSTER3 pour l'authentification :

    sudo bash -c "echo  hacluster:haCLUSTER3 | chpasswd"
    
  7. Exécutez le script corosync-keygen pour générer une clé d'autorisation de cluster de 128 bits et écrivez-la dans /etc/corosync/authkey :

    sudo corosync-keygen -l
    
  8. Copiez authkey sur l'instance database2. Lorsque vous êtes invité à entrer une phrase secrète, appuyez sur Enter :

    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/authkey
    
  9. Cré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 totem configure 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œuds database1 et database2.
    • 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" pour two_node dans la section quorum.

    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.

  10. Créez le répertoire de service pour corosync :

    sudo mkdir -p /etc/corosync/service.d
    
  11. Configurez corosync pour qu'il prenne en compte Pacemaker :

    sudo bash -c 'cat <<EOF  > /etc/corosync/service.d/pcmk
    service {
        name: pacemaker
        ver: 1
    }
    EOF'
    
  12. Activez le service corosync par 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'
    
  13. Redémarrez les services corosync et pacemaker :

    sudo service corosync restart
    sudo service pacemaker restart
    
  14. Installez le package de périphérique de quorum Corosync :

    sudo apt -y install corosync-qdevice
    
  15. Installez 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

  1. Connectez-vous à l'instance database2 via SSH.
  2. 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'
    
  3. 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-mysql
    
  4. Mettez à jour la liste de packages :

    sudo apt update
    
  5. Installez le serveur MySQL :

    sudo apt -y install mysql-server
    

    Lorsque vous êtes invité à entrer un mot de passe, saisissez DRBDha2.

  6. Arrêtez le serveur MySQL :

    sudo /etc/init.d/mysql stop
    
  7. Cré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'
    
  8. Supprimez les données sous /var/lib/mysql et ajoutez un lien symbolique à la cible du point d'installation du volume DRBD répliqué. Le volume DRBD (/dev/drbd0) ne sera installé sur /srv qu'en cas de basculement.

    sudo rm -rf /var/lib/mysql
    sudo ln -s /srv/mysql /var/lib/mysql
    
  9. 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 database2

  1. Chargez les variables de métadonnées à partir du fichier .varsrc :

    source ~/.varsrc
    
  2. Installez Pacemaker :

    sudo apt -y install pcs
    
  3. Déplacez le fichier Corosync authkey que 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/authkey
    
  4. Activez pcsd, corosync et pacemaker au 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 enable
    
  5. Configurez corosync pour qu'il démarre avant pacemaker :

    sudo update-rc.d corosync defaults 20 20
    sudo update-rc.d pacemaker defaults 30 10
    
  6. Dé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'instance database1.

    sudo bash -c "echo  hacluster:haCLUSTER3 | chpasswd"
    
  7. 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"
    
  8. Créez le répertoire de service Corosync :

    sudo mkdir /etc/corosync/service.d
    
  9. Configurez corosync pour qu'il prenne en compte Pacemaker :

    sudo bash -c 'cat <<EOF  > /etc/corosync/service.d/pcmk
    service {
    name: pacemaker
    ver: 1
    }
    EOF'
    
  10. Activez le service corosync par 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'
    
  11. Redémarrez les services corosync et pacemaker :

    sudo service corosync restart
    sudo service pacemaker restart
    
  12. Installez le package de périphérique de quorum Corosync :

    sudo apt -y install corosync-qdevice
    
  13. Installez 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
    
  14. Vé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

  1. Connectez-vous à l'instance database2 via SSH.
  2. Chargez les variables de métadonnées à partir du fichier .varsrc :

    source ~/.varsrc
    
  3. Authentifiez-vous auprès des nœuds de cluster :

    sudo pcs cluster auth --name mysql_cluster ${DATABASE1_INSTANCE_NAME} ${DATABASE2_INSTANCE_NAME} -u hacluster -p haCLUSTER3
    
  4. Démarrez le cluster :

    sudo pcs cluster start --all
    
  5. Vérifiez le statut du cluster :

    sudo pcs status
    

    Le 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.

  1. Connectez-vous à l'instance database1 via SSH.
  2. Utilisez l'utilitaire Pacemaker pcs pour 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_cfg
    
  3. Désactivez STONITH, car vous déploierez le périphérique de quorum ultérieurement :

    sudo pcs -f clust_cfg property set stonith-enabled=false
    
  4. Dé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=stop
    
  5. Empêchez Pacemaker de remettre les ressources à leur place après une récupération :

    sudo pcs -f clust_cfg resource defaults resource-stickiness=200
    
  6. Cré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=60
    
  7. Assurez-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=true
    
  8. Cré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"
    
  9. 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=Master
    
  10. Configurez 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_FS
    
  11. Cré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=30s
    
  12. Configurez 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 INFINITY
    
  13. Assurez-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_service
    
  14. Cré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.log
    
  15. Validez les modifications dans le cluster :

    sudo pcs cluster cib-push clust_cfg
    
  16. Vérifiez que toutes les ressources sont en ligne :

    sudo pcs status
    

    Le 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

  1. Connectez-vous à l'instance qdevice via SSH.
  2. Installez pcs et corosync-qnetd :

    sudo apt update && sudo apt -y install pcs corosync-qnetd
    
  3. Démarrez le service daemon (pcsd) du système de configuration Pacemaker/Corosync et activez-le au démarrage du système :

    sudo service pcsd start
    sudo update-rc.d pcsd enable
    
  4. Définissez le mot de passe de l'utilisateur du cluster (haCLUSTER3) pour l'authentification :

    sudo bash -c "echo  hacluster:haCLUSTER3 | chpasswd"
    
  5. Vérifiez l'état du périphérique de quorum :

    sudo pcs qdevice status net --full
    

    Le 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

  1. Connectez-vous au nœud database1 via SSH.
  2. Chargez les variables de métadonnées à partir du fichier .varsrc :

    source ~/.varsrc
    
  3. Authentifiez 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 haCLUSTER3
    
  4. Ajoutez 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=ffsplit
    
  5. Ajoutez 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"
    
  6. Redémarrez le service corosync pour recharger le nouveau paramètre de périphérique de quorum :

    sudo service corosync restart
    
  7. Démarrez le daemon du périphérique de quorum corosync et 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

  1. Connectez-vous au nœud database2 via SSH.
  2. Chargez les variables de métadonnées à partir du fichier .varsrc :

    source ~/.varsrc
    
  3. Ajoutez 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"
    
  4. Redémarrez le service corosync pour recharger le nouveau paramètre de périphérique de quorum :

    sudo service corosync restart
    
  5. Dé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.

  1. Connectez-vous à l'instance database1 via SSH.
  2. Vérifiez le statut du cluster :

    sudo pcs status
    

    Le 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/enabled
    
  3. Affichez le statut du quorum :

    sudo pcs quorum status
    

    Le 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            Qdevice
    
  4. Affichez l'état du périphérique de quorum :

    sudo pcs quorum device status
    

    Le 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

  1. Ouvrez Cloud Shell.

    Ouvrir Cloud Shell

  2. 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}
    
  3. 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}
    
  4. Créez une vérification de l'état pour le port 3306 :

    gcloud compute health-checks create tcp mysql-backend-healthcheck \
        --port 3306
    
  5. Cré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 tcp
    
  6. Ajoutez 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}
    
  7. 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-ilb
    
  8. Cré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=mysql
    
  9. Pour vérifier l'état de votre équilibreur de charge, accédez à la page Load balancing (Équilibrage de charge) dans la console Google Cloud.

    ACCÉDER À LA PAGE "ÉQUILIBRAGE DE CHARGE"

  10. Cliquez sur mysql-ilb :

    image

    É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.

    image

Se connecter au cluster depuis le client MySQL

  1. Connectez-vous à l'instance mysql-client via SSH.
  2. Mettez à jour les définitions de package :

    sudo apt-get update
    
  3. Installez le client MySQL :

    sudo apt-get install -y mysql-client
    
  4. Cré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()
    EOF
    
  5. Cré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 database1 pour tester si la base de données maître peut basculer vers l'instance database2.
  • Démarrez l'instance database1 pour voir si database1 peut rejoindre le cluster.
  • Arrêtez l'instance database2 pour tester si la base de données maître peut basculer vers l'instance database1.
  • Démarrez l'instance database2 pour voir si database2 peut rejoindre le cluster et si l'instance database1 conserve toujours le rôle "maître".
  • Créez une partition réseau entre database1 et database2 pour simuler un problème de split-brain.

  1. Ouvrez Cloud Shell.

    Ouvrir Cloud Shell

  2. Arrêtez l'instance database1 :

    gcloud compute instances stop ${DATABASE1_INSTANCE_NAME} \
        --zone=${DATABASE1_INSTANCE_ZONE}
    
  3. 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/enabled
    
  4. Démarrez l'instance database1 :

    gcloud compute instances start ${DATABASE1_INSTANCE_NAME} \
        --zone=${DATABASE1_INSTANCE_ZONE}
    
  5. 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/enabled
    
  6. Arrêtez l'instance database2 :

    gcloud compute instances stop ${DATABASE2_INSTANCE_NAME} \
        --zone=${DATABASE2_INSTANCE_ZONE}
    
  7. 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/enabled
    
  8. Démarrez l'instance database2 :

    gcloud compute instances start ${DATABASE2_INSTANCE_NAME} \
        --zone=${DATABASE2_INSTANCE_ZONE}
    
  9. 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/enabled
    
  10. Créez une partition réseau entre database1 et database2 :

    gcloud compute firewall-rules create block-comms \
        --description="no MySQL communications" \
        --action=DENY \
        --rules=all \
        --source-tags=mysql \
        --target-tags=mysql \
        --priority=800
    
  11. Après quelques minutes, vérifiez l'état du cluster. Notez que database1 conserve 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 MySQL database2 est 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 database1
    
  12. Supprimez la règle de pare-feu de réseau pour supprimer la partition réseau. (Appuyez sur Y lorsque vous y êtes invité.)

    gcloud compute firewall-rules delete block-comms
    
  13. Vé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 database1
    
  14. Connectez-vous à l'instance mysql-client via SSH.

  15. 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 :

  1. Le périphérique de quorum et le nœud de secours perdent tous deux la connectivité avec le nœud principal.
  2. Le périphérique de quorum vote pour le nœud de secours et le nœud de secours vote pour lui-même.
  3. Le quorum est acquis par le nœud de secours.
  4. Le nœud de secours devient le nœud principal.
  5. Le nouveau nœud principal effectue les opérations suivantes :
    1. Promeut le DRBD en DRBD principal.
    2. Installe le disque de données MySQL à partir de DRBD.
    3. Démarre MySQL.
    4. Devient opérationnel pour l'équilibreur de charge.
  6. L'équilibreur de charge commence à envoyer du trafic au nouveau nœud principal.

Nettoyer

Supprimer le projet

  1. In the Google Cloud console, go to the Manage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then click Delete.
  3. In the dialog, type the project ID, and then click Shut down to delete the project.

Étape suivante