Evolución de la validación de red en Hostinger
La red es la parte más sensible de una infraestructura. Para que siga funcionando con menos tiempos de inactividad, es necesario validar la configuración antes de implementar nuevos cambios en el entorno de producción.
Este artículo proporciona información sobre cómo probamos y validamos los cambios en la red, y cómo esta evolución contribuye al nivel de confianza que nosotros y nuestros clientes tenemos en los servicios de Hostinger.
Razones detrás
En 2015, no teníamos ninguna automatización de red en Hostinger. En cambio, había un par de enrutadores centrales (serie Cisco 6500) por centro de datos y muchos conmutadores HP bastante no administrados para proporcionar conectividad L2 básica. Bastante simple, sin alta disponibilidad, un gran dominio de fallas, sin dispositivos de repuesto, etc.
No existía control de versiones en ese momento en Hostinger, lo que significa que las configuraciones se guardaban en algún lugar o en las computadoras de alguna persona. Entonces, esto plantea la siguiente pregunta: ¿cómo logramos ejecutar esta red sin automatización, validación e implementación?
¿Cómo validamos la configuración si es buena o no? De ningún modo. Solo un poco de observación, empujando los cambios directamente a través de CLI y rezando. Incluso la función de reversión de la configuración no estaba disponible. La red fuera de banda no existía. Si cortas la conexión, está perdidos, algo como lo hizo Facebook recientemente, y solo el acceso físico puede ayudarte a recuperarlo.
El diseño y la implementación estuvieron en la parte superior de la cabeza de dos personas. Los cambios en la red de producción fueron dolorosos y propensos a errores humanos. Tuvimos un monitoreo deficiente con reglas básicas de alerta, un par de gráficos de tráfico y errores. No hay un sistema de registro centralizado, pero eso definitivamente era mejor que nada. No es exagerado decir que hoy en día, las pequeñas empresas utilizan este tipo de método simple para monitorear la red. Si funciona bien y es lo suficientemente bueno para funcionar, no lo toques.
Cuanto menos sepas sobre el estado de la red, menos problemas tendrás. En general, no teníamos herramientas internas o externas para hacer eso fundamentalmente.
La solución de Hostinger para la validación de la red
En 2016 comenzamos a desarrollar Awex, un servicio solo IPv6. Dado que se estaba construyendo desde cero, comenzamos a enviar la automatización desde el día 0. Tan pronto como notamos el buen impacto en la automatización, comenzamos a construir nuevos centros de datos usando Cumulus Linux, automatizándolos con Ansible, implementando los cambios usando Jenkins.
El flujo de trabajo simplificado fue:
- Hacer cambios.
- Confirmar los cambios, crear una solicitud de extracción en Github.
- Esperar una revisión de otras personas.
- Fusionar solicitud de extracción.
- Esperar a que Jenkins implemente los cambios en los conmutadores.
El inconveniente de este esquema es que los cambios de configuración se automatizan pero no se validan ni siquiera se prueban antes de la implementación. Eso puede causar una falla sustancial en el radio de explosión. Por ejemplo, si se implementa una dirección de bucle de retorno o un mapa de ruta incorrectos, puede causar que las sesiones de BGP se agiten o envíen toda la red al caos.
La razón principal para agregar automatización y validación es ahorrar tiempo en la depuración de problemas reales en la producción, reducir el tiempo de inactividad y hacer más felices a los usuarios finales. Sin embargo, siempre debes preguntarte: ¿dónde trazas la línea para la automatización? ¿Cuándo la automatización deja de agregar valor? Cómo llevar el proceso de automatización al punto en el que tenga sentido.
Desde entonces, nos hemos centrado en cómo mejorar aún más este proceso. Cuando tu red está creciendo y construyes más y más centros de datos, el mantenimiento se vuelve más difícil, lo que ralentiza el proceso de impulsar cambios en la producción.
Como siempre, hay que disyuntiva entre más lenta vs . despliegue más seguro. En Hostinger, estamos obsesionados con el cliente, y eso dice claramente que debemos preferir una gestión de procesos más lenta que conduzca a menos tiempos de inactividad no planificados.
Cada falla te da una nueva lección sobre cómo mejorar las cosas y evitar que ocurran las mismas pérdidas en el futuro. Es por eso que la validación es imprescindible para una red moderna.
Si bien la mayoría de los cambios implican básicamente probar 2, 3, 4, 7 capas del modelo OSI, siempre hay solicitudes que Layer8 debe probar, que no es el alcance de esta publicación de blog.
Un par de años después, ya tenemos algunos centros de datos completamente automatizados. Durante ese tiempo, comenzamos a utilizar CumulusVX + Vagrant para las pruebas previas a la implementación. Ahora, el objetivo principal es detectar errores más rápido que el informe de los clientes.
Pruebas previas a la implementación
Básicamente, este es el escenario de prueba de la vida real en el que construyes virtualmente un centro de datos nuevo casi idéntico al que usamos en producción, excepto que la parte de hardware (ASIC) no se puede simular (programar). Todo lo demás se puede probar bastante bien, y eso ahorra cientos de horas de depuración en producción. Más sueño para los ingenieros. 🙂
Entonces, al crear una solicitud de extracción en Github, la fase previa a la implementación lanza un centro de datos virtual a gran escala y ejecuta un montón de pruebas unitarias. Y, por supuesto, algunas pruebas de integración para ver cómo interactúan los conmutadores entre sí. O simula otros escenarios de la vida real, como conectar un servidor a EVPN y ver si dos hosts en el mismo L2VNI pueden comunicarse entre dos racks separados. Eso toma alrededor de 30 minutos. Si bien no impulsamos decenas de cambios todos los días, es lo suficientemente bueno.
Además, realizamos pruebas en dispositivos de producción durante las fases de pre-implementación y post-implementación. Esto nos permite detectar la diferencia cuando la producción era verde antes de la fusión y cuando, de repente, algo anda mal después de los cambios.
Los problemas conocidos pueden acechar durante los meses de producción y, sin un control adecuado, no se pueden detectar correctamente. O peor aún, puede comportarse incorrectamente incluso si pensabas que estaba bien.
Para lograrlo, utilizamos el marco Suzieq y PyTest para integrar ambas herramientas. Suzieq es una plataforma/aplicación de observación de red de múltiples proveedores de código abierto que se utiliza para planificar, diseñar, monitorear y solucionar problemas de redes. Es compatible con todos los principales proveedores de enrutadores y puentes utilizados en el centro de datos.
Proporciona múltiples formas de usarlo, desde una CLI amigable para el operador de red hasta una GUI, un servidor REST y una API de Python. Aprovechamos principalmente la API de Python para escribir nuestras pruebas. Suzieq normaliza los datos entre varios proveedores y presenta la información en un formato sencillo y neutral para el proveedor. Nos permite centrarnos en escribir pruebas en lugar de recopilar los datos (y mantenernos al tanto de los cambios relacionados con los proveedores en sus sistemas operativos de red). Encontramos que los desarrolladores son útiles y la comunidad activa, lo cual es muy importante para obtener las correcciones lo más rápido posible.
Actualmente solo usamos Cumulus Linux, pero nunca se sabe qué cambiará en el futuro, lo que significa que la abstracción es la clave.
A continuación se muestran buenos ejemplos de cómo comprobar si los enlaces de estructura EVPN están conectados correctamente con MTU y velocidades de enlace correctas.
O verifica si la tabla de enrutamiento no cayó a menos de lo esperado y mantén un estado consistente entre compilaciones. Por ejemplo, espera más de 10.000 rutas de IPv4 e IPv6 cada una por conmutador de columna. De lo contrario, algunos problemas en la naturaleza: los vecinos están inactivos, se ha aplicado el filtro incorrecto, la interfaz está inactiva, etc.
Acabamos de comenzar este tipo de pruebas y esperamos extenderlas más en el futuro. Además, realizamos más comprobaciones previas a la implementación. Usamos Ansible para impulsar cambios en la red, y debemos validar cuidadosamente los libros de jugadas, los roles y los atributos de Ansible.
La implementación previa es crucial, e incluso durante la fase de prueba, puedes darte cuenta de que estás tomando decisiones absolutamente equivocadas, lo que eventualmente conduce a desastres complejos de ingeniería excesiva. Y arreglar eso más tarde es más que horrible. Las cosas fundamentales deben seguir siendo fundamentales, como la aritmética matemática básica: sumar, restar. No puedes tener cosas complejas en tu cabeza si quieres operar a escala. Esto es válido para cualquier ingeniería de software y, por supuesto, también para redes.
Además, vale la pena mencionar que también evaluamos Batfish para el análisis de configuración. Pero, por lo que probamos, no era lo suficientemente maduro para Cumulus Linux, y simplemente lo abandonamos para tiempos mejores. Fallos de análisis inesperados como advertencia de Parse – No se reconoce esta sintaxis . Por lo tanto, volveremos a Batfish el próximo año para verificar si todo está bien con nuestra configuración.
Despliegue
Esto es casi lo mismo que en el viaje de automatización inicial. Jenkins impulsa los cambios a producción si toda la validación previa a la implementación es verde y la solicitud de extracción se fusiona en la rama principal.
Para acelerar la implementación, utilizamos varios esclavos Jenkins para distribuir y dividir ejecuciones entre regiones a dispositivos cercanos. Usamos una red fuera de banda (OOB) que está separada del plano de control principal, lo que nos permite cambiar fácilmente incluso las partes más críticas del equipo de la red. En aras de la resiliencia, mantenemos la alta disponibilidad de la red OOB para evitar un solo punto de falla y mantenerla en funcionamiento. Esta red incluso está conectada a varios ISP.
Si perdimos la red OOB y la accesibilidad de la red central, probablemente sean problemas del centro de datos. Desafortunadamente, no ejecutamos servidores de consola ni redes de consola porque es demasiado costoso y un poco crítico para la seguridad.
Cada Pull Request verifica si el inventario de Ansible se analiza correctamente, la sintaxis es correcta, ejecute ansible-lint para cumplir con la estandarización. También confiamos mucho en Git.
Cada confirmación está estrictamente validada y, como debes notar, usamos etiquetas adicionales como Deploy-Tags: cumulus_frr que dice que solo ejecutes tareas de Ansible que tengan esta etiqueta. Está aquí solo para decir explícitamente qué ejecutar en lugar de todo.
También tenemos Deploy-Info: etiqueta Git de kitchen, que genera centros de datos virtuales en un entorno Vagrant utilizando el marco de la cocina, y puedes verificar el estado en la etapa previa a la implementación. Como mencionamos antes, Git es el núcleo para reflejar los cambios que prueban o ejecutan para esta confirmación.
Después de la implementación
La validación posterior a la implementación se realiza después de implementar los cambios en la red, para verificar si tuvieron el impacto deseado. Los errores pueden llegar a la red de producción, pero la duración de su impacto se reduce. Por lo tanto, cuando los cambios se envían a los dispositivos, ejecutamos instantáneamente las mismas pruebas de Suzieq previas a la implementación para verificar si tenemos el mismo estado deseado de la red.
¿Qué aprendimos?
Todavía estamos aprendiendo, ya que es un proceso interminable. Por ahora, podemos impulsar los cambios de forma más segura a la producción porque tenemos una capa que da un poco de confianza sobre los cambios que se están introduciendo en la producción. Si confiamos en nuestra red, ¿por qué no deberían hacerlo nuestros clientes? En Hostinger, siempre tratamos de crear un servicio, una red y un software pensando en las fallas. Eso significa pensar siempre que tu software o red fallará algún día, y debes estar preparado o al menos listo para solucionarlo lo antes posible.