Ningún sistema o plataforma en producción es infalible a caídas. Tampoco podemos asegurar que el lanzamiento de ningún producto se venga abajo a las pocas horas. Quizás en algunos casos se podría haber evitado con un mayor esfuerzo de desarrolladores de software y los administradores de sistemas en las configuración de las aplicaciones, pero nada es así de obvio cuando dispones de una vasta infraestructura distribuida y en diferentes servicios en la nube.
Los usuarios de internet parecen acostumbrados a que sea “normal” que alguna de sus apps o plataformas en la nube se caiga cada cierto tiempo. Pasen horas sin poder acceder al servicio o no puedan ver el último capítulo de su serie. Lo hemos visto con Facebook, Whatsapp o, incluso con algo mucho más frustrante, como HBO España en el estreno de Juego de Tronos. ¿Pero cómo evitar esas caídas masivas? ¿Y, por supuesto, evitar las pérdidas de monetarias que se producen cuando esto sucede?
De aquí surge Chaos Engineering poniendo sobre la mesa la idea de cómo afrontaría cualquier infraestructura distribuida el hecho de que un ejército de monos entrara a sabotear cada una de las configuraciones de red, apagando máquinas en AWS o tirando de forma aleatoria algunos de los microservicios conectados. ¿Qué ocurría? ¿Seguimos respondiendo con normalidad? ¿O por el contrario responderemos con terribles errores 500, 503 o nada de nada?
Chaos Engineering no es algo nuevo, ni el hype del momento
Tenemos que remontarnos a finales de 2010 cuando Netflix publicó su magnífico post sobre las lecciones aprendidas migrando a Amazon Web Service. Por un lado dejaba claro, como una empresa de sus dimensiones necesitaba la nube para poder seguir creciendo y, por otro lado, dejaba claro la preocupación de cómo iba asegurar que todo funcionará bien teniendo ya decenas de servicios distribuidos y ahora totalmente deslocalizados de sus data centers.
De este modo, lo primero que hicieron fue crear un conjunto de herramientas llamadas como el cariñoso apelativo de Chaos Monkey. En un principio, para matar aleatoriamente instancias de AWS y ver cómo afectaba sobre su infraestructura.
De este modo, Netflix se aseguraba tener un control predictivo de cuál sería la experiencia del usuario cuando alguno de sus elementos más importantes se viniera abajo. Así, si el sistema de recomendaciones se caía, ellos podrían redirigir ese tráfico a algo más estático como el listado de de series más populares. O si el sistema de streaming de la plataforma fallaba podría empezar a ajustar la calidad de la reproducción hasta estabilizar la plataforma, de modo que el usuario pudiera seguir usandolo sin cortes. En ningún caso, si la base de datos de recomendaciones falla debería afectar a otro servicio aislado como el servicio de streaming. Si esto sucediera tendríamos un problema, probablemente una dependencia mal configurada totalmente innecesaria.
Causar fallos intencionadamente para descubrir errores en nuestra plataforma en producción
Los primeros en convencerse en usar Chaos Engineering serán aquellos que han tenido que luchar con fallos en producción un viernes por la noche o un día festivo. No están dispuestos a que eso vuelva a ocurrir.
La metodología que promueve Chaos Engineering es simple en concepto, pero complicada de ejecutar. Si los test unitarios son la parte más “micro” centrada en que nuestro código haga lo que dice que hace, entonces Chaos Engineering se puede considerar perfectamente como la parte “macro” para asegurar el correcto funcionamiento en conjunto de toda nuestra infraestructur (en producción).
Es muy complicado a día de hoy introducir la importancia de Chaos Engineering en la cultura de muchos equipos de desarrollo. Posiblemente culpa de los responsables técnicos como el director de tecnología (CTO o CIO) incapaces de comprender lo que cuesta realmente esos fallos de producción cuando ocurren y lo que cuesta a la empresa.
Obviamente, introducir una cultura entre el equipo de desarrolladores de software en la que busquemos proactivamente los fallos de nuestro sistema no es algo habitual, más bien nos tiramos de los pelos a posteriori cuando algo falla inexplicablemente.
Aunque cueste, necesitamos encontrar esos fallos antes de que pasen en nuestra arquitectura: esas latencias innecesarias, esos fallos aleatorios que no sabemos descubrir o que nos impediría servir adecuadamente todas las peticiones que nos lleguen cuando nuestra plataforma tenga un pico de usuarios activos.
Probablemente, los primeros en convencerse serán aquellos que han tenido que luchar con fallos en producción un viernes por la noche o un día festivo. No están dispuestos a que eso vuelva a ocurrir.
Chaos Engineering en la práctica
Tal como describe el manifiesto de Chaos Engineering, para abordar la incertidumbre de los distribuidos a gran escala debemos seguir una serie de pasos para realizar los experimentos necesarios:
Tenemos que ser capaces de medir nuestro sistema en condiciones normales. Si no estamos monitorizando nuestra plataforma, ya no sólo no podremos averiguar qué falla cuando ejecutemos el experimento, sino que a día de hoy somos incapaces de ver que algo está dando errores. Importante siempre monitorizar tus aplicaciones y la salud de tus componentes.
Realizar hipótesis sobre estado al que llevaremos al sistema en producción con los fallos. ¿Cómo debería comportarse? ¿Qué esperamos de él?
Definiendo los puntos de fallo de nuestro sistema tenemos que acordar ciertos eventos que provocarán errores lo más parecidos al mundo real: servidores que dejan de funcionar, discos que se quedan sin espacio o pasan a modo lectura, conexiones de red inestables, latencias altas de respuestas,..
Trazar un plan revisando los resultados del experimento. Si se ha cumplido nuestra hipótesis o si nos hemos dado cuenta que hay debilidades reales que hacen caer al sistema. Tenemos que solucionarlas antes de que se produzcan de forma real.
Herramientas para utilizar Chaos Monkey en tus aplicaciones
Durante estos años tanto Netflix como AWS han ido desarrollando algunas herramientas para poder simular esos eventos en entornos complejos. Netflix los bautizó como su SimianArmy donde encontramos distintos agentes encargados de elementos fundamentales dentro de nuestra configuración:
Introducir delays artificiales a la capa RESTful client-servidor para simular la degradación del servicio y medir si los tiempos de respuestas finales se ven afectados y de qué modo.
Encontrar instancias que no se adhieren a los best-practices definidas y ser apagadas. Por ejemplo, esas máquinas puede que estén mal configuradas y no estén siendo autoescaladas adecuadamente.
Detectar recursos que no se estén usando en AWS y ser eliminados o descubrir vulnerabilidades o configuración erróneas de seguridad.
Podéis consultar el proyecto open source en Github de SimianArmy y su migración dentro de la infraestructura de CI de Spinnaker. También hay algunos proyectos como Gremlin que intenta acercar los conceptos de Chaos Engineering a más empresas de forma intuitiva a través de su plataforma.
Y si os interesa más el tema aquí os recomiendo este listado sobre recursos en Github: Awesome Chaos Engineering. Así como el libro que escribió el equipo de Netflix sobre el tema.
Como mencionamos más arriba, es necesario que estos experimentos sean adoptados como algo cultural del equipo de desarrollo. Para llevar a cabo los pasos descritos necesitamos flexibilidad para poder simular estos eventos en nuestro entorno de producción o si tenemos un entorno de staging para un experimento inicial más aislado.
Aunque tenemos que recordar que nuestro objetivo es encontrar fallos lo más reales posibles. Y, aunque suena mal, debemos hacer esas pruebas en producción.
Foto | howling red on Unsplash
Ver 4 comentarios