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,
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