Aparte de todas las discusiones recientes sobre Kubernetes y si deberías Dockerizar tu base de datos o no, hoy me gustaría mostrarte por qué esas dos cosas podrían ser buenas soluciones cuando la escalabilidad y la elasticidad son un gran requisito en tu arquitectura.

La salsa secreta es sencilla: Spring Boot con Kubernetes para desplegar tanto su aplicación como su base de datos utilizando NoSQL.

 

¿Por qué NoSQL y Spring Data?

Con las bases de datos de documentos, puede evitar muchas uniones innecesarias, ya que toda la estructura se almacena en un único documento. Por tanto, su rendimiento será más rápido que el de un modelo relacional a medida que crezcan los datos.

Si estás utilizando alguno de los lenguajes JVM, Spring Data y Spring Boot pueden ser algo bastante familiar para ti. Así, puedes empezar rápidamente con NoSQL incluso sin ningún conocimiento previo.

 

¿Por qué Kubernetes?

Kubernetes (K8s) le permite escalar hacia arriba y hacia abajo su aplicación sin estado en un entorno agnóstico de nube. En las últimas versiones, K8s también ha añadido la capacidad de ejecutar aplicaciones con estado, como bases de datos, que es una de las (muchas) razones por las que es un tema tan candente hoy en día.

He mostrado en mi anterior entrada en el blog cómo desplegar Couchbase en K8s y cómo hacerlo "elástico" escalando fácilmente hacia arriba y hacia abajo. Si aún no lo has leído, dedica unos minutos extra a leer la transcripción del vídeo, ya que es una parte importante de lo que vamos a hablar aquí.

 

Creación de un microservicio de perfil de usuario

En la mayoría de los sistemas, el usuario (y todas las entidades relacionadas) es el dato al que se accede con más frecuencia. En consecuencia, es una de las primeras partes del sistema que tiene que pasar por algún tipo de optimización a medida que sus datos crecen.

Añadir una capa de Caché es el primer tipo de optimización que se nos ocurre. Sin embargo, todavía no es la "solución final". Las cosas podrían complicarse un poco más si tienes miles de usuarios, o si necesitas almacenar entidades relacionadas con los usuarios también en memoria.

La gestión de cantidades masivas de perfiles de usuario es una buena opción para las bases de datos documentales. Basta con echar un vistazo a la Caso práctico de Pokémon Gopor ejemplo. Por lo tanto, la creación de un servicio de perfil de usuario altamente escalable y elástico parece ser un reto lo suficientemente bueno como para demostrar cómo diseñar un microservicio altamente escalable.

Lo que vas a necesitar:

  • Couchbase
  • JDK y el plugin de Lombok para Eclipse o Intellij
  •  Maven
  • Un clúster Kubernetes - Estoy ejecutando este ejemplo en 3 nodos en AWS (no recomiendo usar minikube). Si no sabes cómo configurar uno, mira esto vídeo.

El Código

Puede clonar el proyecto completo aquí:

 

Empecemos creando nuestra entidad principal llamada Usuario:

 

En esta entidad tenemos dos propiedades importantes:

  • securityRoles: Todos los roles que el usuario puede desempeñar dentro del sistema.
  • preferencias: Todas las posibles preferencias que pueda tener el usuario, como idioma, notificaciones, moneda, etc.

Ahora, vamos a jugar un poco con nuestro Repositorio. Como estamos usando Spring Data, puedes usar casi todas sus capacidades aquí:

Si quieres saber más sobre Couchbase y Spring Data, consulte este tutorial.

También aplicamos otros dos métodos:

 

  • hasRole: Comprueba si un usuario tiene un rol especificado:
  • findUsersByPreferencyName: Como su nombre indica, busca todos los usuarios que contienen una preferencia determinada.

Observe que estamos utilizando la sintaxis N1QL en el código anterior, ya que hace que las cosas sean mucho más sencillas de consultar que utilizando JQL simple.

Además, puede ejecutar todas las pruebas para asegurarse de que todo funciona correctamente:

No olvides cambiar tu application.properties con las credenciales correctas de tu base de datos:

Para probar nuestro microservicio, he añadido algunos puntos finales Restful:

 

Dockerización de microservicios

En primer lugar, cambie su aplicación.propiedades para obtener las credenciales de conexión de las variables de entorno:

Y ahora podemos crear nuestro Dockerfile:

A continuación, construimos y publicamos nuestra imagen en Docker Hub:

  • Crea tu imagen:

 

  • Inicie sesión en Docker Hub desde la línea de comandos

  •  Tomemos el imageId de nuestra imagen recién creada:

  • Crea tu nueva etiqueta utilizando el imageId:

 

  • Por último, empuja tu imagen:

Tu imagen debería estar ahora disponible en Docker Hub:

 

Configurar la base de datos

Escribí un artículo entero sobre ello aquípero para ser breves. Simplemente ejecute los siguientes comandos dentro del directorio kubernetes.

Después de un rato, las 3 instancias de nuestra base de datos deberían estar funcionando:

Reenviemos el puerto de la Consola Web a nuestra máquina local:

Y ahora podemos acceder a la consola web en http://localhost:8091. Puede iniciar sesión con el nombre de usuario Administrador y la contraseña contraseña

Ir a Seguridad -> AÑADIR USUARIO con las siguientes propiedades:

  • Nombre de usuario: couchbase-sample
  • Nombre completo: couchbase-sample
  • Contraseña: couchbase-sample
  • Verifica la contraseña: couchbase-sample
  • Funciones: Según la imagen siguiente:

OBS: En un entorno de producción, por favor, no agregue su aplicación como un administrador

 

Despliegue del microservicio

En primer lugar, vamos a crear un secreto de Kubernetes donde almacenaremos la contraseña para conectarnos a nuestra base de datos:

Ejecute el siguiente comando para crear el secreto:

El expediente spring-boot-app.yaml es el responsable de desplegar nuestra aplicación. Echemos un vistazo a su contenido:

Me gustaría destacar algunas partes importantes de este expediente:

  • réplicas: 2 -> Kubernetes lanzará 2 instancias de nuestra aplicación
  •  imagen: deniswsrosa/kubernetes-starter-kit -> La imagen docker que hemos creado antes.
  • contenedores: nombre: -> Aquí es donde definimos el nombre del contenedor que ejecuta nuestra aplicación. Utilizarás este nombre en Kubernetes siempre que quieras definir cuántas instancias deben ejecutarse, estrategias de autoescalado, equilibrio de carga, etc.
  • env: -> Aquí es donde definimos las variables de entorno de nuestra aplicación. Ten en cuenta que también estamos haciendo referencia al secreto que creamos antes.

Ejecute el siguiente comando para desplegar nuestra aplicación:

En unos segundos, observará que las dos instancias de su aplicación ya se están ejecutando:

Por último, expongamos nuestro microservicio al mundo exterior. Hay docenas de posibilidades diferentes de cómo se puede hacer. En nuestro caso, vamos a crear simplemente un Load Balancer:

El selector es una de las partes más importantes del archivo anterior. Es donde definimos los contenedores a los que se redirigirá el tráfico. En este caso, sólo estamos apuntando a la aplicación que hemos desplegado antes.

Ejecute el siguiente comando para crear nuestro equilibrador de carga:

El balanceador de carga tardará unos minutos en estar levantado y redirigiendo tráfico a nuestros pods. Puede ejecutar el siguiente comando para comprobar su estado:

Como puede ver en la imagen anterior, nuestro Load Balancer es accesible en ad84a916d65ad11e884a20266aaa53c9-1223617270.us-west-2.elb.amazonaws.com, y el targetPort 8080 redirigirá el tráfico a dos endpoints: 10.2.1.6:8080 y 10.2.2.7:8080

Por último, podemos acceder a nuestra aplicación y empezar a enviarle peticiones:

  • Insertar un nuevo usuario:
  • Búsqueda de usuarios:

 

¿Qué hay de ser elástico?

Aquí es donde las cosas se ponen realmente interesantes. ¿Y si necesitamos escalar todo nuestro microservicio? Digamos que se acerca el Black Friday y necesitamos preparar nuestra infraestructura para soportar este flujo masivo de usuarios que llegan a nuestra web. Bien, ese es un problema fácil de resolver:

  •  Para ampliar nuestra aplicación, sólo tenemos que cambiar el número de réplicas en el archivo spring-boot-app.yaml archivo.

    Y luego, ejecute el siguiente comando:

¿Falta algo? Sí. ¿Y nuestra base de datos? Deberíamos ampliarla también:

  • Cambie el atributo de tamaño en el couchbase-cluster.yaml file:

 

Por último, ejecute el siguiente comando:

 

¿Cómo puedo reducirlo?

Reducir la escala es tan fácil como aumentarla; sólo tiene que cambiar ambos couchbase-cluster.yaml y spring-boot-app.yaml:

  • couchbase-cluster.yaml

  • spring-boot-app.yaml:

 

Y ejecuta los siguientes comandos:

 

Autoescalado de microservicios en Kubernetes

Profundizaré en este tema en la parte 2 de este artículo. Mientras tanto, puedes ver este vídeo sobre el autoescalado de pods.

Resolución de problemas en la implantación de Kubernetes

Si sus Pods no se inician, hay muchas formas de solucionar el problema. En el siguiente caso, ambas aplicaciones no se iniciaron:

Puesto que forman parte del despliegue, vamos a describir el despliegue para intentar comprender lo que está ocurriendo:

Bueno, nada es realmente relevante en este caso. Veamos entonces uno de los registros de la cápsula:

¡Te pillé! La aplicación no arrancó porque olvidamos crear el usuario en Couchbase. Con sólo crear el usuario, los pods arrancarán en unos segundos:

Conclusión

Las bases de datos son aplicaciones con estado, y escalarlas no es tan rápido como escalar las que no tienen estado (y probablemente nunca lo será), pero si necesitas hacer una arquitectura verdaderamente elástica, deberías planear escalar todos los componentes de tu infraestructura. De lo contrario, sólo estarás creando un cuello de botella en otro lugar.

En este artículo, he tratado de mostrar sólo una pequeña introducción acerca de cómo usted puede hacer su aplicación y base de datos en Kubernetes elástica. Sin embargo, todavía no es una arquitectura lista para producción. Hay un montón de otras cosas a considerar todavía, y voy a abordar algunos de ellos en los próximos artículos.

Mientras tanto, si tienes alguna pregunta, envíame un tweet a @deniswsrosa o deje un comentario a continuación.

 

Lea también:

Autor

Publicado por Denis Rosa, Defensor del Desarrollador, Couchbase

Denis Rosa es un Developer Advocate para Couchbase y vive en Munich - Alemania. Tiene una sólida experiencia como ingeniero de software y habla con fluidez Java, Python, Scala y Javascript. A Denis le gusta escribir sobre búsqueda, Big Data, AI, Microservicios y todo lo que pueda ayudar a los desarrolladores a hacer una aplicación hermosa, más rápida, estable y escalable.

Dejar una respuesta