En este instructivo, se explica el proceso de implementación de una base de datos de MySQL 5.6 en Google Cloud mediante un dispositivo de bloques replicados distribuidos (DRBD) y Compute Engine. DRBD es un sistema de almacenamiento replicado distribuido para la plataforma Linux.
Este instructivo te resultará útil si eres un administrador de sistemas, desarrollador, ingeniero, administrador de base de datos o ingeniero DevOps. Es posible que desees administrar tu propia instancia de MySQL en lugar de usar el servicio administrado por varias razones, entre ellas:
- Usas instancias de MySQL entre regiones.
- Debes configurar los parámetros que no están disponibles en la versión administrada de MySQL.
- Deseas optimizar el rendimiento de formas que no se pueden configurar en la versión administrada.
DRBD proporciona replicación a nivel del dispositivo de bloques. Esto significa que no debes configurar la replicación en MySQL y obtienes beneficios de DRBD inmediatos, por ejemplo, compatibilidad con balanceo de cargas de lectura y conexiones seguras.
En el instructivo, se usan los siguientes sistemas:
No se requieren conocimientos avanzados para usar estos recursos, aunque en este documento, se hace referencia a competencias avanzadas como el agrupamiento en clústeres de MySQL, la configuración de DRBD y la administración de recursos de Linux.
Arquitectura
Pacemaker es un administrador de recursos de clúster. Corosync es un paquete de comunicación y participación en clúster, que usa Pacemaker. En este instructivo, usarás DRBD para replicar el disco de MySQL de la instancia principal a la instancia en espera. Para que los clientes se conecten al clúster de MySQL, también implementarás un balanceador de cargas interno.
Implementarás un clúster administrado por Pacemaker de tres instancias de procesamiento. Instalarás MySQL en dos instancias, que actúan como la instancia principal y en espera. La tercera instancia actúa como un dispositivo de quórum.
En un clúster, cada nodo vota por el que debería ser el nodo activo, es decir, el que ejecuta MySQL. En un clúster de dos nodos, solo se necesita un voto para determinar el nodo activo. En ese caso, el comportamiento del clúster puede ocasionar problemas de cerebro dividido o tiempo de inactividad. Los problemas de cerebro dividido ocurren cuando ambos nodos toman el control porque solo se necesita un voto en una situación de dos nodos. El tiempo de inactividad se produce cuando el nodo que se detiene es el que está configurado para ser el principal en caso de pérdida de la conectividad. Si ambos nodos pierden conectividad entre sí, existe el riesgo de que más de un nodo de clúster suponga que es el nodo activo.
Agregar un dispositivo de quórum evita esta situación. Un dispositivo de quórum funciona como árbitro, su único trabajo es emitir un voto. De esta manera, en una situación en la que las instancias database1
y database2
no puedan comunicarse, este nodo de dispositivo de quórum puede comunicarse con una de las dos instancias y se puede llegar a una mayoría.
En el siguiente diagrama, se muestra la arquitectura del sistema descrito aquí.
Objetivos
- Crear las instancias de clústeres
- Instalar MySQL y DRBD en dos instancias
- Configurar la replicación de DRBD
- Instalar Pacemaker en las instancias
- Configurar el agrupamiento en clústeres de Pacemaker en las instancias
- Crear una instancia y configurarla como un dispositivo de quórum
- Probar la conmutación por error
Costos
Usa la calculadora de precios para generar una estimación de los costos según el uso previsto.
Antes de comenzar
- 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.
-
Make sure 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.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Compute Engine API.
En este instructivo, ingresarás comandos con Cloud Shell, a menos que se indique lo contrario.
Cuando finalices las tareas que se describen en este documento, puedes borrar los recursos que creaste para evitar que continúe la facturación. Para obtener más información, consulta Cómo realizar una limpieza.
Configuración
En esta sección, configurarás una cuenta de servicio, crearás variables de entorno y reservarás direcciones IP.
Configura una cuenta de servicio para las instancias de clústeres
Abre Cloud Shell:
Crea la cuenta de servicio:
gcloud iam service-accounts create mysql-instance \ --display-name "mysql-instance"
Adjunta las funciones necesarias para este instructivo a la cuenta de servicio:
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 variables de entorno de Cloud Shell
Crea un archivo con las variables de entorno necesarias para este instructivo:
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
Carga las variables de entorno en la sesión actual y configura Cloud Shell para que cargue de forma automática las variables cuando accedas en el futuro:
source ~/.mysqldrbdrc grep -q -F "source ~/.mysqldrbdrc" ~/.bashrc || echo "source ~/.mysqldrbdrc" >> ~/.bashrc
Reserva direcciones IP
En Cloud Shell, reserva una dirección IP interna para cada uno de los tres nodos del clúster:
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
Crea las instancias de Compute Engine
En los pasos siguientes, las instancias de clústeres usan Debian 9 y las instancias de cliente usan Ubuntu 16.
En Cloud Shell, crea una instancia de MySQL llamada
database1
en la 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 una instancia de MySQL llamada
database2
en la 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 de quórum para que Pacemaker lo use en la 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 una instancia de cliente 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}"
Instala y configura DRBD
En esta sección, instalarás y configurarás los paquetes DRBD en las instancias database1
y database2
y, luego, iniciarás la replicación DRBD de database1
a database2
.
Configura DRBD en database1
En la consola de Google Cloud, ve a la página Instancias de VM.
En la fila de la instancia
database1
, haz clic en SSH para conectarte a la instancia.Crea un archivo para recuperar y almacenar metadatos de instancias en variables de entorno:
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
Carga las variables de metadatos desde el archivo:
source ~/.varsrc
Formatea el disco de datos:
sudo bash -c "mkfs.ext4 -m 0 -F -E \ lazy_itable_init=0,lazy_journal_init=0,discard /dev/sdb"
Para obtener una descripción detallada de las opciones
mkfs.ext4
, consulta la página de manual mkfs.ext4.Instala DRBD:
sudo apt -y install drbd8-utils
Crea el archivo de configuración de DRBD:
sudo bash -c 'cat <<EOF > /etc/drbd.d/global_common.conf global { usage-count no; } common { protocol C; } EOF'
Crea un archivo de recursos de 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"
Carga el módulo de kernel de DRBD:
sudo modprobe drbd
Borra el contenido del disco
/dev/sdb
:sudo dd if=/dev/zero of=/dev/sdb bs=1k count=1024
Crea el recurso de DRBD
r0
:sudo drbdadm create-md r0
Abre DRBD:
sudo drbdadm up r0
Inhabilita DRBD cuando se inicie el sistema para permitir que el software de administración de recursos del clúster abra todos los servicios necesarios en orden:
sudo update-rc.d drbd disable
Configura DRBD en database2
Ahora instalarás y configurarás los paquetes de DRBD en la instancia database2
.
- Conéctate a la instancia
database2
a través de SSH. Crea un archivo
.varsrc
para recuperar y almacenar metadatos de instancias en variables de entorno: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
Carga las variables de metadatos desde el archivo:
source ~/.varsrc
Formatea el disco de datos:
sudo bash -c "mkfs.ext4 -m 0 -F -E lazy_itable_init=0,lazy_journal_init=0,discard /dev/sdb"
Instala los paquetes de DRBD:
sudo apt -y install drbd8-utils
Crea el archivo de configuración de DRBD:
sudo bash -c 'cat <<EOF > /etc/drbd.d/global_common.conf global { usage-count no; } common { protocol C; } EOF'
Crea un archivo de recursos de 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"
Carga el módulo de kernel de DRBD:
sudo modprobe drbd
Borrar el disco
/dev/sdb
:sudo dd if=/dev/zero of=/dev/sdb bs=1k count=1024
Crea el recurso de DRBD
r0
:sudo drbdadm create-md r0
Abre DRBD:
sudo drbdadm up r0
Inhabilita DRBD cuando se inicie el sistema para permitir que el software de administración de recursos del clúster abra todos los servicios necesarios en orden:
sudo update-rc.d drbd disable
Inicia la replicación de DRBD de database1 a database2
- Conéctate a la instancia
database1
a través de SSH. Reemplaza todos los recursos
r0
en el nodo principal:sudo drbdadm -- --overwrite-data-of-peer primary r0 sudo mkfs.ext4 -m 0 -F -E lazy_itable_init=0,lazy_journal_init=0,discard /dev/drbd0
Verifica el estado de DRBD:
sudo cat /proc/drbd | grep ============
La salida obtenida se verá así:
[===================>] sync'ed:100.0% (208/307188)M
Activa
/dev/drbd
en/srv
:sudo mount -o discard,defaults /dev/drbd0 /srv
Instala MySQL y Pacemaker
En esta sección, instalarás MySQL y Pacemaker en cada instancia.
Instala MySQL en database1
- Conéctate a la instancia
database1
a través de SSH. Actualiza el repositorio de APT con las definiciones del paquete de 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'
Agrega las claves de GPG al archivo
repository.srv
de 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
Actualiza la lista de paquetes:
sudo apt update
Instala el servidor MySQL:
sudo apt -y install mysql-server
Cuando se te solicite una contraseña, ingresa
DRBDha2
.Detén el servidor MySQL:
sudo /etc/init.d/mysql stop
Crea el archivo de configuración de 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 un directorio temporal para el servidor MySQL (configurado en
mysql.conf
):sudo mkdir /srv/tmp sudo chmod 1777 /srv/tmp
Mueve todos los datos de MySQL al directorio de DRBD
/srv/mysql
:sudo mv /var/lib/mysql /srv/mysql
Vincula
/var/lib/mysql
a/srv/mysql
en el volumen de almacenamiento replicado de DRBD:sudo ln -s /srv/mysql /var/lib/mysql
Cambia el propietario de
/srv/mysql
a un proceso demysql
:sudo chown -R mysql:mysql /srv/mysql
Quita los datos iniciales de
InnoDB
para asegurarte de que el disco esté lo más limpio posible:sudo bash -c "cd /srv/mysql && rm ibdata1 && rm ib_logfile*"
InnoDB es un motor de almacenamiento para el sistema de administración de bases de datos de MySQL.
Inicia MySQL:
sudo /etc/init.d/mysql start
Otorga acceso al usuario raíz para las conexiones remotas a fin de probar la implementación en el futuro:
mysql -uroot -pDRBDha2 -e "GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'DRBDha2' WITH GRANT OPTION;"
Inhabilita el inicio automático de MySQL, del que se ocupa la administración de recursos del clúster:
sudo update-rc.d -f mysql disable
Instala Pacemaker en database1
Carga las variables de metadatos desde el archivo
.varsrc
que creaste antes:source ~/.varsrc
Detén el servidor MySQL:
sudo /etc/init.d/mysql stop
Instala Pacemaker:
sudo apt -y install pcs
Habilita
pcsd
,corosync
ypacemaker
cuando se inicie el sistema en la instancia principal:sudo update-rc.d -f pcsd enable sudo update-rc.d -f corosync enable sudo update-rc.d -f pacemaker enable
Configura
corosync
para que comience antes depacemaker
:sudo update-rc.d corosync defaults 20 20 sudo update-rc.d pacemaker defaults 30 10
Establece la contraseña de usuario del clúster como
haCLUSTER3
para la autenticación:sudo bash -c "echo hacluster:haCLUSTER3 | chpasswd"
Ejecuta la secuencia de comandos de
corosync-keygen
para generar una clave de autorización de clúster de 128 bits y escríbela en/etc/corosync/authkey
:sudo corosync-keygen -l
Copia
authkey
a la instanciadatabase2
. Cuando se te solicite una frase de contraseña, presionaEnter
: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 archivo de configuración de clúster de 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"
En la sección
totem
se configura el protocolo de Totem para proporcionar una comunicación confiable. Corosync usa esta comunicación para controlar la pertenencia al clúster y especifica cómo los miembros del clúster deben comunicarse entre sí.A continuación, se indican las opciones de configuración importantes:
transport
: Especifica el modo de unidifusión (udpu).Bindnetaddr
: Especifica la dirección de red a la que se vincula Corosync.nodelist
: Define los nodos en el clúster y cómo se puede llegar a ellos, en este caso, los nodosdatabase1
ydatabase2
.quorum
/two_node
: De forma predeterminada, en un clúster de dos nodos, ningún nodo adquirirá un quórum. A fin de anular esto, especifica el valor “1” paratwo_node
en la secciónquorum
.
Esto te permite configurar el clúster y prepararlo para usarlo en el futuro, cuando agregues un tercer nodo que funcionará como un dispositivo de quórum.
Crea el directorio de servicio para
corosync
:sudo mkdir -p /etc/corosync/service.d
Configura
corosync
para que sea compatible con Pacemaker:sudo bash -c 'cat <<EOF > /etc/corosync/service.d/pcmk service { name: pacemaker ver: 1 } EOF'
Habilita el servicio
corosync
de forma predeterminada: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'
Reinicia los servicios
corosync
ypacemaker
:sudo service corosync restart sudo service pacemaker restart
Instala el paquete de dispositivo de quórum de Corosync:
sudo apt -y install corosync-qdevice
Instala una secuencia de comandos de shell para controlar las fallas de 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
Instala MySQL en database2
- Conéctate a la instancia
database2
a través de SSH. Actualiza el repositorio de APT con el paquete de 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'
Agrega las claves de GPG al repositorio de 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
Actualiza la lista de paquetes:
sudo apt update
Instala el servidor MySQL:
sudo apt -y install mysql-server
Cuando se te solicite una contraseña, ingresa
DRBDha2
.Detén el servidor MySQL:
sudo /etc/init.d/mysql stop
Crea el archivo de configuración de 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'
Quita los datos en
/var/lib/mysql
y agrega un vínculo simbólico al destino del punto de activación para el volumen replicado de DRBD. El volumen de DRBD (/dev/drbd0
) se activará en/srv
solo cuando se produzca una conmutación por error.sudo rm -rf /var/lib/mysql sudo ln -s /srv/mysql /var/lib/mysql
Inhabilita el inicio automático de MySQL, del que se ocupa la administración de recursos del clúster:
sudo update-rc.d -f mysql disable
Instala Pacemaker en database2
Carga las variables de metadatos desde el archivo
.varsrc
:source ~/.varsrc
Instala Pacemaker:
sudo apt -y install pcs
Mueve el archivo
authkey
de Corosync que copiaste antes en/etc/corosync/
:sudo mv ~/authkey /etc/corosync/ sudo chown root: /etc/corosync/authkey sudo chmod 400 /etc/corosync/authkey
Habilita
pcsd
,corosync
ypacemaker
cuando se inicie el sistema en la instancia en espera:sudo update-rc.d -f pcsd enable sudo update-rc.d -f corosync enable sudo update-rc.d -f pacemaker enable
Configura
corosync
para que comience antes depacemaker
:sudo update-rc.d corosync defaults 20 20 sudo update-rc.d pacemaker defaults 30 10
Establece la contraseña de usuario del clúster para la autenticación. La contraseña es la misma (
haCLUSTER3
) que usaste para la instanciadatabase1
.sudo bash -c "echo hacluster:haCLUSTER3 | chpasswd"
Crea el archivo de configuración
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 el directorio de servicios de Corosync:
sudo mkdir /etc/corosync/service.d
Configura
corosync
para que sea compatible con Pacemaker:sudo bash -c 'cat <<EOF > /etc/corosync/service.d/pcmk service { name: pacemaker ver: 1 } EOF'
Habilita el servicio
corosync
de forma predeterminada: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'
Reinicia los servicios
corosync
ypacemaker
:sudo service corosync restart sudo service pacemaker restart
Instala el paquete de dispositivo de quórum de Corosync:
sudo apt -y install corosync-qdevice
Instala una secuencia de comandos de shell para controlar las fallas de 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
Verifica el estado del clúster de Corosync:
sudo corosync-cmapctl | grep "members...ip"
La salida obtenida se verá así:
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)
Inicia el clúster
- Conéctate a la instancia
database2
a través de SSH. Carga las variables de metadatos desde el archivo
.varsrc
:source ~/.varsrc
Autentica con los nodos del clúster:
sudo pcs cluster auth --name mysql_cluster ${DATABASE1_INSTANCE_NAME} ${DATABASE2_INSTANCE_NAME} -u hacluster -p haCLUSTER3
Inicia el clúster:
sudo pcs cluster start --all
Verifica el estado del clúster:
sudo pcs status
La salida obtenida se verá así:
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
Configura Pacemaker para administrar los recursos del clúster
Luego, configura Pacemaker con los recursos de DRBD, MySQL, quórum y del disco.
- Conéctate a la instancia
database1
a través de SSH. Usa la utilidad
pcs
de Pacemaker para poner en cola varios cambios en un archivo y, luego, enviar esos cambios a la base de información del clúster (CIB) de forma atómica:sudo pcs cluster cib clust_cfg
Inhabilita STONITH, ya que implementarás el dispositivo de quórum más adelante:
sudo pcs -f clust_cfg property set stonith-enabled=false
Inhabilita la configuración relacionada con el quórum. Configurarás el nodo del dispositivo de quórum más tarde.
sudo pcs -f clust_cfg property set no-quorum-policy=stop
Evita que Pacemaker retire los recursos después de una recuperación:
sudo pcs -f clust_cfg resource defaults resource-stickiness=200
Crea el recurso de DRBD en el clúster:
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
Asegúrate de que solo se asigne una función principal al recurso de DRBD:
sudo pcs -f clust_cfg resource master primary_mysql mysql_drbd \ master-max=1 master-node-max=1 \ clone-max=2 clone-node-max=1 \ notify=true
Crea el recurso del sistema de archivos para activar el disco de DRBD:
sudo pcs -f clust_cfg resource create mystore_FS Filesystem \ device="/dev/drbd0" \ directory="/srv" \ fstype="ext4"
Configura el clúster para colocar el recurso de DRBD con el recurso del disco en la misma VM:
sudo pcs -f clust_cfg constraint colocation add mystore_FS with primary_mysql INFINITY with-rsc-role=Master
Configura el clúster para que el recurso del disco aparezca después de que el DRBD principal ascienda:
sudo pcs -f clust_cfg constraint order promote primary_mysql then start mystore_FS
Crea un servicio de 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 el clúster para colocar el recurso de MySQL con el recurso del disco en la misma VM:
sudo pcs -f clust_cfg constraint colocation add mysql_service with mystore_FS INFINITY
Asegúrate de que el sistema de archivos de DRBD preceda al servicio de MySQL en el orden de inicio:
sudo pcs -f clust_cfg constraint order mystore_FS then mysql_service
Crea el agente de alerta y agrega el parche al archivo de registro como su 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
Confirma los cambios en el clúster:
sudo pcs cluster cib-push clust_cfg
Verifica que todos los recursos estén en línea:
sudo pcs status
La salida obtenida se verá así:
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
Configura un dispositivo de quórum
- Conéctate a la instancia
qdevice
a través de SSH. Instala
pcs
ycorosync-qnetd
:sudo apt update && sudo apt -y install pcs corosync-qnetd
Inicia el servicio de daemon del sistema de configuración de Pacemaker o Corosync (
pcsd
) y habilítalo cuando comience el sistema:sudo service pcsd start sudo update-rc.d pcsd enable
Establece la contraseña de usuario del clúster (
haCLUSTER3
) para la autenticación:sudo bash -c "echo hacluster:haCLUSTER3 | chpasswd"
Verifica el estado del dispositivo de quórum:
sudo pcs qdevice status net --full
La salida obtenida se verá así:
QNetd address: *:5403 TLS: Supported (client certificate required) Connected clients: 0 Connected clusters: 0 Maximum send/receive size: 32768/32768 bytes
Establece la configuración del dispositivo de quórum en database1
- Conéctate al nodo
database1
a través de SSH. Carga las variables de metadatos desde el archivo
.varsrc
:source ~/.varsrc
Autentica el nodo del dispositivo de quórum para el clúster:
sudo pcs cluster auth --name mysql_cluster ${QUORUM_INSTANCE_NAME} -u hacluster -p haCLUSTER3
Agrega el dispositivo de quórum al clúster. Usa el algoritmo
ffsplit
, que garantiza que el nodo activo se decidirá en función del 50% de los votos o más:sudo pcs quorum device add model net host=${QUORUM_INSTANCE_NAME} algorithm=ffsplit
Agrega la configuración de quórum 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"
Reinicia el servicio de
corosync
para volver a cargar la configuración nueva del dispositivo de quórum:sudo service corosync restart
Inicia el daemon del dispositivo de quórum de
corosync
y ábrelo cuando comience el sistema:sudo service corosync-qdevice start sudo update-rc.d corosync-qdevice defaults
Establece la configuración del dispositivo de quórum en database2
- Conéctate al nodo
database2
a través de SSH. Carga las variables de metadatos desde el archivo
.varsrc
:source ~/.varsrc
Agrega una configuración de quórum 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"
Reinicia el servicio de
corosync
para volver a cargar la configuración nueva del dispositivo de quórum:sudo service corosync restart
Inicia el daemon del dispositivo de quórum de Corosync y configúralo para que se abra cuando comience el sistema:
sudo service corosync-qdevice start sudo update-rc.d corosync-qdevice defaults
Verifica el estado del clúster
El siguiente paso es verificar que los recursos del clúster estén en línea.
- Conéctate a la instancia
database1
a través de SSH. Verifica el estado del clúster:
sudo pcs status
La salida obtenida se verá así:
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
Muestra el estado del quórum:
sudo pcs quorum status
La salida obtenida se verá así:
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
Muestra el estado del dispositivo de quórum:
sudo pcs quorum device status
La salida obtenida se verá así:
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
Configura un balanceador de cargas interno como la IP del clúster
Abre Cloud Shell:
Crea un grupo de instancias no administrado y agrégale la instancia
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 grupo de instancias no administrado y agrégale la instancia
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 una verificación de estado para
port 3306
:gcloud compute health-checks create tcp mysql-backend-healthcheck \ --port 3306
Crea un servicio de backend interno regional:
gcloud compute backend-services create mysql-ilb \ --load-balancing-scheme internal \ --region ${CLUSTER_REGION} \ --health-checks mysql-backend-healthcheck \ --protocol tcp
Agrega los dos grupos de instancias como backends al servicio de backend:
gcloud compute backend-services add-backend mysql-ilb \ --instance-group ${DATABASE1_INSTANCE_NAME}-instance-group \ --instance-group-zone ${DATABASE1_INSTANCE_ZONE} \ --region ${CLUSTER_REGION} gcloud compute backend-services add-backend mysql-ilb \ --instance-group ${DATABASE2_INSTANCE_NAME}-instance-group \ --instance-group-zone ${DATABASE2_INSTANCE_ZONE} \ --region ${CLUSTER_REGION}
Crea una regla de desvío para el balanceador de cargas:
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 regla de firewall para permitir una verificación de estado del balanceador de cargas 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
Para verificar el estado de tu balanceador de cargas, ve a la página Balanceo de cargas en la consola de Google Cloud.
Haz clic en
mysql-ilb
:Debido a que el clúster permite que una sola instancia ejecute MySQL en cualquier momento, solo una instancia se encuentra en buen estado desde la perspectiva del balanceador de cargas interno.
Conéctate al clúster desde el cliente MySQL
- Conéctate a la instancia
mysql-client
a través de SSH. Actualiza las definiciones de paquetes:
sudo apt-get update
Instala el cliente MySQL:
sudo apt-get install -y mysql-client
Crea un archivo de secuencia de comandos que cree y propague una tabla con datos de muestra:
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 tabla:
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
Prueba el clúster
Para verificar la capacidad de alta disponibilidad del clúster implementado, puedes realizar las siguientes pruebas:
- Cierra la instancia
database1
para probar si la base de datos principal puede conmutar por error a la instanciadatabase2
. - Inicia la instancia
database1
para ver sidatabase1
puede volver a unirse al clúster de manera correcta. - Cierra la instancia
database2
para probar si la base de datos principal puede conmutar por error a la instanciadatabase1
. - Inicia la instancia
database2
para ver sidatabase2
puede volver a unirse al clúster de manera correcta y si la instanciadatabase1
aún conserva la función principal. - Crea una partición de red entre
database1
ydatabase2
para simular un problema de cerebro dividido.
Abre Cloud Shell:
Detén la instancia
database1
:gcloud compute instances stop ${DATABASE1_INSTANCE_NAME} \ --zone=${DATABASE1_INSTANCE_ZONE}
Verifica el estado del clúster:
gcloud compute ssh ${DATABASE2_INSTANCE_NAME} \ --zone=${DATABASE2_INSTANCE_ZONE} \ --command="sudo pcs status"
El resultado se verá de la siguiente manera. Verifica si se implementaron los cambios de configuración que hiciste:
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
Inicia la instancia
database1
:gcloud compute instances start ${DATABASE1_INSTANCE_NAME} \ --zone=${DATABASE1_INSTANCE_ZONE}
Verifica el estado del clúster:
gcloud compute ssh ${DATABASE1_INSTANCE_NAME} \ --zone=${DATABASE1_INSTANCE_ZONE} \ --command="sudo pcs status"
La salida obtenida se verá así:
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
Detén la instancia
database2
:gcloud compute instances stop ${DATABASE2_INSTANCE_NAME} \ --zone=${DATABASE2_INSTANCE_ZONE}
Verifica el estado del clúster:
gcloud compute ssh ${DATABASE1_INSTANCE_NAME} \ --zone=${DATABASE1_INSTANCE_ZONE} \ --command="sudo pcs status"
La salida obtenida se verá así:
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
Inicia la instancia
database2
:gcloud compute instances start ${DATABASE2_INSTANCE_NAME} \ --zone=${DATABASE2_INSTANCE_ZONE}
Verifica el estado del clúster:
gcloud compute ssh ${DATABASE1_INSTANCE_NAME} \ --zone=${DATABASE1_INSTANCE_ZONE} \ --command="sudo pcs status"
La salida obtenida se verá así:
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 partición de red entre
database1
ydatabase2
:gcloud compute firewall-rules create block-comms \ --description="no MySQL communications" \ --action=DENY \ --rules=all \ --source-tags=mysql \ --target-tags=mysql \ --priority=800
Después de unos minutos, verifica el estado del clúster. Observa que
database1
mantiene su función principal, porque la política de quórum consiste en el nodo de ID más bajo primero en una situación de partición de red. Mientras tanto, el servicio de MySQL dedatabase2
se detiene. Este mecanismo de quórum evita el problema de cerebro dividido cuando se produce la partición de red.gcloud compute ssh ${DATABASE1_INSTANCE_NAME} \ --zone=${DATABASE1_INSTANCE_ZONE} \ --command="sudo pcs status"
La salida obtenida se verá así:
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
Borra la regla de firewall de red para quitar la partición de red (presiona
Y
cuando se te solicite).gcloud compute firewall-rules delete block-comms
Verifica que el estado del clúster vuelva a la normalidad:
gcloud compute ssh ${DATABASE1_INSTANCE_NAME} \ --zone=${DATABASE1_INSTANCE_ZONE} \ --command="sudo pcs status"
La salida obtenida se verá así:
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
Conéctate a la instancia
mysql-client
a través de SSH.En tu shell, consulta la tabla que creaste con anterioridad:
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"
El resultado debe incluir 10 registros con el siguiente formato, que verifiquen la coherencia de los datos en el clúster:
+----+---------------------+------------+ | 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 | +----+---------------------+------------+
Secuencia de conmutación por error
Si el nodo principal del clúster falla, la secuencia de conmutación por error se verá de la siguiente manera:
- El dispositivo de quórum y el nodo en espera pierden conectividad con el nodo principal.
- El dispositivo de quórum vota por el nodo en espera y el nodo en espera vota por sí mismo.
- El nodo en espera adquiere el quórum.
- El nodo en espera cambia a principal.
- El nodo principal nuevo realiza lo siguiente:
- Asciende DRBD a principal
- Activa el disco de datos de MySQL desde DRBD
- Inicia MySQL
- Adquiere buen estado para el balanceador de cargas
- El balanceador de cargas comienza a enviar tráfico al nodo principal nuevo.
Realiza una limpieza
Borra el proyecto
- 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.
¿Qué sigue?
- Obtén más información sobre DRBD.
- Obtén más información sobre Pacemaker.
- Obtén más información sobre Corosync Cluster Engine.
- Para obtener una configuración más avanzada del servidor MySQL 5.6, consulta el manual de administración del servidor MySQL.
- Si deseas configurar el acceso remoto a MySQL, consulta Cómo configurar el acceso remoto a MySQL en Compute Engine.
- Para obtener más información acerca de MySQL, consulta la documentación oficial de MySQL.
- Explora arquitecturas de referencia, diagramas y prácticas recomendadas sobre Google Cloud. Consulta nuestro Cloud Architecture Center.