viernes, 22 de junio de 2018

EUREKA - RIBBON - Client Load Balancing (III)

Vamos añadiendo elementos a esta prueba de concepto.

Añadimos en esta entrada despliegue en Docker. Para ello hemos modificado y añadido diferentes elementos de configuración en gitlab.

Por tanto, si ya os habíais descargado el código de las anteriores entradas, deberéis actualizarlo. Recuerdo los enlaces de las anteriores entradas (I y II)


Recuerdo también el objetivo de este ciclo de entradas
  • Un microservicio con tres replicas en ejecución, mediante tres puertos diferentes.
  • Un segundo microservicio usará RIBBON para invocar al primero mediante balanceo desde cliente. Lo haremos de dos formas:
    • Mediante EUREKA (con conocimiento del nombre del primer microservicio)
    • Sin EUREKA (invocando en lugar del nombre a "localhost")
Por tanto, si eso ya nos funcionaba en un entorno local "habitual" ahora le añadimos docker. Se requiere tener instalado docker, docker-compose y docker-machine (este último no sería indispensable si trabajamos con la machine "default", si queremos crear otra si que hará falta).

Al final de esta entrada tendremos los siguientes containers en ejecución:

  1. Un contenedor con nuestro eureka-server
  2. Tres contenedores con el microservicio uno
  3. Un contenedor con el microservicio dos invocando vía RIBBON a los tres contenedores anteriores.
Comencemos.


Previo

Hemos de comentar un detalle importante. Para optimizar el lanzamiento de nuestras aplicaciones en docker nos hemos creado un sistema de despliegues propio que merece ser explicado. Lo hacemos en entrada aparte ya que os lo encontraréis en el código de todos los proyectos.

Por tanto, será necesario leerlo si se quiere adoptar ese sistema. En otro caso, se deberá lanzar de forma manual (docker-compose up -d......). Este es el procedimiento que si que documentamos en esta y sucesivas entradas que tengan que ver con docker.


docker-compose y Dockerfile
Necesitaremos un docker-compose.yml por cada elemento, uno para eureka, otro para el microservicio uno (con tres containers) y otro para el microservicio dos.


Eureka

El docker-compose-yml de eureka es el siguiente:

    version: '3.5'
    services:
      eureka-server:
        build: 
          context: .
          dockerfile: ./docker/Dockerfile
        image: eureka-server-img
        container_name: eureka-server-ct
        environment:
           - "SPRING_PROFILES_ACTIVE=dev" 
        ports:
          - "8761:8761"
        networks:
          - arq-net
  
    networks:
      arq-net:
        name: arq-net
        driver: bridge

Como datos a tener en cuenta:
  • Se lanza con "docker-compose up -d --build" desde el directorio raíz del proyecto, donde se encuentra el fichero.
  • Es el primero que se ha de lanzar.
  • crea una red, necesaria para que exista la comunicación entre containers lanzados desde diferentes docker-compose.
  • Los microservicios referenciarán (como veremos) esa red creada

En "dockerfile" aparece la ruta del fichero Dockerfile que creará la imagen en base a una imagen publicada en docker hub. Este es el contenido del Dockerfile:

    FROM java:openjdk-8-jdk-alpine

    # add el jar con el nombre del "finalName" del pom.xml
    ADD target/eureka-server.jar /app.jar

    # se modifica la fecha a la actual
    RUN sh -c 'touch /app.jar'

    # comando a ejecutar
    CMD ["java", "-jar", "/app.jar"]


Como se puede ver, la imagen base (FROM) es la "java:openjdk-8-jdk-alpine". Es decir, para hacer correr nuestro server eureka sólo necesitamos una imagen con java8 instalado. Suficiente.

Le introducimos el jar (con ADD) y lo ejecutamos (CMD) con "java -jar ....". por tanto, aunque es obvio, es imprescindible haber lanzado un "mv clean install" (por ejemplo) de nuestro proyecto, para que genere el artefacto a desplegar en nuestro container.



Microservicio uno

El docker-compose.yml del microservicio uno es un poco más largo, ya que contiene la descripción de los tres contenedores. Sólo copio aquí el de uno, indicando en negrita lo que se debe cambiar para los otros dos

    version: '3.5'
    services:
      client-one-load-balancing-1:
        build: 
          context: .
          dockerfile: ./docker/Dockerfile
        image: client-one-load-balancing-img
        container_name: client-one-load-balancing-ct-1
        environment:
           - "SPRING_PROFILES_ACTIVE=dev" 
           - "SERVER_PORT=8090"
        ports:
          - "8090:8090"
        networks:
          - arq-net

    client-one-load-balancing-2:
    .....
      environment:
        - "SERVER_PORT=8091"
      ports:
        - "8091:8091"

    client-one-load-balancing-3:
    ....
      environment:
        - "SERVER_PORT=8092"
      ports:

        - "8091:8091"

    networks:
      arq-net:
        external: true

La imagen (image) no cambia, será la misma para los tres. El puerto pondremos 8091 y 8092 siguiendo el mismo patrón.

La red (arq-net) ahora se referencia la creada por el docker-compose de eureka. Se especifica como "external: true" (ya creada).

El Dockerfile es exactamente igual al del eureka, cambiando el nombre al del jar del microservicio

    ADD target/client-one-load-balancing.jar /app.jar

Arrancamos como antes, lanzando el comando "docker-compose up -d --build" desde el directorio raíz del proyecto, al mismo nivel del docker-compose.yml


Microservicio dos

Su docker-compose.yml es muy parecido a los anteriores

    version: '3.5'
    services:
      client-two-load-balancing:
        build: 
          context: .
          dockerfile: ./docker/Dockerfile
        image: client-two-load-balancing-img
        container_name: client-two-load-balancing-ct
        environment:
           - "SPRING_PROFILES_ACTIVE=dev" 
        ports:
          - "9999:9999"
        networks:
          - arq-net
  
    networks:
      arq-net:
      external: true

Y su Dockerfile también, sólo se ha de cambiar la siguiente línea:

    ADD target/client-two-load-balancing.jar /app.jar

Arrancamos como antes, lanzando el comando "docker-compose up -d --build" desde el directorio raíz del proyecto, al mismo nivel del docker-compose.yml


Prueba

Accedemos a Eureka (http://192.168.99.100:8761/) y vemos el primer microservicio replicado tres veces. Vemos también el segundo microservicio:


Ahora invocamos nuestro primer microservicio a partir de la url "http://192.168.99.100:9999/hola?nombre=José". Si vamos refrescando obtenemos una respuesta por cada uno de las réplicas del microservicio uno:






Miscelánea 


La ip de acceso es la de la docker-machine activa y donde hemos desplegado los containers. La obtenemos mediante "docker-machine ip nombre_machine"

Para ver los containers activos "docker ps"
Para ver los containers activos y parados "docker ps -a"

Para ver los logs de uno de los microservicios ejecutamos "docker logs -f id_container" (con -f se nos queda la consola enlazada a la salida del container).

Para ver la red creada "docker network list"

Para parar todos los containers mejor hacerlo con "docker-compose down" desde los directorios desde los que hemos lanzado anteriormente los "... up...".
También se pueden parar directamente con "docker stop id_container" y eliminarlos con "docker rm id_container".

Paramos la docker-machine con "docker-machine stop nombre_machine"

En una entrada posterior añadiremos la configuración para extender la prueba de concepto a Minikube, un cluster Kubernetes de un sólo nodo, a modo de laboratorio.


No hay comentarios:

Publicar un comentario