Hace algún tiempo, empezamos a discutir el significado de Cloud Native en Codurance con el fin de formar algún tipo de consenso en torno a nuestra interpretación. A medida que íbamos estudiando el tema, nos dimos cuenta de que en realidad había mucho más que una simple respuesta o un artículo. De hecho, enseguida nos dimos cuenta que había una serie de artículos sobre los que escribir. El resultado es este artículo de prueba que señalará el camino a los otros temas que creemos que son una parte esencial de lo que significa Cloud Native y por qué debería interesarnos.
Introducción
A principios de la década de 2000 escuchamos mucho sobre los principios SOLID. A medida que el mundo del software se alejaba de las aplicaciones de Windows hacia la funcionalidad basada en la web, empezamos a escuchar sobre aplicaciones de 12 factores. Este concepto fue propuesto por primera vez por Heroku alrededor de 2011. Diez años después, la web ha madurado. En particular, la mayoría de las organizaciones han trasladado su patrimonio de IT de sus instalaciones o del centro de datos físico a la nube. Esto ha abierto un gran potencial incluso para las empresas más pequeñas. Pero con ese potencial adicional han surgido nuevos desafíos de diseño.
¿Cómo puedes aprovechar al máximo el poder de la nube para desbloquear un nuevo valor para tu negocio? Diseñar sistemas y soluciones para aprovechar al máximo la nube, eliminar los grilletes impuestos por las restricciones del hardware tradicional y comprender cuándo y cómo aprovechar las soluciones comercializadas existentes se conoce como arquitectura Cloud Native. En este artículo discutimos lo que realmente se entiende por 'arquitectura Cloud Native', cómo podemos aprovecharla y cómo podría aplicarse a tu organización.
Breve historia de la nube
AWS lanzó S3, SQS y EC2, inicialmente sólo en América, durante el 2006. GCP se lanzó en abril de 2008 y Microsoft Azure salió al mercado en febrero de 2010. Durante muchos años, la principal funcionalidad que ofrecían estos nuevos servicios de computación en la nube, era que proporcionaban abstracciones en la nube que imitaban la funcionalidad del hardware que se mantenía en salas de servidores privadas o centros de datos privados o públicos. Algunas de las ventajas inmediatas de este nuevo paradigma de alojamiento eran:
- Como todas las máquinas eran ahora virtuales, poner en línea nuevas máquinas o sacarlas de un clúster se convirtió en algo rápido y sencillo. En mayo de 2009, Amazon lanzó los Grupos de Auto Escalado de AWS, que permitían a las empresas escalar de forma automática y rápida en respuesta a los cambios en la demanda.
- Los servidores dejaron de ser algo que requería inversión en mantenimiento y, por lo tanto, se abarataron.
- Los servidores ya no eran un único punto de falla.
Abstracciones decepcionantes
El valiente nuevo mundo de la computación en la nube no estuvo exento de dificultades. En los primeros días de la infraestructura en la nube, las abstracciones ofrecidas por AWS y Azure reflejaban exactamente la infraestructura física que intentaban sustituir. Azure ofrecía servidores basados exclusivamente en Windows de 2010 para alojar aplicaciones, mientras que AWS ofrecía servidores EC2 (Elastic Compute Cloud) de 2006 que ejecutaban diversos sistemas operativos.
Además de producir una abstracción de un servidor, tanto AWS como Azure crearon abstracciones para dispositivos de hardware comunes. Así, en AWS teníamos ELB (Load balancer), NAT Gateway, VPC y Subnet, entre otras cosas. Aunque estas abstracciones sin duda tenían sentido para los ingenieros de infraestructura, no ofrecían ninguna ayuda nueva a los equipos de entrega de software, que seguían dependiendo de los ingenieros de infraestructura para desplegar y ejecutar sus aplicaciones.
Por lo tanto, aunque la nueva naturaleza flexible de los servicios en la nube puso más poder en manos de los equipos de desarrollo, fue difícil aprovechar este potencial y pasar a una mentalidad DevOps, ya que la primera oleada de abstracciones en la nube no abordó la tradicional división de competencias y conocimientos entre desarrolladores y operaciones.
Migración a la nube Lift and Shift
Muchas organizaciones consideran el traslado de sus servidores a la nube como un fin en sí mismo. A menudo planean una migración apresurada a la nube, posiblemente porque su contrato en el centro de datos está expirando y estarán ansiosos por asegurarse de que todo funciona en la nube como lo hace en el centro de datos. Se trata de una ansiedad perfectamente razonable y la forma lógica de asegurarse que el negocio continúe sin problemas es comprobar que todos los servidores y la infraestructura de red se copien en la nube tal y como están. Este es el (anti) patrón de la 'migración a la nube Lift and Shift'.
Hay dos problema obvios con Lift and Shift:
- Cualquier deficiencia arquitectónica que se haya acumulado a lo largo de la vida del sistema se reproducirá en la arquitectura de la nube porque es exactamente la misma.
- No se aprovechará ninguno de los servicios específicos de la nube que podrían satisfacer las necesidades de tu empresa de forma más adecuada y barata.
Las promesas de la nube: Escalabilidad/ Aislamiento/ Mantenibilidad/ Extensibilidad/ Desacoplar equipos/ Control del gasto/ Resiliencia
Escalabilidad
El balanceo de carga no es un concepto nuevo, ni de la nube. La idea es que el tráfico entrante es recibido por un tipo especial de servidor web llamado equilibrador de carga. Este componente pasa el tráfico hacia un grupo de servidores (generalmente llamado clúster) y hay un mecanismo por el cual el equilibrador de carga rota el tráfico entre los servidores en su clúster. Antes de la nube, la configuración general era tener un número fijo de servidores en el clúster que fuera capaz de manejar el tráfico a cualquier nivel de la demanda esperada.
Todos los proveedores de nube ofrecen algún tipo de escalado automático de servidores. AWS introdujo el concepto de grupos de autoescalado en mayo de 2009. En un grupo de autoescalado, el equilibrador de carga reenvía el tráfico de la misma manera que un equilibrador de carga tradicional, pero la diferencia es que hay un mecanismo que supervisa los niveles de tráfico y añade o elimina nodos del clúster en función del nivel de la demanda.
Aislamiento
Una promesa clave de la nube es aislar los componentes de tu solución entre sí. En los viejos tiempos de los servidores alojados u on-prem, los fallos solían ser globales (con respecto a una sola organización) o, al menos, de muy amplio alcance. Si un solo servidor se caía, tendía a colapsar muchos servicios, tanto externos como internos. Los problemas de red solían provocar todo tipo de problemas, tanto dentro como fuera de la organización. La nube ofrece la tentadora posibilidad de limitar el radio de explosión de los fallos aislando los fallos en servicios individuales, en lugar de a nivel de servidores o redes. A estas alturas, debería estar bastante claro que para aprovechar las ventajas del aislamiento de componentes debes tener ya componentes desplegables por separado. Si tu solución es, por ejemplo, una aplicación monolítica de Ruby on Rails, sólo será posible desplegarla como una sola unidad.
Mantenibilidad
La nube ofrece la promesa de simplificar tu carga de soporte operativo. Ya no tienes que cuidar cuidadosamente de servidores físicos, como un cuidador de zoológico que asegura la salud de cada servidor (nombrado individualmente). En lugar de ello, tu mentalidad operativa puede asemejarse más a la de un ganadero de ovejas con un gran número de activos innominados, en gran medida autosuficientes y fungibles, que en conjunto garantizan la salud de la organización en general.
Extensibilidad
La nube debería permitirnos desplegar rápidamente nuevas capacidades mediante el uso de una infraestructura gestionada por productos básicos. Pero esto conlleva también un coste. Cuando teníamos un monolito podíamos permitirnos el lujo de idear un sistema de autenticación exclusivo para nuestro monolito, como el uso de usuarios activos del directorio en la base de datos y el control de los permisos a través del motor de la base de datos. No es práctico extender tu propia seguridad a cada nuevo componente. Así que tenemos que empezar a entender cómo funciona un servicio generalizado. Podemos utilizar plantillas de servicios o similares, pero esencialmente estamos hablando de reconocer aquellas partes de la pila de software que son productos básicos frente a aquellas partes que son factores de diferenciación de tu negocio respecto a tus competidores.
Desacoplar equipos
La nube ofrece formas de desacoplar a tus equipos. Esto es importante porque significa que cada equipo puede poseer su propio flujo de valor y desplegar nuevo valor cuando sea necesario. Además, elimina la sobrecarga de coordinación, liberando a las personas para que añadan valor real a la empresa, y reduce drásticamente el time to market, o plazo de lanzamiento. Sin embargo, para desacoplar a los equipos hay que desacoplar el software. Esto introduce una sobrecarga en la madurez de la organización, de las herramientas y de la ingeniería.
También hay una barrera más sutil que hay que superar. Para desacoplar por completo a los equipos, tienes que confiar en ellos para que consigan sus objetivos. Esto significa que la empresa en su conjunto y, en particular, los niveles de dirección, tienen que dejar de ser gestores y empezar a ser facilitadores. Tienen que entender cómo confiar en los equipos para que obtengan buenos resultados. Este es otro artículo completo en sí mismo.
Control del gasto
En el antiguo modelo de infraestructura basado en servidores metálicos y granjas de servidores, los servidores físicos tenían un alto precio, tanto en términos de coste absoluto como de tiempo de aprovisionamiento de nuevos servidores. Esto dificultaba la optimización de los costes de dos maneras diferentes:
- El retraso asociado a la puesta en línea de nuevos servidores obligaba a la mayoría de las organizaciones a pagar por más capacidad de la que necesitaban, para evitar que los clientes tuvieran una mala experiencia en momentos de alta demanda. Esto suponía una dificultad especial para las empresas de comercio electrónico establecidas en una estrecha franja horaria, como Europa Occidental, donde la demanda sería alta sólo durante unas pocas horas predecibles cada día.
- El alto coste de aprovisionar un nuevo servidor llevó a los equipos de infraestructura a instalar muchos servicios diferentes en cada servidor. Esto hacía imposible escalar por componentes o servicios, ya que la unidad de escalabilidad era el propio servidor. Así, potencialmente, un clúster podría requerir instancias de recursos adicionales porque uno de sus muchos servicios instalados experimenta picos regulares de tráfico. De este modo, se aprovisionarán recursos adicionales para muchos servicios que no los necesitan.
Una de las principales promesas de la computación en la nube es que, al segregar tus servicios en unidades desplegables más pequeñas, puedes optimizar el coste del alojamiento de tus servicios.
Resiliencia
La nube promete que sus componentes pueden seguir funcionando incluso si la funcionalidad de la que dependen no está disponible por cualquier motivo. Esto es crucial cuando se trata de un sistema de gran tamaño. Por ejemplo, podría ser que no pudieras realizar transacciones a una determinada parte del país porque la API de un servicio de mensajería que necesitas para cumplir con esos pedidos no está disponible. No tendría sentido rechazar las transacciones que no necesitan de esa mensajería y menos sentido tendría rechazar el tráfico entrante a tu sitio web. La nube promete que podemos mantener un servicio adecuado para las dependencias que si están disponibles. Esto nos permite mantener algo cercano al 100% de tiempo de funcionamiento, incluso cuando la fiabilidad de las dependencias descendentes está lejos de ser total.
La Cloud Native Premium
En 2015 Martin Fowler escribió sobre los Microservicios Premium. Gran parte de lo que se escribió en el pasado sobre los microservicios podría aplicarse igualmente a Cloud Native en la actualidad. El lector más observador se habrá dado cuenta de que muchas de las promesas de la nube mencionadas anteriormente dependerán de que el sistema general en cuestión tenga un grado de separación de componentes. Si bien no es necesario entrar en la definición precisa de una arquitectura de microservicios, es seguro decir que si tienes una aplicación monolítica en el núcleo de tu negocio, tendrás que considerar la división de ese monolito para considerarte nativo de la nube.
Dividir el monolito
Muchas de las promesas de la nube exigen que hayas dividido tu aplicación monolítica en unidades desplegables más pequeñas. No puedes escalar componentes individuales, desplegar unidades por separado o desacoplar tus equipos de forma efectiva si tienes una solución monolítica. Esto no tiene por qué significar la implementación de una "verdadera" arquitectura de microservicios. Por ejemplo, puedes tener una gran base de datos monolítica que subyace a toda tu operatividad y sirve como un gran punto de acoplamiento. Podrías lograr muchas promesas de la nube aceptando, al menos por el momento, que este punto de acoplamiento permanecerá mientras divides el código base en sus partes verticales lógicas. Hay varias estrategias para dividir una aplicación monolítica que no cubriremos en detalle aquí.
Fracasar con elegancia
La nube promete que podemos mantener nuestro servicio incluso cuando las dependencias no estén disponibles. Mantener la experiencia del usuario es vital, así como permitir que tus usuarios hagan todo lo que quieran mientras se relacionan con tu empresa. Para que esto suceda, es importante que tu solución esté diseñada para fallar con elegancia y sin degradar la experiencia del cliente. La solución para conseguirlo es una combinación de estrategias que garanticen la continuidad del servicio, como el almacenamiento en caché, la redundancia y la replicación, combinadas con una cultura de desarrolladores sobre la tolerancia a los fallos. Hay muchas maneras de asegurarse de que su solución falla de una manera que no degrada la experiencia del cliente, pero el punto clave es que tenemos que esperar el fracaso de las dependencias (tanto internas como externas), asumir que va a suceder y asegurarnos de que lo tratamos adecuadamente. Este será el tema de un próximo artículo.
Monitoring
Si asumimos que nuestra arquitectura se ha convertido en nativa de la nube y suponemos que hemos evolucionado hasta un lugar en el que somos capaces de aprovechar todo el potencial que ofrece el proveedor de la nube que hemos elegido, entonces es justo asumir que estamos gestionando un gran número de servicios o aplicaciones que se despliegan a través de un gran número de entornos diferentes. Como hemos visto, los fallos no sólo son probables, sino inevitables, y cuando aceptamos que van a ocurrir, tenemos que centrar nuestra atención en restablecer el servicio lo más rápido posible y luego designar la causa de la falla.
Para diagnosticar con rapidez los fallos y poder analizar la secuencia de acontecimientos que han conducido a un error es fundamental disponer de una instrumentación eficaz en torno a toda nuestra solución. No será posible gestionar la enorme cantidad de activos en constante evolución sin un método sofisticado y específico de control, registro y visualización de todos los datos relevantes. Esto significa que un prerrequisito esencial para la arquitectura nativa de la nube es la existencia de un marco sólido para cotejar y visualizar cualquier información de seguimiento relevante, y una comprensión clara por parte de los equipos de entrega en torno a sus responsabilidades para instrumentar de forma coherente y eficaz su aplicación y servicios.
Además de las soluciones de registro y observabilidad ofrecidas por los principales proveedores de nube, hay varios fabricantes, como logz.io, que las ofrecen. Las estrategias de monitorización y alerta son un tema que se analizará en un próximo artículo.
Romper los muros de la infraestructura de desarrollo
Será muy difícil aprovechar al máximo la nube, incluso si cumples con todas las opciones de diseño recomendadas, si mantienes una separación entre las preocupaciones de los desarrolladores y las de las operaciones. Tenemos que asegurarnos que los equipos de entrega puedan construir y ejecutar cosas sin depender de un equipo separado. Esto significa apropiarse del código, del canal de despliegue y de la infraestructura. Nótese que no significa ser dueño de las cuentas de la infraestructura, sólo de la parte de la infraestructura que se necesita para alojar las unidades desplegables que tu equipo posee. Ciertamente, no significa, por ejemplo, que los equipos de desarrollo deban ser dueños de las preocupaciones transversales, como la infraestructura SSO.
Todavía hay un caso para tener un equipo de operaciones que tal vez posea la funcionalidad que es utilizada por todos, como la infraestructura de monitoreo. También hay un buen caso, si el tamaño de la organización es apropiado, para que haya un "equipo de infraestructura" que actúe como consultores internos expertos o facilitadores de valor, para los equipos de desarrollo puros. Hay muchas maneras de garantizar que los profesionales de la infraestructura añadan valor a tu negocio y no cubrimos esas estrategias aquí. El punto clave es que cada equipo de entrega debe ser capaz de aportar valor a su flujo de valor sin la aportación directa de otro equipo.
Próximamente escribiremos un artículo sobre cómo abordar la adopción de prácticas de ingeniería DevOps dentro de tu organización.
Te dejamos un link a nuestro podcast en el que hablamos de los retos y oportunidades de la ingeniería de plataformas y DevOpsis.
Marcos de proveedores Cloud Native
Los grandes proveedores tienen sus propias ideas de lo que significa Cloud Native, pero en realidad, esto suele significar la optimización de tu arquitectura para aprovechar las herramientas que son específicas de ese proveedor de la nube. Este enfoque es valioso y puede ayudarte a sacar el máximo provecho del proveedor que hayas elegido, pero por la propia naturaleza de la optimización de tu arquitectura para un proveedor específico, te arriesgas a quedar atrapado en ese proveedor.
Por lo tanto, aunque Cloud Native puede significar algo ligeramente diferente en AWS que en, por ejemplo, GCP, hay un número limitado de casos de uso en los que las consideraciones de alto nivel de lo que significa ser nativo de la nube serían lo suficientemente diferentes como para marcar una diferencia en lo que Cloud Native significa para tu solución. Las diferencias en los proveedores de la nube es un tema que se tratará en un próximo artículo.
Conclusión
Cloud Native significa cosas diferentes para muchas personas distintas. Creo que se puede resumir de forma concisa como:
Cloud Native es la práctica de diseñar y evolucionar una solución que aproveche al máximo las capacidades de producción de la computación en nube, y así permitir que los equipos de entrega se concentren sólo en los aspectos de la solución que diferencian al negocio.
Así, mientras que los diferentes proveedores de la nube, consultores y empresas de productos tendrán su propia definición de lo que diferencia a su negocio, lo que lleva a su propia definición adaptada de "nativo de la nube", esta definición más general permite matices en la descripción y debería ayudarte a determinar tu propia definición.
Entonces, ¿por qué debería tenerlo en cuenta?
La respuesta es muy sencilla. Si quieres obtener todos los beneficios de la nube, si quieres que tus desarrolladores se concentren en diferenciar tu negocio y quieres estar seguro de que tu empresa está bien preparada para afrontar los inevitables e imprevisibles cambios que se avecinan, NECESITAS interesarte por Cloud Native.