Computación Cloud
Es un hecho indiscutible que la computación en la nube (cloud computing) ha sido la gran revolución tecnológica de los últimos años. Cada vez más empresas se han dado cuenta de que la migración a la nube permite agilizar los procesos, mejorar su productividad y, en definitiva, reducir costes.
Pero, ¿qué es la nube? El término nube generalmente se ha usado para describir los recursos remotos accesibles a una serie de sistemas cliente a través de Internet. En los gráficos donde se describe la arquitectura de los sistemas se suele pintar una nube para representar los recursos que son externos a la infraestructura de red local. Con la computación en la nube, las empresas (ahora como usuarias de servicios) pueden disponer de recursos que permiten ejecutar sus aplicaciones sin necesidad de tener sus propios servidores ni centros de datos, y pagar solo por el uso que hagan de estos recursos.
El concepto contrario y el más extendido hasta hace unos años es usar instalaciones propietarias, on-premises. Este paradigma está basado en la instalación de las aplicaciones en los servidores propiedad de la empresa que lo explota, lo cual implica tener un centro de datos propio o contratar los servicios de un tercero que proporcione dicho centro de datos.
La migración hacia modelos de computación en la nube minimiza el consumo de energía y de producción de productos electrónicos, ya que los recursos físicos son realmente compartidos y mutualizados por varios clientes y usados a demanda, lo que optimiza su uso y reduce la cantidad de máquinas necesarias. Esto conlleva no solo beneficios para las empresas, sino también para el medio ambiente. Un menor consumo energético y una menor fabricación de electrónica contribuye directamente a la reducción de emisiones.
Evolución del desarrollo software
Analicemos los problemas históricos relacionados con el desarrollo de software para los sistemas informáticos y la evolución que se ha ido produciendo para solucionarlos.
Metodologías
El ciclo de vida en cascada se vio ineficiente debido a que está pensado para producir software estático que no se adapta a las necesidades cambiantes de los clientes. Además, una mala interpretación de los requisitos en las fases iniciales se veía multiplicado (como una bola de nieve) al realizar la entrega del producto final, produciéndose entregas de ínfima calidad y el consiguiente descontento de los clientes. Esto llevó a un replanteamiento de las metodologías de proyectos de desarrollo software y al auge de las metodologías llamadas ágiles.
Estas nuevas metodologías (metodologías ágiles) definen ciclos de vida iterativos donde cada iteración produce una entrega que aporta nuevo valor a la solución, lo cual se traduce en despliegues frecuentes de software. Para ello es necesario definir procesos de integración y despliegue de forma continuada. Es lo que se conoce como Continuous Integration y Continuous Deployment, o por sus siglas CI/CD.
Para dar solución a esta necesidad existen múltiples herramientas que proporcionan la capacidad de sincronizar el código que generan los desarrolladores y automatizar las compilaciones y despliegues en diferentes entornos.
Arquitecturas
Las aplicaciones que se construían hasta hace no mucho seguían una arquitectura monolítica. Un monolito no es más que un pedazo de piedra de composición homogénea erguida sobre el suelo. El símil es muy gráfico: las aplicaciones se construían con grandes archivos de código que se compilaban todos simultáneamente y generaban un artefacto ejecutable que contenía toda la funcionalidad de la aplicación. El desarrollo y, aún más, el mantenimiento de este tipo de aplicaciones era realmente complejo aun cuando la aplicación, en sí misma, no representaba gran complejidad.
La puesta en servicio de estos sistemas normalmente requería una parada temporal de servicio y la atención de los equipos técnicos encargados del mantenimiento de los sistemas informáticos. Estos equipos normalmente eran ajenos a los desarrollos de las aplicaciones y, en muchas ocasiones, desconocían las necesidades de despliegue en cuanto a requerimientos de dependencias y otros aspectos técnicos necesarios para que la ejecución de las aplicaciones fuese viable. Habitualmente se daban situaciones en las que la ejecución era inviable por aspectos técnicos y se producía una guerra entre los equipos de sistemas y los de desarrollo. En esta pugna, la máxima defensa de éstos últimos era la frase ‘en mi máquina funciona’, refiriéndose a que en sus entornos de desarrollo la aplicación se ejecuta sin ningún problema. Además, los despliegues de varias aplicaciones se hacían en un mismo sistema operativo, lo que hacía que el mal funcionamiento de alguna de las aplicaciones desplegadas pudiese afectar al resto. Se necesitaba un mecanismo de aislamiento entre aplicaciones.
Para dar solución a estos problemas se comenzaron a usar máquinas virtuales y, un poco más tarde, contenedores. Las máquinas virtuales permiten la instalación de un sistema operativo en un hardware virtualizado dentro de un hardware físico. De esta manera. dentro de un mismo hardware se pueden tener instalados varios sistemas operativos independientes. Los contenedores son unidades estandarizadas que empaquetan piezas de software y que incluyen todo lo necesario para que se ejecuten, incluyendo bibliotecas y herramientas de sistema. La ventaja de los contenedores frente a las máquinas virtuales es que, los primeros, están basados en virtualización a nivel del sistema operativo y los segundos a nivel de hardware, lo que hace a los contenedores más livianos y rápidos de ejecutar.
Siguiendo la máxima ‘divide y vencerás’, la evolución de la arquitectura monolítica fue la división de piezas de código, en un principio con forma de librerías que se compilan de forma independiente y exponen una interfaz de programación (Application Programming Interface o, por sus siglas, API) para que desde la aplicación principal pudiese acceder a la funcionalidad de estas librerías. Más tarde estas API se fueron implementando en forma de servicios que exponen su interfaz a través del protocolo HTTP y que se ejecutan de forma independiente. De esta manera, una aplicación que exponga únicamente la interfaz gráfica o front-end puede hacer uso de estos servicios que serán los que realicen las tareas complejas, lo que se suele llamar lógica de negocio. Esta es la base de la arquitectura de microservicios.
Esta división en microservicios permite el despliegue de cada uno de ellos en un contenedor distinto y, por lo tanto, un aislamiento no solo entre aplicaciones, sino entre las diferentes partes de una misma aplicación. La arquitectura de microservicios permite cumplir con las entregas de forma continuada fácilmente ya que los despliegues se limitan solo a las piezas que han sido modificadas y no a todo el grueso de la aplicación. También fomenta un mejor control de calidad (QA, quality assurance) ya que al dividir también las pruebas en pequeñas piezas se permite detectar fallos en las partes concretas del software defectuoso.
Escalabilidad, disponibilidad, y tolerancia a fallos
Por otro lado, los despliegues de las grandes aplicaciones monolíticas eran lentos y necesitaban planificación anticipada. Cuando se producían errores toda la aplicación dejaba de funcionar con la consiguiente parada de servicio. Cuando aumentaba la necesidad de disponer de más memoria o más capacidad de proceso había que pensar en comprar máquinas más potentes y con más recursos. Las nuevas arquitecturas de desarrollo software intentan evitar estos problemas.
Hace unos años era impensable desarrollar aplicaciones que dieran servicio al público en general a nivel mundial. Ahora es muy común y todos las usamos continuamente, solo hay que pensar en tiendas online de productos, redes sociales o sistemas de mensajería.
Debido a las nuevas necesidades de procesamiento de datos a gran escala para dar servicio a un número masivo de usuarios, es necesario agilizar los despliegues para que sea fácil aumentar o disminuir los recursos de potencia computacional y memoria cuando sea necesario, atendiendo a la demanda. También es importante tener en cuenta la necesidad de alta disponibilidad. Con alta disponibilidad se entiende la capacidad de garantizar la continuidad de los servicios, incluso en situaciones en las que se produzcan errores o averías.
Ventajas de la computación en la nube
La computación en la nube permite cumplir con las nuevas necesidades de una manera sencilla y económica.
Por una parte, permite escalar horizontalmente los sistemas. El concepto de escalabilidad horizontal está relacionado con la arquitectura de microservicios. En lugar de aumentar los recursos de memoria o capacidad de proceso que sería una escalado vertical, se aumenta el número de instancias que se ejecutan de uno o varios de los servicios.
También permiten alta disponibilidad y tolerancia a fallos ya que los proveedores de servicios en la nube pueden reubicar el despliegue de los servicios de los clientes entre los cientos o miles de servidores de que disponen. Si alguno de estos servidores falla, los despliegues serán asignados a otros servidores automáticamente.
Cultura DevOps
Otra ventaja que aporta la computación en la nube es la sencillez del mantenimiento de los sistemas, facilitando la cultura Devops. Por Devops se entiende el conjunto de prácticas que agrupan el desarrollo de software y las operaciones relacionadas con la puesta en producción. Los equipos de desarrollo y los de sistemas trabajan con mayor cohesión e incluso pudiendo estar integrados en el mismo equipo.
Herramientas usadas en la computación en la Nube
Hay muchas plataformas que disponen de servicios para computación en la nube. Como ejemplos podemos nombrar a Amazon Web Services, Microsoft Azure, Google Cloud o IBM Cloud.
Todas estas plataformas incluyen una herramienta que proporciona, entre otras cosas, gestión de los contenedores donde se despliegan servicios, automatización de estos despliegues, escalabilidad horizontal, redireccionamiento y balanceado de las peticiones entrantes hacia los servicios, y ocultación datos sensibles de configuración (secrets). Nos estamos refiriendo, evidentemente, a Kubernetes.
Kubernetes
Kubernetes es un software de código abierto que proporciona una plataforma portable y extensible para administrar cargas de trabajo y servicios. Originalmente fue desarrollado por Google y lo usó ejecutando aplicaciones en producción durante quince años hasta que en el año 2014 lo liberó, pasando a ser un proyecto de código abierto.
Kubernetes ofrece un entorno orientado a contenedores que permite configurar un conjunto de componentes y herramientas que facilitan el despliegue, el escalado y la administración de aplicaciones. No limita de ninguna forma el tipo de aplicación que se despliega, cualquier aplicación que pueda ejecutarse en un contenedor lo puede hacer en Kubernetes. Tampoco impone herramientas CI/CD concretas, middleware como buses de datos o herramientas de monitorización, pero se integra bien con cualquiera de ellas.
Una de las bondades de Kubernetes es que expone una API que sirve para configurar el sistema de forma declarativa. También proporciona una herramienta para ejecutar desde la línea de comandos (kubectl) que permite crear, actualizar, eliminar y consultar objetos a través de la API. Esta API permite construir otras herramientas que se benefician de la funcionalidad que proporciona Kubernetes. Por poner un ejemplo: OpenShift es una plataforma de Kubernetes empresarial. Es una distribución de Kubernetes con algunos elementos añadidos como la interfaz gráfica.
Tiene un gran ecosistema, hay multitud de herramientas que trabajan en colaboración con Kubernetes y día a día se van renovando. También tiene una amplia comunidad detrás de ella que proporciona el soporte, las herramientas y los servicios para que las empresas puedan usar este software sin grandes riesgos.
Otros sitios donde encontramos Kubernetes es en las plataformas Cloud antes citadas, por ejemplo Amazon Elastic Kubernetes Service (EKS), Azure Kubernetes Service (AKS), Google Kubernetes Engine (GKE), o IBM Cloud Kubernetes Service, entre otros.
Hay que puntualizar que no por el hecho de ser una herramienta popular y usada extendidamente se tenga que adaptar adecuadamente a cualquier tipo de desarrollo. Por el contrario, se debe analizar con detenimiento para determinar si se ajusta a las necesidades de nuestro proyecto o no. Hay que tener en cuenta que esta tecnología aporta mucha flexibilidad a costa de cierta complejidad en la configuración y es necesario contar con personal formado para su uso, ya que adquirir el conocimiento necesario para dominar la herramienta puede llevar tiempo.
Hay alternativas para el despliegue de desarrollos de menor escala en plataformas cloud. Un ejemplo son los servicios que permiten ejecutar código sin aprovisionar ni administrar servidores. Es lo que se denomina computación sin servidor o serverless. Simplemente se sube el código de una función determinada y el servicio la ejecuta en una infraestructura de alta disponibilidad y realiza un escalado automático según la demanda que tenga dicha función. Ejemplos de este tipo de servicios son Amazon AWS Lambda, Microsoft Azure Functions, Google Cloud Functions, o IBM Cloud Functions.
No ha sido el propósito de este artículo el hacer una introducción a Kubernetes, de ese tema ya hay infinidad de artículos; sino explicar el contexto en el que nace y su importancia en la actualidad por ser una herramienta consolidada como estándar de facto que agiliza y robustece el desarrollo de software en la actualidad.
Jorge Berjano Pérez
Arquitectura Software en decide4AI
Puedes seguirnos en las redes sociales (Linkedin, Twitter, Youtube) para no perderte nada y mantenerte al tanto de futuros eventos o acciones.