Configura una instancia de clúster de conmutación por error de SQL Server en Linux con un disco de varios escritores

Para lograr una alta disponibilidad de SQL Server en dos zonas distintas de Compute Engine, puedes implementar una instancia de clústeres de conmutación por error (FCI) de SQL Server en Linux que use discos de multiescritura. A diferencia de las arquitecturas tradicionales sin recursos compartidos, esta configuración te permite conectar nodos en diferentes zonas al mismo disco de forma simultánea. En esta guía, se describe cómo implementar un FCI de SQL Server con alta disponibilidad en Linux en Compute Engine con la replicación síncrona de baja latencia de Google Cloud Hyperdisk.

Este diseño garantiza que SQL Server siga disponible incluso en el improbable caso de una interrupción zonal. La combinación de Pacemaker para la organización del clúster con la resiliencia entre zonas de Compute Engine proporciona una solución sólida y de alto rendimiento para las cargas de trabajo de bases de datos esenciales que requieren la simplicidad del almacenamiento compartido.

Beneficios de implementar la alta disponibilidad con discos de multiescritura

Usar una FCI de SQL Server con discos de multiescritura en lugar de grupos de disponibilidad (AG) Always On en Linux elimina la complejidad de administrar varias copias de datos y la sobrecarga de sincronización que generan las configuraciones de AG.

Una arquitectura de volúmenes compartidos también es más eficiente en el almacenamiento en comparación con las arquitecturas de AG que usan réplicas de datos completas en cada nodo. Los volúmenes compartidos también pueden reducir los costos de disco en situaciones de duplicación.

Aspectos destacados de esta arquitectura

  • Redundancia zonal: Protección de datos en el caso poco frecuente de una falla de nodo o una interrupción zonal.
  • Administración simplificada: Reduce la complejidad de administrar varias copias de datos en comparación con los grupos de disponibilidad Always On.
  • Eficiencia de almacenamiento: Utiliza un solo volumen compartido para los datos y los registros, optimizado con la capacidad de varios escritores.
  • Organización nativa de Linux: Utiliza extensiones de alta disponibilidad (HAE) estándares de la industria para una conmutación por error sin problemas.

En un entorno local, puedes permitir que WSFC realice anuncios ARP si se produce una conmutación por error para notificar al equipo de red sobre un cambio en la dirección IP. Sin embargo,Cloud de Confianceignora los anuncios de ARP. Por lo tanto, debes implementar un balanceador de cargas interno (consulta Ejecuta los clústeres de conmutación por error de Windows Server)

Arquitectura

En el artículo, se supone que tienes conocimientos básicos de SQL Server, Active Directory y Compute Engine.

Objetivos

En este instructivo, se muestra cómo completar las siguientes tareas para alcanzar tu objetivo:

  • Crea una implementación de SQL Server en Linux.
  • Crea, conecta y configura un disco de multiescritura.
  • Configura el clúster de Pacemaker.
  • Configura el balanceador de cargas.
  • Realiza una prueba de conmutación por error.

Costos

En este instructivo, se usan los siguientes componentes facturables de Cloud de Confiance by S3NS:

Usa la calculadora de precios para generar una estimación de los costos según el uso previsto.

Antes de comenzar

  1. Para este instructivo, necesitas un proyecto Cloud de Confiance . Puedes crear uno nuevo o seleccionar un proyecto que ya hayas creado:

    1. En la consola de Cloud de Confiance , en la página del selector de proyectos, selecciona o crea un proyecto de Cloud de Confiance .

      Roles necesarios para seleccionar o crear un proyecto

      • Selecciona un proyecto: Para seleccionar un proyecto, no se requiere un rol de IAM específico. Puedes seleccionar cualquier proyecto en el que se te haya otorgado un rol.
      • Crear un proyecto: Para crear un proyecto, necesitas el rol de Creador de proyectos (roles/resourcemanager.projectCreator), que contiene el permiso resourcemanager.projects.create. Obtén más información para otorgar roles.

      Ir al selector de proyectos

    2. Verifica que la facturación esté habilitada para tu proyecto de Cloud de Confiance .

    3. En la consola de Cloud de Confiance , activa Cloud Shell.

      Activa Cloud Shell

Prepara el proyecto y la red

Para preparar tu proyecto Cloud de Confiance y la VPC para la implementación de las FCI de SQL Server, haz lo siguiente:

  1. En la Cloud de Confiance consola, haz clic en el botón Activar Cloud Shell Activar Cloud Shell. para abrir Cloud Shell.

    Ir a la consola de Cloud de Confiance

  2. Establece tu ID del proyecto predeterminado:

    gcloud config set project PROJECT_ID
    

    Reemplaza PROJECT_ID por el ID de tu Cloud de Confiance proyecto.

  3. Configura la región predeterminada:

    gcloud config set compute/region REGION
    

    Reemplaza REGION por el ID de la región en la que deseas realizar la implementación.

Crea los nodos del clúster

Implementa dos VMs como nodos de clúster y una tercera como cliente dedicado para validar la conectividad y el rendimiento de la conmutación por error.

  1. Inicializa las siguientes variables que se usarán para los comandos restantes.

    BOOT_DISK_SIZE=50
    BOOT_IOPS=10000
    BOOT_THROUGHPUT=400
    DATA_IOPS=10000
    DATA_THROUGHPUT=400
    DATA_DISK_SIZE=200
    REGION=$(gcloud config get-value compute/region)
    ZONE1=$REGION-a
    ZONE2=$REGION-b
    SUBNET=SUBNET_NAME
    MACHINE_TYPE=c3-standard-8
    VPC_NAME=VPC_NAME
    
  2. Crea dos discos regionales, uno para los datos y otro para el registro. Para permitir que ambas instancias accedan a los discos, habilita el modo de multiescritura para ambos discos con la marca --access-mode=READ_WRITE_MANY.

    gcloud compute disks create sqlfci-mw-data-disk \
    --size=$DATA_DISK_SIZE \
    --type=hyperdisk-balanced-high-availability \
    --region=$REGION \
    --replica-zones=$ZONE1,$ZONE2 \
    --provisioned-iops=$DATA_IOPS \
    --provisioned-throughput=$DATA_THROUGHPUT \
    --access-mode=READ_WRITE_MANY
    
    gcloud compute disks create sqlfci-mw-log-disk \
    --size=$DATA_DISK_SIZE \
    --type=hyperdisk-balanced-high-availability \
    --region=$REGION \
    --replica-zones=$ZONE1,$ZONE2 \
    --provisioned-iops=$DATA_IOPS \
    --provisioned-throughput=$DATA_THROUGHPUT \
    --access-mode=READ_WRITE_MANY
    
  3. Crea las VMs de Linux y conecta los discos de multiescritura que creaste.

    gcloud compute instances create node-1 \
    --boot-disk-size=$BOOT_DISK_SIZE \
    --boot-disk-type=hyperdisk-balanced \
    --boot-disk-provisioned-iops=$BOOT_IOPS \
    --boot-disk-provisioned-throughput=$BOOT_THROUGHPUT \
    --zone $ZONE1 \
    --machine-type $MACHINE_TYPE \
    --subnet $SUBNET \
    --image-family ubuntu-2204-lts \
    --image-project ubuntu-os-cloud \
    --disk="name=sqlfci-mw-data-disk,scope=regional,mode=rw" \
    --disk="name=sqlfci-mw-log-disk,scope=regional,mode=rw" \
    --scopes=compute-rw,trace,service-control,service-management,pubsub,monitoring-write,logging-write,storage-rw \
    --tags=sqlfci
    
    gcloud compute instances create node-2 \
    --boot-disk-size=$BOOT_DISK_SIZE \
    --boot-disk-type=hyperdisk-balanced \
    --boot-disk-provisioned-iops=$BOOT_IOPS \
    --boot-disk-provisioned-throughput=$BOOT_THROUGHPUT \
    --zone $ZONE2 \
    --machine-type $MACHINE_TYPE \
    --subnet $SUBNET \
    --image-family ubuntu-2204-lts \
    --image-project ubuntu-os-cloud \
    --disk="name=sqlfci-mw-data-disk,scope=regional,mode=rw" \
    --disk="name=sqlfci-mw-log-disk,scope=regional,mode=rw" \
    --scopes=compute-rw,trace,service-control,service-management,pubsub,monitoring-write,logging-write,storage-rw \
    --tags=sqlfci
    
  4. Crea la VM de cliente de Windows, cl-node, que usarás para probar la conexión.

    gcloud compute instances create cl-node \
    --boot-disk-size=100 \
    --boot-disk-type=hyperdisk-balanced \
    --machine-type $MACHINE_TYPE \
    --image-family windows-2025 \
    --image-project windows-cloud \
    --zone $ZONE1 \
    --subnet $SUBNET \
    --scopes=compute-rw,trace,service-control,service-management,pubsub,monitoring-write,logging-write,storage-rw
    

Crea un balanceador de cargas interno

  1. Reserva una dirección IP para el clúster y el balanceador de cargas.

    gcloud compute addresses create sqlfci-lb-ipaddress \
    --region=$REGION \
    --subnet=$SUBNET \
    --purpose="SHARED_LOADBALANCER_VIP"
    CLUSTER_ADDRESS=$(gcloud compute addresses describe sqlfci-lb-ipaddress \
    --region $REGION \
    --format=value\(address\)) && \
    echo "Cluster IP address: $CLUSTER_ADDRESS"
    
  2. Crea una verificación de estado para el clúster.

    gcloud compute health-checks create tcp sqlfci-healthcheck \
    --port="60008" \
    --region=$REGION \
    --check-interval=3 \
    --timeout=2 \
    --unhealthy-threshold=2 \
    --healthy-threshold=5
    
  3. Para permitir una conexión al puerto de verificación de estado, crea una regla de firewall.

    gcloud compute firewall-rules create "allow-sqlfci-healthcheck-60008" \
    --allow "tcp:60008" \
    --target-tags sqlfci \
    --network $VPC_NAME \
    --source-ranges="35.191.0.0/16,130.211.0.0/22" \
    --priority="1000"
    

    SI quieres obtener más información, consulta las Reglas de firewall para las verificaciones de estado.

  4. Crea grupos de instancias para los nodos del clúster.

    gcloud compute instance-groups unmanaged create sqlfci-1-uig \
    --zone=$ZONE1
    gcloud compute instance-groups unmanaged add-instances sqlfci-1-uig \
    --zone=$ZONE1 \
    --instances=node-1
    
    gcloud compute instance-groups unmanaged create sqlfci-2-uig \
    --zone=$ZONE2
    gcloud compute instance-groups unmanaged add-instances sqlfci-2-uig \
    --zone=$ZONE2 \
    --instances=node-2
    
  5. Crea el servicio de backend del balanceador de cargas.

    gcloud compute backend-services create sqlfci-backend-services \
    --region=$REGION \
    --load-balancing-scheme="INTERNAL" \
    --protocol="TCP" \
    --health-checks=sqlfci-healthcheck \
    --health-checks-region=$REGION
    
    gcloud compute backend-services add-backend sqlfci-backend-services \
    --region=$REGION \
    --instance-group=sqlfci-1-uig \
    --instance-group-zone=$ZONE1
    
    gcloud compute backend-services add-backend sqlfci-backend-services \
    --region=$REGION \
    --instance-group=sqlfci-2-uig \
    --instance-group-zone=$ZONE2
    
  6. Crea la regla de reenvío del balanceador de cargas.

    gcloud compute forwarding-rules create "sqlfci-forwarding-rule" \
    --load-balancing-scheme=INTERNAL \
    --network=$VPC_NAME \
    --subnet=$SUBNET \
    --region=$REGION \
    --address=$CLUSTER_ADDRESS \
    --ip-protocol="TCP" \
    --ports="ALL" \
    --backend-service=sqlfci-backend-services \
    --backend-service-region=$REGION
    
  7. Crea un bucket de Cloud Storage para transferir archivos de los nodos del clúster principal a los secundarios.

    gcloud storage buckets create gs://BUCKET_NAME \
    --location=$REGION \
    --public-access-prevention
    

    Reemplaza BUCKET_NAME por el nombre del bucket que deseas crear.

    Para obtener más información, consulta Crea buckets.

Instala el software necesario

Descarga, instala y configura el motor de SQL Server y la administración de clústeres en las dos VMs de Linux, node-1 y node-2, que participarán en el clúster de conmutación por error.

  1. Conéctate a cada una de tus VMs con SSH. Para obtener más información, consulta Conéctate a VMs de Linux y Prácticas recomendadas para controlar el acceso de red con SSH.

  2. Actualiza hosts file en node-1 y node-2.

    1. Abre hosts file para editarlo.

      sudo vi /etc/hosts
      
    2. Busca la dirección IP interna de cada VM de Linux y agrega las entradas del host en la parte inferior del archivo.

      Ir a Compute Engine

      NODE1_INTERNAL_IP node-1
      NODE2_INTERNAL_IP node-2
      

      Reemplaza NODE1_INTERNAL_IP y NODE2_INTERNAL_IP por la dirección IP interna de cada VM de Linux.

  3. Verifica la comunicación entre tus VMs. Todas las VMs que participan en el grupo de disponibilidad Always On deben poder comunicarse con otras VMs: Regresa a cada VM de Linux, ejecuta los comandos desde cada una y verifica que todas las VMs puedan comunicarse entre sí.

    ping -c 4 node-1
    ping -c 4 node-2
    

    El resultado es similar al que se muestra a continuación:

    PING node-1 (10.128.0.37) 56(84) bytes of data.
    64 bytes from node-1 (10.128.0.37): icmp_seq=1 ttl=128 time=1.91 ms
    64 bytes from node-1 (10.128.0.37): icmp_seq=2 ttl=128 time=0.234 ms
    64 bytes from node-1 (10.128.0.37): icmp_seq=3 ttl=128 time=0.249 ms
    64 bytes from node-1 (10.128.0.37): icmp_seq=4 ttl=128 time=0.263 ms
    
  4. Instala SQL Server 2025.

    1. Agrega el repositorio de SQL Server al sistema.

      curl https://packages.microsoft.com/keys/microsoft.asc | sudo tee /etc/apt/trusted.gpg.d/microsoft.asc
      curl -fsSL https://packages.microsoft.com/config/ubuntu/22.04/mssql-server-2025.list | sudo tee /etc/apt/sources.list.d/mssql-server-2025.list
      sudo apt-get update
      
    2. Instala SQL Server.

      sudo apt-get install -y mssql-server
      
    3. Instala las herramientas para desarrolladores de SQL Server. Descarga e instala las herramientas de SQL Server en las dos VMs de Linux que participarán en el clúster de conmutación por error.

      curl https://packages.microsoft.com/config/ubuntu/22.04/prod.list | sudo tee /etc/apt/sources.list.d/mssql-release.list
      sudo apt-get update
      
      sudo ACCEPT_EULA=Y apt-get install -y mssql-tools18 unixodbc-dev
      
  5. Instala Pacemaker. Pacemaker es un software de administrador de recursos de alta disponibilidad de código abierto que se usa con el motor del clúster de Corosync. En esta sección, instalarás Pacemaker en ambas VMs del clúster.

    1. Instala Pacemaker en node-1 y node-2.

      sudo apt-get install -y pacemaker pcs fence-agents resource-agents pacemaker-cli-utils crmsh
      
    2. Instala el agente de recursos de SQL Server para Pacemaker.

      sudo apt-get install -y mssql-server-ha
      
  6. Si tienes un firewall habilitado en tus VMs, ábrelo para SQL Server.

    1. Ejecuta el siguiente comando para verificar si Uncomplicated Firewall está instalado y habilitado.

      sudo ufw status
      
    2. Si el estado está activo, ejecuta los siguientes comandos para abrir los puertos. Si el servicio de firewall no se está ejecutando, puedes ignorar este paso.

      sudo ufw allow 1433
      sudo ufw allow 5022
      sudo ufw reload
      

Configura el nodo de la base de datos principal

En esta sección, inicializarás los dos discos de multiescritura y configurarás cada disco con grupos de volúmenes y grupos lógicos.

Configura el LVM.

Configura los parámetros del LVM.

  1. Crea una copia de seguridad de la configuración existente.

    sudo cp /etc/lvm/lvm.conf /etc/lvm/lvm.conf.bak
    
  2. Actualiza la fuente del ID del sistema:

    sudo sed -i 's/^\(\s*system_id_source\s*=\s*\)"none"/\1"uname"/' /etc/lvm/lvm.conf
    
  3. Verifica que el cambio se haya realizado correctamente.

    grep 'system_id_source *= *"uname"' /etc/lvm/lvm.conf
    
  4. Configura los grupos de volúmenes y los volúmenes lógicos de LVM.

    sudo pvcreate /dev/nvme0n2 /dev/nvme0n3
    sudo pvs
    sudo vgcreate vgdata /dev/nvme0n2
    sudo lvcreate -l 100%FREE -n lvdata vgdata
    sudo vgcreate vglogtmp /dev/nvme0n3
    sudo lvcreate -l 70%FREE  -n lvlog vglogtmp
    sudo lvcreate -l 100%FREE -n lvtmp vglogtmp
    sudo vgs -o+systemid
    
  5. Formatea volúmenes con el sistema de archivos xfs y un tamaño de bloque de 64 KB.

    sudo mkfs.xfs -d su=64k,sw=1 -L data /dev/vgdata/lvdata -f
    sudo mkfs.xfs -d su=64k,sw=1 -L dblog /dev/vglogtmp/lvlog -f
    sudo mkfs.xfs -d su=64k,sw=1 -L tmp /dev/vglogtmp/lvtmp -f
    
  6. Verifica que se hayan creado los volúmenes.

    sudo lvs
    

Activa y formatea los discos

Configura los puntos de montaje para los discos compartidos y otorga acceso al usuario mssql.

  1. Crea puntos de activación para los volúmenes nuevos.

    sudo mkdir /mssql
    sudo mkdir -p /mssql/db_data
    sudo mkdir -p /mssql/db_log
    sudo mkdir -p /mssql/db_temp
    
  2. Activa los volúmenes de LVM en los puntos de activación.

    sudo mount /dev/vgdata/lvdata /mssql/db_data
    sudo mount /dev/vglogtmp/lvlog /mssql/db_log
    sudo mount /dev/vglogtmp/lvtmp /mssql/db_temp
    
  3. Establece el usuario mssql como propietario de los puntos de montaje.

    sudo chown mssql:mssql /mssql/db_data
    sudo chown mssql:mssql /mssql/db_log
    sudo chown mssql:mssql /mssql/db_temp
    
  4. Configura SQL Server:

    1. Establece variables que reubiquen la base de datos principal en el almacenamiento compartido y ejecuta la herramienta mssql-conf.

      sudo MSSQL_MASTER_DATA_FILE="/mssql/db_data/master.mdf" MSSQL_MASTER_LOG_FILE="/mssql/db_data/mastlog.ldf" /opt/mssql/bin/mssql-conf setup
      
    2. Elige la edición Desarrollador para la edición SQL Server y acepta el contrato de licencia.

      La edición para desarrolladores tiene todas las funciones empresariales incluidas, pero solo puedes usarla en entornos que no son de producción. Hay más información disponible sobre las ediciones de SQL Server y las licencias de Microsoft.

    3. Especifica una contraseña para la cuenta AS.

    4. Verifica que el servicio mssql-server esté en ejecución:

      systemctl status mssql-server --no-pager
      

Configura SQL Server y Pacemaker

  1. Crea un usuario de SQL Server para Pacemaker. Reemplaza SA_PASSWORD por la contraseña de la cuenta de AS en SQL Server y PA_PASSWORD por la contraseña que se usará para la cuenta de pacemaker.

    QUERY="
    CREATE LOGIN [pacemaker] with PASSWORD= N'PA_PASSWORD';
    ALTER SERVER ROLE [sysadmin] ADD MEMBER [pacemaker];
    GO"
    
    /opt/mssql-tools18/bin/sqlcmd -No -S localhost -U sa -P 'SA_PASSWORD' -Q "$QUERY"
    
  2. Agrega el acceso y la contraseña de Pacemaker a la carpeta de secretos de SQL Server.

    {
      echo 'pacemaker'
      echo PA_PASSWORD'
    } | sudo tee /var/opt/mssql/secrets/passwd > /dev/null
    sudo chown root:root /var/opt/mssql/secrets/passwd
    sudo chmod 400 /var/opt/mssql/secrets/passwd
    
  3. Actualiza la configuración de SQL Server para usar las nuevas ubicaciones de datos, registros y temporales. También establecerás la configuración recomendada de SQL Server.

    sudo /opt/mssql/bin/mssql-conf set filelocation.defaultdatadir /mssql/db_data
    sudo /opt/mssql/bin/mssql-conf set filelocation.defaultlogdir /mssql/db_log
    sudo /opt/mssql/bin/mssql-conf set filelocation.defaultdumpdir /mssql/db_log
    sudo /opt/mssql/bin/mssql-conf traceflag 9944 3979 on
    sudo /opt/mssql/bin/mssql-conf set control.alternatewritethrough 0
    sudo /opt/mssql/bin/mssql-conf set control.writethrough 1
    

Mueve TempDB a un disco compartido

  1. Obtén la lista de archivos TempDB y úsalos para crear la consulta Alter. Esta consulta se usará en el siguiente paso para establecer la nueva ubicación de los archivos de TempDB.

    QUERY="
    SET NOCOUNT ON;
    SELECT 'ALTER DATABASE tempdb MODIFY FILE (NAME = [' + f.name + '],' + ' FILENAME = ''/mssql/db_temp/' + f.name + CASE WHEN f.type = 1 THEN '.ldf' ELSE '.mdf' END + ''');' FROM sys.master_files f WHERE f.database_id = DB_ID(N'tempdb');"
    
    /opt/mssql-tools18/bin/sqlcmd -No -S localhost -U sa -P 'SA_PASSWORD' -Q "$QUERY"
    
  2. Captura el resultado del comando anterior. Usarás el resultado para formar el siguiente comando que se ejecutará.

    QUERY="QUERY_OUTPUT"
    

    Ejemplo de consulta con el resultado:

    QUERY="
    ALTER DATABASE tempdb MODIFY FILE (NAME = [tempdev], FILENAME = '/mssql/db_temp/tempdev.mdf');
    ALTER DATABASE tempdb MODIFY FILE (NAME = [templog], FILENAME = '/mssql/db_temp/templog.ldf');
    ALTER DATABASE tempdb MODIFY FILE (NAME = [tempdev2], FILENAME = '/mssql/db_temp/tempdev2.mdf');
    ALTER DATABASE tempdb MODIFY FILE (NAME = [tempdev3], FILENAME = '/mssql/db_temp/tempdev3.mdf');"
    

  3. Ejecuta el comando SQL generado para mover los archivos TempDB.

    /opt/mssql-tools18/bin/sqlcmd -No -S localhost -U sa -P 'SA_PASSWORD' -Q "$QUERY"
    
  4. Reinicia el servicio de SQL Server para que se apliquen los cambios.

    sudo systemctl restart mssql-server.service
    
  5. Verifica que se hayan creado los archivos de TempDB.

    ls -l /mssql/db_temp/
    
  6. Verifica que el servicio de SQL Server esté en ejecución.

    systemctl status mssql-server --no-pager
    

Configura HAProxy

  1. Establece una contraseña nueva para hacluster.

    sudo passwd hacluster
    
  2. Para completar la configuración y probar si el balanceador de cargas de red está configurado de forma correcta, instala y configura HAProxy tcp listener en ambos nodos del clúster:

    1. Instala HAProxy.

      sudo apt-get install haproxy
      
    2. Escribe Y para completar la instalación.

    3. Edita el archivo haproxy.cfg.

      sudo vi /etc/haproxy/haproxy.cfg
      
    4. En la sección defaults de haproxy.cfg file, cambia el modo a tcp.

    5. Agrega la siguiente sección al final del archivo haproxy.cfg.

      #---------------------------------------------------------------
      # Set up health check listener for SQL Server Availability Group
      #---------------------------------------------------------------
      listen healthcheck
      bind *:60008
      
  3. Inicia el servicio de HAProxy.

    sudo systemctl start haproxy.service
    sudo systemctl status haproxy.service
    
  4. Detén y deshabilita el servicio de HAProxy.

    sudo systemctl stop haproxy.service
    sudo systemctl disable haproxy.service
    
  5. Sube el archivo de clave de la máquina a Cloud Storage con el siguiente comando.

    sudo gcloud storage cp /var/opt/mssql/secrets/machine-key gs://BUCKET_NAME/
    

    Reemplaza BUCKET_NAME por el nombre del bucket creado.

  6. Detén y deshabilita el servicio de SQL Server. El servicio desde este punto será controlado por el clúster.

    sudo systemctl stop mssql-server.service
    sudo systemctl disable mssql-server.service
    
  7. Desactiva el almacenamiento compartido.

    sudo umount /mssql/db_data
    sudo umount /mssql/db_log
    sudo umount /mssql/db_temp
    
  8. Limpia la configuración predeterminada existente del clúster.

    sudo pcs cluster destroy
    

Configura el nodo secundario

  1. Crea puntos de activación para los volúmenes de LVM. No es necesario que formatees el disco, ya que se comparte con node-1. Ya formateaste el disco y configuraste los volúmenes de LVM cuando configuraste node-1.

    sudo mkdir /mssql
    sudo mkdir -p /mssql/db_data
    sudo mkdir -p /mssql/db_log
    sudo mkdir -p /mssql/db_temp
    
    sudo chown mssql:mssql /mssql/db_data
    sudo chown mssql:mssql /mssql/db_log
    sudo chown mssql:mssql /mssql/db_temp
    
  2. Configura SQL Server.

    1. Para reubicar la base de datos principal en el disco de datos compartido, configura las siguientes variables y, luego, ejecuta la herramienta mssql-conf para aplicar los cambios.

      sudo MSSQL_MASTER_DATA_FILE="/mssql/db_data/master.mdf" MSSQL_MASTER_LOG_FILE="/mssql/db_data/mastlog.ldf" /opt/mssql/bin/mssql-conf setup
      
    2. Elige la edición Desarrollador para la edición SQL Server y acepta el contrato de licencia.

      La edición para desarrolladores tiene todas las funciones empresariales incluidas, pero solo puedes usarla en entornos que no son de producción. Hay más información disponible sobre las ediciones de SQL Server y las licencias de Microsoft.

    3. Especifica una contraseña para la cuenta AS.

    4. Verifica que el servicio mssql-server esté en ejecución:

      systemctl status mssql-server --no-pager
      
  3. Crea un usuario de SQL Server para el clúster de Pacemaker. Reemplaza SA_PASSWORD por la contraseña de la cuenta de AS en SQL Server y PA_PASSWORD por la contraseña que se usará para la cuenta de pacemaker.

    QUERY="
    CREATE LOGIN [pacemaker] with PASSWORD= N'PA_PASSWORD';
    ALTER SERVER ROLE [sysadmin] ADD MEMBER [pacemaker];
    GO"
    
    /opt/mssql-tools18/bin/sqlcmd -No -S localhost -U sa -P 'SA_PASSWORD' -Q "$QUERY"
    
  4. Agrega el acceso y la contraseña de Pacemaker a la carpeta de secretos de SQL Server.

    {
      echo 'pacemaker'
      echo 'PA_PASSWORD'
    } | sudo tee /var/opt/mssql/secrets/passwd > /dev/null
    sudo chown root:root /var/opt/mssql/secrets/passwd
    sudo chmod 400 /var/opt/mssql/secrets/passwd
    
  5. Actualiza la configuración de SQL Server para usar las nuevas ubicaciones de datos, registros y temporales. También establecerás la configuración recomendada de SQL Server.

    sudo /opt/mssql/bin/mssql-conf set filelocation.defaultdatadir /mssql/db_data
    sudo /opt/mssql/bin/mssql-conf set filelocation.defaultlogdir /mssql/db_log
    sudo /opt/mssql/bin/mssql-conf set filelocation.defaultdumpdir /mssql/db_log
    sudo /opt/mssql/bin/mssql-conf traceflag 9944 3979 on
    sudo /opt/mssql/bin/mssql-conf set control.alternatewritethrough 0
    sudo /opt/mssql/bin/mssql-conf set control.writethrough 1
    
  6. Mueve TempDB al disco de datos compartido.

    1. Obtén la lista de archivos TempDB y úsala para crear la consulta Alter.

      QUERY="
      SET NOCOUNT ON;
      SELECT 'ALTER DATABASE tempdb MODIFY FILE (NAME = [' + f.name + '],' + ' FILENAME = ''/mssql/db_temp/' + f.name + CASE WHEN f.type = 1 THEN '.ldf' ELSE '.mdf' END + ''');' FROM sys.master_files f WHERE f.database_id = DB_ID(N'tempdb');"
      
      /opt/mssql-tools18/bin/sqlcmd -No -S localhost -U sa -P 'SA_PASSWORD' -Q "$QUERY"
      
    2. Captura el resultado del comando anterior. Usarás el resultado para formar el siguiente comando que se ejecutará.

      QUERY="QUERY_OUTPUT"
      

      Ejemplo de consulta con el resultado:

      QUERY="
      ALTER DATABASE tempdb MODIFY FILE (NAME = [tempdev], FILENAME = '/mssql/db_temp/tempdev.mdf');
      ALTER DATABASE tempdb MODIFY FILE (NAME = [templog], FILENAME = '/mssql/db_temp/templog.ldf');
      ALTER DATABASE tempdb MODIFY FILE (NAME = [tempdev2], FILENAME = '/mssql/db_temp/tempdev2.mdf');
      ALTER DATABASE tempdb MODIFY FILE (NAME = [tempdev3], FILENAME = '/mssql/db_temp/tempdev3.mdf');"
      
    3. Para mover los archivos TempDB, ejecuta el comando SQL generado.

      /opt/mssql-tools18/bin/sqlcmd -No -S localhost -U sa -P 'SA_PASSWORD' -Q "$QUERY"
      
    4. Para que los cambios surtan efecto, reinicia el servicio de SQL Server.

      sudo systemctl restart mssql-server.service
      
    5. Verifica que el servicio de SQL Server esté en ejecución.

      sudo systemctl status mssql-server --no-pager
      
    6. Verifica que se hayan creado los archivos de TempDB.

      ls -l /mssql/db_temp/
      
  7. Detén y deshabilita temporalmente el servicio de SQL Server.

    sudo systemctl stop mssql-server.service
    sudo systemctl disable mssql-server.service
    
  8. Para asegurarte de que ambos nodos usen la misma clave para SQL Server, descarga el archivo de clave de la máquina desde node-1.

    sudo rm /var/opt/mssql/secrets/machine-key
    sudo gcloud storage cp gs://BUCKET_NAME/machine-key /var/opt/mssql/secrets/machine-key
    sudo chown mssql:mssql /var/opt/mssql/secrets/machine-key
    sudo chmod 0600  /var/opt/mssql/secrets/machine-key
    
  9. Establece la configuración de LVM.

    1. Crea una copia de seguridad de la configuración existente.

      sudo cp /etc/lvm/lvm.conf /etc/lvm/lvm.conf.bak
      
    2. Actualiza la fuente del ID del sistema.

      sudo sed -i 's/^\(\s*system_id_source\s*=\s*\)"none"/\1"uname"/' /etc/lvm/lvm.conf
      

      Ejecuta el siguiente comando para verificar el cambio:

      cat /etc/lvm/lvm.conf | grep uname
      

      El resultado es similar al que se muestra a continuación:

      #     Set the system ID from the hostname (uname) of the system.
      system_id_source = "uname"
      
    3. Verifica que el cambio se haya realizado correctamente.

      grep 'system_id_source *= *"uname"' /etc/lvm/lvm.conf
      
  10. Establece una contraseña nueva para hacluster.

    sudo passwd hacluster
    
  11. Para completar la configuración y probar si el balanceador de cargas de red está configurado de forma correcta, instala y configura HAProxy tcp listener en ambos nodos del clúster.

    1. Instala HAProxy.

      sudo apt-get install haproxy
      

    2. Elige Y para completar la instalación.

    3. Edita el archivo haproxy.cfg.

      sudo vi /etc/haproxy/haproxy.cfg
      
    4. En la sección de valores predeterminados de haproxy.cfg file, cambia el modo a tcp.

    5. Agrega la siguiente sección al final del archivo haproxy.cfg.

      #---------------------------------------------------------------
      # Set up health check listener for SQL Server Availability Group
      #---------------------------------------------------------------
      listen healthcheck
      bind *:60008
      
    6. Inicia el servicio de HAProxy.

      sudo systemctl start haproxy.service
      sudo systemctl status haproxy.service
      
  12. Detén y deshabilita el servicio de HAProxy.

    sudo systemctl stop haproxy.service
    sudo systemctl disable haproxy.service
    
  13. Borra la configuración predeterminada existente del clúster.

    sudo pcs cluster destroy
    

Complete la configuración del clúster

Vuelve a node-1 para continuar con la configuración del clúster.

  1. Autentícate como el usuario hacluster.

    sudo pcs host auth node-1 node-2 -u hacluster -p "HA_PASSWORD"
    
  2. Crea un clúster llamado ubuntu_fci.

    sudo pcs cluster setup ubuntu_fci node-1 addr="NODE1_INTERNAL_IP" node-2 addr="NODE2_INTERNAL_IP" --start --enable
    
  3. Establece la política de no quórum para un clúster de dos nodos.

    sudo pcs property set no-quorum-policy="ignore"
    
  4. Crea el recurso de clúster de dirección IP virtual.

    sudo pcs resource create pcs-cluster-vip ocf:heartbeat:IPaddr2 ip="CLUSTER_ADDRESS" cidr_netmask=32 nic=ens3 op monitor interval=30s
    

    Reemplaza CLUSTER_ADDRESS por la dirección IP que se reservó antes.

  5. Crea objetos de recursos de clúster para todos los volúmenes compartidos.

    sudo pcs resource create vgdata ocf:heartbeat:LVM-activate vgname=vgdata vg_access_mode=system_id activation_mode=exclusive
    sudo pcs resource create vglogtmp ocf:heartbeat:LVM-activate vgname=vglogtmp vg_access_mode=system_id activation_mode=exclusive
    sudo pcs resource create data_dir ocf:heartbeat:Filesystem device="/dev/mapper/vgdata-lvdata" directory="/mssql/db_data" fstype="xfs"
    sudo pcs resource create log_dir ocf:heartbeat:Filesystem device="/dev/mapper/vglogtmp-lvlog" directory="/mssql/db_log" fstype="xfs"
    sudo pcs resource create tmp_dir ocf:heartbeat:Filesystem device="/dev/mapper/vglogtmp-lvtmp" directory="/mssql/db_temp" fstype="xfs"
    
  6. Crea un grupo de recursos y agrega todos los objetos creados al grupo nuevo.

    sudo pcs resource group add sql_group pcs-cluster-vip vgdata vglogtmp data_dir log_dir tmp_dir
    
  7. Crea el recurso de clúster para el servicio de Microsoft SQL Server y agrégalo al grupo de recursos existente.

    sudo pcs resource create sql_fci ocf:mssql:fci  op stop timeout=60s --group sql_group
    
  8. Crea un recurso de clúster para HAProxy y agrégalo al mismo grupo.

    sudo pcs resource create pcs-healthcheck systemd:haproxy.service op monitor interval=20s timeout=30s --group sql_group
    
  9. Crea una restricción de clúster que controle la secuencia de inicio de los recursos.

    sudo pcs constraint order set  pcs-cluster-vip vgdata vglogtmp data_dir log_dir tmp_dir sql_fci pcs-healthcheck
    

Configura una valla STONITH

STONITH es una estrategia de protección para mantener la integridad de los nodos en un clúster de alta disponibilidad. El servicio de STONITH funciona a nivel del nodo y protege el clúster de los nodos que no responden o que se encuentran en estado desconocido. Recomendamos el dispositivo de protección fence_gce especializado para Compute Engine en Cloud de Confiance by S3NS.

Configura los dispositivos de protección

  1. Verifica si el agente de protección fence_gce para Compute Engine está instalado en node-1.

    sudo pcs stonith list | grep fence_gce
    

    Para obtener más información, consulta las secciones siguientes:

  2. Configura los recursos de protección del clúster.

    sudo pcs stonith create node-1-fence fence_gce \
    plug=node-1 \
    zone=ZONE1 \
    project=PROJECT_ID \
    pcmk_reboot_timeout=300 pcmk_monitor_retries=4 pcmk_delay_max=30 \
    op monitor interval="300s" timeout="120s" \
    op start interval="0" timeout="60s"
    
    sudo pcs stonith create node-2-fence fence_gce \
    plug=node-2 \
    zone=ZONE2 \
    project=PROJECT_ID \
    pcmk_reboot_timeout=300 pcmk_monitor_retries=4 pcmk_delay_max=30 \
    op monitor interval="300s" timeout="120s" \
    op start interval="0" timeout="60s"
    

    Reemplaza ZONE1 y ZONE2 por la zona en la que se implementan las VMs de Linux y PROJECT_ID por el ID del proyecto.

  3. Puedes probar el estado de los agentes de protección con la ejecución del comando de estado.

    sudo fence_gce -o status -n node-1 --zone=ZONE1
    sudo fence_gce -o status -n node-2 --zone=ZONE2
    

    El resultado es similar al que se muestra a continuación:

    Status: ON
    

Reemplaza ZONE1 y ZONE2 por la zona en la que se implementan las VMs de Linux.

  1. Crea restricciones de ubicación para tus dispositivos de protección y podrás asegurarte de que se ejecuten solo en las instancias previstas.

    sudo pcs constraint location node-1-fence avoids node-1
    sudo pcs constraint location node-2-fence avoids node-2
    
  2. Habilita la protección en el clúster de marcapasos y establece el tiempo de espera de la protección del clúster.

    sudo pcs -f stonith_cfg property set stonith-enabled=true
    sudo pcs property set stonith-timeout="300s"
    
  3. Se limpió el proceso de inicio del clúster.

    sudo pcs resource cleanup
    
  4. Verifica el estado del clúster.

    sudo crm status
    

    El resultado es similar al que se muestra a continuación:

      Cluster Summary:
        * Stack: corosync
        * Current DC: node-1 (version 2.1.2-ada5c3b36e2) - partition with quorum
        * Last updated: Tue Jun  2 21:36:47 2026
        * Last change:  Mon Apr 27 12:31:58 2026 by root via crm_resource on node-1
        * 2 nodes configured
        * 10 resource instances configured
    
      Node List:
        * Online: [ node-1 node-2 ]
    
      Full List of Resources:
        * Resource Group: sql_group:
          * pcs-cluster-vip   (ocf:heartbeat:IPaddr2):         Started node-2
          * vgdata    (ocf:heartbeat:LVM-activate):    Started node-2
          * vglogtmp  (ocf:heartbeat:LVM-activate):    Started node-2
          * data_dir  (ocf:heartbeat:Filesystem):      Started node-2
          * log_dir   (ocf:heartbeat:Filesystem):      Started node-2
          * tmp_dir   (ocf:heartbeat:Filesystem):      Started node-2
          * sql_fci   (ocf:mssql:fci):                 Started node-2
          * pcs-healthcheck   (systemd:haproxy.service):       Started node-2
        * node-1-fence       (stonith:fence_gce):     Started node-2
        * node2-fence        (stonith:fence_gce):     Started node-1
    

Prueba los dispositivos de protección

Después de configurar los dispositivos de protección, te recomendamos que los pruebes con los siguientes pasos.

  1. Detén la protección en node-2.

    1. Conéctate a node-1 y ejecuta el siguiente comando para probar el dispositivo de protección asociado con node-2 desde tu clúster.

      fence_gce -o off -n node-2 --zone=ZONE2
      

      El resultado es similar al que se muestra a continuación:

      Success: Powered OFF
      
    2. Verifica el estado del clúster.

      sudo crm status
      

      El resultado es similar al que se muestra a continuación:

        Cluster Summary:
          * Stack: corosync
          * Current DC: node-1 (version 2.1.2-ada5c3b36e2) - partition with quorum
          * Last updated: Tue Jun  2 21:52:00 2026
          * Last change:  Mon Apr 27 12:31:58 2026 by root via crm_resource on node-1
          * 2 nodes configured
          * 10 resource instances configured
    
        Node List:
          * Online: [ node-1 ]
          * OFFLINE: [ node-2 ]
    
        Full List of Resources:
          * Resource Group: sql_group:
            * pcs-cluster-vip   (ocf:heartbeat:IPaddr2): Started node-1
            * vgdata    (ocf:heartbeat:LVM-activate):    Started node-1
            * vglogtmp  (ocf:heartbeat:LVM-activate):    Started node-1
            * data_dir  (ocf:heartbeat:Filesystem):      Started node-1
            * log_dir   (ocf:heartbeat:Filesystem):      Started node-1
            * tmp_dir   (ocf:heartbeat:Filesystem):      Started node-1
            * sql_fci   (ocf:mssql:fci):                 Started node-1
            * pcs-healthcheck   (systemd:haproxy.service):       Started node-1
          * node-1-fence       (stonith:fence_gce):     Stopped
          * node-2-fence        (stonith:fence_gce):     Started node-1
    
    1. También verás que node-2 está desactivado en Compute Engine.

      Ir a Compute Engine

  2. Reinicia la protección en node-2.

    1. Regresa a node-1 y reinicia la instancia de nuevo con la ejecución del siguiente comando.

      fence_gce -o on -n node-2 --zone=ZONE2
      

      El resultado es similar al que se muestra a continuación:

      Success: Powered ON
      
    2. Comprueba el estado del clúster en Pacemaker y Compute Engine. Después de un momento, verás que node-2 vuelve a estar en línea.

       $ sudo crm status
      

Prueba la conmutación por error

Ahora estás listo para probar si la conmutación por error funciona como se esperaba:

  1. Crea un nombre de usuario y una contraseña para la instancia de VM.
  2. Conéctate a la VM mediante el escritorio remoto y accede con el nombre de usuario y la contraseña que creaste en el paso anterior.
  3. Conéctate a la VM de Windows en cl-node a través del escritorio remoto.
  4. Abre una sesión de PowerShell.
  5. Para conectarte al servidor, ejecuta la siguiente secuencia de comandos. Cada cinco segundos, la secuencia de comandos se conecta a SQL Server a través del objeto de escucha del grupo de disponibilidad y consulta el nombre del servidor.

    while ($True){
      try {
        $Conn = New-Object System.Data.SqlClient.SqlConnection
        $Conn.ConnectionString = "Server=CLUSTER_ADDRESS;User ID=sa;Password=SA_PASSWORD;Initial Catalog=master"
        $Conn.Open()
    
        $Cmd =  $Conn.CreateCommand()
        $Cmd.CommandText = "SELECT SERVERPROPERTY('ComputerNamePhysicalNetBIOS')"
    
        $Result = $Cmd.ExecuteReader()
        if ($Result.Read()) {
          $currentNode = $Result.GetString(0)
          Write-Host "Current Node: $currentNode at $(Get-Date)"
        }
    
        $Conn.Close()
        Start-Sleep -Seconds 5
      }
      catch {
          Write-Host "SQL Connection Failed at $(Get-Date). Retrying..."
          Start-Sleep -Seconds 15 # Wait before retrying
      }
    }
    

    Reemplaza CLUSTER_ADDRESS por la dirección IP del objeto de escucha y SA_PASSWORD por la contraseña de la cuenta de AS en SQL Server.

    El resultado es similar al que se muestra a continuación:

      Current Node: node-1 at 06/09/2026 20:24:35
      Current Node: node-1 at 06/09/2026 20:24:40
      Current Node: node-1 at 06/09/2026 20:24:45
      Current Node: node-1 at 06/09/2026 20:24:50
      Current Node: node-1 at 06/09/2026 20:24:55
    

    Deja la secuencia de comandos en ejecución.

  6. Activa una conmutación por error a node-2: Desde node-1, regresa a la terminal SSH y ejecuta el siguiente comando.

    sudo pcs resource move sql_group node-2
    
  7. Regresa a la sesión de PowerShell en cl-node.

    1. Observa el resultado de la secuencia de comandos en ejecución y observa que el nombre del servidor cambia de node-1 a node-2 como resultado de la conmutación por error.

    El resultado es similar al que se muestra a continuación:

      Current Node: node-1 at 06/09/2026 20:28:51
      Current Node: node-1 at 06/09/2026 20:28:56
      SQL Connection Failed at 06/09/2026 20:29:16. Retrying...
      Current Node: node-2 at 06/09/2026 20:29:31
      Current Node: node-2 at 06/09/2026 20:29:36
    
  8. Inicia una conmutación por recuperación a node-1. En la línea de comandos de node-1, ejecuta el siguiente comando:

    sudo pcs resource move sql_group node-1
    
  9. Regresa a PowerShell en cl-node. Para detener la secuencia de comandos, presiona Ctrl+C.

Realiza una limpieza

Una vez que completes el instructivo, puedes limpiar los recursos que creaste para que dejen de usar la cuota y generar cargos. En las siguientes secciones, se describe cómo borrar o desactivar estos recursos.

Borra el proyecto

La manera más fácil de eliminar la facturación es borrar el proyecto que creaste para el instructivo.

Para borrar el proyecto, sigue estos pasos:

  1. En la Cloud de Confiance consola, ve a la página Administrar recursos.

    Ir a Administrar recursos

  2. En la lista de proyectos, elige el proyecto que quieres borrar y haz clic en Borrar.
  3. En el diálogo, escribe el ID del proyecto y, luego, haz clic en Cerrar para borrar el proyecto.

¿Qué sigue?