Enmilocalfunciona

Thoughts, stories and ideas.

Desplegando microservicios Java con Docker y JIB

Publicado por Oscar Sanz el

Arquitectura de SolucionesDockerJIBMicroservicios

Este artículo es el comienzo de una serie de posts para analizar las nuevas herramientas que están apareciendo y que nos permiten optimizar ciertas tareas durante el desarrollo de software en entornos Cloud.

En concreto en este artículo vamos a hablar de la utilidad JIB "Java Image Builder", herramienta creada por el equipo de Google Cloud.

Las funcionalidades/ventajas que nos proporciona está herramienta son:

  • No es necesario el uso de un fichero DockerFile para generar nuestra imagen.
  • Integración con Maven y Gradle.
  • Optimización de los tiempos de desarrollo para generar nuestra imagen Docker. En cada proceso de construcción sólo se actualizan las capas "layers" modificadas permitiendo que la generación de la imagen y publicación en nuestro repository sea de unos pocos segundos. Incluso en nuestro proveedor Cloud.

Esta herramienta puede sustituir a las soluciones de "Spotify" o "Fabric8".

A continuación vamos a analizar cómo funciona con un pequeño ejemplo.

Para empezar vamos a descargar un ejemplo de un microservicio con SpringBoot del siguiente repositorio de GitHub.

git clone https://github.com/osanzs/helloworld-jib.git

Analizando la estructura del proyecto nos vamos a centrar en el fichero pom.xml, en la sección Plugins:

<!-- Jib -->
        <plugin>
            <groupId>com.google.cloud.tools</groupId>
            <artifactId>jib-maven-plugin</artifactId>
            <version>${jib-maven-plugin.version}</version>
            <configuration>
                <container>
                    <ports>
                        <port>8082</port>
                    </ports>
                </container>
                <from>
                    <image>openjdk:8u212-jre</image>
                </from>
                <to>
                    <image>osanz/helloworld-jib:${project.version}</image>
                </to>
            </configuration>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>build</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>

En el ejemplo mostrado nos tenemos que fijar en la sección configuration:

  • from: Identifica la imagen base que vamos a utilizar para componer nuestra imagen (opcional, JIB construye las imágenes a partir de distro-less java image
  • to: Nombre de la imagen que se va a generar (obligatorio). En este sección debemos indicar el Docker Registry que vamos a utilizar. Por defecto es Docker Hub y sólo necesitamos incluir el nombre del usuario.
  • port: Puertos que vamos a exponer para acceder a la funcionalidad del contenedor (opcional, por defecto JIB utiliza el puerto 8080).

En el siguiente enlace podemos consultar todos los parámetros de configuración que nos proporciona este plugin para Maven.

Prueba de Concepto

A continuación vamos a ver cómo funciona con un pequeño servicio en Spring Boot. Para ello necesitamos cumplir los siguientes pre-requisitos:

  • Visual Studio Code.
  • Maven 3.x
  • Java JDK 8 o superior.
  • Docker Runtime.
  • Credenciales de acceso de un Registro Docker (Ej. Docker Hub).

1.- Abrimos el proyecto con Visual Studio.

alt

2.- Comprobamos que no tenemos ninguna imagen de nuestro proyecto en local ejecutando en el terminal el comando docker images.

alt

3.- Incluimos las credenciales de acceso en el fichero $HOME/.m2/settings.xml en la sección servers:

<servers>
    <server>
      <id>registry.hub.docker.com</id>
      <username>username</username>
      <password>password-docker-hub</password>
   </server>
</servers>

Si disponemos de diferentes proveedores cloud en esta sección debemos de incluir todos los proveedores Cloud que vayamos a utilizar con JIB.

Para Google Cloud la configuración es:

<servers>
    <server>
        <id>gcr.io</id>
        <username>username</username>
        <password>password-google-cloud</password>
    </server>
</servers>

4.- Para generar la imagen en local ejecutaremos el siguiente comando:

mvn compile jib:dockerBuild
alt

5.- Consultamos nuestro repositorio local Docker docker images.

alt

En la captura anterior vemos que tenemos una nueva imagen osanz/helloworld-jib (la fecha de creación no es correcta porque JIB utiliza Reproducible Builds por defecto y no incluye información de referente "Timestamps".

6.- Ejecutamos el microservicio arrancando un contenedor con el siguiente comando:

docker run -p 8080:8082 osanz/helloworld-jib:0.0.1-SNAPSHOT

alt

7.- Si accedemos a la siguiente URL: http://localhost:8080/hello?name=Oscar

alt

8.- Para subir nuestra imagen a Docker Hub necesitamos ejecutar el siguiente comando mvn compile jib:build o mvn clean package.

alt

En la captura anterior vemos que la operación ha necesitado 36 segundos.

Si consultamos nuestro repositorio en Docker Hub veremos nuestra imagen:

alt

9.- Actualizamos nuestro microservicio aplicando los siguientes cambios:

  • Cambiar el mensaje de la operacion "hello".
  • Subir la versión de nuestra imagen a 0.0.2-SNAPSHOT.

Para ello debemos de actualizar los ficheros:

  • HelloController.java para cambiar el mensaje.
  • pom.xml para cambiar la versión de la imagen.

Si volvemos a repetir el proceso de generar la imagen Docker:

  • Maven con mvn clean package
alt
  • Docker Hub  utilizando este enlace.
alt
  • Prueba del Servicio con el comando docker run -p 8080:8082 osanz/helloworld-jib:0.0.2-SNAPSHOT
alt

Podemos concluir que este proceso ha consumido sólo 10 segundos. Esto es debido a que sólo ha tenido que modificar un capa "layer" de nuestra imagen Docker.

Conclusiones

Esta herramienta, desde el punto de vista de un desarrollador, implica que:

  • No es necesario generar y mantener el fichero DockerFile asociado a cada microservicio.
  • La actualización de las imágenes es practicamente automática, incluso en un proveedor Cloud externo.
  • No requiere tener un Docker Daemon para generar las imágenes, pudiéndose subir directamente a un repositorio de imágenes.
alt
alt
  • Sólo es compatible con proyectos Java. De momento no es posible generar imágenes Docker de microservicios desarrollados en Golang o Python.

En los siguientes artículos veremos más herramientas que nos permitan desarrollar y testear nuestro software en entornos Cloud.

Si te ha gustado, ¡síguenos en Twitter para estar al día de nuevas entregas!