Despliega tu aplicación de Node.js en Kubernetes con autoescalado y HELM: tutorial paso a paso

Aprende a desplegar una aplicación Node.js en Kubernetes con autoescalado y Helm. Nuestro tutorial paso a paso te guiará a través del proceso. ¡Comienza hoy mismo!

Despliega tu aplicación de Node.js en Kubernetes con autoescalado y HELM: tutorial paso a paso
Photo by Loik Marras / Unsplash

En la actualidad, Kubernetes se ha convertido en una de las herramientas más utilizadas en el mundo de la nube. Se trata de un orquestador de contenedores que nos permite desplegar nuestras aplicaciones de manera eficiente y escalable. En este tutorial, vamos a ver cómo desplegar una aplicación de Node.js en Kubernetes incluyendo autoescalado utilizando HELM.

¿Qué es Kubernetes? ¿Y Helm?

Si no conoces estas dos tecnologías, es importante que antes de continuar leas el post en el que hablo de ambas. Es muy corto y rápido de leer y te dará los conocimientos necesarios para continuar así que te recomiendo que primero leas este post:

Kubernetes y Helm: la combinación perfecta para la orquestación de contenedores
Descubre cómo Kubernetes y Helm trabajan juntos para proporcionar la orquestación de contenedores perfecta. Aprende cómo usar Helm para administrar tus aplicaciones de Kubernetes. ¡Obtén más información hoy!
Kubernetes y Helm: la combinación perfecta para la orquestación de contenedores

¿Qué es autoescalado?

El autoescalado es una funcionalidad de Kubernetes que permite escalar automáticamente el número de réplicas de un conjunto de pods. Esto significa que si la carga de la aplicación aumenta, Kubernetes aumentará automáticamente el número de réplicas de la aplicación para asegurar que se mantenga el rendimiento.

Requisitos previos

Antes de comenzar con el tutorial, necesitarás los siguientes requisitos:

  • Un clúster de Kubernetes configurado en tu proveedor de nube o en local
  • Conocimientos básicos de Node.js y Docker.

Paso 1: Crear una aplicación de Node.js

Lo primero que debemos hacer es preparar nuestra aplicación. En nuestro caso y para que sirva como ejemplo tenemos preparado un servidor con express que devuelve: Hello-world. Muy sencillo e ilustrativo.

Realmente no necesitas clonarte el repositorio porque utilizaremos la imagen de Docker que ya he generado previamente.

GitHub - TechBcknd/hello-world
Contribute to TechBcknd/hello-world development by creating an account on GitHub.
Repositorio de Node.js como ejemplo de microservicio

Paso 2: Crear un archivo Dockerfile

Ahora que tenemos nuestra aplicación de Node.js, necesitamos crear una imagen de Docker para poder desplegarla en Kubernetes. Para ello, crearemos un archivo Dockerfile con el siguiente contenido:

# Utiliza la imagen oficial de node.js
FROM node:lts-alpine

# Crea el directorio de la aplicación
RUN mkdir -p /usr/src/app

# Establece el directorio de trabajo
WORKDIR /usr/src/app

# Instala las dependencias de la aplicación
COPY package.json /usr/src/app/
RUN npm install

# Instala la aplicación
COPY . /usr/src/app

# Expone el puerto de la aplicación
EXPOSE 3000

# Ejecuta la aplicación
CMD [ "npm", "start" ]

Este archivo especifica la imagen base de Node.js que vamos a utilizar, copia los archivos de la aplicación, instala las dependencias y expone el puerto 3000.

Paso 3: Construir la imagen de Docker

Una vez que tenemos nuestro Dockerfile, podemos construir la imagen de Docker utilizando el siguiente comando:

docker build -t tu-usuario/app-nodejs .
💡
No olvides subir la imagen de docker a un repositorio si la vas a utilizar en un cluster de Kubernetes remoto

Para hacerlo puedes utilizar:
$ docker push tu-usuario/app-nodejs

Paso 4: Crear un chart de HELM

Ahora que tenemos nuestra imagen de Docker, podemos crear un chart de HELM para desplegar nuestra aplicación en Kubernetes. Lo más sencillo y más rápido es utilizar el comando de HELM que nos genera un chart preconfigurado.

# El comando que tienes que utilizar es:
helm create mi-chart

# En nuestro caso:
helm create hello-world

Esto creará los siguientes archivos y carpetas:

Lo sé, hay mucho código generado y es posible que te resulte complicado leer que hace cada cosa al principio, pero no te preocupes ahora te explico para qué sirve cada uno.

  • values.yaml: Este archivo es el que almacena los valores finales del chart. Es decir, la configuración (el puerto, número de replicas, nombre del pod...)
  • Chart.yaml: contiene la información sobre el chart. Por ejemplo: el nombre, la descripción, la versión de la aplicación y la versión del chart.
  • NOTES.txt: este archivo se utiliza para imprimir información cuando acaba de instalarse el chart. Es lo que se muestra al usuario una vez que se ha instalado.
  • deployment.yaml: Este archivo describe cómo se debe desplegar la aplicación, incluyendo la imagen de contenedor que se debe usar, la cantidad de réplicas que se deben crear, la política de actualización, entre otros aspectos importantes.
  • hpa.yaml: Este archivo describe cómo se debe escalar automáticamente la aplicación en función de la carga que esté recibiendo. Se define el umbral de carga que se debe alcanzar para aumentar o disminuir el número de réplicas de la aplicación.
  • ingress.yaml: Este archivo describe cómo se deben exponer los servicios de la aplicación al mundo exterior. Incluye la configuración de los balanceadores de carga, los certificados SSL, entre otros aspectos importantes.
  • service.yaml: Este archivo describe cómo se deben conectar los diferentes componentes de la aplicación. Define los puertos y protocolos que se deben utilizar para la comunicación entre los diferentes contenedores.
  • serviceaccount.yaml: Este archivo describe las políticas de seguridad que se deben aplicar a la aplicación. Define qué permisos tienen los contenedores para acceder a otros recursos del clúster, como bases de datos, almacenamiento, entre otros aspectos importantes.

En mi caso en el values.yaml he puesto:

# Default values for hello-world.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.

replicaCount: 1

image:
  tag: "docker.io/techbcknd/hello-world:latest"
  pullPolicy: IfNotPresent

imagePullSecrets: []
nameOverride: "hello-world"
fullnameOverride: "hello-world"

serviceAccount:
  # Specifies whether a service account should be created
  create: false

podAnnotations: {}

podSecurityContext: {}

securityContext: {}

service:
  type: NodePort
  port: 3000

ingress:
  enabled: false

resources:
  requests:
    cpu: 100m
    memory: 128Mi

autoscaling:
  enabled: true
  minReplicas: 1
  maxReplicas: 3
  targetCPUUtilizationPercentage: 80
  targetMemoryUtilizationPercentage: 80

nodeSelector: {}

tolerations: []

affinity: {}

Así si el porcentaje de CPU y de memoria supera el 80% escalará hasta 3 pods de forma automática.

⚠️
¡IMPORTANTE!: El cluster de kubernetes tiene que tener desplegado el llamado: metrics-server para poder utilizar el autoescalado.
Si no lo tenemos, Kubernetes no sabrá cuánta CPU y Memoria está utilizando nuestro servicio y, por lo tanto, no escalará de forma automática.

Si estamos utilizando un cluster en local sobre Docker necesitaremos desactivar la comprobación del TLS del kubelet. Este issue de Github explica cómo hacerlo:

Metrics server not running · Issue #1081 · kubernetes-sigs/metrics-server
Hi, I have deployed the metrics server but it’s not running I have added the below lines after “args” in “components.yaml ” command: - /metrics-server - --kubelet-insecure-tls - --kubelet-preferred…

Pero básicamente podemos aplicar el deployment del metrics-server con:

kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

Y luego editar el deployment para añadir en la parte de args: - --kubelet-insecure-tls

Quedando algo así:

Así podremos ver las métricas de consumo de nuestro autoscaler:

kubectl get horizontalpodautoscaler.autoscaling/hello-world --watch
NAME          REFERENCE                TARGETS           MINPODS   MAXPODS   REPLICAS   AGE
hello-world   Deployment/hello-world   41%/80%, 1%/80%   1         3         1          103m

El repositorio de prueba con el chart de HELM que yo he utilizado en este tutorial está en el siguiente enlace:

GitHub - TechBcknd/helm-basic: Repositorio básico de helm para microservicios
Repositorio básico de helm para microservicios. Contribute to TechBcknd/helm-basic development by creating an account on GitHub.

Paso 5: Desplegar la aplicación en Kubernetes

Una vez que tenemos nuestro chart de HELM, podemos desplegar nuestra aplicación en Kubernetes utilizando el siguiente comando:

helm install nombre-instalacion nombre-chart

# En nuestro caso:
helm install hello-world hello-world

Ahora podremos comprobar la instalación con:

kubectl get all

Paso 6: Probar la aplicación

Ahora que tenemos nuestra aplicación desplegada en Kubernetes, podemos probarla accediendo a su dirección IP en un navegador web. Si todo ha ido bien, deberíamos ver el mensaje de "Hello World" que devuelve nuestra aplicación.

Paso 7: Escalar la aplicación

Para probar el autoescalado de nuestra aplicación, podemos utilizar una herramienta de carga como: autocannon

GitHub - mcollina/autocannon: fast HTTP/1.1 benchmarking tool written in Node.js
fast HTTP/1.1 benchmarking tool written in Node.js - GitHub - mcollina/autocannon: fast HTTP/1.1 benchmarking tool written in Node.js
# Creamos un test de carga para comprobar el auto-escalado
autocannon -c 100 -w 4 -d 120 "http://localhost:<puerto>"


Si observamos la salida de kubectl get pods, veremos cómo Kubernetes ha aumentado automáticamente el número de réplicas de nuestra aplicación para gestionar la carga. Podemos ajustar los valores de autoescalado en el archivo values.yaml para controlar el comportamiento de autoescalado de nuestra aplicación.

Conclusión

En este tutorial, hemos visto cómo desplegar una aplicación de Node.js en Kubernetes utilizando autoescalado y HELM. Kubernetes es una herramienta muy potente que nos permite gestionar aplicaciones de manera sencilla y eficiente. Utilizando autoescalado, podemos asegurar que nuestras aplicaciones mantengan el rendimiento incluso en momentos de alta demanda.


¡Nos encantaría saber tu opinión! Déjanos un comentario contándonos qué te ha parecido nuestro contenido y qué temas te gustaría que abordáramos en el futuro.

Además, al dejar un comentario, estarás contribuyendo a crear una comunidad de lectores interesados en la tecnología, donde se puedan intercambiar ideas y puntos de vista. ¡No lo dudes y comparte tu opinión con nosotros!

¡Gracias por leernos y por tu interés en la tecnología!