DevOps desde un punto de vista práctico para aplicaciones multitudinarias

Este artículo es una pequeña introducción a este mundo de DevOps tan fascinante y engañoso en su volumen; además, y con una frecuencia que asusta, siendo una gran caja negra. Está orientado a perfiles con curiosidad sin esperar entrar en difíciles tecnicismos.

El CI/CD (Continuous Integration y Continuous Delivery) de las aplicaciones debe ser estable, fiable y escalable. Tenerlo bien organizado va a marcar la diferencia en los tiempos de entrega y la correspondiente calidad a obtener.

Vamos a tratar un flujo completo e interesante partiendo de los llamados andamios o más conocidos como Scaffoldings para la creación de repositorios, alojamiento de código basado en GIT, servidor de integración, repositorio de artefactos compilados, gestor de despliegues y despliegue en contenedores.

Vamos a centrarnos en ver el flujo tanto en FrontEnd con Single Page Applications (SPAs) como en BackEnd con nodeJS. En el lado de Front podría ser Angular o React por ejemplo, y en el lado Back podría ser ExpressJS o NestJS.

Sin entrar en detalle con la seguridad o el conocido como DevSecOps, se van a comentar algunas pinceladas que de manera colateral conllevan a tener una mayor seguridad en los proyectos. En cada una de las capas debe haber un control de accesos y lo más cómodo es tener los usuarios y los permisos en un LDAP externo para conseguir linealidad y velocidad a la hora de conceder, editar o eliminar accesos.

Alojar el código

Comenzando por lo más sencillo, elegir dónde guardar el código para poder tener un ambiente de colaboración. Sin poner en duda el uso de GIT, tenemos varias opciones como pueden ser GitHub, GitLab, etc. Hay que elegir si el código está alojado de modo público o privado. Lo recomendado es tenerlo exclusivamente dentro de una intranet.

Scaffoldings

Empezamos a meternos en harina. Parte importante que la mayoría de las veces se ignora y supone una diferencia de tiempo invertido abismal.

Se recomiendan usar en arquitecturas de MicroFrontEnds y/o MicroServicios. ¿por qué? Porque el planteamiento de la independización de código conlleva a tener multitud de repositorios todos con el mismo planteamiento, y como pueden estar desarrollados con diferentes lenguajes o diferentes frameworks será necesario tener diferentes niveles de scaffoldings.

Digital Lover

Tener scaffoldings supone tener corriendo la aplicación en el servidor en literalmente minutos con al menos un hola mundo, toda la seguridad que deba tener la web en particular con Gateway o validación de permisos o cookie, todas las dependencias, los componentes reutilizables, conexiones, métodos de utilidad ya disponibles, configuraciones de despliegues, complementos para el IDE, etc. Lo que quizá de normal puede llevar varios días, se debe hacer solo. Es importante llevar una mentalidad de no perder el tiempo en tareas repetitivas o que no aporten.

Creación de repositorios

No solo está el hecho de crearlo allí donde se quiere alojar y ya. Consiste en crear con una sola acción todo su flujo de DevOps y sea una caja negra para los desarrolladores.

Tener automatizado el proceso de creación de repositorios supone tener de base configurados los permisos, hooks, vinculación de su pipeline y creado o referenciado el componente allí donde sea necesario. Con esto no será necesario hacer modificaciones manuales para conseguir que el repositorio llegue a estar desplegado y corriendo con ese hola mundo del apartado anterior.

Es importante elegir una nomenclatura a seguir para conseguir un escalado sin lugar a equivocación y deje clara la función y ámbito de cada repositorio. El nombrado debe permitir relacionarlo visualmente entre las diferentes piezas.

Servidor de integración

Nos referimos a herramientas como bamboo, Jenkins, travis, etc. Parecen de inicio piezas que no aportan mucho, porque al fin y al cabo uno mismo puede compilar el código en local y subirlo al repositorio de artefactos o desplegarlo directamente. Cuando se trabaja en un proyecto de manera individual, no es muy útil a priori, sin embargo, cuando el proyecto es colaborativo, la cosa cambia.

  • En muchas ocasiones los ordenadores o las VDIs no tienen muchos recursos y tardan en compilar el código. Ese tiempo el desarrollador lo puede invertir en dedicarse a otros temas.
  • Las pipelines, debe haber una por tecnología, lo más genérica posible, de modo que las pipelines tengan y compartan elementos comunes.
  • Se suelen añadir a las pipelines pasos donde se ejecutan: test vinculando SmartBear, Embold, Kiuwan, SonarQube, etc. Subida al repositorio de artefactos. Vinculación con el gestor de despliegues. Cerrado de versiones.
  • Se ocultan los usuarios de servicio que conectan a todas las piezas.
  • Modificación automática de la versión en develop al cerrar versión de master.
  • No todas las ramas por defecto deberían provocar acciones en el servidor de integración. Quizá el código de las features y bugfixs no debiera ir hacia el repositorio de artefactos.

Repositorio de artefactos

Una vez la construcción del repositorio ha terminado y la pipeline acaba, esta debe finalmente subir el código compilado a un servidor de paquetes, como pueden ser JFrog Artifactory, Nexus repository, etc. Aquí se van acumulando, según unas reglas para establecer ciclos de vida de los mismos y no generar innecesariamente un gran volumen de datos que no tengan utilidad. Las versiones cerradas deben perdurar mucho más que las versiones sin cerrar (de ramas distintas a master). Es posible que en algún momento se requiera volver a una versión anterior o buscar el estado del código en un momento determinado a causa de una incidencia. Este último caso, si se gestionan los TAGs en GIT puede ser más sencillo revisar el código.

Solo los usuarios de servicio deben poder tener permiso de edición en estos repositorios de artefactos.

Gestor de despliegues

Se pueden añadir pasos en la pipeline del servidor de integración para controlar los despliegues a los entornos mediante aprobaciones o se puede delegar en un gestor de despliegues como puede ser Octopus deploy, UrbanCode deploy, etc. Estos gestores te permiten trazar lo que ocurre, obtener métricas, ver cadencias o cuellos de botella, tener históricos filtrando bien por componente, por entorno, por perfil ejecutor, etc.

Cada entorno tiene configuraciones y conexiones diferentes, además se permiten almacenar usuarios de servicio particulares. A nivel de permisos se puede desgranar qué componentes y a qué entornos puede desplegar quién consiguiendo que se respeten competencias.

Nuevamente, es una pieza prescindible, sin embargo, una vez que se utiliza y está bien configurada, no es una opción dejar de usarla.

Un punto negativo a destacar es la mencionada configuración. Puede ocurrir que en alguna iteración del flujo no se quede bien marcado si ha sido un éxito o no algún paso del flujo. Por ejemplo, en el caso de conectar con los contenedores, puede que el contenedor se cree y ya con eso se considere un éxito, sin embargo, puede darse que el servidor de ese contenedor no levante. Esto, debería llegar como error al gestor de despliegues a través de algún evento o prueba de salud (health probe). Es entendible que tanto la complejidad como los beneficios se multipliquen.

Despliegue en contenedores

ECS o EKS en AWS, kubernetes, nomad, etc. Lo más cómodo de cara a escalabilidad de cualquier tipo es trabajar con contenedores. Cada uno independiente, con la posibilidad de crecer tanto vertical como horizontalmente y con mucho control a nivel de permisos, namespaces y seguridad. Con autoescalados y fijando valores máximos y mínimos de recursos se puede conseguir una gran eficiencia en el reparto según necesidades en cada momento.

Monitoreo y logs

Monitoreo con por ejemplo Dynatrace, AppDynamics, New Relic, Instana, etc. Y colección de logs con splunk, Kibana, Knowi, Grafana, etc. Esta sección en muchos proyectos tiende a dejarse para una vez la web está corriendo en Producción, ya que no es indispensable para conseguir tener el producto disponible orientado a los potenciales clientes.

Es cierto que no es imperativo, se pueden obtener los logs directamente de los contenedores y si algún POD está caído, simplemente se levanta cuando sea detectado.

Cuando la aplicación deje de correr significa una gran pérdida de ingresos, entonces es acuciante escalar la monitorización y tener equipos 24/7 disponibles ante cualquier eventualidad.

Una visión 360 de estado del aplicativo facilita y reduce los tiempos de la intervención. Además, permite tomar decisiones en función de estadísticas y sobre todo, prevenir y evitar acontecimientos antes de que ocurran.

Conclusiones

Como vemos, no se ha especificado qué herramienta es mejor usar, depende mucho del conjunto, del presupuesto, y de lo que ya exista en la casa previamente.

El uso de Terraform, Helm o Ansible Automation Platform es una opción igualmente para conseguir mayor automatización, aunque quizá estén pensados para proyectos mucho más grandes y maduros en su definición.

Lo ideal, como se comentaba al inicio, es que todas estas piezas estén vinculadas a por ejemplo un mismo LDAP de usuarios y haya una capa más de seguridad envolviendo el conjunto, de este modo se previene una gran cantidad de tiempo desechado y configuraciones ad hoc.

Cuanto más independientes sean las piezas más sencillo será usar otros productos en caso de necesidad o escalar.

- La política a tomar se puede asimilar bastante a los principios SOLID en desarrollo de código.

- ¿Qué qué?

- Revisa y piénsalo..

 

 

 

Tags

He leído y acepto la política de privacidad
Acepto recibir emails sobre actividades de recruiting NTT DATA