jueves, 18 de junio de 2020

De Regreso & Docker

Hola que tal a todos,

Pues como a muchos nos ha pasado en este 2020 y con toda la locura del corona virus (SARS COv2), los proyectos en el trabajo y en la vida personal han disminuido. A Varios meses ya de estar encerrado y con algo de tiempo libre. He decidido re tomar este blog y escribir un poco sobre lo he aprendido durante esta cuarentena. Durante el encierro he estado desarrollando algunos proyectos que me parecen interesantes y que quisiera compartir en una serie de posts. Empezaremos con algunas entradas básicas que serán fundamentales para poder avanzar y entender un poco más sobre el desarrollo en la nube (cloud computing).

Esta entrada se tratara sobre docker y algunas de sus características un poco avanzadas sobre el sistema. Ya llevo varios años trabajando con docker en varias de las compañías en las que he desarrollado proyectos y la verdad es que es una herramienta fácil de entender y una vez que nos acostumbremos a desarrollar con docker no nos podremos imaginar no instalarlo tan pronto obtengamos una nueva computadora.

Una explicación sencilla


Algunos de nosotros todavía nos acordaremos de los viejos tiempos del desarrollo de software (no soy tan antiguo como otros pero sí me han tocado varias transformaciones). Primero se obtenía el código fuente, se modificaba y se probaba localmente. Luego se enviaba a otro grupo para que estos compilaran, lo empaquetaran y lo instalaran en la maquina donde se ejecutaba. Pero qué pasa?, si el sistema operativo, las librerías,  las versiones de las herramientas de compilación, etc son diferentes en cada uno de los diferentes pasos. Esto podría provocar problemas en el desarrollo.

Docker intenta minimizar estos problemas al empaquetar la aplicación y las librerías que se necesitan en un solo contenedor que puede ser ejecutado en una gran variedad de plataformas. Algunas personas mencionan a las Maquinas Virtuales (virtualbox) como un paso intermedio entre maquinas físicas y docker para ejecutar programas. La diferencia es que las maquinas virtuales necesitan un sistema operativo base + librerías para poder ejecutar programas.

Docker agrupa las librerías y herramientas básicas para ejecutar el sistema y tu programa sobre la plataforma docker que corre encima de un el sistema operativo nativo.

Para mas información sobre como instalar docker y mas explicaciones visita https://docs.docker.com/get-docker/ o https://docs.docker.com/get-started/part2/


Un simple ejemplo de como construir una imagen (Dockerfile).


En la actualidad la mayoría de los proyectos utilizan alguna herramienta de construcción como Maven, Npm o Make. Estas herramientas simplifican la compilación, prueba y empaquetamiento del programa. Pero aun tenemos el problema de la distribución es por eso que muchos proyectos agregan el archivo Dockerfile al lado del archivo de proyecto como el pom.xml.

Todos los ejemplos los podemos encontrar en el repositorio: https://github.com/ti3r/demostracion-simple-java-docker

Una vez que los desarrolladores modifican el código es tan fácil como ejecutar para obtener la imagen final:

docker build -t proyecto:latest .

(este comando utiliza el archivo: https://github.com/ti3r/demostracion-simple-java-docker/blob/main/Dockerfile)

Con esta técnica, el proyecto debe de estar compilado, probado y empaquetado para que el resultado final sea agregado a la imagen de docker. Generalmente este paso es realizado en un servidor de Integración Continua (CI), como CircleCI, Jenkins, etc. el cual se encargara de construir la imagen de docker que sera ejecutada.



Un ejemplo un poco mas complejo (Dockerfile multi stage build)


Cómo vemos empaquetar aplicaciones con docker es muy sencillo. Es muy común también que nuevos desarrolladores no tengan las herramientas para construir la aplicación, o que algún servidor de CI tenga versiones diferentes o que haya librerías diferentes o que no tengamos acceso a instalar algunos requerimientos para poder compilar, probar y empaquetar la aplicación. Una manera de resolver estos problemas es utilizar Multi-Stage Docker Builds. Para este ejercicio utilizaremos el archivo:

Podemos ejecutar:

docker build -t proyecto:latest -f Dockerfile.multi .


Una explicación rápida de que es lo que pasa en este archivo.

  1. Definimos un stage utilizando una image base con nómbre "build"
  2. Definimos un directorio donde se copiaran los archivos del proyecto
  3. Copiamos todos los archivos fuente, el archivo pom y el wrapper de maven a ejecutar (para saber mas sobre mvn wrapper puedes leerlo aquí: https://github.com/takari/maven-wrapper)
  4. Ejecutamos maven para que cree el programa final
  5. Definimos la imagen base del programa de resultado
  6. Definimos las etiquetas y directorios de la imagen final 
  7. Copiamos el resultado de la compilación del stage "build" a nuestra imagen final

Utilizar multi-stage builds en docker resuelve varios problemas sobre cómo el preparar y compilar nuestra aplicación final. De esta manera podemos:
  • Estandarizar todas las herramientas necesarias para obtener nuestra aplicación final dentro de nuestro repositorio. 
  • Utilizar diferentes imágenes para compilar y correr nuestro programa reduciendo el tamaño de la imagen final ya que no necesitamos
  • Acelerar el desarrollo del proyecto ya que nuevos desarrolladores no necesitaran instalar nada en el sistema antes de aportar. Solo tener docker, clonar el repositorio y ejecutar los comandos necesarios 



No hay comentarios:

Publicar un comentario