Deployment di un cluster MySQL 5.6 a disponibilità elevata con DRBD su Compute Engine

Last reviewed 2019-05-10 UTC

Questo tutorial illustra il processo di deployment di un database MySQL 5.6 in Google Cloud utilizzando Distributed Replicated Block Device (DRBD) e Compute Engine. DRBD è un sistema di archiviazione replicato distribuito per la piattaforma Linux.

Questo tutorial è utile se sei un amministratore di sistema, uno sviluppatore, un ingegnere, un amministratore di database o un ingegnere DevOps. Potresti voler gestire la tua istanza MySQL anziché utilizzare il servizio gestito per diversi motivi, tra cui:

  • Stai utilizzando istanze di MySQL tra regioni.
  • Devi impostare i parametri che non sono disponibili nella versione gestita di MySQL.
  • Vuoi ottimizzare le prestazioni in modi non configurabili nella versione gestita.

DRBD fornisce la replica a livello di dispositivo a blocchi. Ciò significa che non devi configurare la replica in MySQL stesso e ottieni vantaggi immediati DRBD, ad esempio supporto per il bilanciamento del carico in lettura e connessioni sicure.

Il tutorial utilizza i seguenti strumenti:

Non è richiesta alcuna conoscenza avanzata per utilizzare queste risorse, anche se questo documento fa riferimento a funzionalità avanzate come il clustering MySQL, la configurazione DRBD e la gestione delle risorse Linux.

Architettura

Pacemaker è un gestore di risorse del cluster. Corosync è un pacchetto di comunicazione e partecipazione al cluster, utilizzato da Pacemaker. In questo tutorial utilizzerai DRBD per replicare il disco MySQL dall'istanza principale a quella in standby. Per consentire ai client di connettersi al cluster MySQL, esegui anche il deployment di un bilanciatore del carico interno.

Esegui il deployment di un cluster di tre istanze di calcolo gestito da Pacemaker. Puoi installare MySQL su due istanze, che fungono da istanze principali e di standby. La terza istanza funge da quorum.

In un cluster, ogni nodo vota per il nodo che dovrebbe essere attivo, ovvero quello che esegue MySQL. In un cluster a due nodi, occorre un solo voto per determinare il nodo attivo. In tal caso, il comportamento del cluster potrebbe causare problemi di cervello diviso o tempi di inattività. I problemi di split-brain si verificano quando entrambi i nodi assumono il controllo perché è necessario un solo voto in uno scenario a due nodi. Il tempo di inattività si verifica quando il nodo arrestato è quello configurato per essere sempre il principale in caso di perdita di connettività. Se i due nodi perdono connettività l'uno con l'altro, c'è il rischio che più di un nodo del cluster presuma che sia il nodo attivo.

L'aggiunta di un dispositivo del quorum impedisce questa situazione. Il quorum funge da arbitro, il cui unico compito è quello di votare. In questo modo, in una situazione in cui le istanze database1 e database2 non possono comunicare, questo nodo del dispositivo con quorum può comunicare con una delle due istanze ed è comunque possibile raggiungerne la maggior parte.

Il seguente diagramma mostra l'architettura del sistema qui descritta.

Architettura che mostra un database MySQL 5.6 di cui è stato eseguito il deployment in Google Cloud tramite DRBD e Compute Engine

Obiettivi

  • Crea le istanze del cluster.
  • Installa MySQL e DRBD su due istanze.
  • Configura la replica DRBD.
  • Installare Pacemaker sulle istanze.
  • Configura il clustering di Pacemaker sulle istanze.
  • Crea un'istanza e configurala come dispositivo del quorum.
  • Testa il failover.

Costi

Utilizza il Calcolatore prezzi per generare una stima dei costi in base all'utilizzo previsto.

Prima di iniziare

  1. Accedi al tuo account Google Cloud. Se non conosci Google Cloud, crea un account per valutare le prestazioni dei nostri prodotti in scenari reali. I nuovi clienti ricevono anche 300 $di crediti gratuiti per l'esecuzione, il test e il deployment dei carichi di lavoro.
  2. Nella pagina del selettore di progetti della console Google Cloud, seleziona o crea un progetto Google Cloud.

    Vai al selettore progetti

  3. Assicurati che la fatturazione sia attivata per il tuo progetto Google Cloud.

  4. Attiva l'API Compute Engine.

    Abilita l'API

  5. Nella pagina del selettore di progetti della console Google Cloud, seleziona o crea un progetto Google Cloud.

    Vai al selettore progetti

  6. Assicurati che la fatturazione sia attivata per il tuo progetto Google Cloud.

  7. Attiva l'API Compute Engine.

    Abilita l'API

Se non diversamente specificato, in questo tutorial imparerai a inserire i comandi utilizzando Cloud Shell.

Una volta completate le attività descritte in questo documento, puoi evitare la fatturazione continua eliminando le risorse che hai creato. Per ulteriori informazioni, consulta la pagina Pulizia.

Configurazione in corso...

In questa sezione configurerai un account di servizio, creerai variabili di ambiente e prenoterai indirizzi IP.

Configura un account di servizio per le istanze del cluster

  1. Apri Cloud Shell:

    APRI Cloud Shell

  2. Crea l'account di servizio:

    gcloud iam service-accounts create mysql-instance \
        --display-name "mysql-instance"
    
  3. Collega i ruoli necessari per questo tutorial all'account di servizio:

    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
    

Crea variabili di ambiente Cloud Shell

  1. Crea un file con le variabili di ambiente richieste per questo tutorial:

    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. Carica le variabili di ambiente nella sessione corrente e imposta Cloud Shell in modo da caricarle automaticamente per gli accessi futuri:

    source ~/.mysqldrbdrc
    grep -q -F "source ~/.mysqldrbdrc" ~/.bashrc || echo "source ~/.mysqldrbdrc" >> ~/.bashrc
    

Prenota indirizzi IP

  • In Cloud Shell, prenota un indirizzo IP interno per ciascuno dei tre nodi del 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
    

Creazione delle istanze di Compute Engine

Nei passaggi seguenti, le istanze del cluster utilizzano Debian 9 e le istanze client utilizzano Ubuntu 16.

  1. In Cloud Shell, crea un'istanza MySQL denominata database1 nella zona 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. Crea un'istanza MySQL denominata database2 nella zona 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. Crea un nodo del quorum per l'utilizzo da parte di Pacemaker nella zona 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. Crea un'istanza 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}"
    

Installazione e configurazione di DRBD

In questa sezione installerai e configurerai i pacchetti DRBD nelle istanze database1 e database2, quindi avvierai la replica DRBD da database1 a database2.

Configura DRBD su database1

  1. Nella console Google Cloud, vai alla pagina Istanze VM:

    PAGINA ISTANZE VM

  2. Nella riga dell'istanza database1, fai clic su SSH per connetterti all'istanza.

  3. Crea un file per recuperare e archiviare i metadati dell'istanza nelle variabili di ambiente:

    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. Carica le variabili dei metadati dal file:

    source ~/.varsrc
    
  5. Formatta il disco dati:

    sudo bash -c  "mkfs.ext4 -m 0 -F -E \
    lazy_itable_init=0,lazy_journal_init=0,discard /dev/sdb"
    

    Per una descrizione dettagliata delle opzioni di mkfs.ext4, consulta la pagina di manuale mkfs.ext4.

  6. Installa DRBD:

    sudo apt -y install drbd8-utils
    
  7. Crea il file di configurazione DRBD:

    sudo bash -c 'cat <<EOF  > /etc/drbd.d/global_common.conf
    global {
        usage-count no;
    }
    common {
        protocol C;
    }
    EOF'
    
  8. Crea un file di risorse 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. Carica il modulo kernel DRBD:

    sudo modprobe drbd
    
  10. Cancella i contenuti del disco /dev/sdb:

    sudo dd if=/dev/zero of=/dev/sdb bs=1k count=1024
    
  11. Crea la risorsa DRBD r0:

    sudo drbdadm create-md r0
    
  12. Attiva DRBD:

    sudo drbdadm up r0
    
  13. Disabilita DRBD all'avvio del sistema, consentendo al software di gestione delle risorse del cluster di visualizzare tutti i servizi necessari in ordine:

    sudo update-rc.d drbd disable
    

Configura DRBD su database2

Ora installerai e configurerai i pacchetti DRBD sull'istanza database2.

  1. Connettiti all'istanza database2 tramite SSH.
  2. Crea un file .varsrc per recuperare e archiviare i metadati dell'istanza nelle variabili di ambiente:

    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. Carica le variabili dei metadati dal file:

    source ~/.varsrc
    
  4. Formatta il disco dati:

    sudo bash -c  "mkfs.ext4 -m 0 -F -E  lazy_itable_init=0,lazy_journal_init=0,discard /dev/sdb"
    
  5. Installa i pacchetti DRBD:

    sudo apt -y install drbd8-utils
    
  6. Crea il file di configurazione DRBD:

    sudo bash -c 'cat <<EOF  > /etc/drbd.d/global_common.conf
    global {
        usage-count no;
    }
    common {
        protocol C;
    }
    EOF'
    
  7. Crea un file di risorse 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. Carica il modulo kernel DRBD:

    sudo modprobe drbd
    
  9. Svuota il disco /dev/sdb:

    sudo dd if=/dev/zero of=/dev/sdb bs=1k count=1024
    
  10. Crea la risorsa DRBD r0:

    sudo drbdadm create-md r0
    
  11. Attiva DRBD:

    sudo drbdadm up r0
    
  12. Disabilita DRBD all'avvio del sistema, consentendo al software di gestione delle risorse del cluster di visualizzare tutti i servizi necessari in ordine:

    sudo update-rc.d drbd disable
    

Avvia la replica DRBD da database1 a database2

  1. Connettiti all'istanza database1 tramite SSH.
  2. Sovrascrivi tutte le risorse r0 nel nodo primario:

    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. Verifica lo stato di DRBD:

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

    L'output sarà simile al seguente:

    [===================>] sync'ed:100.0% (208/307188)M
    
  4. Monta /dev/drbd su /srv:

    sudo mount -o discard,defaults /dev/drbd0 /srv
    

Installazione di MySQL e pacemaker

In questa sezione installerai MySQL e Pacemaker su ciascuna istanza.

Installa MySQL su database1

  1. Connettiti all'istanza database1 tramite SSH.
  2. Aggiorna il repository APT con le definizioni dei pacchetti 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. Aggiungi le chiavi GPG al file 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. Aggiorna l'elenco di pacchetti:

    sudo apt update
    
  5. Installa il server MySQL:

    sudo apt -y install mysql-server
    

    Quando viene chiesta una password, inserisci DRBDha2.

  6. Arresta il server MySQL:

    sudo /etc/init.d/mysql stop
    
  7. Crea il file di configurazione 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. Crea una directory temporanea per il server MySQL (configurata in mysql.conf):

    sudo mkdir /srv/tmp
    sudo chmod 1777 /srv/tmp
    
  9. Sposta tutti i dati MySQL nella directory DRBD /srv/mysql:

    sudo mv /var/lib/mysql /srv/mysql
    
  10. Collega /var/lib/mysql a /srv/mysql nel volume di archiviazione replicato DRBD:

    sudo ln -s /srv/mysql /var/lib/mysql
    
  11. Modifica il proprietario di /srv/mysql in un processo mysql:

    sudo chown -R mysql:mysql /srv/mysql
    
  12. Rimuovi i dati iniziali di InnoDB per assicurarti che il disco sia il più pulito possibile:

    sudo bash -c "cd /srv/mysql && rm ibdata1 && rm ib_logfile*"
    

    InnoDB è un motore di archiviazione per il sistema di gestione dei database MySQL.

  13. Avvia MySQL:

    sudo /etc/init.d/mysql start
    
  14. Concedi l'accesso all'utente root per le connessioni remote in modo da poter testare il deployment in un secondo momento:

    mysql -uroot -pDRBDha2 -e "GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'DRBDha2' WITH GRANT OPTION;"
    
  15. Disabilita l'avvio automatico di MySQL, che si occupa della gestione delle risorse del cluster:

    sudo update-rc.d -f mysql disable
    

Installa Pacemaker su database1

  1. Carica le variabili dei metadati dal file .varsrc che hai creato in precedenza:

    source ~/.varsrc
    
  2. Arresta il server MySQL:

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

    sudo apt -y install pcs
    
  4. Abilita pcsd, corosync e pacemaker all'avvio del sistema nell'istanza principale:

    sudo update-rc.d -f pcsd enable
    sudo update-rc.d -f corosync enable
    sudo update-rc.d -f pacemaker enable
    
  5. Configura corosync in modo che inizi prima del giorno pacemaker:

    sudo update-rc.d corosync defaults 20 20
    sudo update-rc.d pacemaker defaults 30 10
    
  6. Imposta la password utente del cluster su haCLUSTER3 per l'autenticazione:

    sudo bash -c "echo  hacluster:haCLUSTER3 | chpasswd"
    
  7. Esegui lo script corosync-keygen per generare una chiave di autorizzazione del cluster a 128 bit e scrivila in /etc/corosync/authkey:

    sudo corosync-keygen -l
    
  8. Copia authkey nell'istanza database2. Quando ti viene richiesta una passphrase, premi 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. Crea un file di configurazione del 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 sezione totem configura il protocollo Totem per una comunicazione affidabile. Corosync utilizza questa comunicazione per controllare l'appartenenza al cluster e specifica in che modo i membri del cluster devono comunicare tra loro.

    Le impostazioni importanti della configurazione sono le seguenti:

    • transport: specifica la modalità unicast (udpu).
    • Bindnetaddr: specifica l'indirizzo di rete a cui si associa Corosync.
    • nodelist: definisce i nodi nel cluster e il modo in cui possono essere raggiunti, in questo caso i nodi database1 e database2.
    • quorum/two_node: per impostazione predefinita, in un cluster a due nodi, nessun nodo acquisirà un quorum. Puoi eseguire l'override di questo valore specificando il valore "1" per two_node nella sezione quorum.

    Questa configurazione consente di configurare il cluster e di prepararlo in un secondo momento, quando aggiungi un terzo nodo che sarà un dispositivo del quorum.

  10. Crea la directory dei servizi per corosync:

    sudo mkdir -p /etc/corosync/service.d
    
  11. Configura corosync per essere a conoscenza di Pacemaker:

    sudo bash -c 'cat <<EOF  > /etc/corosync/service.d/pcmk
    service {
        name: pacemaker
        ver: 1
    }
    EOF'
    
  12. Abilita il servizio corosync per impostazione predefinita:

    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. Riavvia i servizi corosync e pacemaker:

    sudo service corosync restart
    sudo service pacemaker restart
    
  14. Installa il pacchetto del dispositivo Corosync quorum:

    sudo apt -y install corosync-qdevice
    
  15. Installa uno script shell per gestire gli eventi di errore 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
    

Installa MySQL su database2

  1. Connettiti all'istanza database2 tramite SSH.
  2. Aggiorna il repository APT con il pacchetto 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. Aggiungi le chiavi GPG al repository 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. Aggiorna l'elenco di pacchetti:

    sudo apt update
    
  5. Installa il server MySQL:

    sudo apt -y install mysql-server
    

    Quando viene chiesta una password, inserisci DRBDha2.

  6. Arresta il server MySQL:

    sudo /etc/init.d/mysql stop
    
  7. Crea il file di configurazione 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. Rimuovi i dati in /var/lib/mysql e aggiungi un link simbolico alla destinazione del punto di montaggio per il volume DRBD replicato. Il volume DRBD (/dev/drbd0) verrà montato in /srv solo quando si verifica un failover.

    sudo rm -rf /var/lib/mysql
    sudo ln -s /srv/mysql /var/lib/mysql
    
  9. Disabilita l'avvio automatico di MySQL, che si occupa della gestione delle risorse del cluster:

    sudo update-rc.d -f mysql disable
    

Installa Pacemaker su database2

  1. Carica le variabili dei metadati dal file .varsrc:

    source ~/.varsrc
    
  2. Installare Pacemaker:

    sudo apt -y install pcs
    
  3. Sposta il file Corosync authkey che hai copiato in precedenza in /etc/corosync/:

    sudo mv ~/authkey /etc/corosync/
    sudo chown root: /etc/corosync/authkey
    sudo chmod 400 /etc/corosync/authkey
    
  4. Abilita pcsd, corosync e pacemaker all'avvio del sistema nell'istanza in standby:

    sudo update-rc.d -f pcsd enable
    sudo update-rc.d -f corosync enable
    sudo update-rc.d -f pacemaker enable
    
  5. Configura corosync in modo che inizi prima del giorno pacemaker:

    sudo update-rc.d corosync defaults 20 20
    sudo update-rc.d pacemaker defaults 30 10
    
  6. Imposta la password utente del cluster per l'autenticazione. La password è la stessa (haCLUSTER3) che hai utilizzato per l'istanza database1.

    sudo bash -c "echo  hacluster:haCLUSTER3 | chpasswd"
    
  7. Crea il file di configurazione 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. Crea la directory del servizio Corosync:

    sudo mkdir /etc/corosync/service.d
    
  9. Configura corosync per essere a conoscenza di Pacemaker:

    sudo bash -c 'cat <<EOF  > /etc/corosync/service.d/pcmk
    service {
    name: pacemaker
    ver: 1
    }
    EOF'
    
  10. Abilita il servizio corosync per impostazione predefinita:

    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. Riavvia i servizi corosync e pacemaker:

    sudo service corosync restart
    sudo service pacemaker restart
    
  12. Installa il pacchetto del dispositivo Corosync quorum:

    sudo apt -y install corosync-qdevice
    
  13. Installa uno script shell per gestire gli eventi di errore 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. Controlla lo stato del cluster Corosync:

    sudo corosync-cmapctl | grep "members...ip"
    

    L'output sarà simile al seguente:

    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)
    

Avvio del cluster

  1. Connettiti all'istanza database2 tramite SSH.
  2. Carica le variabili dei metadati dal file .varsrc:

    source ~/.varsrc
    
  3. Esegui l'autenticazione sui nodi del cluster:

    sudo pcs cluster auth --name mysql_cluster ${DATABASE1_INSTANCE_NAME} ${DATABASE2_INSTANCE_NAME} -u hacluster -p haCLUSTER3
    
  4. Avvia il cluster:

    sudo pcs cluster start --all
    
  5. Verifica lo stato del cluster:

    sudo pcs status
    

    L'output sarà simile al seguente:

    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
    

Configurazione di Pacemaker per gestire le risorse del cluster

Successivamente, configurerai Pacemaker con le risorse DRBD, disco, MySQL e quorum.

  1. Connettiti all'istanza database1 tramite SSH.
  2. Utilizza l'utilità pcs di Pacemaker per inserire in coda diverse modifiche in un file e inviarle in un secondo momento alla base di informazioni del cluster (CIB) a livello atomico:

    sudo pcs cluster cib clust_cfg
    
  3. Disabilita STONITH, perché eseguirai il deployment del dispositivo quorum in un secondo momento:

    sudo pcs -f clust_cfg property set stonith-enabled=false
    
  4. Disattiva le impostazioni relative al quorum. Configurerai il nodo del quorum in un secondo momento.

    sudo pcs -f clust_cfg property set no-quorum-policy=stop
    
  5. Impedisci a Pacemaker di spostare indietro le risorse dopo un ripristino:

    sudo pcs -f clust_cfg resource defaults resource-stickiness=200
    
  6. Crea la risorsa DRBD nel 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. Assicurati che alla risorsa DRBD sia assegnato un solo ruolo principale:

    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. Crea la risorsa del file system per montare il disco DRBD:

    sudo pcs -f clust_cfg resource create mystore_FS Filesystem \
        device="/dev/drbd0" \
        directory="/srv" \
        fstype="ext4"
    
  9. Configura il cluster in modo da collocare la risorsa DRBD con la risorsa disco sulla stessa VM:

    sudo pcs -f clust_cfg constraint colocation add mystore_FS with primary_mysql INFINITY with-rsc-role=Master
    
  10. Configura il cluster per visualizzare la risorsa disco solo dopo aver promosso il DRBD principale:

    sudo pcs -f clust_cfg constraint order promote primary_mysql then start mystore_FS
    
  11. Crea un servizio 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. Configura il cluster in modo da collocare la risorsa MySQL con la risorsa disco sulla stessa VM:

    sudo pcs -f clust_cfg constraint colocation add mysql_service with mystore_FS INFINITY
    
  13. Assicurati che il file system DRBD preceda il servizio MySQL nell'ordine di avvio:

    sudo pcs -f clust_cfg constraint order mystore_FS then mysql_service
    
  14. Crea l'agente di avviso e aggiungi la patch al file di log come destinatario:

    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. Esegui il commit delle modifiche al cluster:

    sudo pcs cluster cib-push clust_cfg
    
  16. Verifica che tutte le risorse siano online:

    sudo pcs status
    

    L'output sarà simile al seguente:

    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
    

Configurare un dispositivo del quorum

  1. Connettiti all'istanza qdevice tramite SSH.
  2. Installa pcs e corosync-qnetd:

    sudo apt update && sudo apt -y install pcs corosync-qnetd
    
  3. Avvia il servizio daemon del sistema di configurazione Pacemaker/Corosync (pcsd) e abilitalo all'avvio del sistema:

    sudo service pcsd start
    sudo update-rc.d pcsd enable
    
  4. Imposta la password utente del cluster (haCLUSTER3) per l'autenticazione:

    sudo bash -c "echo  hacluster:haCLUSTER3 | chpasswd"
    
  5. Controlla lo stato del quorum:

    sudo pcs qdevice status net --full
    

    L'output sarà simile al seguente:

    QNetd address:                  *:5403
    TLS:                            Supported (client certificate required)
    Connected clients:              0
    Connected clusters:             0
    Maximum send/receive size:      32768/32768 bytes
    

Configura le impostazioni del dispositivo del quorum su database1

  1. Connettiti al nodo database1 tramite SSH.
  2. Carica le variabili dei metadati dal file .varsrc:

    source ~/.varsrc
    
  3. Autentica il nodo del dispositivo del quorum per il cluster:

    sudo pcs cluster auth --name mysql_cluster ${QUORUM_INSTANCE_NAME} -u hacluster -p haCLUSTER3
    
  4. Aggiungi il dispositivo del quorum al cluster. Utilizza l'algoritmo ffsplit, che garantisce che il nodo attivo venga deciso in base al 50% dei voti o più:

    sudo pcs quorum device add model net host=${QUORUM_INSTANCE_NAME} algorithm=ffsplit
    
  5. Aggiungi l'impostazione del quorum a 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. Riavvia il servizio corosync per ricaricare la nuova impostazione del dispositivo del quorum:

    sudo service corosync restart
    
  7. Avvia il daemon del dispositivo con quorum corosync e attivalo all'avvio del sistema:

    sudo service corosync-qdevice start
    sudo update-rc.d corosync-qdevice defaults
    

Configura le impostazioni del dispositivo del quorum su database2

  1. Connettiti al nodo database2 tramite SSH.
  2. Carica le variabili dei metadati dal file .varsrc:

    source ~/.varsrc
    
  3. Aggiungi un'impostazione del quorum a 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. Riavvia il servizio corosync per ricaricare la nuova impostazione del dispositivo del quorum:

    sudo service corosync restart
    
  5. Avvia il daemon del dispositivo Corosync quorum e configuralo in modo da visualizzarlo all'avvio del sistema:

    sudo service corosync-qdevice start
    sudo update-rc.d corosync-qdevice defaults
    

Verifica dello stato del cluster

Il passaggio successivo consiste nel verificare che le risorse del cluster siano online.

  1. Connettiti all'istanza database1 tramite SSH.
  2. Verifica lo stato del cluster:

    sudo pcs status
    

    L'output sarà simile al seguente:

    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. Mostra lo stato del quorum:

    sudo pcs quorum status
    

    L'output sarà simile al seguente:

    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. Mostra lo stato del quorum:

    sudo pcs quorum device status
    

    L'output sarà simile al seguente:

    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
    

Configurazione di un bilanciatore del carico interno come IP del cluster

  1. Apri Cloud Shell:

    APRI Cloud Shell

  2. Crea un gruppo di istanze non gestite a cui aggiungi l'istanza 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. Crea un gruppo di istanze non gestite a cui aggiungi l'istanza 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. Crea un controllo di integrità per port 3306:

    gcloud compute health-checks create tcp mysql-backend-healthcheck \
        --port 3306
    
  5. Crea un servizio di backend interno a livello di regione:

    gcloud compute backend-services create mysql-ilb \
        --load-balancing-scheme internal \
        --region ${CLUSTER_REGION} \
        --health-checks mysql-backend-healthcheck \
        --protocol tcp
    
  6. Aggiungi i due gruppi di istanze come backend al servizio di 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. Crea una regola di forwarding per il bilanciatore del carico:

    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. Crea una regola firewall per consentire il controllo di integrità del bilanciatore del carico interno:

    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. Per verificare lo stato del bilanciatore del carico, vai alla pagina Bilanciamento del carico nella console Google Cloud.

    APRI LA PAGINA LOAD BALANCING

  10. Fai clic su mysql-ilb:

    immagine

    Poiché il cluster consente a una sola istanza di eseguire MySQL alla volta, solo un'istanza è in stato integro dal punto di vista del bilanciatore del carico interno.

    immagine

Connessione al cluster dal client MySQL

  1. Connettiti all'istanza mysql-client tramite SSH.
  2. Aggiorna le definizioni del pacchetto:

    sudo apt-get update
    
  3. Installa il client MySQL:

    sudo apt-get install -y mysql-client
    
  4. Crea un file di script che crei e compili una tabella con dati di esempio:

    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. Crea la tabella:

    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
    

Test del cluster

Per testare la capacità ad alta disponibilità del cluster di cui è stato eseguito il deployment, puoi eseguire i seguenti test:

  • Arresta l'istanza database1 per verificare se il database master può eseguire il failover sull'istanza database2.
  • Avvia l'istanza database1 per verificare se database1 può entrare di nuovo nel cluster.
  • Arresta l'istanza database2 per verificare se il database master può eseguire il failover sull'istanza database1.
  • Avvia l'istanza database2 per verificare se database2 può rientrare nel cluster e se l'istanza database1 mantiene ancora il ruolo master.
  • Crea una partizione di rete tra database1 e database2 per simulare un problema di suddivisione del cervello.

  1. Apri Cloud Shell:

    APRI Cloud Shell

  2. Arresta l'istanza database1:

    gcloud compute instances stop ${DATABASE1_INSTANCE_NAME} \
        --zone=${DATABASE1_INSTANCE_ZONE}
    
  3. Controlla lo stato del cluster:

    gcloud compute ssh ${DATABASE2_INSTANCE_NAME} \
        --zone=${DATABASE2_INSTANCE_ZONE} \
        --command="sudo pcs status"
    

    L'output è simile al seguente. Verifica che le modifiche apportate alla configurazione siano state effettuate:

    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. Avvia l'istanza database1:

    gcloud compute instances start ${DATABASE1_INSTANCE_NAME} \
        --zone=${DATABASE1_INSTANCE_ZONE}
    
  5. Controlla lo stato del cluster:

    gcloud compute ssh ${DATABASE1_INSTANCE_NAME} \
        --zone=${DATABASE1_INSTANCE_ZONE} \
        --command="sudo pcs status"
    

    L'output sarà simile al seguente:

    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. Arresta l'istanza database2:

    gcloud compute instances stop ${DATABASE2_INSTANCE_NAME} \
        --zone=${DATABASE2_INSTANCE_ZONE}
    
  7. Controlla lo stato del cluster:

    gcloud compute ssh ${DATABASE1_INSTANCE_NAME} \
        --zone=${DATABASE1_INSTANCE_ZONE} \
        --command="sudo pcs status"
    

    L'output sarà simile al seguente:

    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. Avvia l'istanza database2:

    gcloud compute instances start ${DATABASE2_INSTANCE_NAME} \
        --zone=${DATABASE2_INSTANCE_ZONE}
    
  9. Controlla lo stato del cluster:

    gcloud compute ssh ${DATABASE1_INSTANCE_NAME} \
        --zone=${DATABASE1_INSTANCE_ZONE} \
        --command="sudo pcs status"
    

    L'output sarà simile al seguente:

    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. Crea una partizione di rete tra database1 e 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. Dopo un paio di minuti, controlla lo stato del cluster. Nota come database1 mantiene il proprio ruolo principale, perché il criterio del quorum è il nodo ID più basso nella situazione della partizione di rete. Nel frattempo, il servizio MySQL database2 è stato interrotto. Questo meccanismo del quorum evita il problema dello split-brain quando si verifica la partizione di rete.

    gcloud compute ssh ${DATABASE1_INSTANCE_NAME} \
        --zone=${DATABASE1_INSTANCE_ZONE} \
        --command="sudo pcs status"
    

    L'output sarà simile al seguente:

    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. Elimina la regola firewall di rete per rimuovere la partizione di rete. Premi Y quando richiesto.

    gcloud compute firewall-rules delete block-comms
    
  13. Verifica che lo stato del cluster sia tornato alla normalità:

    gcloud compute ssh ${DATABASE1_INSTANCE_NAME} \
        --zone=${DATABASE1_INSTANCE_ZONE} \
        --command="sudo pcs status"
    

    L'output sarà simile al seguente:

    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. Connettiti all'istanza mysql-client tramite SSH.

  15. Nella tua shell, esegui una query sulla tabella creata in precedenza:

    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"
    

    L'output deve elencare 10 record nel formato seguente, verificando la coerenza dei dati nel 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 |
    +----+---------------------+------------+
    

Sequenza di failover

Se il nodo primario nel cluster smette di funzionare, la sequenza di failover sarà simile alla seguente:

  1. Sia il dispositivo quorum che il nodo in standby perdono la connettività con il nodo principale.
  2. Il dispositivo del quorum vota per il nodo in standby, mentre il nodo standby si vota per se stesso.
  3. Il quorum viene acquisito dal nodo standby.
  4. Il nodo standby viene promosso a principale.
  5. Il nuovo nodo primario:
    1. Promuove DRBD a principale
    2. Monta il disco dati MySQL da DRBD
    3. Avvia MySQL
    4. Diventa integro per il bilanciatore del carico
  6. Il bilanciatore del carico inizia a inviare traffico al nuovo nodo primario.

Esegui la pulizia

Elimina il progetto

  1. Nella console Google Cloud, vai alla pagina Gestisci risorse.

    Vai a Gestisci risorse

  2. Nell'elenco dei progetti, seleziona il progetto che vuoi eliminare, quindi fai clic su Elimina.
  3. Nella finestra di dialogo, digita l'ID del progetto e fai clic su Chiudi per eliminare il progetto.

Passaggi successivi