Post del Camp «Alta Disponibilidad en Azure IaaS y despliegue con plantillas»
Arranca el mes de Abril, y regresamos de Semana Santa con el Camp de Alta Disponibilidad en Azure IaaS y despliegue con plantillas. Presentan Santiago Ochoa y Roberto Rodríguez, Cloud Architects de myCloudDoor, quienes se presentan recordándonos que ellos estuvieron en nuestro sitio, como estudiantes de Tajamar hace unos años.
Como Architects de infraestructuras en Cloud, Santiago y Roberto nos presentan el diseño de la arquitectura de red que vamos a montar, tendremos dos secciones base, una subnet con un Domain Controller y otra subnet con un Availability Set que cuenta con dos servidores SQL en alta disponibilidad, y conectaremos las dos subredes con un Load Balancer (O Equilibrador de Carga, como lo traducen en Azure). Aunque en realidad, haremos una triquiñuela para que el Load Balancer no se comporte como Load Balancer sino como un mecanismo Failover. No nos interesa que “balancee”, necesitamos que “conmute” en un esquema de nodos activo-pasivo.
¿Qué significa todo eso? Significa que vamos a simular, en un entorno Azure, que tenemos nuestro dominio, y vamos a “construir” a través de plantillas, una infraestructura que permita a nuestra infraestructura, conectarse a un servicio lanzado por una “cara visible” (Front-End del Load Balancer) de otra subred, que a su vez conectará con dos servidores SQL (Back-End del Load Balancer), que prestarán servicio de forma que sólo estemos conectando con uno de los servidores SQL (el nodo activo), pero si ese servidor fallara, esa “cara visible” seguiría dando respuesta, porque “saltaría” al segundo servidor (conmutación por fallo o Failover).
Plantillas de despliegue, hablamos en JSON
JavaScript Object Notation o «JSON» es el lenguaje más adecuado para realizar nuestro despliegue. Derivado de JavaScript, JSON especifica una serie de características para, a partir de las mismas, generar un esquema completo de elementos que definirán la configuración base de una Máquina Virtual. En nuestro caso, se trata de dos plantillas JSON. Una para “declarar” los elementos que vamos a usar para crear nuestro “recurso” (En Azure RM se habla de “recursos”, en la anterior versión de Azure, llamada “clásica” se hablaba de Servicios) y otra llamada “parameters” para establecer valores para esos elementos. Cuando tratamos con Visual Studio, un software que nos viene muy a mano para gestionar estas plantillas, vemos que a estas dos plantillas JSON, se suma una tercera parte en PowerShell, que es la que “transforma” estas plantillas en órdenes concretas que se envían a nuestro Tenant de Azure para poder crear los recursos en nuestra infraestructura on-cloud.
Visual Studio permite operar con las plantillas de una forma un poco menos “codificada” con nuestras plantillas, ordenando los parámetros, variables y recursos de una forma algo más humana, para que no tengamos que bucear entre llaves y paréntesis hasta dar con el fragmento de código que nos interesa.
La propia implementación del portal se parece mucho a Visual Studio y ofrece facilidades tales como cargar la primera plantilla (la de “declaración” de parámetros) y podemos introducir los valores de esos parámetros en cajas de texto, o cargar esos valores desde la segunda plantilla de «parameters», si la tenemos. En este caso, la tenemos, por lo que podríamos cargar toda la configuración de un recurso sin tener que indicar más que unos pocos valores.
Si tuviéramos que explicar los vericuetos de las configuraciones que definimos en las plantillas JSON para cada uno de los recursos que vamos a crear, tal vez estaríamos escribiendo hasta pasado mañana. En vez de eso, intentaremos “abstraernos” del código en la medida de lo posible y explicar qué estaremos logrando con cada plantilla.
Con la primera plantilla, lo que crearíamos sería una red virtual, y dentro de ella, una máquina virtual en nuestro Tenant de Azure, todo dentro de un “grupo de recursos” (la unidad básica de contenidos en Azure). Esta primera VM es nuestro DC. La primera parte es crearla, luego habrá que entrar en ella por su IP pública (Azure nos facilita las cosas con una opción de “conectar” que nos dará su acceso directo por RDP), y tendremos que crear el dominio ahí dentro para promocionar la máquina a Domain Controller.
En una infraestructura on-cloud cambian algunas cuestiones que hasta ahora habían permanecido relativamente inamovibles en la computación. Antes, en nuestra infraestructura, un disco era un disco, una tarjeta de red era una tarjeta de red y una conexión necesitaba un cable de un punto A a un punto B. Ahora debemos olvidarnos del hardware. Ahora todo es virtual y lo llaman “recursos”.
Azure Resource Management, donde todo es «Resource»
Una de las cuestiones más importantes de Azure es que en el despliegue RM (la versión moderna), es que TODO es un recurso; desde una máquina virtual hasta un disco duro, una IP o una red, todo es un recurso, y como recursos que son, van a parar a un Grupo de recursos o Resource Group, de forma que recomiendan “bloquear” los grupos de recursos.
Eliminar un grupo de recursos significa eliminar todos los recursos incluidos dentro, que pueden ser muchos y muy importantes, y no conviene dejar un Resource Group con pocos “niveles” de protección contra un posible borrado accidental.
La experiencia de Santiago y Roberto es que la seguridad en el acceso a los recursos en Azure (máquinas virtuales o servicios configurados on-cloud), en entornos reales de producción, rara vez se realiza con filtrados propios de grupos de seguridad de Azure (que son, como no podía ser de otra manera, recursos), sino que se montan y configuran aplicaciones virtuales que segurizan la infraestructura on-cloud.
Los despliegues en Cloud, por futuristas que suenen, todavía pueden ser propensos a fallos a la hora de desplegar, y ya tenemos nuestro primer “efecto estadístico”, en una misma instrucción para todos, ya se suceden los primeros fallos de implementación. Nuevamente la experiencia de Santiago y Roberto nos explica que a veces los fallos de implementación de Azure ofrecen información intuitiva para poder diagnosticar y resolver los problemas… Otras veces, los errores son códigos de error difíciles de interpretar y toca buscarse la vida.
Alta disponibilidad, el azucarillo de sistemas
Hablar de alta disponibilidad es como el adjetivo “mejorado” en cualquier término de la infraestructura. A todo el mundo le gusta, y suena bien para todos. Los versados en sistemas ya saben de sobra que hablar de Alta Disponibilidad implica duplicidades, redundancias, adquisición de recursos que tal vez no entren nunca en acción y, dicho en cristiano: Para resistir posibles fallos en tu infraestructura necesitas, simplemente más infraestructura. Es la rueda de repuesto en el maletero del coche. Pero claro, cuando se habla de HA (High Availability, nosotros siempre acabamos con los términos anglicanos para no liarnos), tarde o temprano tenemos que hablar de ¿cómo de “Alta” es esa “Alta Disponibilidad”? ¿Cuánto puedes garantizar que tu coche continuará rodando si algo se estropea? Esto, en términos profesionales, se suele denominar SLA: Service License Agreement.
Y es que si garantizas que tu coche puede continuar rodando si se pincha una rueda, necesitarás tener una rueda de repuesto, pero si quieres garantizar que el coche no se detendrá más de X minutos en un viaje, tal vez necesites tener otro coche de reserva, o tres coches, o un parking de repuesto con un par de mecánicos y piezas sueltas por si hicieran falta… Y así, se configura un SLA de un “noventa y nueve coma X nueves” porciento de disponibilidad de tu vehículo (cuantos más nueves añadas, más repuestos necesitaremos, pero más seguridad tendrá el viajero de que el coche seguirá en marcha), sabiendo que nunca llegaremos al 100% de disponibilidad garantizada, porque nunca podrás garantizar que tu vehículo (o servicio) sea infalible.
En informática, esto se traduce en tener varios ordenadores lanzando un mismo servicio, pero seguimos pensando en un esquema on-premise ¿Cómo se entiende la alta disponibilidad en Azure? Lo podemos entender cuando hablamos de “availability sets” o conjuntos de disponibilidad. Azure nos ofrece la posibilidad de crear recursos en varias localizaciones a la vez al incluirlos en un Availability Set, de forma que lo que creemos se replicará en varios lugares, para poder resistir un posible fallo mecánico o una actualización de sistema que forzaría a los sistemas a estar fuera de servicio por mantenimiento. En Azure (al menos, en este momento, porque quién sabe cuándo y cómo cambiará la tecnología on-cloud en el futuro próximo) debemos distinguir los Failure Domain y los Update Domain, ya que en los “availability sets” necesitamos definir esos dos aspectos:
- Los Failure Domains son los lugares físicos en los que se irán agregando nuestros recursos. Dos VMs diferentes en dos Failure Domains estará en dos máquinas diferentes de Azure, de forma que, si un fallo eléctrico apaga una de esas máquinas, siempre quedará la segunda máquina para prestar servicio como si no hubiera pasado nada.
- Los Update Domains son agrupaciones lógicas (a diferencia de los Failure Domains, que son físicas), son nodos sobre los cuales estará replicado un recurso. Si esos nodos requirieran una tarea de mantenimiento que obligara a sacarlos del servicio, se caerían todos los recursos cargados en ese nodo.
De forma que si definiéramos un Availability Set con dos Failure Domains y cinco Update Domains, estaríamos hablando de poder agregar recursos en dos lugares físicos y cinco nodos posibles. Gracias a esta cantidad de recursos de replicación, Azure nos garantiza una disponibilidad de hasta un 99.95%. Por increíble que parezca, puede haber servicios tan críticos que un 99,95% de disponibilidad seguiría siendo insuficiente. Por otra parte, por obvio que resulte, es necesario recordar que una rueda de repuesto es más barata que un coche de repuesto, que dos, que cinco. La alta disponibilidad, cuanto más alta, más cara. Cada nueve añadido al porcentaje que garantizamos de disponibilidad se traduce en más recursos para aumentar la tolerancia a posibles fallos y como tal implica costes adicionales. Y en Azure no es excepción. Al definir en un Availability Set más Failure Domains y más Update Domains, el coste asignado va en incremento.
Regresamos a la realidad más práctica del Camp. Con nuestra red virtual montada y un DC, levantamos dos máquinas similares en su configuración, siendo ambas VMs, máquinas con un servidor SQL instalado, que tras unir a dominio, conviene instalar el rol de “Failover” y SQL Management Studio, herramienta útil para tener una interfaz más “user-friendly” al conectarse a nuestra base de datos y más tarde, haremos que estos servidores SQL sean parte de un cluster que ofrezca el servicio SQL. Para poder hacer esto, Azure tiene un recurso llamado “equilibrador de carga” (Load Balancer), que permite conectar nuestro Availability Set como “Back-End” de un servicio, que prestamos por un “Front-End”, una IP que, a través del Load Balancer, pondrá en contacto.
En un principio, con dos máquinas servidores SQL, hay dos instancias SQL, son bases de datos separadas. Para poder unirlas y que ambas ofrezcan la misma base de datos desde ambos servidores, nos vamos a valer de una funcionalidad propia de SQL llamado Always-On (disponible sólo si nuestros servidores pertenecen a un cluster). Si bien debemos recordar algunos aspectos básicos de SQL como que, aunque seamos administradores de una máquina, si nuestro usuario no tiene creada una cuenta con permisos hacia nuestra instancia de SQL, no tendremos acceso a la base de datos. El Management Studio nos permite crear usuarios dentro de nuestra instancia SQL. Necesitaremos conocer esta diferencia, ya que las credenciales de acceso y ejecución en una máquina para un servicio SQL no es igual que el acceso a la propia base de datos.
Antes dijimos que habría una “triquiñuela” para que un balanceador de carga se convirtiera en un Failover Cluster ¿Cómo haremos tal cosa?
Instalando el rol de Failover, tendremos la posibilidad de crear un cluster SQL por Failover, de forma que pasaremos de dos servidores separados a un servicio prestado por dos nodos. Una vez unidos al cluster y activado el Always-On en ambos, hay que asegurarse de que ambos nodos estén replicando, de forma que los cambios en un nodo actúen sobre una base de datos conjunta, y no dos bases de datos separadas en cada servidor (en el Manager se denomina Data Loss).
La triquiñuela en cuestión es conectar el balanceador de carga de Azure, que debería funcionar como un “repartidor” de trabajo entre más de una máquina puesta en la “trastienda” (nuestro Back-End), y servirá para dar ese servicio SQL. Pero conectándolo balanceador, funcionará en modo round-robin. Cada nueva conexión irá a parar a los diferentes servidores, y lo que queremos es que “virtualmente” sea un nodo el que da servicio y sólo si falla, el otro nodo levante el servicio y mantenga su disponibilidad. Aquí es donde vamos a dar el golpe de efecto.
Los balanceadores de Azure requieren un “health probe” y una regla de balanceo. El balanceador como tal no sabe (hasta que nosotros se lo indiquemos) cómo comprobar que un nodo de su Back-End está vivo, y aunque lo sepa, no sabe qué hacer si detecta que está vivo o muerto ¿Cuál es la triquiñuela, pues? Que si designamos un puerto para el “health probe” que sólo esté activo en el nodo activo del cluster failover que hemos montado (en este caso, un puerto TCP privado por el que sacaremos el servicio SQL en el nodo activo, que debe ser exactamente el mismo tanto en el cluster como en el balanceador, y de esto debemos asegurarnos, ya que si apuntamos a una IP y puerto donde no estemos lanzando el servicio, el balanceador no detectará nada, y no habrá servicio alguno desde el Front-End), el balanceador entenderá que las peticiones sólo se pueden dirigir al único nodo activo del cluster, y en caso de que el nodo falle, el cluster conmutará por Failover al otro nodo, el Balancer lo detectará, redirigiendo sus consultas a ese nodo, y como nota de experiencia, nos comentan que conviene agregar el “floating IP” a las reglas de balanceo.
Este “workaround” es la forma de generar un cluster Failover en Azure, ya que la Virtual IP generada en el cluster on-premise no nos servirá, al funcionar Azure en una capa diferente del modelo OSI, y al tener un balanceador que, así como viene, no funciona como un conmutador por fallo, en caso de que no queramos un balanceador de carga, sino un conmutador por fallo en nuestra infraestructura on-cloud. El funcionamiento lo comprobaremos conectándonos al servicio lanzado por el balanceador de carga, desde nuestro DC, situado en la otra parte de la red virtual, asegurando que, si un nodo cae, el otro retomará su servicio, y a ése nuevo nodo se redirigirán las consultas SQL.
Regresamos al título: una de IaaS, despliegue por plantilla y Alta disponibilidad.
Estamos en la recta final de este Camp y tal vez sea buena idea recordar dónde encajan estos términos en nuestro periplo informático de hoy.
¿IaaS? Azure nos ha permitido levantar una infraestructura sin tener que enchufar un equipo, atornillar nada en un rack ni crimpar un cable. Nuestra Infraestructura es el servicio de Azure.
¿Despliegue por plantilla? Nuestras plantillas JSON nos han facilitado la creación de máquinas virtuales, redes virtuales y esto es tal vez más importante de lo que nos ha podido parecer, porque si bien hemos levantado dos máquinas, un despliegue por plantilla facilita el escalado del despliegue a costa de un mayor tiempo de planificación, existiendo una diferencia de tiempos mínima entre un despliegue de pocas máquinas y un despliegue más voluminoso.
¿Alta Disponibilidad? Levantar una infraestructura de dos nodos, crear un cluster de conmutación y “burlar” al balanceador para que actúe como un Failover garantiza que el servicio prestado por el cluster se mantenga, resistiendo el fallo de uno de los nodos, pero no termina aquí. Azure nos da opciones para tener nuestros recursos replicados en distintas ubicaciones físicas y agrupaciones lógicas gracias a sus Availability Sets, y sus Failure Domains y Update Domains.
Y ya cerramos, apagamos (y con mucho pesar, borramos, para evitar gastos en nuestra suscripción de Azure) las máquinas e infraestructura creada en el día de hoy, entendiendo un poco más, ya no sólo sobre el comportamiento de una infraestructura en alta disponibilidad, sino también un poco más los resquicios de las diferencias entre la infraestructura on-premise y on-cloud, ya que aunque por fuera pudiera parecer o funcionar de forma idéntica, hay pequeños matices que pueden cambiar (a veces mucho) las reglas del juego, nos despedimos. Agradeciendo a Santiago y a Roberto tamaña master-class, hasta el siguiente Camp de Sistemas.
Autores: Gabriel Piuzzi Martínez y Juan José Dorado
Coordinadores Tech Club Tajamar
Alumnos del Máster Microsoft MCSA Windows Server 2016 + MCSE Cloud Platform & Infrastructure.
Año académico: 2017-2018