APIs y MicroServicios en Empresas Monolíticas — Deploy y escalamiento de microservicios con Kubernetes #7

Jovani Arzate
12 min readApr 14, 2019

--

La necesidad de escalar microservicios de forma global hoy en día es necesaria, siendo la forma mas adecuada para que los recursos se puedan gestionar según la demanda y esta es una de la ventajas que nos provee Kubernetes.

El uso de contenedores y de orquestadores como Kubernetes, permite automatizar el despliegue, escalado y gestión de las aplicaciones que se ejecutan dentro de dichos contenedores.

Existen dos opciones de implementación de auto escalado de microservicios, con contenedores y Kubernetes.

Horizontal Pod Autoscaling (HPA)
Monitorización y escalado por script

¿Cómo funciona el autoescalador de POD horizontal HPA?

Al iniciar el despliege de microservicios en Kubernetes, inicialmente crearemos un deployment y con ello crear solo un POD para ejecutar nuestra aplicación. cuando el tráfico aumente, tendremos que escalar la aplicación para satisfacer la demanda de los usuarios.

El escalado se realiza cambiando el número de réplicas en una implementación.

La ampliación de una implementación garantizará que se creen nuevos PODS y se programen en nodos con los recursos disponibles,

Kubernetes también admite el escalado automático de PODS, la escala a cero también es posible, y terminará todos los PODS de la implementación especificada.

La ejecución de varias instancias de una aplicación requerirá una forma de distribuir el tráfico a todas ellas.

Los servicios tienen un balanceador de carga integrado, que distribuirá el tráfico de red a todos los PODS de una implementación expuesta.

Los servicios supervisarán continuamente los PODS en ejecución utilizando puntos finales, para garantizar que el tráfico se envíe solo a los PODS disponibles.

Lo que hace es crear un punto de entrada que recibe el tráfico por el puerto definido y balancea entre las distintas replicas del pod. (kube-proxy)

• El algoritmo de balanceo es RoundRobin si el proxy
mode se configura en userspace
• El algoritmo de balanceo es Random si el proxy
mode se configura en iptables

Una vez que tenga varias instancias de una aplicación en ejecución, podrá realizar actualizaciones continuas sin tiempo de inactividad. ZERO DOWTIME

pero….

El HorizontalPodAutoscaler normalmente obtiene métricas de una serie de API agregadas (metrics.k8s.io, custom.metrics.k8s.io, y external.metrics.k8s.io). La métrica metrics.k8s.io generalmente la proporciona metrics-server, que debe iniciarse por separado.

El HorizontalPodAutoscaler también puede obtener métricas directamente de Heapster.

Horizontal Pod Autoscaling (HPA)

Este escalado se hace por uso de recursos como CPU/Memoria, aunque en futuras versiones Kubernetes llegará a soportar otras métricas adicionales.

Ahora manos a la obra….

Primeramente:

1.- Para realizar esta ambientación es necesario bajar el proyecto de clientes de las siguientes url’s.

https://github.com/jovaniac/api-clientes-microservicios-scaling.git

Prerequisitos
1.- Tener un Cluster de Kubernetes, podemos instalar Minikube, en este caso se uso GKE como cluster.

Crearemos en cluster básico en Google Cloud Plattform:

caracteristicas del Cluster

El cluster de Kubernetes se aproviciona rápidisimo!!

Cluster de 4 nodos 8vCPUs con 30 GB de RAM Total

Obtenemos los datos de conexión al cluster para Kubectl, con gcloud, es necesario tener instalado y configurado.

> gcloud container clusters get-credentials standard-cluster-1  --zone us-central1-a --project  true-hook-237600

Donde:

standard-cluster-1 es tu cluster

— zone us-centra1-a indicamos la zona donde se desplegará el cluster

— project nombre del proyecto de google

Validamos que kubectl en nuestra maquina local, ya esta configurado con los datos en el archivo .config el cual apunta a nuestro cluster previamente creado, para esto obtendremos los datos con la siguiente instruccion de gcloud.

Validamos el cluster con:

> kubectl cluster-info

Nos asigna una IP en este caso 35.239.75.155

Nodos del CLuster en estatus READY.

kubectl get nodes

Verificamso que todos los PODs para el funcionamiento del Cluster se hayan creado correctamente con:

kubectl get pods --all-namespaces

Deploy y Services de MicroServicios
Es necesario crear los archivos de deploy y service para nuestro microservicios de clientes, este se deberán de ejecutar con kubectl en Kubernetes.

> kubectl apply -f kubernetes/

Deploy y Service de Clientes

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: servicio-cliente
labels:
app: servicio-cliente
spec:
replicas: 1
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 2
maxUnavailable: 0
selector:
matchLabels:
app: servicio-cliente
template:
metadata:
labels:
app: servicio-cliente
spec:
containers:
- name: servicio-cliente
image: jovaniac/servicio-cliente:0.0.1-snapshot
ports:
- containerPort: 8081
protocol: TCP
imagePullPolicy: Always
resources:
#solicitud de memoria
requests:
memory: "256Mi"
cpu: "250m"
#limite de memoria
limits:
memory: "1024Mi"
cpu: "500m"
---
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: servicio-cliente
spec:
maxReplicas: 5
minReplicas: 1
targetCPUUtilizationPercentage: 70
scaleTargetRef:
apiVersion: extensions/v1beta1
kind: Deployment
name: servicio-cliente

Importante la siguiente configuración, para especificar la asignación de CPU y RAM para la aplicación interna del contenedor, en este caso microservicios con Spring Boot. estableciendo la memoria inicial y el máximo.

#solicitud de memoria
requests:
memory: "256Mi"
cpu: "250m"
#limite de memoria
limits:
memory: "1024Mi"
cpu: "500m"

Donde en requests se especifica la memoria solicitada al contenedor, limits indicamos cual seria el limite para poder escalar.

Ahora, especificamos cuanto queremos ESCALAR, cuantas REPLICAS se crearán al momento de hacer SCALING.

spec:
maxReplicas: 5
minReplicas: 1
targetCPUUtilizationPercentage: 70
scaleTargetRef:
apiVersion: extensions/v1beta1
kind: Deployment
name: servicio-cliente

Se indica cuales serán el número de replicas cuando se ESCALE maxReplicas, y a cuantas va decrementar Scaling DOWN minReplicas. así mismo cuanto será el porcentaje de CPU usado para iniciar el SCALING UP targetCPUUtilizationPercentage, en este caso lo hacemos por CPU 70%.

Por qué 70%, no esperamos a escalar cuando nuestra aplicación ya este apunto de colapsar NO?

La imagen que se expresa en el Deploy de Cliente en este caso se publico en el registry de DockerHub.

Para poder crear la imagen, se creo el siguiente Dockerfile.

FROM openjdk:8u151-jre-slim
MAINTAINER jovaniac@gmail.com
COPY servicio-cliente.jar /opt/servicio-cliente.jar
EXPOSE 8081
ENTRYPOINT [“java”, “-Djava.awt.headless=true”, “-Xms256m”, “-Xmx256m”, “-jar”, “/opt/servicio-cliente.jar”]

Service Discovery de Clientes, importante no definir como LoadBalancer los services, ya que queremos que la comunicación sea por el ingresgateway de Istio.

apiVersion: v1
kind: Service
metadata:
name: servicio-cliente
labels:
app: servicio-cliente
spec:
spec:
type: LoadBalancer
ports:
- port: 8081
name: http
selector:
app: servicio-cliente

Nos ponemos en la raiz del proyecto de clientes y ejecutamos la siguiente instrucción, la cual nos servirá para poder instalar el microservicio en Kubernetes

> kubectl apply -f kubernetes/

Se realizó correctamente el deploy, veremos que nos generé una IP publica para poder realizar las pruebas de SCALING. en la columna de EXTERNAL-IP nos aprovicionará una IP Elastica, inicialmente inicia como PENDING.

Veremos que tambien nos creará un HPA, con las caracteristicas que establecimos y podemos visualizar el consumo actual del microservicio de clientes.

> kubectl get pods,svc,hpa — all-namespaces

Vemos que en la columna TARGET, indica cual es el portentaje para que ESCALE el POD en este caso 70%, y que el estado actual es DESCONOCIDO, pero aqui veremos el porcentaje de la memoria USADA.

Dejamos pasar algunso segundos y ahora veremso reflejado el siguiente TARGET 0% / 70%.

El log del microservicio para ver si ya se inicio.

> kubectl logs -f servicio-cliente-669bd54644-zbwmf

Verificamos que ya nos haya aprovicionado la IP publica, la ip que nos da es 34.66.232.240.

default service/servicio-cliente LoadBalancer 10.11.251.249 34.66.232.240 8081:31362/TCP 12m

Momento de ESCALAR…

Herramienta de benchmarking HTTP

Para esto necesitaremos instalar WRK a HTTP benchmarking tool, wrk es una herramienta de evaluación comparativa de HTTP moderna capaz de generar una carga significativa cuando se ejecuta en una única CPU de múltiples núcleos.

ooooosea tirarle una carga significativa de REQUEST,s o SOLICITUDES al microservicio para que este comience a gastar mas recursos y pueda ESCALAR.

Para poder instalar la herramienta ir a https://github.com/wg/wrk/wiki/Installing-wrk-on-Linux

ahora realizamos un request al micoservicio de clientes:

> http://34.66.232.240:8081/api/v1/clientes

payload de entrada:

{
“apellidoMaterno”: “cabrera”,
“apellidoPaterno”: “arzate”,
“direccion”: “test”,
“edad”: 29,
“email”: “jovaniac@gmail.com”,
“genero”: “h”,
“nombre”: “jovani”
}

request con postman:

respuesta, vemos que genera un folio de creación del cliente.

{
"folioCliente": "-1804035403",
"nombre": "jovani",
"apellidoPaterno": "arzate",
"apellidoMaterno": "cabrera",
"email": "jovaniac@gmail.com",
"direccion": "test",
"genero": "h",
"edad": 29
}

Log del Container, en Kubernetes, vemos como aparece 1 peticion que hemos realizado al microservicio de clientes construido con Spring Boot

> kubectl logs -f servicio-cliente-669bd54644-zbwmf

okok, ahora comencemos a generar TRAFICO y verificar que se esten creando las REPLICAS de los PODs y se balance vía SERVICE las solicitudes.

Abriremos varias ventanas para poder ver que se están atendiendo las solicitudes en los multiples PODs.

Haya vamos!, con la siguiente instrucción realizaremos la carga de Trafico.

Donde:

-c, --connections: total number of HTTP connections to keep open with
each thread handling N = connections/threads

-d, --duration: duration of the test, e.g. 2s, 2m, 2h

-t, --threads: total number of threads to use

-s, --script: LuaJIT script, see SCRIPTING

-H, --header: HTTP header to add to request, e.g. "User-Agent: wrk"

--latency: print detailed latency statistics

--timeout: record a timeout if a response is not received within
this amount of time.

Quedando de las siguiente forma, comenzaremos poco a poco.

wrk -t1 -c1 -d30s http://34.66.232.240:8081/api/v1/clientes

Comienza a llegar el tráfico.

El HPA vía Heapster comienza a actualiza el uso de CPU.

8% de uso

Momento de ESCALAR!!!!, entramos a cada uno de los logs de los PODs, vemos que comienza a llegar peticiones al mismo microservicio en cada container.

peticiones que llegan a cada POD

El targer indica que ya sobrepaso del 70%.

Se comienzan a crear REPLICAS y ahora tenemos 2 PODs, atendiendo el tráfico.

Abrimos varias terminales para poder lanzar el tráfico, ahora con:

> wrk -t100 -c100 -d300s http://34.66.232.240:8081/api/v1/clientes

Se crean 3 REPLICAS y tenemos 3 PODs, atendiendo cada solicitud de forma balanceada.

El porcentaje de consumo esta al doble y se aproviciona más replicas, ahora tenemos 5 PODS atendiendo el tráfico.

5 Replicas, 5 PODS, con ello atendemos 100 hilos x 100 conexiones durante 300 segundos.

Tenemos abiertos 3 ventanas para ver los logs de 3 PODs, y el consumo de CPU comienza a disminuir.

Saturando el ancho de banda :), al estar enviando mucho tráfico estoy saturando mi ancho de banda de subida :)

Terminamos las peticiones hacia el microservicio y poco a poco se comienzan a morir cada POD que se creo, por lo cual me sale la leyenda de NO SUCH Container por que se produce SCALE DOWN, una vez que ya no se están recibiendo tantas solicitudes, Kubernetes automaticamente comienza a liberar recursos terminando los PODs, sin dejar de atender el tráfico entrante.

EL SCALING DOW llega a tener solo 1 replica, ya que nuestra configuración indica que como minimo existe 1.

Como podemos ver el consumo de CPU bajo, y así se redujo automáticamente el número de réplicas a 1.

Algunas evidencias del Scaling realizado en tiempo REAL.

escalando microservicios video 1
escalando microservicios video 2

En el siguiente artículo, hablaremos sobre Monitoreo de Microservicios con Istio y Grafana.

— — — — — — — — — — — — — — — — — — — — — — — — — —

Todo el año 2021 estaré impartiendo diferentes tranings, bootcamps y workshops de Apigee, Cloud y Microservicios en APIXCLOUD Service y Certificatic en la CIUDAD DE MÉXICO, les comparto el link donde vienen los telefonos y redes sociales de contacto.

BOOTCAMP : ARQUITECTO EN APIGEE Y MICROSERVICIOS CLOUD NATIVE:

🔻 Sede: APIX&CLOUD — Services / MODO ONLINE CON INSTRUCTOR EN TIEMPO REAL

🏆 Instructor: Jovani Arzate

⏰ Horario: 8:00am a 2:00pm.

⏳ Duración: 64 Horas dividido en 10 sesiones tomando 6 horas cada domingo.

🔻SOLO 15 LUGARES

📲 Contáctanos 👉 wa.link/v22o0v

contacto@apixcloudservice.com

Temas que se verán en el entranamiento:

1. APIs — APIficando productos digitales
2. APIs — OpenAPI Spec 2.0 y 3.0
3. Gobierno de APIs, Metodología, Roles
4. API Management, Desarrollo en Apigee, CI/CD
5. Monolíticos, Arquitectura SOA y principios de diseño
6. Contenedores, despliegue y CI/CD
7. Microservicios — patrones de diseño, arquitectura y desarrollo
8. Kubernetes para despliegue de microservicios

#openapi #apificacion #apidevelopers #certificatic #microservices #k8s #containers #apis #apigee #patterns #domaindrivendesing #cloudnative #docker #servicediscovery #tracing #logs #monitoring #faulttolerance #eventdriven #scaling #apigateway #servicemesh #governance #arquitectura #cloud #12factores #contractfirst #apifirstdevelopment #rest #swagger #microservicios

Te invito a que leas el overview de microservicios en el siguiente Link.

y mi artículo del Patron Service Discovery en Kubernetes.

así como:

y por último DataManagement y Trazabilidad Distribuida:

Mi canal de youtube: https://www.youtube.com/channel/UC-eLSM45n_ZSYr1T749E6KA/videos?view_as=subscriber

Jovani Arzate Cabrera| Entrepreneur | Public Cloud Specialist | Cloud Governance | API Evangelist | API Architect | Apigee | Microservicios | AWS | Azure | GCP

--

--

Jovani Arzate

Entrepreneur | Public Cloud Specialist | Cloud Governance | API Evangelist | API Architect | Apigee | Microservicios