Uno de los inconvenientes del diseño de micro servicios es la interacción entre ellos, incluso la comunicación entre nuestro gateway y un micro servicio cualquiera.

Podríamos pensar en configurar, como propiedades, nuestras rutas a nuestros micro servicios. Qué pasaría si la plataforma crece, si queremos varios servicios que hagan los mismo, detrás de un balanceador de carga. En este escenario estaríamos un poco en la mierda.

Para solucionar este par de problemas: dónde están los micro servicios y cómo reparto la carga

DÓNDE ESTÄN LOS MICRO SERVICIOS

Si pensamos en patrones de arquitectura, con el tiempo, pensaríamos en el patron registry a nivel de infraestructura. Obviamente sí estamos en nun cloud y queremos explotar nuestro proveedor, existen alternativas dentro de AWS. Pero en este caso usaremos Netflix OSS, concretamente Eureka.

Otra vez, si tenemos un cloud, con cara y ojos, como un kubernetes, en la nube o estamos en AWS, tenemos alternativas, aquí volveremos a recurrir de Netflix OSS y usaremos Ribbon un load-balancer, aunque aquí nos centraremos sólo en Eureka, en próximos post Ribbon,

La imagen la he obtenido de: mediun

Llegados a este punto, con Eureka, podremos levantar una versión de nuestro micro servicio en varios contenedores, sirviendo alta disponibilidad en nuestro micro servicio

CONFIGURANDO SPRING & EUREKA

Podría ser tranquilamente un application.properties, pero utilizaré, para la configuración de nuestros micro servicios el formato YML

server:
port: 8761
spring:
application:
name: eureka
eureka:
instance:
hostname: localhost
client:
registerWithEureka: true
fetchRegistry: true
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/,${ADDITIONAL_EUREKA_SERVER_LIST}

Tenéis que tener en cuenta que sino, configuramos ADDITIONAL_EUREKA_SERVER_LIST intentará conectarse y lanzará alguna que otra traza de error.

Jib – Containerize your Maven project

Tengo un post, hablando un poco por encima de JIB aquí, recomiendo que entréis si os parece interesante

            <plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<version>1.1.2</version>
<configuration>
<to>
<image>apascualco/eureka:${project.version}</image>
<tags>
<tag>latest</tag>
</tags>
</to>
</configuration>
</plugin>

El primer paso, es compilar nuestro proyecto con maven utilizando jib, de la siguiente manera:

mvn compile jib:dockerBuild -f pom.xml

Esto nos generaría la image en nuestro hub local, si hiciéramos una $docker images, nos devolvería algo similar a esto (dependiendo de tu configuración).

Obviamente, es una configuración que hice para mi, pero podéis cambiar el nombre y los tags generados: apascualco/eureka:${project.version} / latest. Por otro lado la parte de project.version, gracias a maven nos pondrá la versión del proyecto

docker run -it -p 8761:8761 eureka:latest

Al no usar una configuración de composición, nos dará un error de conexión, ya que espera una lista de servidores, puesto que es una configuración de alta disponibilidad, bastante básica.

Aunque tendremos acceso y funcionará, no es lo mas adecuado.

DOCKER PORTAINER

Vamos a facilitar la gestión de nuestros contenedores/stacks, mediante esta herramienta UI. Aunque solo, sea para acceder, de manera más cómoda a los logs, la recomiendo fuertemente.

docker pull portainer/portainer

docker run -d -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock portainer/portainer

Una vez instalado, accederemos a el desde el navegador por el puerto 9000, configuraremos la password y veremos algo tal que así

DOCKER SWARM

Nuestro gestor de contenedores en local. He probado minikube y otras herramientas, para la orquestación de contenedores y la más fácil es la nativa, para local.

El mecanismo es el mismo que un k8s o por lo menos es la misma manera de trabaja, por lo tanto si empiezas por aquí, tampoco te vendrá mal y será ms fácil la curva de aprendizaje de k8s o aws.

Llegados a este punto ya tenemos instalado portainer, ahora toca iniciar docker swarm

docker swarm init

LANZAR NUESTRA APLICACION EN UN STACK

El primer paso, deberíamos crear una red, para nuestra aplicación

docker network create -d overlay apascualco

Una vez creado, seguiremos generando un yml, para definir nuestro stack en swarm, en nuestro caso, pondremos 1 por app, pero en tres puertos diferentes.

version: '3'
services:
registry1:
image: apascualco/eureka:1.0.0-SNAPSHOT
networks:
apascualco:
aliases:
- registry1
ports:
- "8761:8761"
environment:
- ADDITIONAL_EUREKA_SERVER_LIST=http://registry2:8761/eureka/,http://registry3:8761/eureka/
registry2:
image: apascualco/eureka:1.0.0-SNAPSHOT
networks:
apascualco:
aliases:
- registry2
ports:
- "8762:8761"
environment:
- ADDITIONAL_EUREKA_SERVER_LIST=http://registry1:8761/eureka/,http://registry3:8761/eureka/
registry3:
image: apascualco/eureka:1.0.0-SNAPSHOT
networks:
apascualco:
aliases:
- registry3
ports:
- "8763:8761"
environment:
- ADDITIONAL_EUREKA_SERVER_LIST=http://registry1:8761/eureka/,http://registry2:8761/eureka/
networks:
apascualco:
external:
name: apascualco

Aquí definimos la variable de entorno ADDITIONAL_EUREKA_SERVER_LIST, puede que al inicio, de algunas trazas de error, hasta que conecten y se encuentren entre si.

DEPLOYING

Ya tenemos nuestro yml, ahora toca a desplegar nuestro stack:

docker stack deploy --compose-file registry.yml registry

Si quisiéramos bajar el stack, utilizaríamos:

docker stack rm registry

Personalmente, me gusta hacerme unos script, para manejar esto. Al final veréis la implementación, bueno mas bien la configuración y los scripts, pero cuidado con los path

RESULTADOS

Cualquier duda, tenéis, los comentarios o mi email: apascualco@gmail.com, un saludo!

GITHUB

Deja una respuesta