Despliega tu aplicación de Node.js en Kubernetes con autoescalado y HELM: tutorial paso a paso
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:
¿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.
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 .
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.
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:
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:
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
# 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!