Enrutamiento de microservicios en Openshift sin Zuul

La primera vez que entre en el mundo de los microservicios fue con Spring Boot y Netflix OSS. En ese momento me encanto el concepto a nivel de microservicio pero también encontré en falta un entorno cómodo donde poder desplegar todo ese ecosistema de micros y gestionar su producción de forma cómoda.

No fui el Ășnico en ver eso y gracias a ello hoy tenemos soluciones como Kubernetes y/o Openshift (entre otros) que nos facilitan su despliegue y operaciĂłn.

En mi experiencia he podido gozar o sufrir (segĂșn como se mire) la migraciĂłn de microservicios en entornos donde se ejecutaban los procesos Java a pelo a entornos dockerizados y gestionados por Kubernetes. Esta transiciĂłn pone sobre la mesa algo a lo que estamos acostumbrados en nuestro gremio y es que las piezas de software se van quedando obsoletas por otras que cubren las necesidades de forma mĂĄs adaptada a los nuevos tiempos.

En este post querĂ­a plantear el uso del Router de Openshift como Gateway Server en vez del Zuul, pieza la cual creo que poco a poco se queda fuera de la ecuaciĂłn en entornos Kubernetes.

Con Zuul de Netflix OSS nos encontramos que es el Ășnico punto de entrada a la capa de microservicios y este en base a la URL de entrada y con soporte de un sistema de Service Discovery (Eureka, Consul....) se encarga de enrutar las peticiones a los microservicios.

Netflix OSS en su momento fue una catapulta para potenciar el uso de microservicios y Kubernetes ha sabido, entre otras cosas, aprovechar lo mejor de Netflix OSS para ofrecerlo de serie en su plataforma.

No es la intenciĂłn de este post explicar como migrar cada una de las funcionalidades de Netflix OSS a Kubernetes, sino centrarnos Ășnicamente en el enrutamiento que hasta ahora se hacĂ­a con Zuul.

Sin querer entrar mĂĄs en la teorĂ­a, pasemos a exponer un ejemplo muy sencillo con Zuul y ver como podemos migrarlo a Openshift.

Si tenemos 2 microservicios llamados "fulanito" y "menganito" y Zuul como Gateway Server, para poder realizar invocaciones sobre estos micros podemos realizar llamadas sobre Zuul como las siguientes.


http://<server host>:<server port>/fulanito/<endpoint rest>
http://<server host>:<server port>/menganito/<endpoint rest>

Se asume que Zuul tiene configurado el acceso a un Service Discovery, el mĂĄs comĂșnmente usado es Eureka. Cuando Zuul recibe las peticiones, extrae de la URL el nombre del microservicio y gracias al Service Discovery realiza el enrutamiento de la siguiente manera.


http://<fulanito host>:<fulanito port>/<endpoint rest>
http://<menganito host>:<menganito port>/<endpoint rest>

Observemos que Zuul ha eliminado en el enrutamiento el nombre del microservicio, de manera que a efectos prĂĄcticos Zuul realiza un "Path Rewrite".

Cuando Zuul Ășnicamente se encuentra disponible para realizar el enrutamiento sin ningĂșn tipo acciĂłn extra como gestiĂłn de cabeceras por ejemplo, entonces podemos hacer uso del Router de Openshift de la siguiente manera.

Si queremos mantener la retrocompatibilidad y realizar las mismas invocaciones que con Zuul, entonces deberemos configurar las Routes de Openshift para que se expongan por path en vez de subdominio y estas redireccionen a un Service Kubernetes que balancearan sobre las diferentes instancias (pods) de nuestro microservicio.


http://<router>:<port>/fulanito/<endpoint rest> --> Kubernetes Service fulanito
http://<router>:<port>/menganito/<endpoint rest> --> Kubernetes Service menganito

Aqui nos encontramos con un pequeño problema y es que el Router de Openshift no permite (actualmente) realizar "Path Rewrite" por lo que los microservicios recibirån las peticiones con el nombre del microservicio como "Base Context" cuando en realidad no se deberían poner.

Spring Boot permite definir un "Base Context" y no requiere que se especifique en los endpoints REST que exponemos, de manera que dependiendo del entorno en que nos encontremos y si se requiere o no un base context, simplemente indicando una propiedad podremos levantar el microservicio exponiendose con un base context o no.

Veamos un ejemplo muy tonto de un microservicio con Spring Boot 2.0.


package org.jrovira.microservices.test.context;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
@EnableAutoConfiguration
public class ContextController {
 
 @RequestMapping("/test")
 @ResponseBody
 public String test( ) {
  return "test";
 }
 
 
 public static void main(String [] args) throws Exception {
  SpringApplication.run(ContextController.class, args);
 }

}

Mediante propiedades podemos definir nuestro base context. Personalmente me gusta el uso de los Spring Profiles, por lo que voy a mostrar dos ficheros de propiedades basados en profiles.

El primero de todos serĂĄ el application-zuul.properties


server.servlet.contextPath=/

y el otro el application-nozuul.properties


server.servlet.contextPath=/fulanito

Cuando arranquemos el microservicio informaremos la propiedad "spring.profiles.active" con el profile "zuul" o "nozuul". Dependiendo del profile que le hayamos indicado en el arranque se expondrĂĄ la operaciĂłn /test con un base context u otro sin necesidad de realizar modificaciones en nuestro cĂłdigo fuente.


/test (con profile zuul)
/fulanito/test (con profile nozuul)

Con esta adaptaciĂłn, por cada Microservicio nos deberemos encargar de tener nuestra Route mas el Kubernetes Service y no harĂ­a falta el uso de Zuul.

Esta es una de las muchas formas de solucionar el enrutamiento con Openshift e ir descatalogando el uso de Zuul, pero obviamente podrĂ­amos hacer un enciclopedia de distintas formas en que se puede ir resolviendo nuestras necesidades.

Como opiniĂłn personal, a la plataforma de Openshift y Kubernetes todavĂ­a le falta proporcionar de fĂĄbrica una buena soluciĂłn de API Gateway o Gateway Server para no requerir de otras soluciones, pero si que es cierto que con un buen API Gateway y el Router de Openshift se pueden hacer cosas muy interesantes sin necesidad de ir arrastrando Zuul en el camino.

En otros posts expondré posibles soluciones alternativas a Netflix OSS con Kubernetes/Openshift.

No hay comentarios