Configura un clúster de SQL Server en Linux con grupos de disponibilidad Always On y Pacemaker


En este instructivo, se describe cómo implementar un sistema de base de datos de Microsoft SQL Server en Linux con un grupo de disponibilidad siempre activado (AOAG) y Pacemaker como una solución de alta disponibilidad (HA) y recuperación ante desastres (DR). Para los fines de este documento, un desastre es un evento en el que una base de datos principal falla o deja de estar disponible.

Una base de datos principal puede fallar cuando la región en la que se encuentra falla o se vuelve inaccesible. Incluso si una región está disponible y funciona con normalidad, una base de datos principal puede fallar debido a un error del sistema. En estos casos, la recuperación ante desastres es el proceso de hacer que una base de datos secundaria esté disponible para los clientes con un procesamiento continuo.

Este instructivo está dirigido a personas que son ingenieras, administradoras y arquitectas de bases de datos.

Objetivos

Costos

En este instructivo, se usan los siguientes componentes facturables de Google Cloud:

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

Antes de comenzar

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

  1. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  2. Make sure that billing is enabled for your Google Cloud project.

  3. Asegúrate de que la API de NetApp Cloud Volumes esté habilitada para tu proyecto de Google Cloud.
  4. In the Google Cloud console, activate Cloud Shell.

    Activate Cloud Shell

Prepara el proyecto y la red

Haz lo siguiente para preparar tu proyecto de Google Cloud y la VPC para la implementación de grupos de disponibilidad AlwaysOn de SQL Server:

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

    Ve a la consola de Google Cloud.

  2. Establece tu ID del proyecto predeterminado:

    gcloud config set project PROJECT_ID
    

    Reemplaza PROJECT_ID por el ID del proyecto de Google Cloud.

  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.

  4. Establece la zona predeterminada:

    gcloud config set compute/zone ZONE
    

    Reemplaza ZONE por el ID de la zona en la que deseas realizar la implementación. Debe ser una zona válida en la región especificada en el paso anterior.

Crea VMs de Linux

Para lograr la alta disponibilidad y el quórum para el clúster de SQL Server, implementa tres máquinas virtuales (VMs) de Linux que alojan el clúster de SQL Server.

  1. Inicializa las siguientes variables:

    PD_SIZE=30
    MACHINE_TYPE=n2-standard-8
    
  2. Crea las VMs de Linux:

    gcloud compute instances create node-1 \
    --project=PROJECT_ID \
    --zone REGION-a \
    --machine-type $MACHINE_TYPE \
    --subnet SUBNET_NAME \
    --create-disk=auto-delete=yes,boot=yes,device-name=node-1,image=projects/ubuntu-os-cloud/global/images/ubuntu-2004-focal-v20240426,mode=rw,size=$PD_SIZE,type=projects/PROJECT_ID/zones/ZONE/diskTypes/pd-balanced \
    --scopes=https://www.googleapis.com/auth/compute,https://www.googleapis.com/auth/servicecontrol,https://www.googleapis.com/auth/service.management.readonly,https://www.googleapis.com/auth/logging.write,https://www.googleapis.com/auth/monitoring.write,https://www.googleapis.com/auth/trace.append,https://www.googleapis.com/auth/devstorage.read_write
    
    gcloud compute instances create node-2 \
    --project=PROJECT_ID \
    --zone REGION-b \
    --machine-type $MACHINE_TYPE \
    --subnet SUBNET_NAME \
    --create-disk=auto-delete=yes,boot=yes,device-name=node-2,image=projects/ubuntu-os-cloud/global/images/ubuntu-2004-focal-v20240426,mode=rw,size=$PD_SIZE,type=projects/PROJECT_ID/zones/ZONE/diskTypes/pd-balanced \
    --scopes=https://www.googleapis.com/auth/compute,https://www.googleapis.com/auth/servicecontrol,https://www.googleapis.com/auth/service.management.readonly,https://www.googleapis.com/auth/logging.write,https://www.googleapis.com/auth/monitoring.write,https://www.googleapis.com/auth/trace.append,https://www.googleapis.com/auth/devstorage.read_write
    
    gcloud compute instances create node-3 \
    --project=PROJECT_ID \
    --zone REGION-c \
    --machine-type $MACHINE_TYPE \
    --subnet SUBNET_NAME \
    --create-disk=auto-delete=yes,boot=yes,device-name=node-3,image=projects/ubuntu-os-cloud/global/images/ubuntu-2004-focal-v20240426,mode=rw,size=$PD_SIZE,type=projects/PROJECT_ID/zones/ZONE/diskTypes/pd-balanced \
    --scopes=https://www.googleapis.com/auth/compute,https://www.googleapis.com/auth/servicecontrol,https://www.googleapis.com/auth/service.management.readonly,https://www.googleapis.com/auth/logging.write,https://www.googleapis.com/auth/monitoring.write,https://www.googleapis.com/auth/trace.append,https://www.googleapis.com/auth/devstorage.read_write
    

    Reemplaza la subred SUBNET_NAME por el nombre de tu subred de VPC.

  3. Actualiza el archivo de hosts en node-1, node-2 y node-3:

    1. Conéctate a cada una de tus VMs con SSH. Consulta la documentación de Conexión a VMs de Linux para obtener más información.
    2. Abre el archivo de hosts para editarlo.

      sudo vi /etc/hosts
      
    3. 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
      NODE3_INTERNAL_IP node-3
      

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

  4. 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:

    1. 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
      ping -c 4 node-3
      

Instala y configura SQL Server

Descarga, instala y configura el motor de SQL Server en las tres VMs de Linux que participarán en el grupo de disponibilidad Always On.

  1. Establece una conexión SSH a node-1, node-2 y node-3, y ejecuta los siguientes pasos:

    1. Importa las claves del repositorio público.

      wget -qO- https://packages.microsoft.com/keys/microsoft.asc \
      | sudo tee /etc/apt/trusted.gpg.d/microsoft.asc
      
    2. Registra el repositorio de Ubuntu de SQL Server.

      sudo add-apt-repository \
      "$(wget -qO- https://packages.microsoft.com/config/ubuntu/20.04/mssql-server-2019.list)"
      
    3. Actualiza los archivos de índice del paquete y, luego, instala SQL Server.

      sudo apt-get update
      sudo apt-get install -y mssql-server
      
      
  2. Configura SQL Server:

    1. Ejecuta la herramienta mssql-conf.

      sudo /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. Si tienes un firewall habilitado en tus VMs, abre el firewall 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.

      sudo ufw allow 1433
      sudo ufw allow 5022
      sudo ufw reload
      

Conéctate a SQL Server

En este punto, está instalado SQL Server. Para conectarte a ella, crea una máquina de Windows en la misma VPC y, luego, instala SQL Server Management Studio (SSMS) para conectarte a la instancia de SQL Server que acabas de crear en tus VMs:

  1. Crea una VM de Windows:

    1. Vuelve a tu Cloud Shell y ejecuta el siguiente comando:

      gcloud compute instances create node4 \
      --project=PROJECT_ID \
      --zone ZONE \
      --subnet SUBNET_NAME \
      --machine-type=n2-standard-4 \
      --create-disk=auto-delete=yes,boot=yes,device-name=node4,image=projects/windows-cloud/global/images/windows-server-2022-dc-v20240415,mode=rw,size=50,type=projects/p3rf-sqlserver/zones/ZONE/diskTypes/pd-balanced
      
  2. Conéctate a la VM de Windows en node-4 con el escritorio remoto:

  3. Actualiza el archivo hosts en node-4:

    1. Abre el bloc de notas en modo de administrador.
    2. Haz clic en Archivo > Abrir y abre el archivo de hosts.

      c:\Windows\System32\drivers\etc\hosts
      
    3. Adjunta las entradas del host en la parte inferior del archivo.

      NODE1_INTERNAL_IP node-1
      NODE2_INTERNAL_IP node-2
      NODE3_INTERNAL_IP node-3
      

      Reemplaza NODE1_INTERNAL_IP, NODE2_INTERNAL_IP y NODE3_INTERNAL_IP por la dirección IP interna correspondiente de cada VM.

    4. Guarda y cierra.

  4. Verifica la conexión a las VMs de Linux:

    1. Conéctate a la VM de Windows en node-4
    2. Haz clic en el botón Iniciar y, luego, escribe powershell en la barra de búsqueda.
    3. Haz clic para abrir la aplicación Windows PowerShell ISE.
    4. Prueba la conectividad con la ejecución de los siguientes comandos.

      ping node-1
      ping node-2
      ping node-3
      
  5. Instala Microsoft SQL Server Management Studio (SSMS) con los siguientes pasos:

    1. Conéctate a la VM de Windows en node-4 con el escritorio remoto.

    2. En tu sesión de RDP, minimiza todas las ventanas y luego inicia la app de Windows PowerShell ISE.

    3. Cuando recibas el mensaje de PowerShell, descarga y ejecuta el instalador de SSMS.

      Start-BitsTransfer `
      -Source "https://aka.ms/ssmsfullsetup" `
      -Destination "$env:Temp\ssms-setup.exe"
      & $env:Temp\ssms-setup.exe
      
    4. En el instalador de SSMS, haz clic en Instalar.

    5. Acepta la solicitud para permitir cambios.

    6. Cuando finalice la instalación, haz clic en Reiniciar para reiniciar la máquina remota. Esto cierra la sesión de RDP.

  6. Conéctate a la instancia de SQL Server en nodo-1:

    1. Regresa a la VM node-4 con RDP.

    2. Abre SSMS y conéctate a node-1 con los siguientes parámetros.

      Server name: node-1
      Authentication: SQL Server Authentication
      Login: sa
      

      Para obtener más información, consulta cómo conectarse a una instancia de SQL Server con la documentación de SQL Server Management Studio.

    3. Escribe la contraseña de la cuenta de AS creada durante la instalación.

    4. Elige Certificado de servidor de confianza.

    5. Haz clic en Conectar.

Habilita el grupo de disponibilidad siempre activado

En Linux, primero debes crear un grupo de disponibilidad antes de poder agregarlo como un recurso que Pacemaker administrará:

  1. Habilita la característica de grupo de disponibilidad Always On para cada instancia de SQL Server que participe en el grupo de disponibilidad. Ejecuta los siguientes comandos en node-1, node-2 y node-3:

    sudo /opt/mssql/bin/mssql-conf set hadr.hadrenabled 1
    sudo systemctl restart mssql-server
    
  2. Conéctate a la instancia que es el host principal en el grupo de disponibilidad con SSMS:

    1. Abre una nueva ventana de consulta.

    2. Ejecuta el siguiente fragmento de código para crear una clave de encriptación, un certificado y una clave privada.

      USE MASTER;
      
      CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'ENCRYPTION_KEY_PASSWORD';
      CREATE CERTIFICATE my_ag_certificate WITH SUBJECT = 'my_ag_cert';
      BACKUP CERTIFICATE my_ag_certificate
      TO FILE = '/var/opt/mssql/data/my_ag_certificate.cer'
      WITH PRIVATE KEY (
          FILE = '/var/opt/mssql/data/my_ag_certificate.pvk',
          ENCRYPTION BY PASSWORD = 'PRIVATE_KEY_PASSWORD'
      );
      

      Reemplaza ENCRYPTION_KEY_PASSWORD y PRIVATE_KEY_PASSWORD por las contraseñas de la clave de encriptación y la clave privada.

Transfiere el certificado y los archivos de claves

El certificado y los archivos de claves creados en los pasos anteriores deben moverse a los nodos secundarios de SQL Server. Existen varios métodos para mover el certificado y los archivos de claves a los nodos secundarios en node-2 y node-3.

Para conocer otras opciones de transferencia, consulta Transfiere archivos a VMs de Linux

Transfiere el certificado y los archivos de claves con Cloud Storage

Crea un entorno de Cloud Storage para transferir archivos de los nodos del clúster principal a los secundarios.

  1. Crea un bucket de Cloud Storage:

    1. Regresa a Cloud Shell y ejecuta el siguiente comando:

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

      Reemplaza BUCKET_NAME por el nombre del bucket que deseas crear. Reemplaza PROJECT_ID por el ID de tu proyecto de Google Cloud y reemplaza REGION por el ID de la región en la que deseas implementar el bucket.

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

  2. Regresa a SSh en node-1, node-2 y node-3 para inicializar Google Cloud CLI:

    1. Ejecuta el siguiente comando para inicializar Google Cloud CLI.

      gcloud init
      
    2. Elige option [1] para usar la cuenta de servicio preinstalada.

    3. Escribe el nombre de tu proyecto en Name (Nombre).

    4. Escribe n en la pregunta para configurar la región y zona predeterminadas.

  3. Regresa a node-1 para copiar los archivos a Cloud Storage:

    1. Sube los dos archivos recién creados a Cloud Storage con el siguiente comando.

      sudo gcloud storage cp /var/opt/mssql/data/my_ag_certificate.cer gs://BUCKET_NAME/
      sudo gcloud storage cp /var/opt/mssql/data/my_ag_certificate.pvk gs://BUCKET_NAME/
      

      Reemplaza BUCKET_NAME por el nombre del bucket creado.

  4. Regresa a node-2 y node-3 para copiar los archivos desde Cloud Storage:

    1. Descarga los dos archivos desde Cloud Storage a node-2.

      sudo gcloud storage cp gs://BUCKET_NAME/my_ag_certificate.cer /var/opt/mssql/data/
      sudo gcloud storage cp gs://BUCKET_NAME/my_ag_certificate.pvk /var/opt/mssql/data/
      

      Reemplaza BUCKET_NAME por el nombre del bucket creado.

    2. Cambia la propiedad de los archivos en node-2 y node-3 con la ejecución del comando en una shell raíz.

      chown mssql:mssql /var/opt/mssql/data/my_ag_certificate.*
      chmod 660 /var/opt/mssql/data/my_ag_certificate.*
      
      

Configura el extremo de duplicación de la base de datos

En esta sección, crearás el extremo de la base de datos con una clave de encriptación y un certificado que compartirá cada nodo en el clúster de SQL Server para garantizar una replicación segura de los datos.

  1. Regresa a la VM de Windows en node-4 para crear los extremos de duplicación de la base de datos:

    1. Conéctate a las bases de datos de SQL Server en node-1, node-2 y node-3 con SSMS. Sigue los pasos de la página Conéctate a SQL Server con node-1, node-2 y node-3 como el nombre del servidor y las correspondientes contraseñas que establezcas para la cuenta con AS.

    2. Crea el certificado en las VMs secundarias node-2 y node-3 desde los archivos copiados. Usa las contraseñas que proporcionaste cuando creaste el certificado y la clave en el nodo principal.

      USE MASTER;
      
      CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'ENCRYPTION_KEY_PASSWORD';
      CREATE CERTIFICATE my_ag_certificate
      FROM FILE = '/var/opt/mssql/data/my_ag_certificate.cer'
      WITH PRIVATE KEY (
          FILE = '/var/opt/mssql/data/my_ag_certificate.pvk',
          DECRYPTION BY PASSWORD = 'PRIVATE_KEY_PASSWORD'
      );
      

      Reemplaza ENCRYPTION_KEY_PASSWORD y PRIVATE_KEY_PASSWORD por las contraseñas de la clave de encriptación y la clave privada.

    3. Regresa a SSMS para crear extremos de duplicación de bases de datos con la ejecución del comando de T-SQL para node-1, node-2 y node-3.

      CREATE ENDPOINT [my_ag_endpoint]
          AS TCP (LISTENER_PORT = 5022)
          FOR DATABASE_MIRRORING (
              ROLE = ALL,
              AUTHENTICATION = CERTIFICATE my_ag_certificate,
              ENCRYPTION = REQUIRED ALGORITHM AES
          );
      
      ALTER ENDPOINT [my_ag_endpoint] STATE = STARTED;
      

Crea y configura el grupo de disponibilidad siempre activado

A continuación, crea el grupo de disponibilidad Always On de SQL Server con SQL Server Management Studio y usa los extremos creados anteriormente para la replicación.

  1. Regresa a la VM de Windows y abre SSMS:

    1. Conéctate al motor de base de datos de SQL Server en node-1 y abre una nueva ventana de consulta.
  2. Crea una base de datos y crea una copia de seguridad de ella como preparación para la replicación:

    USE MASTER;
    
    CREATE DATABASE [bookshelf];
    ALTER DATABASE [bookshelf] SET RECOVERY FULL;
    BACKUP DATABASE [bookshelf]
    TO DISK = N'/var/opt/mssql/data/bookshelf.bak';
    
  3. Crea el grupo de disponibilidad siempre activado:

    1. Ejecuta el siguiente comando de T-SQL en SSMS en node-1, node-2 y node-3. Esto garantizará que los extremos estén habilitados y que SQL Server en cada nodo esté listo para la replicación de datos.

      IF (SELECT state FROM sys.endpoints WHERE name = N'my_ag_endpoint') <> 0
      BEGIN
          ALTER ENDPOINT [my_ag_endpoint] STATE = STARTED
      END
      GO
      
      IF EXISTS(SELECT * FROM sys.server_event_sessions WHERE name='AlwaysOn_health')
      BEGIN
          ALTER EVENT SESSION [AlwaysOn_health] ON SERVER WITH (STARTUP_STATE=ON);
      END
      IF NOT EXISTS(SELECT * FROM sys.dm_xe_sessions WHERE name='AlwaysOn_health')
      BEGIN
          ALTER EVENT SESSION [AlwaysOn_health] ON SERVER STATE=START;
      END
      GO
      
    2. Ejecuta el siguiente comando de T-SQL en node-1 para crear el AOAG.

      USE [master]
      GO
      
      CREATE AVAILABILITY GROUP [aoag1]
      WITH (
          AUTOMATED_BACKUP_PREFERENCE = SECONDARY,
          DB_FAILOVER = OFF,
          DTC_SUPPORT = NONE,
          CLUSTER_TYPE = EXTERNAL,
          REQUIRED_SYNCHRONIZED_SECONDARIES_TO_COMMIT = 0
      )
      FOR DATABASE [bookshelf]
      REPLICA ON N'node-1' WITH (
          ENDPOINT_URL = N'TCP://node-1:5022', FAILOVER_MODE = EXTERNAL, AVAILABILITY_MODE = SYNCHRONOUS_COMMIT, BACKUP_PRIORITY = 50, SEEDING_MODE = AUTOMATIC, SECONDARY_ROLE(ALLOW_CONNECTIONS = NO)),
          N'node-2' WITH (ENDPOINT_URL = N'TCP://node-2:5022', FAILOVER_MODE = EXTERNAL, AVAILABILITY_MODE = SYNCHRONOUS_COMMIT, BACKUP_PRIORITY = 50, SEEDING_MODE = AUTOMATIC, SECONDARY_ROLE(ALLOW_CONNECTIONS = NO)),
          N'node-3' WITH (ENDPOINT_URL = N'TCP://node-3:5022', FAILOVER_MODE = EXTERNAL, AVAILABILITY_MODE = SYNCHRONOUS_COMMIT, BACKUP_PRIORITY = 50, SEEDING_MODE = AUTOMATIC, SECONDARY_ROLE(ALLOW_CONNECTIONS = NO)
      );
      GO
      
    3. Ejecuta el siguiente comando de T-SQL en node-2 y node-3 para cada instancia de SQL Server y podrás unirte al nuevo grupo de disponibilidad.

      ALTER AVAILABILITY GROUP [aoag1] JOIN WITH (CLUSTER_TYPE = EXTERNAL);
      GO
      
      ALTER AVAILABILITY GROUP [aoag1] GRANT CREATE ANY DATABASE;
      GO
      

    Creaste una nueva base de datos llamada biblioteca y la agregaste a un grupo de disponibilidad nuevo llamado aoag1 en la instancia de SQL Server que se ejecuta en node-1. Se agregaron Node-2 y node-3 al grupo de disponibilidad, y los datos de la base de datos de biblioteca se replicarán de forma síncrona en las instancias de SQL Server en los tres nodos.

Instala y configura 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 y configurarás Pacemaker en cada una de tus VMs.

Crea un acceso en SQL Server para el administrador de clústeres de marcapasos

En esta sección, crearás una cuenta de SQL Server nueva para que Pacemaker la use y puedas acceder a cada instancia de SQL Server y administrar el grupo de disponibilidad.

  1. Ejecuta el siguiente comando de T-SQL en node-1, node-2 y node-3:

    USE [master];
    
    CREATE LOGIN [pacemaker] with PASSWORD= N'PACEMAKER_LOGIN_PASSWORD';
    GO
    

    Reemplaza PACEMAKER_LOGIN_PASSWORD por una contraseña para la cuenta de pacemaker.

  2. Ejecuta el comando de T-SQL para otorgar permisos de acceso a Pacemaker al grupo de disponibilidad:

    GRANT ALTER, CONTROL, VIEW DEFINITION ON AVAILABILITY GROUP::[aoag1] TO [pacemaker];
    GRANT VIEW SERVER STATE TO [pacemaker];
    GO
    
  3. Regresa a SSH en node-1, node-2 y node-3 para ejecutar los comandos y guardar el acceso y la contraseña de Pacemaker en la carpeta de secretos de SQL Server:

    echo 'pacemaker' >> ~/pacemaker-passwd
    echo 'PACEMAKER_LOGIN_PASSWORD' >> ~/pacemaker-passwd
    sudo mv ~/pacemaker-passwd /var/opt/mssql/secrets/passwd
    sudo chown root:root /var/opt/mssql/secrets/passwd
    sudo chmod 400 /var/opt/mssql/secrets/passwd
    

    Reemplaza PACEMAKER_LOGIN_PASSWORD por la contraseña de la cuenta de Pacemaker.

Instala Pacemaker

A continuación, instala Pacemaker y configura una cuenta de inicio de sesión en todas las VMs de Linux para la administración de recursos.

  1. Abre puertos de firewall para Pacemaker:

    1. Para verificar si Uncomplicated Firewall está instalado y habilitado, ejecuta el siguiente comando en node-1, node-2 y node-3.

      sudo ufw status
      
    2. Si el ufw está habilitado, abre los puertos de firewall en node-1, node-2 y node-3.

      sudo ufw allow 2224/tcp
      sudo ufw allow 3121/tcp
      sudo ufw allow 5405/udp
      sudo ufw allow 21064/tcp
      sudo ufw allow 1433/tcp
      sudo ufw allow 5022/tcp
      sudo ufw reload
      
  2. Instala Pacemaker en node-1, node-2 y node-3:

    sudo apt-get install -y pacemaker pacemaker-cli-utils crmsh resource-agents  fence-agents corosync python3-azure pcs
    
  3. Establece una contraseña nueva para el usuario hacluster en node-1, node-2 y node-3:

    sudo passwd hacluster
    

Configura Corosync

Ahora configurarás Corosync para administrar la membresía y la mensajería del clúster en todo el clúster.

  1. Crea una clave de autenticación para Corosync en node-1:

    sudo corosync-keygen
    
  2. Modifica el archivo de configuración de Corosync:

    1. Regresa a node-1 y modifica el archivo corosync.conf.

      sudo vi /etc/corosync/corosync.conf
      
    2. Actualiza las secciones destacadas. Después de editar, el archivo debería verse como el siguiente ejemplo.

      # Please read the corosync.conf.5 manual page
      totem {
          version: 2
      
          # Corosync itself works without a cluster name, but DLM needs one.
          # The cluster name is also written into the VG metadata of newly
          # created shared LVM volume groups, if lvmlockd uses DLM locking.
          cluster_name: my_agcluster
      
          # crypto_cipher and crypto_hash: Used for mutual node authentication.
          # If you choose to enable this, then do remember to create a shared
          # secret with "corosync-keygen".
          # enabling crypto_cipher, requires also enabling of crypto_hash.
          # crypto works only with knet transport
          transport: udpu
          crypto_cipher: none
          crypto_hash: none
      }
      
      logging {
          # Log the source file and line where messages are being
          # generated. When in doubt, leave off. Potentially useful for
          # debugging.
          fileline: off
          # Log to standard error. When in doubt, set to yes. Useful when
          # running in the foreground (when invoking "corosync -f")
          to_stderr: yes
          # Log to a log file. When set to "no", the "logfile" option
          # must not be set.
          to_logfile: yes
          logfile: /var/log/corosync/corosync.log
          # Log to the system log daemon. When in doubt, set to yes.
          to_syslog: yes
          # Log debug messages (very verbose). When in doubt, leave off.
          debug: off
          # Log messages with time stamps. When in doubt, set to hires (or on)
          #timestamp: hires
          logger_subsys {
              subsys: QUORUM
              debug: off
          }
      }
      quorum {
          # Enable and configure quorum subsystem (default: off)
          # see also corosync.conf.5 and votequorum.5
          provider: corosync_votequorum
      }
      nodelist {
          # Change/uncomment/add node sections to match cluster configuration
      
          node {
              # Hostname of the node
              name: node-1
              # Cluster membership node identifier
              nodeid: 1
              # Address of first link
              ring0_addr: NODE1_INTERNAL_IP
              # When knet transport is used it's possible to define up to 8 links
              #ring1_addr: 192.168.1.1
          }
          node {
              name: node-2
              nodeid: 2
              ring0_addr: NODE2_INTERNAL_IP
          }
          node {
              name: node-3
              nodeid: 3
              ring0_addr: NODE3_INTERNAL_IP
          }
          # ...
      }
      

      Reemplaza NODE1_INTERNAL_IP, NODE2_INTERNAL_IP y NODE3_INTERNAL_IP por las direcciones IP internas de cada nodo.

Transfiere los archivos de configuración con Cloud Storage

  1. Sube la clave de autenticación generada y los archivos de configuración de corosync de node-1 a tu bucket de Cloud Storage:

    sudo gcloud storage cp /etc/corosync/authkey gs://BUCKET_NAME/
    sudo gcloud storage cp  /etc/corosync/corosync.conf gs://BUCKET_NAME/
    

    Reemplaza BUCKET_NAME por el nombre del bucket creado anteriormente.

  2. Descarga los Authkey y los archivos de configuración en node-2 y node-3:

    sudo gcloud storage cp gs://BUCKET_NAME/authkey /etc/corosync/
    sudo gcloud storage cp gs://BUCKET_NAME/corosync.conf /etc/corosync/
    

    Reemplaza BUCKET_NAME por el nombre del bucket en el que se transfirieron los archivos de configuración de Corosync.

  3. Actualiza los permisos de los archivos en node-2 y node-3:

    sudo chmod 400 /etc/corosync/authkey
    sudo chmod 400 /etc/corosync/corosync.conf
    

Reinicia y verifica la comunicación del clúster

  1. Reinicia los servicios de Pacemaker y Corosync en node-1, node-2 y node-3:

    sudo systemctl restart pacemaker corosync
    
  2. Para confirmar el estado del clúster, ejecuta el comando en node-1:

    sudo crm status
    

    Deberías ver los tres nodos en línea.

Configura el clúster

A continuación, configurarás el clúster de Pacemaker con la creación de un recurso nuevo para el grupo de disponibilidad Always On de SQL Server.

  1. Ejecuta el siguiente comando en node-1 para configurar las propiedades del clúster:

    sudo crm configure property stonith-enabled=false
    sudo crm configure property cluster-recheck-interval=2min
    sudo crm configure property start-failure-is-fatal=true
    

    Para obtener más información, consulta Opciones de clúster.

  2. Autoriza los nodos del clúster con la ejecución del comando en node-1. Usa la contraseña que configuraste anteriormente para la cuenta hacluster:

    sudo pcs cluster auth -u hacluster
    

    Deberías ver que los tres nodos están autorizados.

  3. Instala el agente de recursos de SQL Server para la integración en Pacemaker en node-1, node-2 y node-3:

    sudo apt-get install mssql-server-ha
    
  4. Regresa a node-1 y crea un recurso de grupo de disponibilidad en el clúster:

    1. Ejecutar el Resource Manager del clúster.

      sudo crm
      
    2. Escribe configure para ingresar al menú de configuración.

    3. Escribe la siguiente configuración.

      primitive aoag1-cluster \
      ocf:mssql:ag \
      params ag_name="aoag1" \
      meta failure-timeout=60s \
      op start timeout=60s \
      op stop timeout=60s \
      op promote timeout=60s \
      op demote timeout=10s \
      op monitor timeout=60s interval=10s \
      op monitor timeout=60s on-fail=demote interval=11s role="Master" \
      op monitor timeout=60s interval=12s role="Slave" \
      op notify timeout=60s
      ms ms-ag1 aoag1-cluster \
      meta master-max="1" master-node-max="1" clone-max="3" \
      clone-node-max="1" notify="true"
      
    4. Escribe commit para confirmar los cambios.

    5. Escribe exit para salir del Resource Manager del clúster.

    6. Verifica la configuración

      sudo crm status
      

      Deberías ver que node-1 se ascendió al nodo principal. Node-2 y node-3 deben establecerse como nodos secundarios.

Configura el balanceador de cargas y el objeto de escucha del grupo de disponibilidad

En esta sección, crearás una dirección IP virtual y un recurso de verificación de estado en el clúster con un balanceador de cargas de TCP de transferencia interno que enruta el tráfico al grupo de disponibilidad.

  1. Regresa a Cloud Shell y reserva una dirección IP estática que usarás como IP del clúster:

    gcloud compute addresses create aoag1-cluster \
    --region REGION \
    --subnet SUBNET_NAME
    CLUSTER_ADDRESS=$(gcloud compute addresses describe aoag1-cluster \
    --region $(gcloud config get-value compute/region) \
    --format=value\(address\)) && \
    echo "Cluster IP address: $CLUSTER_ADDRESS"
    

    Reemplaza REGION y SUBNET_NAME por la región y la subred en las que se implementan las VMs de Linux.

  2. Crea grupos de instancias no administrados para cada uno de los nodos del clúster y asígnalos al grupo de instancias recién creado. Ejecuta los siguientes comandos por separado en Cloud Shell:

    gcloud compute instance-groups unmanaged create node-1-uig \
    --zone=REGION-a
    gcloud compute instance-groups unmanaged add-instances node-1-uig \
    --zone=REGION-a \
    --instances=node-1
    
    gcloud compute instance-groups unmanaged create node-2-uig \
    --zone=REGION-b
    gcloud compute instance-groups unmanaged add-instances node-2-uig \
    --zone=REGION-b \
    --instances=node-2
    
    gcloud compute instance-groups unmanaged create node-3-uig \
    --zone=REGION-c
    gcloud compute instance-groups unmanaged add-instances node-3-uig \
    --zone=REGION-c \
    --instances=node-3
    

    Reemplaza REGION por la región en la que se implementan las VMs de Linux.

  3. Crea una verificación de estado de TCP. Los balanceadores de cargas usan verificaciones de estado para determinar qué instancias de backend responden al tráfico de manera correcta.

    gcloud compute health-checks create tcp aoag1-healthcheck \
    --port=HEALTH_CHECK_PORT --proxy-header=NONE \
    --check-interval=10 --timeout=10 --unhealthy-threshold=2 \
    --healthy-threshold=2
    

    Elige y reemplaza HEALTH_CHECK_PORT por el valor de un puerto que sea libre y esté en el rango privado de 49152-65535 . Por ejemplo, 60,000.

    Para obtener más información, consulta la descripción general de las verificaciones de estado.

  4. Agrega etiquetas de red a los nodos del clúster. La regla de firewall usa la etiqueta de red para la verificación de estado:

    gcloud compute instances add-tags node-1 \
    --tags NETWORK_TAG_NAME \
    --zone REGION-a
    gcloud compute instances add-tags node-2 \
    --tags NETWORK_TAG_NAME \
    --zone REGION-b
    gcloud compute instances add-tags node-3 \
    --tags NETWORK_TAG_NAME \
    --zone REGION-c
    

    Reemplaza NETWORK_TAG_NAME por un nombre para la etiqueta de red.

  5. Crea una regla de firewall para permitir que las verificaciones de estado lleguen a los nodos del clúster según el nombre de la etiqueta:

    gcloud compute firewall-rules create mssql-aoag1-fw-rule \
    --network VPC_NAME \
    --action ALLOW \
    --direction INGRESS \
    --source-ranges 35.191.0.0/16,130.211.0.0/22 \
    --target-tags NETWORK_TAG_NAME \
    --rules tcp:HEALTH_CHECK_PORT
    

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

  6. Crea el servicio de backend del balanceador de cargas:

    gcloud compute backend-services create aoag1-backend \
    --load-balancing-scheme internal \
    --health-checks aoag1-healthcheck \
    --no-connection-drain-on-failover \
    --drop-traffic-if-unhealthy \
    --failover-ratio 1.0 \
    --region REGION \
    --global-health-checks
    
  7. Agrega los tres grupos de instancias no administrados al servicio de backend:

    gcloud compute backend-services add-backend aoag1-backend \
    --instance-group node-1-uig \
    --instance-group-zone REGION-a \
    --region REGION
    
    gcloud compute backend-services add-backend aoag1-backend \
    --instance-group node-2-uig \
    --instance-group-zone REGION-b \
    --failover \
    --region REGION
    
    gcloud compute backend-services add-backend aoag1-backend \
    --instance-group node-3-uig \
    --instance-group-zone REGION-c \
    --failover \
    --region REGION
    
  8. Define una regla de reenvío para el balanceador de cargas. Una regla de reenvío especifica el protocolo y los puertos en los que el balanceador de cargas acepta el tráfico.

    gcloud compute forwarding-rules create aoag1-fwd-rule \
    --load-balancing-scheme internal \
    --address CLUSTER_ADDRESS \
    --subnet SUBNET_NAME \
    --region REGION \
    --backend-service aoag1-backend \
    --ports ALL
    

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

    Para obtener más información, consulta las reglas de reenvío

  9. 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 node-1, node-2 y node-3:

    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 *:HEALTH_CHECK_PORT
      

      Reemplaza HEALTH_CHECK_PORT por el puerto de verificación de estado elegido anteriormente. Por ejemplo, 6,000:

    6. Inicia el servicio para confirmar que esté configurado de forma correcta:

      sudo systemctl start haproxy.service
      sudo systemctl enable haproxy.service
      sudo systemctl restart haproxy.service
      
    7. Ve a la página Balanceo de cargas y haz clic en tu balanceador de cargas. Observa tus tres grupos de instancias no administrados; ahora deberían informar que se encuentra en buen estado.

      Ir a Balanceo de cargas

      • Como alternativa, puedes ejecutar el siguiente comando en Cloud Shell para ver el estado del servicio de backend.

        gcloud compute backend-services get-health aoag1-backend \
        --region REGION
        

        Reemplaza REGION por la región en la que se implementan las VMs de Linux.

    8. Una vez que los tres grupos de instancias no administrados informen en buen estado, continúa con el paso siguiente.

      sudo systemctl restart haproxy.service
      
  10. Crea el recurso de verificación de estado en Pacemaker:

    1. Establece una conexión SSH a node-1 y crea un recurso de verificación de estado para el servicio de HAProxy en tu clúster de Pacemaker:

      sudo pcs resource create aoag1-healthcheck \
      service:haproxy \
      op monitor interval=10s timeout=20s
      
    2. Comprueba que el recurso de estado se inicie en el nodo principal node-1:

      sudo crm status
      
    3. Si el recurso de verificación de estado no se inicia en el nodo principal, muévelo con los siguientes comandos:

      sudo pcs resource move aoag1-healthcheck node-1
      sudo pcs resource clear aoag1-healthcheck
      

      Verás que la verificación de estado del balanceador de cargas estará en buen estado solo para node-1.

      Ir a Balanceo de cargas

  11. Crea un recurso de dirección IP virtual en tu clúster de Pacemaker:

    1. Regresa a SSH en node-1 y busca el nombre de la interfaz de red de tu nodo. La necesitarás en el próximo paso.

      ip -c link
      
    2. Crea el recurso de dirección IP virtual.

      sudo pcs resource create aoag1-vip ocf:heartbeat:IPaddr2 \
      ip="CLUSTER_ADDRESS" nic=NIC_NAME cidr_netmask=32 \
      op monitor interval=3600s timeout=60s
      

      Reemplaza NIC_NAME por el nombre de la interfaz de red del paso anterior y CLUSTER_ADDRESS por la dirección IP reservada.

    3. Verifica que el recurso de dirección IP virtual se inicie en el host principal.

      sudo crm status
      
    4. Si el recurso de dirección IP virtual no se inició en el nodo principal, muévelo con los siguientes comandos.

      sudo pcs resource move aoag1-vip node-1
      
    5. Agrupa los recursos de verificación de estado y dirección IP virtual.

      sudo pcs resource group add aoag1-group \
      aoag1-healthcheck aoag1-vip
      
    6. Crea una restricción que ubique el grupo nuevo en el mismo nodo que el principal.

      sudo pcs constraint colocation add master aoag1-group with master ms-ag1 score=INFINITY
      

Crea un objeto de escucha para tu grupo de disponibilidad de SQL Server

Las conexiones a SQL Server con grupos de disponibilidad deben usar un nombre de objeto de escucha de grupo de disponibilidad en lugar del nombre del servidor. Si hay una conmutación por error, el objeto de escucha redireccionará las conexiones al nuevo nodo principal del clúster automáticamente.

  1. Regresa a SSMS y conéctate a la base de datos de node-1.

  2. Ejecuta la siguiente consulta:

    ALTER AVAILABILITY GROUP aoag1
    ADD LISTENER 'aoag1-listener' (
        WITH IP (('CLUSTER_ADDRESS','255.255.255.0')), PORT=1433
    );
    GO
    

    Reemplaza CLUSTER_ADDRESS por la dirección IP reservada.

Configura una cerca 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 Google Cloud.

Configura los dispositivos de cercas

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

    sudo pcs stonith list | grep fence_gce
    

    Para obtener más información, consulta:

  2. En node-1, crea los recursos de tipo de protección fence_gce para cada uno de los nodos participantes:

    sudo pcs stonith create node-1-fence fence_gce \
    plug=node-1 \
    zone=REGION-a \
    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=REGION-b \
    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-3-fence fence_gce \
    plug=node-3 \
    zone=REGION-c \
    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 REGION por la región 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=REGION-a
    sudo fence_gce -o status -n node-2 --zone=REGION-b
    sudo fence_gce -o status -n node-3 --zone=REGION-c
    
  4. 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
    sudo pcs constraint location node-3-fence avoids node-3
    
  5. 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"
    
  6. Verifica el estado del clúster:

    sudo crm status
    

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=REGION-b
      
    2. Verifica el estado del clúster.

      sudo crm status
      
    3. 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=REGION-b
      
    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
      

Configura Corosync para el reinicio retrasado

Para evitar problemas de tiempo y garantizar un orden adecuado de operaciones hechas en caso de una acción de protección, recomendamos retrasar el reinicio del servicio de Corosync durante 60 segundos.

Para obtener más información, consulta el artículo de la base de conocimiento de Red Hat.

  1. Crea un archivo directo systemd que establezca un retraso del inicio del servicio de Corosync en node-1, node-2 y node-3:

    1. Abre corosync.service para editarlo.

      sudo systemctl edit corosync.service
      

    2. Agrega las siguientes líneas, guarda el archivo y sal del editor.

      [Service]
      ExecStartPre=/bin/sleep 60
      
    3. Vuelve a cargar el administrador de servicios y comprueba si se tomó en cuenta la configuración.

      sudo systemctl daemon-reload
      systemctl status corosync.service --no-pager
      
      

      Si ves la sección directa, significa que la configuración del archivo directo se tuvo en cuenta de forma correcta

Prueba la conmutación por error

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

  1. Conéctate a la VM de Windows en node-4 con el escritorio remoto:
  2. Abre una sesión de PowerShell:
  3. Ejecuta la siguiente secuencia de comandos:

    while ($True){
      $Conn = New-Object System.Data.SqlClient.SqlConnection
      $Conn.ConnectionString = "Server=CLUSTER_ADDRESS;User ID=sa;Password=SA_PASSWORD;Initial Catalog=master"
      $Conn.Open()
    
      $Cmd = New-Object System.Data.SqlClient.SqlCommand
      $Cmd.Connection = $Conn
      $Cmd.CommandText = "SELECT @@SERVERNAME"
    
      $Adapter = New-Object System.Data.SqlClient.SqlDataAdapter $Cmd
      $Data = New-Object System.Data.DataSet
      $Adapter.Fill($Data) | Out-Null
      $Data.Tables[0] + (Get-Date -Format "MM/dd/yyyy HH:mm:ss")
    
      Start-Sleep -Seconds 2
    }
    

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

    Cada 2 segundos, la secuencia de comandos se conecta a SQL Server mediante el objeto de escucha del grupo de disponibilidad o el objeto de escucha de DNN, y consulta el nombre del servidor.

    Deja la secuencia de comandos en ejecución.

  4. Regresa a SSH en node-1 y ejecuta los comandos para activar una conmutación por error a node-2:

    sudo pcs resource move ms-ag1 node-2 --master
    sudo pcs resource move aoag1-group  node-2
    sudo pcs resource move aoag1-vip node-2
    
  5. Regresa a la sesión de PowerShell en node-4:

    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.
  6. Regresa a node-1 y, luego, inicia una conmutación por recuperación a node-1:

    sudo pcs resource move ms-ag1 node-1 --master
    sudo pcs resource move aoag1-group  node-1
    sudo pcs resource move aoag1-vip node-1
    
  7. Regresa a Powershell en node-4 y presiona Ctrl+C para detener la secuencia de comandos.

Limpia

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. In the Google Cloud console, go to the Manage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then click Delete.
  3. In the dialog, type the project ID, and then click Shut down to delete the project.