Resumen
This article shows how to seed a database from a SQL instance that is in a Windows availability group into a SQL instance running in a pod in a Kubernetes cluster using a distributed availability group.
Este artículo sobre los grupos de disponibilidad distribuida de SQL Server apareció originalmente en el blog de Andrew Pruski. Se ha vuelto a publicar con el reconocimiento y el consentimiento del autor.
Hace un tiempo, escribí sobre cómo usar un grupo de disponibilidad multiplataforma (o sin clúster) para sembrar una base de datos desde una instancia de Windows SQL en un pod en Kubernetes.
Estaba hablando con un compañero la semana pasada y me preguntaron: “¿Y si la instancia de Windows existente ya está en un grupo de disponibilidad?”
Esta es una pregunta bastante clara, ya que es bastante raro (según mi experiencia) ejecutar una instancia SQL independiente en producción… la mayoría de las instancias tienen algún tipo de configuración HA, ya sea una instancia de clúster de conmutación por error o un grupo de disponibilidad.
Las instancias de clúster de conmutación por error funcionarán con un grupo de disponibilidad sin clúster, pero es una historia diferente cuando se trata de grupos de disponibilidad existentes.
Un nodo Linux no puede añadirse a un grupo de disponibilidad de Windows existente (confíe en mí, he intentado durante más tiempo del que voy a admitir), así que la única manera de hacerlo es usar un grupo de disponibilidad distribuida.
¡Así que vamos a pasar por el proceso!
Este es el grupo de disponibilidad de Windows existente:
Solo un AG estándar de dos nodos con una base de datos ya sincronizada en los nodos. Es esa base de datos que vamos a colocar en el pod que se ejecuta en el clúster de Kubernetes usando un grupo de disponibilidad distribuida.
Así que aquí está el clúster de Kubernetes:
kubectl obtener nodos
Cuatro nodos, un nodo de plano de control y tres nodos de trabajador.
De acuerdo, lo primero que hay que hacer es desplegar un conjunto de estados que ejecute un pod de SQL Server (usando un archivo llamado sqlserver-statefulset.yaml):
kubectl apply -f .\sqlserver-statefulset.yaml
Aquí tiene el manifiesto del conjunto de estados de cuenta:
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
apiVersion: aplicaciones/v1tipo: StatefulSetmetadata: name: mssql-statefulsetspec: serviceName: réplicas "mssql": 1 podManagementPolicy: Selector paralelo: matchLabels: nombre: plantilla mssql-pod: metadatos: etiquetas: nombre: Anotaciones de mssql-pod:stork.libopenstorage.org/disableHyperconvergence: "true" spec: seguridadContexto: fsGroup: 10001 hostAlias: - ip: "10.225.115.129" nombres de host: - contenedores "z-ap-sql-10": - nombre: imagen del contenedor mssql: mcr.microsoft.com/mssql/server:2022-CU15-ubuntu-20.04ports: - containerPort: Nombre del 1433: mssql-port env: - nombre: MSSQL_PID value: "Desarrollador" - nombre: ACCEPT_EULA value: "Y" - nombre: MSSQL_AGENT_ENABLED value: "1" - nombre: MSSQL_ENABLE_HADR value: "1" - nombre: MSSQL_SA_PASSWORD value: Volumen "Testing1122"Montajes: - nombre: sqlsystem mountPath: /var/opt/mssql - nombre: sqldata mountPath: /var/opt/sqlserver/volumen de datosClaimTemplates: - metadatos: nombre: sqlsystem spec: accessModes: - ReadWriteRecursos de org.: solicitudes: almacenamiento: 1GistorageClassName: mssql-sc - metadatos: nombre: sqldata spec: accessModes: - ReadWriteOnce recursos: solicitudes: almacenamiento: 25GistorageClassName: mssql-sc
Al igual que en mi última publicación, esto está bastante arraigado. Sin límites de recursos, tolerancias, etc. Tiene dos volúmenes persistentes: uno para las bases de datos del sistema y otro para las bases de datos de usuario de una clase de almacenamiento ya configurada en el clúster.
Algo que hay que tener en cuenta:
1234 hostAlias:- ip: "10.225.115.129" nombres de host: - "z-ap-sql-10"
Aquí, se crea una entrada en el archivo de hosts del pod para el oyente del grupo de disponibilidad de Windows.
Lo siguiente que hay que hacer es desplegar dos servicios: uno para que podamos conectarnos a la instancia SQL (en el puerto 1433) y otro para el AG (puerto 5022):
kubectl apply -f .\sqlserver-services.yaml
Aquí tiene el manifiesto de los servicios:
12345678910111213141516171819202122232425 apiVersión: v1kind: Servicemetadata: nombre: mssql-servicespec: puertos: - nombre: mssql-puertos puerto: 1433 destinoPuerto: 1433 selector: nombre: mssql-pod tipo: LoadBalancer---apiVersión: v1tipo: Servicemetadata: nombre: mssql-ha-servicespec: puertos: - nombre: mssql-ha-ports puerto: 5022 destinoPuerto: 5022 selector: nombre: mssql-pod tipo: LoadBalancer
Nota: Podríamos usar un solo servicio con múltiples puertos configurados, pero los mantengo separados aquí para tratar de mantener las cosas lo más claras posible.
Uso de la copia de seguridad instantánea T-SQL: Recuperación en el momento
Compruebe que todo parece correcto:
kubectl consigue todo
Ahora, tenemos que crear la clave maestra, el inicio de sesión y el usuario en todos los casos:
123 CREAR UNA ENCRIPCIÓN CLAVE MAESTRA POR CONTRASEÑA = '
Luego, cree un certificado en la instancia SQL del pod:
CREAR CERTIFICADO dbm_certificate CON ASUNTO = 'Mirroring_certificate', EXPIRY_DATE = '20301031'
Haga una copia de seguridad de ese certificado:
123456 CERTIFICADO DE RESERVA dbm_certificatePARA ARCHIVO = '/var/opt/mssql/data/dbm_certificate.cer'CON LLAVE PRIVADA ( ARCHIVO = '/var/opt/mssql/data/dbm_certificate.pvk', ENCRYPTION POR CONTRASEÑA = '
Copie el certificado localmente:
12 kubectl cp mssql-statefulset-0:var/opt/mssql/data/dbm_certificate.cer ./dbm_certificate.cer -n prodkubectl cp mssql-statefulset-0:var/opt/mssql/data/dbm_certificate.pvk ./dbm_certificate.pvk -n prod
Y luego copie los archivos en los cuadros de Windows:
1234 Copia-Artículo dbm_certificate.cer \\z-ap-sql-02\E$\SQLBackup1\ -ForceCopy-Item dbm_certificate.pvk \\z-ap-sql-02\E$\SQLBackup1\ -ForceCopy-Item dbm_certificate.cer \\z-ap-sql-03\E$\SQLBackup1\ -ForceCopy-Item dbm_certificate.pvk \\z-ap-sql-03\E$\SQLBackup1\ -Force
Una vez que los archivos están en los cuadros de Windows, podemos crear el certificado en cada instancia de SQL de Windows:
1234567 CREAR dbm_certificate AUTORIZACIÓN DE CERTIFICADO dbm_user A PARTIR DEL ARCHIVO = 'E:\SQLBackup1\dbm_certificate.cer' CON CLAVE PRIVADA (ARCHIVO = 'E:\SQLBackup1\dbm_certificate.pvk', DECRYPTION MEDIANTE CONTRASEÑA = '')
¡Bien, genial! Ahora tenemos que crear un punto de conexión replicado en la instancia SQL del pod:
123456789101112 CREAR [Hadr_endpoint]ESTADO DE PUNTO FINAL = INICIADOCOMO TCP ( LISTENER_PORT = 5022, LISTENER_IP = TODO)PARA DATA_MIRRORING (FUNCIÓN = TODO, AUTENTICACIÓN = CERTIFICADO DE WINDOWS [dbm_certificate], CIFRADO = ALGORITMO REQUERIDO AES );ALTERAR [Hadr_endpoint] ESTADO DE PUNTO FINAL = INICIADO;CONCEDER CONEXIÓN EN PUNTO FINAL::[Hadr_endpoint] A [dbm_login];
Ya hay terminales en las instancias de Windows, pero tenemos que actualizarlos para usar el certificado para la autenticación:
12345678910 ALTER ENDPOINT [Hadr_endpoint]STATE = STARTEDAS TCP ( LISTENER_PORT = 5022, LISTENER_IP = ALL)FOR DATABASE_MIRRORING ( AUTENTICACIÓN = CERTIFICADO DE WINDOWS [dbm_certificate], CIFRADO = ALGORITMO REQUERIDO AES );CONECTAR EN PUNTO FINAL:[Hadr_endpoint] A [dbm_login];
Ahora podemos crear un grupo de disponibilidad sin clúster de un nodo en la instancia SQL del pod:
12345678910111213 CREAR UN GRUPO DE [AG2]DISPONIBILIDADCON (CLUSTER_TYPE=NONE) FORREPLICA ON'mssql-statefulset-0' CON ( ENDPOINT_URL = 'TCP://mssql-statefulset-0.com:5022', FAILOVER_MODE = MANUAL ,AVAILABILITY_MODE = SYNCHRONOUS_COMMIT ,BACKUP_PRIORITY = 50 ,SEEDING_MODE = AUTOMATIC ,SECONDARY_ROLE(ALLOW_CONNECTIONS = = NO) )
No hay oyente aquí; vamos a usar el servicio mssql-ha-service como punto final para el grupo de disponibilidad distribuida.
Bien, así que en el nodo principal del grupo de disponibilidad de Windows, podemos crear el grupo de disponibilidad distribuida:
1234567891011121314151617 CREAR UN GRUPO DE [DistributedAG]DISPONIBILIDADCON (DISTRIBUIDO) GRUPO DE DISPONIBILIDAD EN'AG1' CON ( LISTENER_URL = 'tcp://Z-AP-SQL-10:5022', AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT, FAILOVER_MODE = MANUAL, SEEDING_MODE = = AUTOMÁTICO ), 'AG2' CON ( LISTENER_URL = 'tcp://10.225.115.131:5022', AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT, FAILOVER_MODE = = MANUAL, SEEDING_MODE = = AUTOMÁTICO );
Podríamos usar una entrada de archivo host para la URL en AG2 (lo hice en la publicación anterior), pero aquí solo usaremos la dirección IP del servicio mssql-ha-service.
Muy bien, ¡casi ahí! Ahora tenemos que unirnos al grupo de disponibilidad en la instancia SQL del pod:
1234567891011121314151617 ALTER A DISPONIBILIDAD GRUPO [DistributedAG]ÚNASE A DISPONIBILIDAD GRUPO ON'AG1' CON ( LISTENER_URL = 'tcp://Z-AP-SQL-10:5022', AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT, FAILOVER_MODE = MANUAL, SEEDING_MODE = = AUTOMÁTICO ), 'AG2' CON ( LISTENER_URL = 'tcp://10.225.115.131:5022', AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT, FAILOVER_MODE = = MANUAL, SEEDING_MODE = = AUTOMÁTICO );
¡Y eso debería ser todo! Si ahora nos conectamos a la instancia SQL del pod, ¡la base de datos está ahí!
¡Aquí está! Vale, una cosa que no he pasado aquí es cómo hacer que la búsqueda automática funcione desde Windows a una instancia de SQL de Linux. He visto cómo funciona en mi publicación anterior, pero lo importante es que, siempre que los datos de la base de datos y los archivos de registro estén ubicados bajo la ruta de datos y de registro predeterminada de la instancia de Windows SQL, se conectarán automáticamente a las rutas de datos y de registro predeterminadas de la instancia de Linux SQL.
Así que así es como sembrar una base de datos desde una instancia SQL que está en un grupo de disponibilidad de Windows en una instancia SQL que se ejecuta en un pod en un clúster de Kubernetes usando un grupo de disponibilidad distribuida.

Stellar Storage
Boost performance for SQL Server with Pure Storage.