Implementación de referencia de la base de datos de MySQL en GDC aislado

En esta guía, se proporciona un instructivo integral paso a paso para implementar un clúster de MySQL 8.4 InnoDB con alta disponibilidad en tres zonas de disponibilidad en un entorno aislado de Google Distributed Cloud (GDC). Esta arquitectura aprovecha la replicación de grupo para el consenso basado en Paxos, el router de MySQL para el enrutamiento inteligente de conexiones y MySQL Shell para la organización de clústeres.

Si se usan estrictamente máquinas virtuales (VMs), esta implementación evita las limitaciones de GDC aislado en relación con los clústeres extendidos de Kubernetes entre zonas, lo que garantiza una resiliencia multizona completa sin riesgo de pérdida de datos.

Este es el diagrama de arquitectura:

Arquitectura de tres VMs que ejecuta una pila de servicios coubicados.

Antes de comenzar

Implementa VMs

Sigue los pasos que se indican en Crea y, luego, inicia una instancia de VM para crear tres VMs en las tres zonas disponibles.

Configura tu entorno local para establecer una conexión SSH a las VMs con un par de claves: Conéctate a una VM

Esto es necesario para usar la copia segura (SCP) y transferir los paquetes: Transfiere archivos

Para la verificación, usamos el SO Ubuntu 22.04 y el tipo de máquina n3-standard-2-gdc. Para un entorno de producción, usa un tipo de máquina con más recursos.

Obtén las IP de las VMs con el siguiente comando:

VM_NAME=$1

if [[ -z "$VM_NAME" ]]; then
  echo "Error: VM_NAME must be provided."
  echo "Usage: $0 <VM_NAME>"
  exit 1
fi

# 1. Get External IP from 'instances list'
EXT_IP=$(gdcloud compute instances list | awk -v vm="${VM_NAME}" '$1 == vm {print $5}')

if [[ -z "$EXT_IP" ]]; then
  echo "Error: Could not find VM '${VM_NAME}' in the instance list."
  exit 1
fi

INTERNAL_IP=$(gdcloud compute instances describe "${VM_NAME}" | awk '/^status:/ {in_status=1} in_status && /- [0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/ {print $2; exit}' | cut -d'/' -f1)

if [[ -z "$INTERNAL_IP" ]]; then
  INTERNAL_IP="<Not assigned or not found>"
fi

echo "${VM_NAME}"
echo "External IP: ${EXT_IP}"
echo "Internal IP: ${INTERNAL_IP}"

Configure las variables de entorno

Establece estas variables en la sesión de shell de tu estación de trabajo local:

export PROJECT_ID="your-project-id"
export VM1_NAME="mysql-node-1"
export VM2_NAME="mysql-node-2"
export VM3_NAME="mysql-node-3"
export VM1_IP="10.0.1.245" # Zone 1
export VM2_IP="10.0.1.241" # Zone 2
export VM3_IP="10.0.1.242" # Zone 3
export CLUSTER_NAME="mysql-ha-cluster"

Configuración de red

En caso de que necesites acceder a la base de datos fuera del proyecto o de la organización, recuerda configurar la PNP (política de red del proyecto) según corresponda.

Sigue las secciones de Descripción general de PNP según el caso de uso.

Preparación del software aislado

Descarga paquetes con Docker

Ejecuta lo siguiente desde una estación de trabajo conectada para recuperar los componentes de MySQL 8.4 y Shell:

mkdir -p ./mysql-packages
docker run --rm -v "$(pwd)/mysql-packages:/packages" ubuntu:22.04 bash -c "
  apt-get update && apt-get install -y curl gnupg apt-rdepends wget lsb-release
  curl -LsS https://dev.mysql.com/get/mysql-apt-config_0.8.39-1_all.deb -o config.deb
  # Configure for MySQL 8.4 LTS
  DEBIAN_FRONTEND=noninteractive dpkg -i config.deb 
  apt-get update
  cd /packages
  PACKAGES='mysql-server mysql-shell mysql-router'
  apt-get download \$(apt-cache depends --recurse --no-recommends --no-suggests --no-conflicts --no-breaks --no-replaces --no-enhances --no-pre-depends \${PACKAGES} | grep '^\w')
"

Transfiere e instala

Sube los archivos .deb a /tmp/packages/ en las tres VMs y, luego, instálalos:

# From workstation: scp ./mysql-packages/*.deb ${VM_IP}:/tmp/packages/
# On each VM:
sudo dpkg -i /tmp/packages/*.deb

Asegúrate de que el dpkg no devuelva errores. Si es así, revisa los registros para ver qué paquetes deb podrían faltar y, luego, inclúyelos en la descarga.

Cuando se te solicite que establezcas la contraseña raíz, déjala en blanco. Estableceremos la contraseña más adelante.

Configuración de nodos de MySQL

Configura MySQL para el uso del clúster

Edita /etc/mysql/mysql.conf.d/mysqld.cnf en todos los nodos para habilitar los GTID y el registro binario:

[mysqld]
bind-address = 0.0.0.0
server-id = 1 # Use 2 and 3 for other VMs
gtid-mode = ON
enforce-gtid-consistency = ON
binlog-format = ROW
log-bin = mysql-bin
report_host = 10.0.1.245 # Use the VM's specific IP

Reinicia el servicio:

sudo systemctl restart mysql

Luego, conéctate a la base de datos:

sudo mysql

y establece la contraseña raíz:

CREATE USER 'root'@'%' IDENTIFIED WITH 'caching_sha2_password' BY 'your_new_secure_password';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;

Inicialización y verificación del clúster de InnoDB

Crea un clúster con MySQL Shell

SOLO en la VM 1, usa MySQL Shell para inicializar el clúster:

mysqlsh --uri root@localhost
# Inside MySQL Shell:
\js
dba.configureInstance('root@VM1_IP')
var cluster = dba.createCluster('mysql-ha-cluster')
cluster.addInstance('root@VM2_IP')
cluster.addInstance('root@VM3_IP')
cluster.status()

Inicia MySQL Router

En las tres VMs, inicia el router para detectar el clúster nuevo:

sudo mysqlrouter --bootstrap root@VM1_IP --user=mysqlrouter
sudo systemctl restart mysqlrouter
sudo systemctl enable mysqlrouter

Verifica el balanceo y las conexiones

Ejecuta estos comandos desde cualquier nodo para asegurarte de que el router distribuya el tráfico de forma correcta.

  1. Verifica el enrutamiento de escritura (principal activo): Consulta el puerto 6446 (RW clásico). Debe devolver estrictamente el nombre de host de la instancia principal actual.

    mysql -u root -pyour_new_secure_password -h 127.0.0.1 -P 6446 -e "SELECT @@hostname;"
    
  2. Verifica el balanceo de lectura (Round-Robin): Consulta el puerto 6447 (RO clásico) varias veces. Debería recorrer los nombres de host de todos los nodos disponibles en el clúster.

    for i in {1..4}; do mysql -u root -pyour_new_secure_password -h 127.0.0.1 -P 6447 -e "SELECT @@hostname;"; done
    
  3. Verifica la topología de conexión: Usa MySQL Shell para confirmar que todos los miembros estén ONLINE y balanceados correctamente.

    mysqlsh --uri root@localhost --cluster
    
    # inside the shell
    > cluster.status()
    

Configuración del balanceador de cargas global

Proporciona una sola IP virtual (VIP) estable para tus aplicaciones con el balanceador de cargas L4 global de GDC. Sigue las instrucciones para configurar balanceadores de cargas globales internos y configurar el balanceador de cargas L4 global interno y tus VMs para que sean el destino de este: Configura VMs como destino del balanceador de cargas.

Verificación de conmutación por error automatizada

Esta prueba confirma que el clúster elige un líder nuevo y que el router redirecciona el tráfico sin intervención manual.

Simula una falla principal

Identifica la instancia principal actual (p.ej., el nodo 1) y detén el servicio de MySQL:

sudo systemctl stop mysql

Verifica la elección y el cambio de enrutamiento

Espera entre 10 y 20 segundos para que el protocolo de consenso elija un líder nuevo.

  1. Verifica el estado del clúster: Desde la VM 2 o 3, verifica que se haya elegido una nueva instancia principal.

    mysqlsh --uri root@localhost --cluster
    
    # inside the shell
    > cluster.status()
    

    Confirma que uno de los nodos restantes esté marcado como PRIMARY y que el nodo con errores esté marcado como UNREACHABLE o MISSING.

  2. Verifica el enrutamiento de escritura: Vuelve a probar el puerto de RW (6446). Ahora debería devolver el nombre de host de la nueva instancia principal.

    mysql -u root -p -h 127.0.0.1 -P 6446 -e "SELECT @@hostname;"
    
  3. Prueba la conectividad de la VIP global: Desde un servidor de aplicaciones, consulta la VIP global.

    mysql -u root -p -h ${LB_IP} -P 3306 -e "SELECT @@hostname;"
    

Recupera y verifica la reincorporación

Inicia el servicio de MySQL en el nodo con errores y verifica que se vuelva a unir como una réplica secundaria.

sudo systemctl start mysql
mysqlsh --uri root@localhost --cluster -e "cluster.status()"

Confirma que los tres nodos devuelvan el estado ONLINE.