Skaffold: construcción y despliegue multipropósito

Introducción

Hace 30 años, la informática era más pausada de lo que lo es en la actualidad. Si queríamos introducir una nueva herramienta, al igual que ahora, se realizaba una prueba de concepto a pequeña escala para probar sus funcionalidades antes de pasar a su uso generalizado.

Eran pruebas lentas y muy intensivas en recursos: cada herramienta requería de su propio sistema de instalación y configuración. La aparición de Docker en 2013, transformó este tipo de escenarios pues al crear paquetes portables, estandarizó el proceso y redujo el esfuerzo necesario para introducir nuevas herramientas o servicios.

A día de hoy, Docker es el estándar de facto a la hora de distribuir aplicaciones, pero para desplegarlas existen múltiples herramientas (Jenkins, ArgoCD, etc), que convierten el proceso en algo muy heterogéneo. Tratando de simplificar aún más el proceso es cómo descubrí Skaffold.

En este post vamos a utilizar dicha herramienta para construir y desplegar una pequeña aplicación (este blog) en varios entornos (en Docker y directamente en la nube en un servicio de Cloud Run). Espero que os guste.

El arte de desaparecer

Ha pasado mucho tiempo desde la última vez que escribí un post. Si me fijo en la fecha del último artículo (como comprobaréis, hace casi un año), no puedo sentir otra cosa que pena y frustración, pero dejad que me explique un poco.

Hace cuatro años, la pandemia de COVID-19 nos cambió la vida a muchos. En España, tuvimos que estar confinados y muchos, además de pasar la enfermedad varias veces, comenzamos a teletrabajar desde casa. Junto a esto, todas las empresas digitales procedieron a ofrecer teletrabajo y el mercado laboral dio un vuelco enorme.

Gestión de certificados con cfssl

La seguridad es un pilar fundamental a la hora de gestionar infraestructura con organización y resiliencia, aunque a veces los proyectos se olvidan un poco de ella dependiendo del presupuesto y del tiempo disponible en el equipo.

A la hora de seguir una mínima política de seguridad, uno de sus pilares fundamentales es el cifrado de datos. Éste protege los datos generados por nuestra aplicación de forma segura: asegura la confidencialidad de datos en tránsito entre el usuario y la aplicación y los datos almacenados de accesos no autorizados.

Integración continua con Github II: Github Actions

La mayoría de plataformas como Github o Gitlab (también llamadas “forjas de código”, aunque a mí no me gusta mucho como suena), no han parado de implementar nuevas funcionalidades, tratando de convencer al público de ser la mejor herramienta para la creación de nuevas aplicaciones.

Hace años, casi todos los proyectos Open Source alojados en Github, utilizaban Travis CI para ejecutar sus pipelines de CICD. Sin embargo, a finales de 2020, dicha plataforma cambió sus condiciones y muchos de sus usuarios tuvieron que buscar otra alternativa.

La simbiosis entre Travis y Github no era oficial y tras un tiempo, esta última presentó su propia solución: Github Actions. En este post, busco actualizar una antigua entrada que escribí sobre Travis CI y replicar las funcionalidades de dicho pipeline pero sobre Actions. Pero antes, un poco de historia.

Restic: Backups fáciles y flexibles para todo el mundo

Cuando mantenemos un servicio o un servidor y éste almacena información importante, siempre puede salir algo mal. Aunque no son muy comunes, las catástrofes ocurren y en algún momento de tu vida te enfrentarás a la posible pérdida de dicha información. Un disco duro puede fallar, un usuario puede borrar datos vitales sin querer y en casos extremos, un CPD puede salir ardiendo por completo, impactando a millones de usuarios en el globo.

Ante una posible pérdida de datos, es importante disponer de un plan B y poder recuperar de alguna manera nuestros datos, por lo que antes de poner cualquier servicio en producción, siempre diseño su sistema de respaldos y su Disaster Recovery Plan, por si hiciera falta en el futuro.

Pese a que estos eventos son muy inusuales (lo que hace que se dejen un poco de lado), cuando ocurren, estar bien preparados es la diferencia entre una pequeña molestia y perderlo absolutamente todo.

Como ya comenté en el post anterior, he estado trabajando en una versión mejorada de mi sistema de backups para volverlo más flexible y moderno, y en este post voy a comentar en profundidad por qué he decidido cambiarlo, el resultado final y mi opinión al respecto. Vamos allá.

Raspberry Cloud: servicios desde casa

Considero que soy una persona con una gran curiosidad investigadora. Cada año diseño mi propio programa de formación con tecnologías para aprender, libros para leer y habilidades que me gustaría conseguir. Llevo unos diez años haciéndolo y aunque los plazos que me autoimpongo no se cumplen jamás, el resultado general es positivo

Este es uno de los motivos por los que me gestiono algunos servidores caseros. Me permiten aprender nuevas tecnologías y probar cosas a cambio de complicarme un poco la vida. Un ejemplo de esto es Ansible: aunque llevo sin usarlo en el trabajo años, sigo manteniendo amplios conocimientos en dicha tecnología al utilizarlo habitualmente en casa.

Trato de dar a mis proyectos personales el mismo mimo que cuando trabajo: un buen mantenimiento, un ciclo de actualizaciones serio y un sistema de testeo relativamente completo para poder iterar sin problemas.

Sin embargo, cada tecnología tiene sus limitaciones, ventajas e inconvenientes. Por eso en este post, voy a explicar los problemas a los que me he enfrentado y cómo voy a transformar estos servidores de cara al futuro.

Aplicaciones para DevOps (II)

Gracias a la proliferación de las aplicaciones web y a su portabilidad entre distintos sistemas operativos, hoy en día es más fácil que esa aplicación que desees esté disponible para Linux. Como usuario del sistema operativo del pingüino os puedo asegurar lo mucho que se nota el cambio de tendencia. Hace años escribí un post sobre este tema y creo que ha pasado el suficiente tiempo para retomarlo.

El uso de frameworks web no es el único motivo. Las grandes forjas de software como Github, Gitlab o más reciente Codeberg, permiten a las comunidades ligadas al software libre o el código abierto comunicarse mejor y organizarse. Todo ello ha contribuido a la creación de mejores herramientas para el desarrollo de herramientas nativas y que el número de ellas se haya disparado. Además, Linux es uno de los sistemas operativos más utilizados por programadores y otra gente del mundillo que busca que sus herramientas sean multiplataforma desde un inicio.

La libertad que caracteriza a Linux también tiene algún inconveniente. Puesto que cada distribución va por libre, se ha generado fragmentación que complicaba el mantenimiento de las aplicaciones. No era nada raro que una distribución no tuviera la librería adecuada para que una aplicación funcionara y en este post, vamos a ver cómo la comunidad ha buscado formas para facilitar este proceso, así cómo aplicaciones que son muy útiles para nuestro día a día.

Controlando el trabajo repetitivo

En un mundo cada vez más digitalizado y acelerado, aparecen nuevos servicios de forma constante para ofrecer soluciones a los problemas cotidianos que nos encontramos en IT. Gracias a una barrera de entrada cada vez más baja, podemos tenerlos listos y funcionando con un poco de conocimiento técnico y siguiendo la propia guía del fabricante (cuando no tienes acceso directamente a su SaaS).

Aunque es algo positivo, puede llegar a convertirse en una trampa. Cada nuevo servicio que añadimos a nuestro stack añade un punto extra de complejidad y mantenimiento y puede que no merezca la pena. Siempre tenemos que decidir entre las funcionalidades y el mantenimiento de dicho servicio. Además, la instalación siempre es la parte que menos trabajo da y posteriormente necesitaremos mantenerlo actualizado, gestionar sus dependencias, y más esporádicamente, realizar migraciones entre versiones.

Aunque Docker y los contenedores facilitan mucho esta tarea, incorporan otros puntos de fricción. Si utilizamos Kubernetes necesitamos tener en cuenta que nuestros servicios soporten las APIs correctamente, que estemos en versiones soportadas, que nuestra aplicación sea segura, etc.

En este post voy a explicar cómo he hecho para gestionar el mantenimiento de servicios y cómo estoy optimizando todo el proceso para que el tiempo que tengo que dedicarle sea cómodo para mi. Espero que os guste.

Atlantis: best practices y limitaciones

Este es el tercer y último post sobre Atlantis que voy a escribir para esta serie. Si los dos primeros explicaban cómo configurar la herramienta y cómo desplegarla sobre Cloud Run, en éste vamos a aplicar algunas buenas prácticas y a mejorar la solución, por lo que asumimos que se han leído los dos anteriores (I y II).

El primer post de la serie, creaba en el servicio de Atlantis una serie de variables de entorno, que tras convertirse temporalmente en ficheros tfvars, nos permitían inicializar y ejecutar nuestro código.

Esta solución, aunque servía como ejemplo, también tenía muchas limitaciones:

  • No escala. Las variables de entorno sólo pueden tener un valor al mismo tiempo. Si nuestra instancia gestiona múltiples proyectos con las mismas variables de entorno, no podría reutilizarlas con seguridad y además, deben de definirse en el servidor, obligando a redesplegar / reiniciar la solución en cada cambio.

  • Los proyectos cliente deben estar autocontenidos, para evitar en la medida de lo posible dependencias externas ajenas a su control y que impacten en su desarrollo.

  • Tal y cómo estaba configurado, tampoco nos proporcionaba garantías ante despliegues más automatizados y por eso vamos a añadir testing.

Cloud Run: orquestando contenedores sin Kubernetes

Kubernetes es el orquestador de contenedores más utilizado del mundo. Gracias a su rápido ciclo de desarrollo, no ha parado de incorporar nuevas funcionalidades, que han cubierto nuevos casos de uso y le han permitido alcanzar un crecimiento casi exponencial.

Este ciclo de desarrollo también tiene sus problemas. Cada vez es más difícil y complejo mantener un cluster de Kubernetes y esto ha hecho que aparezcan orquestadores alternativos para cubrir los casos de uso más habituales.

Tenemos múltiples opciones. Si queremos ejecutar contenedores en nuestros servidores, podemos optar por Docker Swarm (de Docker Inc.), o Nomad (de Hashicorp.) Si somos usuarios de algún proveedor de nube pública, tenemos otras opciones nativas. El primer orquestador en aparecer de este tipo fue Google App Engine Flexible, pero lo que se considera “estándar” para este tipo de servicios fue definido por Amazon en AWS Fargate.

Todos estos orquestadores de nube pública tienen algo en común. Buscan ofrecer una plataforma que permita al desarrollador centrarse lo máximo posible en desarrollar su aplicación y reducir al máximo los costes operacionales y el mantenimiento de la infraestructura. Son servicios privativos, muy integrados con otros servicios de la plataforma.

Si en AWS tenemos Fargate y en Microsoft Azure tenemos Azure Container Apps, la solución de Google Cloud es Cloud Run. En este post vamos a ver las características de Cloud Run y cómo adaptar una aplicación para que ésta pueda ejecutarse en dicha plataforma.