La tendencia hacia soluciones software para storage (SDS) es fuerte especialmente en startups y nuevos entornos. Como casi todas las novedades es frecuente encontrar “resistencias” al cambio. Pensemos lo que ha ocurrido con la virtualización estos últimos años donde hemos pasado desde que un SQL Server virtualizado fuese una rareza hasta convertirse en algo de lo más habitual a día de hoy.

Obviamente hay casos donde esta “resistencia” está provocada por inversiones ya realizadas que están aún pendientes de amortizar, lo cual estaría totalmente justificado. En todo caso conviene explorar las nuevas posibilidades pensando en futuras migraciones y/o en nuevos entornos que puedan requerir moverse a Cloud. Por ejemplo, vemos muchos casos donde se utiliza Azure como una extensión del datacenter para montar entornos de pruebas, de desarrollo o incluso de preproducción.

En este mismo blog tratamos Storage Réplica cuando Windows Server 2016 aún era una beta (Windows Server 10/vNext) en el ya lejano 2015: https://blogs.solidq.com/es/novedades/sql-server-failover-clustering-y-windows-server-10-storage-replica. Más recientemente también comentamos otras opciones “Virtual SAN”, basadas en software de terceros, como Starwind: https://blogs.solidq.com/es/general/virtual-sans-la-tendencia-hacia-sds.

En este post vamos a mostrar cómo podemos de forma rápida y sencilla apoyándonos en las plantillas de Azure crear una POC (prueba de concepto) donde testear el comportamiento de una instancia SQL Server en Failover Cluster sobre dos nodos que ofrecen storage compartido con Windows Server 2016 Storage Spaces Direct. En este caso no tenemos réplica ni síncrona ni asíncrona, la cual podría añadirse posteriormente como mecanismo de DR, sino que lo que tenemos es un sistema donde, grosso modo, los discos locales de cada nodo local se agregan para dar redundancia tal y como ocurre en las múltiples controladoras de una SAN.

Para realizar el despliegue de la POC utilizaremos dos plantillas, la primera de ellas (https://github.com/Azure/azure-quickstart-templates/tree/master/active-directory-new-domain-ha-2-dc) nos permite desplegar una infraestructura básica de Active Directory sobre la que se apoyará el cluster posteriormente. Si ya disponemos de un AD y una VNET podremos obviar este paso. La segunda plantilla (https://github.com/Azure/azure-quickstart-templates/tree/master/301-storage-spaces-direct) es la que realizará la configuración de S2D en dos nodos.

Podemos ver una estimación aproximada de los costes mensuales únicamente de la primera de las plantillas (https://azure.microsoft.com/en-us/resources/templates/active-directory-new-domain-ha-2-dc/) ya que para la segunda aún no está disponible el cálculo automático:

Comenzaremos lanzando la primera de las plantillas simplemente pulsando el botón “Deploy to Azure”:

Una vez nos identifiquemos en el portal de Azure tendremos que rellenar los campos del template. Seleccionaremos la suscripción deseada, así como el datacenter donde queremos desplegar el template. En este caso vamos a indicar un nuevo nombre para el grupo de recursos, de forma que podamos borrar posteriormente todos los recursos de la POC de forma más rápida y sencilla.

El resto de los parámetros necesarios son bastante auto descriptivos: el nombre del administrador del dominio, su password, el FQDN para el dominio, el prefijo DNS por si tenemos que conectar contra estas máquinas y los puertos para el RDP de ambos servidores de AD:

Una vez procedamos con la “compra” del template, iremos monitorizando el proceso de despliegue desde el portal hasta que este finalice (normalmente unos 15-20 minutos):

Cuando finalice podemos ver todos los recursos creados:

Podemos ver que el tamaño que se utiliza para las máquinas virtuales desplegadas es DS2 v2:

El siguiente paso será conectar con nuestro AD y crear la cuenta de servicio que utilizaremos posteriormente para la instalación de SQL Server:

Una vez tenemos el dominio y el usuario el siguiente paso será desplegar el segundo template (https://github.com/Azure/azure-quickstart-templates/tree/master/301-storage-spaces-direct):

Entre los parámetros que se nos solicitarán estará la vnet y subnet donde queremos desplegar los nodos. Normalmente tendríamos, al menos, una subnet dedicada para los nodos de S2D pero por no complicar más el ejemplo vamos a reutizar la misma vnet y subnet donde tenemos ya desplegados los active directory:

Cuando finalice el proceso veremos que los recursos han sido añadidos a nuestro grupo de recursos:

El tiempo total del despliegue de este template es bastante elevado, en torno a 45 minutos, por lo que deberemos ser pacientes.

Conectaremos al cluster vía RDP saltando desde el Active Directory (por defecto el template no asigna IP pública a los nodos del cluster S2D) y comprobaremos que el cluster está correcto:

Podemos ver que la plantilla nos ha configurado un disco de 2 TB con redundancia en espejo (estilo RAID10):

De los 4 discos que tenemos por debajo (4 TB en RAW) dos discos están en un nodo (enclosure) y los otros 2 en el otro:

El siguiente paso es instalar una instancia de SQL Server en failover cluster utilizando dicho storage como almacenamiento compartido. Vamos a instalar SQL Server 2017 RC2 (aunque nos valdría cualquier versión soportada sobre Windows server 2016) por lo que procederemos a su descarga desde la web de evaluación: https://www.microsoft.com/en-us/evalcenter/evaluate-sql-server-2017-ctp/

El proceso de setup será igual que si realizáramos una instalación sobre un disco compartido en una SAN, con la única diferencia que la ruta para los ficheros será \\fs01\data o bien C:\ClusterStorage\Volume1. Con el uso de la ruta UNC podemos aprovechar este almacenamiento desde nodos externos al cluster mientras que con el Cluster Shared Volume el acceso está limitado a los nodos del cluster. Este tipo de almacenamiento CSV es muy habitual en entornos de virtualización donde todas las máquinas virtuales ejecutan en los nodos del cluster. Si optamos por la opción del fileshare, antes de comenzar la instalación deberemos dar permisos a la cuenta que vamos a usar para el servicio sobre dicho share:

Creemos que disponer de ambas opciones simultáneamente también es interesante, ya que por ejemplo si utilizamos LogShipping o replicación de SQL Server y necesitamos una carpeta compartida altamente disponible podemos utilizar la misma infraestructura (aunque quizás un volumen montado sobre discos más económicos). Comprobaremos que no tenemos errores al finalizar la instalación de la instancia:

También revisaremos que los recursos del cluster están correctamente creados. Tened en cuenta que en este caso la IP flotante deberá implementarse vía load balancer en Azure, normalmente un ILB.

Conectaremos al otro nodo del cluster y realizaremos la operación de “Add node” desde el instalador:

El siguiente paso es probar de conectar contra la instancia y forzar un failover entre nodos para asegurarnos que todo funciona correctamente. Para realizar una prueba lo más “dura” posible que haremos es forzar un apagado del nodo de forma forzada, de forma que caiga el operativo, el SQL Server y uno de los nodos de storage de forma repentina. Forzaremos la caída mientras lanzamos transacciones a la base de datos las cuales verificaremos que han quedado persistidas tras la recuperación automática del cluster.

Comprobaremos primero que tenemos los dos roles ejecutando en el mismo nodo:

Comenzaremos lanzando la carga contra la instancia SQL:

create table test (id int identity (1,1))

go

while (1=1)

begin

       select SCOPE_IDENTITY() antes

       insert into test default values

       select SCOPE_IDENTITY() despues

end

Y mientras ejecuta “mataremos” el nodo 0 desde Azure, lo cual provocará que el storage S2D se degrade, pero sin perder disponibilidad:

Tan pronto forcemos el fallo veremos que el SSMS nos devuelve un error de corte de conexión, siendo el último valor que leimos el 429. Por tanto deberíamos tener el 429 o bien el 430 si se hubiese llegado a ejecutado el insert pero no el select posterior. Lo que nunca debería pasar es que el último valor almacenado en la tabla fuese inferior a 429:

Comprobamos que ambos roles levantan en el nodo que queda vivo del cluster:

Lanzaremos una consulta y validamos que no hemos perdido datos ni por la caída del SQL Server ni por el sistema de almacenamiento Windows Server 2016 S2D. Destacar que el sistema S2D no llegó a estar “no disponible” en ningún momento, ya que es una solución activa/activa de alta disponibilidad:

Una vez llegados a este punto nos gustaría comentar que, aunque en este caso hemos usado y desplegado plantillas sin modificar, podemos crear nuestras propias plantillas desde cero o editando plantillas existentes. Para realizar un despliegue de esta forma elegiremos desde el portal de Azure la opción de “Custom deployment”, seleccionaremos el template y/o lo editaremos:

Una vez lo tengamos cargado en el editor podríamos ajustarlo a nuestras necesidades y salvarlo:

El proceso a partir de este punto será el mismo, configuraremos los parámetros y lanzaremos el despliegue. En estos casos de personalizaciones podemos tener algunos problemas con las dependencias si se ven afectadas por nuestros cambios en los scripts:

En este caso podemos ver que está causado por no poder encontrar los “artefactos” del template en la ruta por defecto que tenía el template. Podemos ver que en el template apunta la ruta a /Azure/ cuando debería ser /MSBrett debido a que hemos intentado desplegar un template de un fork de GitHub. En realidad podríamos ubicar estos artefactos en cualquier ubicación y es habitual crear una cuenta de storage privada y pasarle el token SAS apropiado al proceso de despliegue para que tenga acceso a los “artefactos”.

Cambiaremos por tanto dicho parámetro y volvemos a lanzar el template:

La realidad es que depurar estos despliegues puede requerir bastante paciencia. Por ejemplo, en la personalización nos encontramos con un error tras unos 10 minutos de despliegue:

Como la máquina virtual ya está desplegada en este punto comprobamos que el problema es que la ruta indicada en el template es incorrecta, ya que los binarios en las nuevas plantillas están en C:\SQLServerFull, sin indicador de versión:

Como workaround cambiaremos el nombre de la carpeta por SQLServer_13.0_Full, aunque la solución correcta sería cambiar el template y/o parametrizar esta ruta de forma que pudiera modificarse via parámetro.

Para evitar comenzar desde el principio cuando realicemos cambios podremos utilizar el mecanismo de “redeploy” desde el propio template:

Una vez corregido el error el despliegue ya podrá completar:

En conclusión, creemos que, al igual que ocurrió con la virtualización, muy probablemente en un tiempo todos tengamos que manejar soluciones de Software Defined Storage con cierta frecuencia. También los despliegues de SQL Server contra entornos cloud, como Azure, serán más habituales y conviene que estemos familiarizados con los métodos de despliegue mediante templates. Además, consideramos importante el ejercitarnos como administradores en entornos de prueba/POC para mejorar nuestras habilidades de resolución de problemas antes de responsabilizarnos de un entorno de producción basado en estas tecnologías.

Rubén Garrigós

Rubén Garrigós is an expert in high-availability enterprise solutions based on SQL Server design, tuning, and troubleshooting. Over the past fifteen years, he has worked with Microsoft data access technologies in leading companies around the world. He currently is a Microsoft SQL Server and .NET applications architect with SolidQ. Ruben is certified by Microsoft as a Solution Expert on the Microsoft Data Platform (MSCE: Data Platform) and as a Solution Expert on the Microsoft Private Cloud (MSCE: Private Cloud). As a Microsoft Certified Trainer (MCT), Ruben has taught multiple official Microsoft courses as well as other courses specializing in SQL Server. He has also presented sessions at official events for various Microsoft technologies user groups.