Dudas sobre Arquitectura microservicios, y donde desplegar

V

Buenas, estoy aprendiendo la arquitectura de microservicios y quería hacer algunas pruebas.

Hasta ahora, si hago un servicio con node, pues lo subía a heroku y listo. Ahora mi idea, si lo he entendido bien, es dividirlo en varios servicios, que no se muy bien si se pueden encapsular todos en docker, o se suben los servicios individualmente, y luego instalas kubernetes y los gestionas, no se.

Abro hilo para preguntar dudas, y si alguno sabe y me puede ayudar pues mejor.

1º Se puede crear un mismo contenedor para la bbdd , el back y el front?
2º si se crean varias instancias del servicio de autenticación por ejemplo, como se hace el deploy y que redireccione las peticiones?
3º Relacionada con la anterior, si usamos heroku, y clonamos un servicio, como hacemos para que divida el trafico entre las 2 apps? se puede hacer con la versión gratuita?

4º Se pierde rendimiento al usar una sola maquina con varios contenedores? o no afecta xk cada contenedor tiene puertos distintos? (hasta el maximo de procesos que admita el server. Por eso digo que en heroku, creo que es un worker nada más.
5º hay algún sitio mejor (gratuito) para hacer deploy de aplicaciones web?
6º Es mejor comprarse un servidor barato y montarlo en casa?

Un saludo

JuSt1

Muy buenas!

Respondiendo a tus preguntas:

1 - Si, puedes crear un stack con un Docker Compose que te cree todo lo que necesitas, solo que necesitas alimentar los deploys y tener las imagenes base bien aplantilladas a nivel de configuración

Sobre el resto de preguntas, creo que es mejor comentarte que existen dos soluciones a lo que planteas:

  • Docker como tal: tienes que tener la imagen base de lo que quieras desplegar y al final los deploys los asocias a un puerto en concreto y digamos que ese puerto que abres, es tu punto de entrada y con lo que tienes que jugar para hacer el balanceo.

La recomendación es desplegar un servidor Nginx que te haga de proxy inverso para poder realizar lo que necesitas, habilitar dominios y configurar upstreams (por si quieres balancear en dos dockers)

  • Docker Swarm: al final los despliegues no funcionan de la misma forma y lo que se despliegan aquí son servicios que estan balanceados en N nodos de docker, estos servicios son consumidos tambien con puertos o dominios internos ya que en este modelo también está el tema del autodescubrimiento, etc...

Al final todo depende cuanto te quieras complicar o hasta donde quieres llegar para hacer la prueba, si quieres comenta un poco mas esta info y profundizamos un poco mas para orientarte mejor :)

Un saludo!

1 respuesta
V

me pierdo un poco con lo del proxy inverso, pero mañana te contesto más ampliamente y te pregunto más dudas, muchas gracias.

Se puede instalar ese proxy inverso ( que es otra aplicación no? osea otro contenedor) en heroku y balancear?

un saludo

JuSt1

Al final es otro concepto de como servir aplicaciones a través de web sin usar por ejemplo un apache, pero si, echale un ojo y comentame lo que necesites!

Yo no soy muy fan de usar heroku ya que prefiero montarme toda la infra y gestionarlo yo ya que con tres servidores (1 para nginx y 2 para docker) lo tendrías todo listo para balancear, y esos servidores pueden ser virtuales (VPS) para hacer anidamiento de virtualización, posibilidades tienes

JuAn4k4

Service Discovery (gestionar sin DNS/IP dónde está cada cosa)
Load Balancer (múltiples instancias y redirección de Peticiones)

Prueba configurar todo en local, puedes usar k8s o docker compose o lo que quieras para administrar tus servicios.
Puedes poner Traeffik para gestionar las dos primeras cosas que te menciono.

Seguramente necesites algún Bus.
Si pueden usar todos el mismo front y database. Aunque es más común separar absolutamente todo para complicarse la vida y mantener tu puesto de trabajo. (Microfrontends)

Aunque por probar y tal puedes probar. Una solución híbrida dividiendo en según que casos podría tener sentido.

1 respuesta
V

Vamos a ver , voy a estructurar un poco el tema

1. Dudas sobre los elementos necesarios
2.Patrones de diseño
3.Despliegue/ Docker / Devops

Vamos a suponer que vamos a montar todo esto en local, y poder acceder al endpoint desde fuera de la red local, ya llegaremos a las dudas del despliegue.

Entended que no sé que es un proxy inverso, ni balanceador, ni nada de redes, yo programo y poco más. Por eso agradecería explicaciones para tontos.

Vamos a poner el ejemplo de un microservicio, corregidme si algo está mal

front ------ api gateway ------- autenticación / infoUser / notificaciones / pagos

vamos a ver este ejemplo, con 4 servicios. El front consulta al api gateway que es el que balancea? o reparte la carga entre los servicios, no? imaginemos que tenemos cuello de botella en autenticación, y montamos otro contenedor de autenticación-

front ------ api gateway ------- autenticación / autenticación/ infoUser / notificaciones / pagos

Entiendo que aquí se debería ver el trabajo del gateway, al hacer las peticiones a /autenticación, las divide entre los 2 módulos , no se como, ni se como gestiona los puertos. Todos los contenedores están en la misma maquina.

1º esto es correcto? todos los contenedores en la misma maquina, hay perdida de rendimiento así?
2º que paquete npm o que es lo que se usa como api gateway, o como se monta eso?
3º que usamos para exponer fuera la ip del gateway? o de cada uno de los servicios.
4º que papel juega nginx? es lo de la api gateway?
5º todos los módulos van con su contenedor/imagen de docker no? y las bbdd también
6º si se compone todo esto en un solo contenedor, las peticiones van solo a ese contenedor? o a los subcomponentes que lo forman, es decir, perdemos rendimiento al juntarlo todo en un contenedor con docker compose?
7º como montar esto en local? tengo linux, instalo el nginx y las imagenes de docker en la terminal y ya está o tengo que crear una maquina virtual?

2 respuestas
zoeshadow

#2 Esa imagen creo que muestra un ejemplo de algo que no hay que hacer, compartir la base de datos, si todos los MS comparten base de datos pierdes una de las mayores ventajas de usar microservicios (escalabilidad), ya que en la mayoría de las ocasiones los problemas de escalabilidad van a venir por el acceso a datos.

Al principio esto puede ser too much, pero hay maneras de evitar tener que crear una BD nueva por cada MS, usando la misma pero limitando a nivel de usuarios el acceso a las tablas que pertenezcan sólo a ese MS, y por supuesto nada de hacer joins, si necesitas datos de otro MS tienes que plantearte estrategias de replicación de los datos que necesites.

1 respuesta
desu

#5 A que te refieres con bus? Colas no?

#6 Deberias re plantear tu pregunta, porque estas haciendo la falacia del problema XY.

https://xyproblem.info/

Entiendo que lo que quieres y tu pregunta es como tener una arquitectura de microservicios simple funcionadno, con varias replicas de cada servicio. Es ese tu objetivo?

Existen por lo que conozco dos maneras de resolver este problema, como se intuye que estas haciendo con service discovery, api gateway, sidecars... o usando una cola.

Ambas tienen sus pros/cons.

Para resolverlo sin colas. En que lenguaje programas? Tienes el stack de spring https://spring.io/projects/spring-cloud o Traeffik. Yo Traeffik no lo he tocado es demasiado complejo para lo que buscas.

Tus preguntas no tienen mucho sentido. Estan mal formuladas de nuevo (XY). Te falta mucha teoria, estudia primero.

#7 Yo comparto DBs xd Depende de la carga no es problema. El pro/cons es lecturas rapidas y eventual consistency.

2 respuestas
V

#8 pues por eso pedía un poco de ayuda, para entender los conceptos.

Y si, ese es mi objetivo, montar una arquitectura de microservicios simple con varias replicas de algún servicio.

quería hacerlo en nodejs

zoeshadow

#6 I'm going to give it a try

1º esto es correcto? todos los contenedores en la misma maquina, hay perdida de rendimiento así?

Si tienes todas las aplicaciones en contenedores te da igual si corren en una o N maquinas, la idea es acabar teniendo algo a donde subir el contenedor/imagen y que te abstraiga del "metal"

2º que paquete npm o que es lo que se usa como api gateway, o como se monta eso?

Lo mejor es saberse bien estos dos conceptos, ya que van a ir muy de la mano

https://microservices.io/patterns/apigateway.html
https://microservices.io/patterns/server-side-discovery.html

Al final el API Gateway es el encargado de "enrutar" todo el tráfico a los distintos MS, cosas como el service discovery ayudan, además de proveer cosas como load balancing.

Hay muchos frameworks/herramientas para hacer API Gateway, desde Zuul (JVM based), Nginx, o incluso un servicio de Node con express que haga esta labor.

3º que usamos para exponer fuera la ip del gateway? o de cada uno de los servicios.

La idea es que todo el tráfico pase a través del gateway, por lo que el resto de los servicios no deberían de ser públicos, o que tengas una manera en el momento de crear un MS que te permita decidir si es público o no.

En mi empresa por ejemplo se configura en un yml, ahí decides la url si quieres que sea público, por defecto solo es accesible desde dentro.

4º que papel juega nginx? es lo de la api gateway?

nginx puede actuar de API Gateway, pero no sé cómo podrías implementar service discovery usando nginx (según ellos, se puede).

5º todos los módulos van con su contenedor/imagen de docker no? y las bbdd también

No sé a qué te refieres con módulos en este contexto, ten en cuenta que en diferentes lenguajes la palabra módulo tiene diferentes significados.
Lo suyo es que cada aplicación tenga la configuración necesaria para poder crear una imagen de docker con el código de la aplicación y cualquier dependencia (interna, vease node y node-modules).

Cualquier dependencia externa (DB, Redis, kafka), las puedes declarar con docker-compose para que en tiempo de desarrollo puedas levantar los diferentes contenedores.
Para esto necesitarás una configuración diferente dev/prod (donde le digas la url donde encontrará la DB y el resto de dependencias externas)

6º si se compone todo esto en un solo contenedor, las peticiones van solo a ese contenedor? o a los subcomponentes que lo forman, es decir, perdemos rendimiento al juntarlo todo en un contenedor con docker compose?

En un contenedor solo deberías tener la aplicación y si tuviera alguna dependencia nativa (algún módulo para procesado de imagenes, etc), el resto debería ir cada uno en su contenedor. En el registro de docker tienes imágenes de casi todos los tipos (contenedor basado en Alpine Linux con postgresql XX.XX, mysql, redis, kafka, lo que quieras)

Esas las defines en el docker-compose y cuando quieras probar en local levantas docker-compose up y levantará tantos contenedores como dependencias tenga.

7º como montar esto en local? tengo linux, instalo el nginx y las imagenes de docker en la terminal y ya está o tengo que crear una maquina virtual?

Creo que esto ya está aclarado en los puntos anteriores, pero vamos, la idea es que en local levantes el docker-compose y listo.

1 1 respuesta
V

#10 te lo agradezco muchísimo, me ha quedado más claro algunos conceptos, mañana pregunto más, tengo que mirarme lo del server discovery

JuAn4k4

#8 Yo suelo llamar bus a comunicación tanto pub/sub como colas, con vitaminas (pipelinines)

Un API Gateway no es un load balancer, es un enrutador (petición sin destino concreto la manda a un servicio concreto) y agregador (hace varias llamadas y responde una cosa). Se puede enrutadar por service name (que puede ir en request header/path) o por como quieras.

Un loadbalancer/balanceador gestiona las llamadas a 1 solo servicio (puede ser el API GW u otro microservicio), generalmente hace health checks a las "máquinas" a las que deriva la llamada para balancear la carga (según diferentes algoritmos: tiempos de respuesta, round Robbin, etc..)

Traeffik hace muchas de estas cosas, yo diría que te convendría pegarte con su documentación e intentarlo. Acabarás entendiendo algunas cosas aunque lo hagas malamente.

2 respuestas
zoeshadow

#12 Normalmente el que enruta tiene en cuenta cosas como la carga de los servicios, las máquinas que están activas para un determinado servicio, por lo que suele tener mucho sentido que un API Gateway actue como load balancer de una manera u otra

1 respuesta
desu
#12JuAn4k4:

Traeffik hace muchas de estas cosas, yo diría que te convendría pegarte con su documentación e intentarlo. Acabarás entendiendo algunas cosas aunque lo hagas malamente.

Me he mirado https://doc.traefik.io/traefik/getting-started/quick-start/ y me gusta.

Lo recordaba mas complejo porque el caso de uso que tenia que resolver era bastante chungo la verdad... Pero mirandolo ahora me ha parecido mas sencillo que el stack de spring para algo basico. Porque no hay tanto archivo de configuracion, no hay que configurar los componentes por separado, es un todo en uno. Eso si, mucha magia negra por defecto que tienes que vigilar despues.

En temas de proyectos tochos, por curiosidad, como se compara vs alternativas? Lo digo bien que Traefik vs netflix stack seria todo en uno vs componentes separadas?

Pero para el caso que expone #1 lo veo bien. Retiro lo dicho y tambien lo recomiendo para empezar. De hecho lo voy a probar ahora con un par de containers que tengo configurados par ver si de verdad es tan facil xd.

1 respuesta
JuAn4k4

#14 Está al nivel de HAProxy y otros, es cierto que en cuanto a performance no es top, pero es suficiente para casi todos los escenarios. Sus docs están muy bien y es simple de configurar lo básico. Por eso lo doy como opción viable.

#13 Depende de las necesidades, si necesitas HW balancing haría falta otra cosa.

1 respuesta
desu

EDIT ya lo arregle.

Dejo la duda:

spoiler

La solucion es el path strip:
- "traefik.http.routers.ws0.rule=PathPrefix(/ws0)"
- "traefik.http.middlewares.ws0pathstrip.stripprefix.prefixes=/ws0"

Joder he caido porque hice algo por el estilo en un ws con fast api que no lo hacia automatico sino estoy 2 horas mas xd

V

yo he conseguido instalar el nginx proxy manager, pero no se como usarlo de balanceador, alguien sabe?

Usuarios habituales