Questo tutorial spiega il processo di deployment di un database MySQL 5.6 su Google Cloud utilizzando Distributed Replicated Block Device (DRBD) e Compute Engine. DRBD è un sistema di archiviazione distribuito e replicato per la piattaforma Linux.
Questo tutorial è utile se sei un sysadmin, uno sviluppatore, un ingegnere, un amministratore di database o un ingegnere DevOps. Potresti voler gestire la tua istanza MySQL invece di utilizzare il servizio gestito per diversi motivi, tra cui:
- Utilizzi istanze di MySQL tra regioni.
- Devi impostare parametri non disponibili nella versione gestita di MySQL.
- Vuoi ottimizzare il rendimento in modi non impostabili 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 puoi usufruire immediatamente dei vantaggi di DRBD, ad esempio il supporto del bilanciamento del carico di lettura e delle connessioni sicure.
Il tutorial utilizza quanto segue:
Per utilizzare queste risorse non sono necessarie conoscenze avanzate, anche se questo documento fa riferimento a funzionalità avanzate come il clustering MySQL, la configurazione di DRBD e la gestione delle risorse Linux.
Architettura
Pacemaker è un gestore delle risorse del cluster. Corosync è un pacchetto per la comunicazione e la partecipazione al cluster, utilizzato da Pacemaker. In questo tutorial utilizzi DRBD per replicare il disco MySQL dall'istanza principale all'istanza in standby. Affinché i client possano connettersi al cluster MySQL, devi anche eseguire il deployment di un bilanciatore del carico interno.
Esegui il deployment di un cluster gestito Pacemaker di tre istanze di computing. Installi MySQL su due delle istanze, che fungono da istanza principale e in standby. La terza istanza funge da dispositivo di quorum.
In un cluster, ogni nodo vota per il nodo che deve essere attivo, ovvero quello che esegue MySQL. In un cluster a due nodi, è sufficiente un voto per determinare il nodo attivo. In questo caso, il comportamento del cluster potrebbe causare problemi di split-brain o tempo di inattività. I problemi di split-brain si verificano quando entrambi i nodi prendono il controllo perché in uno scenario a due nodi è necessario un solo voto. Il tempo di inattività si verifica quando il nodo che si arresta è quello configurato per essere sempre il principale in caso di perdita di connettività. Se i due nodi perdono la connettività tra loro, esiste il rischio che più di un nodo del cluster presuma di essere il nodo attivo.
L'aggiunta di un dispositivo di quorum impedisce questa situazione. Un dispositivo di quorum funge da
arbitro, il cui unico compito è esprimere un voto. In questo modo, in una situazione in cui
le istanze database1
e database2
non possono comunicare, questo nodo del dispositivo
di quorum può comunicare con una delle due istanze e può essere raggiunta una
maggioranza.
Il seguente diagramma mostra l'architettura del sistema descritto qui.
Obiettivi
- Crea le istanze del cluster.
- Installa MySQL e DRBD su due delle istanze.
- Configura la replica DRBD.
- Installa Pacemaker sulle istanze.
- Configura il clustering Pacemaker sulle istanze.
- Crea un'istanza e configurala come dispositivo di quorum.
- Testa il failover.
Costi
Utilizza il calcolatore prezzi per generare una stima dei costi in base all'utilizzo previsto.
Prima di iniziare
- 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.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Verify that billing is enabled for your Google Cloud project.
-
Enable the Compute Engine API.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Verify that billing is enabled for your Google Cloud project.
-
Enable the Compute Engine API.
In questo tutorial, inserisci i comandi utilizzando Cloud Shell, se non diversamente indicato.
Al termine delle attività descritte in questo documento, puoi evitare l'addebito di ulteriori costi eliminando le risorse che hai creato. Per ulteriori informazioni, vedi Pulizia.
Configurazione
In questa sezione, configuri un service account, crei variabili di ambiente e prenoti indirizzi IP.
Configura un service account per le istanze del cluster
Apri Cloud Shell:
Crea l'account di servizio:
gcloud iam service-accounts create mysql-instance \ --display-name "mysql-instance"
Collega all'account di servizio i ruoli necessari per questo tutorial:
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
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
Carica le variabili di ambiente nella sessione corrente e imposta Cloud Shell in modo che le carichi automaticamente ai successivi accessi:
source ~/.mysqldrbdrc grep -q -F "source ~/.mysqldrbdrc" ~/.bashrc || echo "source ~/.mysqldrbdrc" >> ~/.bashrc
Prenota gli 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 Compute Engine
Nei passaggi successivi, le istanze del cluster utilizzano Debian 9 e le istanze client Ubuntu 16.
In Cloud Shell, crea un'istanza MySQL denominata
database1
nella zonaasia-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}"
Crea un'istanza MySQL denominata
database2
nella zonaasia-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}"
Crea un nodo di quorum da utilizzare con 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}
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, installi e configuri i pacchetti DRBD sulle istanze database1
e database2
, quindi avvii la replica DRBD da database1
a database2
.
Configura DRBD su database1
Nella console Google Cloud , vai alla pagina Istanze VM.
Nella riga dell'istanza
database1
, fai clic su SSH per connetterti all'istanza.Crea un file per recuperare e archiviare i metadati delle istanze 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
Carica le variabili dei metadati dal file:
source ~/.varsrc
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
mkfs.ext4
, consulta la pagina del manuale mkfs.ext4.Installa DRBD:
sudo apt -y install drbd8-utils
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'
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"
Carica il modulo kernel DRBD:
sudo modprobe drbd
Cancella i contenuti del disco
/dev/sdb
:sudo dd if=/dev/zero of=/dev/sdb bs=1k count=1024
Crea la risorsa DRBD
r0
:sudo drbdadm create-md r0
Avvia DRBD:
sudo drbdadm up r0
Disattiva DRBD all'avvio del sistema, consentendo al software di gestione delle risorse del cluster di avviare tutti i servizi necessari in ordine:
sudo update-rc.d drbd disable
Configura DRBD su database2
Ora installi e configuri i pacchetti DRBD sull'istanza database2
.
- Connettiti all'istanza
database2
tramite SSH. Crea un file
.varsrc
per recuperare e archiviare i metadati delle istanze 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
Carica le variabili dei metadati dal file:
source ~/.varsrc
Formatta il disco dati:
sudo bash -c "mkfs.ext4 -m 0 -F -E lazy_itable_init=0,lazy_journal_init=0,discard /dev/sdb"
Installa i pacchetti DRBD:
sudo apt -y install drbd8-utils
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'
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"
Carica il modulo kernel DRBD:
sudo modprobe drbd
Cancella il disco
/dev/sdb
:sudo dd if=/dev/zero of=/dev/sdb bs=1k count=1024
Crea la risorsa DRBD
r0
:sudo drbdadm create-md r0
Avvia DRBD:
sudo drbdadm up r0
Disattiva DRBD all'avvio del sistema, consentendo al software di gestione delle risorse del cluster di avviare tutti i servizi necessari in ordine:
sudo update-rc.d drbd disable
Avvia la replica DRBD dal database1 al database2
- Connettiti all'istanza
database1
tramite SSH. Sovrascrivi tutte le risorse
r0
sul nodo principale: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
Verifica lo stato di DRBD:
sudo cat /proc/drbd | grep ============
L'output ha il seguente aspetto:
[===================>] sync'ed:100.0% (208/307188)M
Monta
/dev/drbd
su/srv
:sudo mount -o discard,defaults /dev/drbd0 /srv
Installazione di MySQL e Pacemaker
In questa sezione, installi MySQL e Pacemaker su ogni istanza.
Installa MySQL su database1
- Connettiti all'istanza
database1
tramite SSH. Aggiorna il repository APT con le definizioni del 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'
Aggiungi le chiavi GPG al file
repository.srv
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
Aggiorna l'elenco dei pacchetti:
sudo apt update
Installa il server MySQL:
sudo apt -y install mysql-server
Quando viene richiesta la password, inserisci
DRBDha2
.Arresta il server MySQL:
sudo /etc/init.d/mysql stop
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'
Crea una directory temporanea per il server MySQL (configurato in
mysql.conf
):sudo mkdir /srv/tmp sudo chmod 1777 /srv/tmp
Sposta tutti i dati di MySQL nella directory DRBD
/srv/mysql
:sudo mv /var/lib/mysql /srv/mysql
Collega
/var/lib/mysql
a/srv/mysql
nel volume di archiviazione replicato DRBD:sudo ln -s /srv/mysql /var/lib/mysql
Cambia il proprietario di
/srv/mysql
in un processomysql
:sudo chown -R mysql:mysql /srv/mysql
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 di database MySQL.
Avvia MySQL:
sudo /etc/init.d/mysql start
Concedi l'accesso all'utente root per le connessioni remote al fine di testare il deployment in un secondo momento:
mysql -uroot -pDRBDha2 -e "GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'DRBDha2' WITH GRANT OPTION;"
Disattiva l'avvio automatico di MySQL, di cui si occupa la gestione delle risorse del cluster:
sudo update-rc.d -f mysql disable
Installa Pacemaker su database1
Carica le variabili dei metadati dal file
.varsrc
creato in precedenza:source ~/.varsrc
Arresta il server MySQL:
sudo /etc/init.d/mysql stop
Installa Pacemaker:
sudo apt -y install pcs
Attiva
pcsd
,corosync
epacemaker
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
Configura
corosync
in modo che si avvii prima dipacemaker
:sudo update-rc.d corosync defaults 20 20 sudo update-rc.d pacemaker defaults 30 10
Imposta la password dell'utente del cluster su
haCLUSTER3
per l'autenticazione:sudo bash -c "echo hacluster:haCLUSTER3 | chpasswd"
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
Copia
authkey
nell'istanzadatabase2
. Quando ti viene richiesta una passphrase, premiEnter
: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
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 nella configurazione sono le seguenti:
transport
: specifica la modalità unicast (udpu).Bindnetaddr
: specifica l'indirizzo di rete a cui esegue il binding Corosync.nodelist
: definisce i nodi del cluster e come possono essere raggiunti, in questo caso i nodidatabase1
edatabase2
.quorum
/two_node
: per impostazione predefinita, in un cluster a due nodi nessun nodo otterrà un quorum. Puoi eseguire l'override di questo valore specificando il valore "1" pertwo_node
nella sezionequorum
.
Questa configurazione ti consente di configurare il cluster e prepararlo per un utilizzo successivo quando aggiungerai un terzo nodo che fungerà da dispositivo di quorum.
Crea la Service Directory per
corosync
:sudo mkdir -p /etc/corosync/service.d
Configura
corosync
in modo che sia consapevole di Pacemaker:sudo bash -c 'cat <<EOF > /etc/corosync/service.d/pcmk service { name: pacemaker ver: 1 } EOF'
Attiva 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'
Riavvia i servizi
corosync
epacemaker
:sudo service corosync restart sudo service pacemaker restart
Installa il pacchetto del dispositivo di quorum Corosync:
sudo apt -y install corosync-qdevice
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
- Connettiti all'istanza
database2
tramite SSH. 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'
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
Aggiorna l'elenco dei pacchetti:
sudo apt update
Installa il server MySQL:
sudo apt -y install mysql-server
Quando viene richiesta la password, inserisci
DRBDha2
.Arresta il server MySQL:
sudo /etc/init.d/mysql stop
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'
Rimuovi i dati in
/var/lib/mysql
e aggiungi un link simbolico al punto di montaggio target per il volume DRBD replicato. Il volume DRBD (/dev/drbd0
) verrà montato in/srv
solo in caso di failover.sudo rm -rf /var/lib/mysql sudo ln -s /srv/mysql /var/lib/mysql
Disattiva l'avvio automatico di MySQL, di cui si occupa la gestione delle risorse del cluster:
sudo update-rc.d -f mysql disable
Installa Pacemaker su database2
Carica le variabili dei metadati dal file
.varsrc
:source ~/.varsrc
Installa Pacemaker:
sudo apt -y install pcs
Sposta il file
authkey
di Corosync 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
Attiva
pcsd
,corosync
epacemaker
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
Configura
corosync
in modo che si avvii prima dipacemaker
:sudo update-rc.d corosync defaults 20 20 sudo update-rc.d pacemaker defaults 30 10
Imposta la password dell'utente del cluster per l'autenticazione. La password è la stessa (
haCLUSTER3
) che hai utilizzato per l'istanzadatabase1
.sudo bash -c "echo hacluster:haCLUSTER3 | chpasswd"
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"
Crea la Service Directory Corosync:
sudo mkdir /etc/corosync/service.d
Configura
corosync
in modo che sia consapevole di Pacemaker:sudo bash -c 'cat <<EOF > /etc/corosync/service.d/pcmk service { name: pacemaker ver: 1 } EOF'
Attiva 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'
Riavvia i servizi
corosync
epacemaker
:sudo service corosync restart sudo service pacemaker restart
Installa il pacchetto del dispositivo di quorum Corosync:
sudo apt -y install corosync-qdevice
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
Controlla lo stato del cluster Corosync:
sudo corosync-cmapctl | grep "members...ip"
L'output ha il seguente aspetto:
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
- Connettiti all'istanza
database2
tramite SSH. Carica le variabili dei metadati dal file
.varsrc
:source ~/.varsrc
Esegui l'autenticazione nei nodi del cluster:
sudo pcs cluster auth --name mysql_cluster ${DATABASE1_INSTANCE_NAME} ${DATABASE2_INSTANCE_NAME} -u hacluster -p haCLUSTER3
Avvia il cluster:
sudo pcs cluster start --all
Verifica lo stato del cluster:
sudo pcs status
L'output ha il seguente aspetto:
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
Poi, configuri Pacemaker con le risorse DRBD, disco, MySQL e quorum.
- Connettiti all'istanza
database1
tramite SSH. Utilizza l'utilità
pcs
di Pacemaker per mettere in coda diverse modifiche in un file e successivamente esegui il push a livello atomico alla Cluster Information Base (CIB):sudo pcs cluster cib clust_cfg
Disattiva STONITH, perché eseguirai il deployment del dispositivo di quorum in un secondo momento:
sudo pcs -f clust_cfg property set stonith-enabled=false
Disattiva le impostazioni relative al quorum. Configurerai il nodo del dispositivo di quorum in un secondo momento.
sudo pcs -f clust_cfg property set no-quorum-policy=stop
Impedisci a Pacemaker di spostare nuovamente le risorse dopo un recupero:
sudo pcs -f clust_cfg resource defaults resource-stickiness=200
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
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
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"
Configura il cluster in modo da collocare la risorsa DRBD con la risorsa del disco sulla stessa VM:
sudo pcs -f clust_cfg constraint colocation add mystore_FS with primary_mysql INFINITY with-rsc-role=Master
Configura il cluster in modo che avvii la risorsa del disco solo dopo la promozione della DRBD principale:
sudo pcs -f clust_cfg constraint order promote primary_mysql then start mystore_FS
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
Configura il cluster in modo da collocare la risorsa MySQL con la risorsa del disco sulla stessa VM:
sudo pcs -f clust_cfg constraint colocation add mysql_service with mystore_FS INFINITY
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
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
Esegui il commit delle modifiche al cluster:
sudo pcs cluster cib-push clust_cfg
Verifica che tutte le risorse siano online:
sudo pcs status
L'output ha il seguente aspetto:
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
Configurazione di un dispositivo di quorum
- Connettiti all'istanza
qdevice
tramite SSH. Installa
pcs
ecorosync-qnetd
:sudo apt update && sudo apt -y install pcs corosync-qnetd
Avvia il servizio daemon del sistema di configurazione Pacemaker o Corosync (
pcsd
) e attivalo all'avvio del sistema:sudo service pcsd start sudo update-rc.d pcsd enable
Imposta la password dell'utente del cluster (
haCLUSTER3
) per l'autenticazione:sudo bash -c "echo hacluster:haCLUSTER3 | chpasswd"
Controlla lo stato del dispositivo di quorum:
sudo pcs qdevice status net --full
L'output ha il seguente aspetto:
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 di quorum su database1
- Connettiti al nodo
database1
tramite SSH. Carica le variabili dei metadati dal file
.varsrc
:source ~/.varsrc
Esegui l'autenticazione del nodo del dispositivo di quorum per il cluster:
sudo pcs cluster auth --name mysql_cluster ${QUORUM_INSTANCE_NAME} -u hacluster -p haCLUSTER3
Aggiungi il dispositivo di quorum al cluster. Utilizza l'algoritmo
ffsplit
, che garantisce che il nodo attivo venga deciso in base al 50% o più dei voti:sudo pcs quorum device add model net host=${QUORUM_INSTANCE_NAME} algorithm=ffsplit
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"
Riavvia il servizio
corosync
per ricaricare la nuova impostazione del dispositivo di quorum:sudo service corosync restart
Avvia il daemon del dispositivo di quorum
corosync
e riavvialo all'avvio del sistema:sudo service corosync-qdevice start sudo update-rc.d corosync-qdevice defaults
Configura le impostazioni del dispositivo di quorum su database2
- Connettiti al nodo
database2
tramite SSH. Carica le variabili dei metadati dal file
.varsrc
:source ~/.varsrc
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"
Riavvia il servizio
corosync
per ricaricare la nuova impostazione del dispositivo di quorum:sudo service corosync restart
Avvia il daemon del dispositivo di quorum Corosync e configuralo in modo che venga avviato 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.
- Connettiti all'istanza
database1
tramite SSH. Verifica lo stato del cluster:
sudo pcs status
L'output ha il seguente aspetto:
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
Mostra lo stato del quorum:
sudo pcs quorum status
L'output ha il seguente aspetto:
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
Mostra lo stato del dispositivo di quorum:
sudo pcs quorum device status
L'output ha il seguente aspetto:
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 cluster
Apri Cloud Shell:
Crea un gruppo di istanze non gestito e 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}
Crea un gruppo di istanze non gestito e 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}
Crea un controllo di integrità per
port 3306
:gcloud compute health-checks create tcp mysql-backend-healthcheck \ --port 3306
Crea un servizio di backend interno regionale:
gcloud compute backend-services create mysql-ilb \ --load-balancing-scheme internal \ --region ${CLUSTER_REGION} \ --health-checks mysql-backend-healthcheck \ --protocol tcp
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}
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
Crea una regola firewall per consentire un 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
Per controllare lo stato del bilanciatore del carico, vai alla pagina Bilanciamento del carico nella console Google Cloud .
Fai clic su
mysql-ilb
:Poiché il cluster consente a una sola istanza di eseguire MySQL in un determinato momento, solo un'istanza è integra dal punto di vista del bilanciatore del carico interno.
Connessione al cluster dal client MySQL
- Connettiti all'istanza
mysql-client
tramite SSH. Aggiorna le definizioni del pacchetto:
sudo apt-get update
Installa il client MySQL:
sudo apt-get install -y mysql-client
Crea un file di script che crea e compila 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
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 funzionalità HA del cluster di cui è stato eseguito il deployment, puoi eseguire i seguenti test:
- Arresta l'istanza
database1
per verificare se il database primario può eseguire il failover all'istanzadatabase2
. - Avvia l'istanza
database1
per verificare sedatabase1
può rientrare correttamente nel cluster. - Arresta l'istanza
database2
per verificare se il database primario può eseguire il failover all'istanzadatabase1
. - Avvia l'istanza
database2
per verificare sedatabase2
può rientrare correttamente nel cluster e se l'istanzadatabase1
mantiene il ruolo di primaria. - Crea una partizione di rete tra
database1
edatabase2
per simulare un problema di split-brain.
Apri Cloud Shell:
Arresta l'istanza
database1
:gcloud compute instances stop ${DATABASE1_INSTANCE_NAME} \ --zone=${DATABASE1_INSTANCE_ZONE}
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 alla configurazione che hai apportato siano state eseguite:
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
Avvia l'istanza
database1
:gcloud compute instances start ${DATABASE1_INSTANCE_NAME} \ --zone=${DATABASE1_INSTANCE_ZONE}
Controlla lo stato del cluster:
gcloud compute ssh ${DATABASE1_INSTANCE_NAME} \ --zone=${DATABASE1_INSTANCE_ZONE} \ --command="sudo pcs status"
L'output ha il seguente aspetto:
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
Arresta l'istanza
database2
:gcloud compute instances stop ${DATABASE2_INSTANCE_NAME} \ --zone=${DATABASE2_INSTANCE_ZONE}
Controlla lo stato del cluster:
gcloud compute ssh ${DATABASE1_INSTANCE_NAME} \ --zone=${DATABASE1_INSTANCE_ZONE} \ --command="sudo pcs status"
L'output ha il seguente aspetto:
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
Avvia l'istanza
database2
:gcloud compute instances start ${DATABASE2_INSTANCE_NAME} \ --zone=${DATABASE2_INSTANCE_ZONE}
Controlla lo stato del cluster:
gcloud compute ssh ${DATABASE1_INSTANCE_NAME} \ --zone=${DATABASE1_INSTANCE_ZONE} \ --command="sudo pcs status"
L'output ha il seguente aspetto:
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
Crea una partizione di rete tra
database1
edatabase2
:gcloud compute firewall-rules create block-comms \ --description="no MySQL communications" \ --action=DENY \ --rules=all \ --source-tags=mysql \ --target-tags=mysql \ --priority=800
Dopo un paio di minuti, controlla lo stato del cluster. Puoi notare che
database1
mantiene il proprio ruolo principale, perché la policy di quorum prevede che, in caso di partizione di rete, venga privilegiato il nodo con l'ID più basso. Nel frattempo, il serviziodatabase2
di MySQL viene interrotto. Questo meccanismo di quorum evita il problema di 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 ha il seguente aspetto:
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
Elimina la regola firewall di rete per rimuovere la partizione di rete. (Premi
Y
quando richiesto).gcloud compute firewall-rules delete block-comms
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 ha il seguente aspetto:
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
Connettiti all'istanza
mysql-client
tramite SSH.Nella 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 del seguente modulo, 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 principale del cluster si arresta in modo anomalo, la sequenza di failover è la seguente:
- Sia il dispositivo di quorum che il nodo di riserva perdono la connettività con il nodo principale.
- Il dispositivo di quorum vota per il nodo di riserva e il nodo di riserva vota per se stesso.
- Il quorum viene ottenuto dal nodo di riserva.
- Il nodo di riserva viene promosso a principale.
- Il nuovo nodo principale esegue le seguenti operazioni:
- Promuove DRBD a principale
- Monta il disco di dati MySQL da DRBD
- Avvia MySQL
- Diventa integro per il bilanciatore del carico
- Il bilanciatore del carico inizia a inviare traffico al nuovo nodo principale.
Liberare spazio
Elimina il progetto
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.
Passaggi successivi
- Scopri di più su DRBD.
- Scopri di più su Pacemaker.
- Scopri di più su Corosync Cluster Engine.
- Per impostazioni più avanzate del server MySQL 5.6, consulta il manuale di amministrazione del server MySQL.
- Se vuoi configurare l'accesso remoto a MySQL, consulta Come configurare l'accesso remoto a MySQL su Compute Engine.
- Per ulteriori informazioni su MySQL, consulta la documentazione ufficiale di MySQL.
- Esplora architetture di riferimento, diagrammi e best practice su Google Cloud. Visita il nostro Cloud Architecture Center.