Escalado automático de Kubernetes: Aprende a escalar tus implementaciones de Kubernetes de manera dinámica

Descubre las diferentes opciones para escalar tu plataforma según la carga de tráfico que recibas

Foto de SpaceX en Unsplash.

Cuando hablamos de Kubernetes, siempre estamos hablando de las opciones de flexibilidad que proporciona. Normalmente, uno de los temas que surgen en la discusión son las opciones de elasticidad que vienen con la plataforma, especialmente cuando se trabaja con un proveedor de nube pública. Pero, ¿cómo podemos implementarlo realmente?

Antes de comenzar a mostrar cómo escalar nuestra plataforma Kubernetes, necesitamos hacer un breve repaso de las opciones que están disponibles para nosotros:

  • Cluster Autoscaler: Cuando la carga de toda la infraestructura alcanza su pico, podemos mejorarla creando nuevos nodos de trabajo para alojar más instancias de servicio.
  • Horizontal Pod Autoscaling: Cuando la carga para un pod específico o conjunto de pods alcanza su pico, desplegamos una nueva instancia para asegurar que podemos tener la disponibilidad global que necesitamos.

Veamos cómo podemos implementar esto usando uno de los servicios gestionados de Kubernetes más populares, los Servicios de Kubernetes Elásticos (EKS) de Amazon.


Configuración

Lo primero que vamos a hacer es crear un clúster con un solo nodo de trabajo para demostrar fácilmente el comportamiento de escalabilidad. Y para hacerlo, vamos a usar la herramienta de línea de comandos eksctl para gestionar fácilmente un clúster EKS.

Para poder crear el clúster, lo haremos con el siguiente comando:

eksctl create cluster --name=eks-scalability --nodes=1 --region=eu-west-2 --node-type=m5.large --version 1.17 --managed --asg-access

Después de unos minutos, tendremos nuestro propio clúster de Kubernetes con un solo nodo para desplegar aplicaciones sobre él.

Ahora vamos a crear una aplicación de muestra para generar carga. Vamos a usar TIBCO BusinessWorks Application Container Edition para generar una aplicación simple. Será una API REST que ejecutará un bucle de 100,000 iteraciones actuando como un contador y devolverá un resultado.

Aplicación de muestra de BusinessWorks para mostrar las opciones de escalabilidad

Y utilizaremos los recursos disponibles en este repositorio de GitHub:

Construiremos la imagen del contenedor y la subiremos a un registro de contenedores. En mi caso, voy a usar mi instancia de Amazon ECR para hacerlo, y usaré los siguientes comandos:

docker build -t testeks:1.0 .
docker tag testeks:1.0 938784100097.dkr.ecr.eu-west-2.amazonaws.com/testeks:1.0
docker push 938784100097.dkr.ecr.eu-west-2.amazonaws.com/testeks:1.0

Y una vez que la imagen esté subida al registro, desplegaremos la aplicación sobre el clúster de Kubernetes usando este comando:

kubectl apply -f .testeks.yaml

Después de eso, tendremos nuestra aplicación desplegada allí, como puedes ver en la imagen a continuación:

Imagen desplegada en el clúster de Kubernetes

Entonces, ahora podemos probar la aplicación. Para hacerlo, haré que el puerto 8080 esté disponible usando un comando de reenvío de puerto como este:

kubectl port-forward pod/testeks-v1-869948fbb-j5jh7 8080:8080

Con eso, puedo ver y probar la aplicación de muestra usando el navegador, como se muestra a continuación:

Probador de Swagger UI para la aplicación de muestra de Kubernetes

Escalado automático de pods horizontales

Ahora, necesitamos comenzar a definir las reglas de escalado automático, y comenzaremos con la regla de Escalado Automático de Pods Horizontales (HPA). Necesitaremos elegir el recurso que nos gustaría usar para escalar nuestro pod. En esta prueba, usaré la utilización de CPU para hacerlo, y usaré el siguiente comando:

kubectl autoscale deployment testeks-v1 --min=1 --max=5 --cpu-percent=80

Ese comando escalará el conjunto de réplicas testeks de una (1) instancia a cinco (5) instancias cuando el porcentaje de utilización de CPU sea superior al 80%.

Si ahora verificamos el estado de los componentes, obtendremos algo similar a la imagen a continuación:

Definición de regla HPA para la aplicación usando la utilización de CPU como la métrica clave

Si verificamos la columna TARGETS, veremos este valor: <unknown>/80%. Eso significa que el 80% es el objetivo para activar las nuevas instancias y el uso actual es <unknown>.

No tenemos nada desplegado en el clúster para obtener las métricas de cada uno de los pods. Para resolver eso, necesitamos desplegar el Servidor de Métricas. Para hacerlo, seguiremos la documentación de Amazon AWS:

Entonces, ejecutando el siguiente comando, tendremos el Servidor de Métricas instalado.

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

Y después de hacer eso, si verificamos nuevamente, podemos ver que el uso actual ha reemplazado el <unknown>:

Utilización actual de recursos después de instalar el Servidor de Métricas en el clúster de Kubernetes

Si eso funciona, voy a comenzar a enviar solicitudes usando una Prueba de Carga dentro del clúster. Usaré la aplicación de muestra definida a continuación:

Para desplegar, usaremos un archivo YAML con el siguiente contenido:

https://gist.github.com/BetterProgramming/53181f3aa7bee7b7e3adda7c4ed8ca40#file-deploy-yaml

Y lo desplegaremos usando el siguiente comando:

kubectl apply -f tester.yaml

Después de hacer eso, veremos que la utilización actual está aumentando. Después de unos segundos, comenzará a girar nuevas instancias hasta que alcance el número máximo de pods definido en la regla HPA.

Aumento de pods cuando la carga excede el objetivo definido en pasos anteriores.

Luego, tan pronto como la carga también disminuya, el número de instancias será eliminado.

Los pods se eliminan tan pronto como la carga disminuye.

Escalado automático de clústeres

Ahora, necesitamos ver cómo podemos implementar el Escalador Automático de Clústeres usando EKS. Usaremos la información que proporciona Amazon:

https://github.com/alexandrev/testeks

El primer paso es desplegar el escalado automático del clúster, y lo haremos usando el siguiente comando:

kubectl apply -f https://raw.githubusercontent.com/kubernetes/autoscaler/master/cluster-autoscaler/cloudprovider/aws/examples/cluster-autoscaler-autodiscover.yaml

Luego ejecutaremos este comando:

kubectl -n kube-system annotate deployment.apps/cluster-autoscaler cluster-autoscaler.kubernetes.io/safe-to-evict=”false”

Y editaremos el despliegue para proporcionar el nombre actual del clúster que estamos gestionando. Para hacer eso, ejecutaremos el siguiente comando:

kubectl -n kube-system edit deployment.apps/cluster-autoscaler

Cuando tu editor de texto predeterminado se abra con el contenido del texto, necesitas hacer los siguientes cambios:

  • Establece el nombre de tu clúster en el marcador de posición disponible.
  • Agrega estas propiedades adicionales:
- --balance-similar-node-groups
- --skip-nodes-with-system-pods=false
Ediciones de despliegue necesarias para configurar el Escalador Automático de Clústeres

Ahora necesitamos ejecutar el siguiente comando:

kubectl -n kube-system set image deployment.apps/cluster-autoscaler cluster-autoscaler=eu.gcr.io/k8s-artifacts-prod/autoscaling/cluster-autoscaler:v1.17.4

Lo único que queda es definir la política de AutoScaling. Para hacerlo, usaremos el portal de Servicios de AWS:

  • Ingresa a la página de servicio EC en la región en la que hemos desplegado el clúster.
  • Selecciona las opciones de Grupo de Auto Scaling.
  • Selecciona el Grupo de Auto Scaling que se ha creado como parte del proceso de creación del clúster EKS.
  • Ve a la pestaña de Escalado Automático y haz clic en el botón Agregar Política disponible.
Opción de política de escalado automático en la consola de servicio EC2

Luego deberíamos definir la política. Usaremos la utilización promedio de CPU como la métrica y estableceremos el valor objetivo en 50%:

Diálogo de creación de política de escalado automático

Para validar el comportamiento, generaremos carga usando el probador como lo hicimos en la prueba anterior y validaremos la carga del nodo usando el siguiente comando:

kubectl top nodes
Salida de muestra de kubectl top nodes

Ahora desplegamos el probador nuevamente. Como ya lo tenemos desplegado en este clúster, necesitamos eliminarlo primero para desplegarlo nuevamente:

kubectl delete -f .tester.yaml
kubectl apply -f .tester.yaml

Tan pronto como comience la carga, se crearán nuevos nodos, como se muestra en la imagen a continuación:

kubectl top nodes mostrando cómo los nodos han sido escalados hacia arriba

Después de que la carga termine, volvemos a la situación anterior:

kubectl top nodes mostrando cómo los nodos han sido escalados hacia abajo

Resumen

En este artículo, hemos mostrado cómo podemos escalar un clúster de Kubernetes de manera dinámica tanto a nivel de nodo de trabajo usando la capacidad de Escalador Automático de Clústeres como a nivel de pod usando el Escalador Automático de Pods Horizontales. Eso nos da todas las opciones necesarias para crear un entorno verdaderamente elástico y flexible capaz de adaptarse a las necesidades de cada momento con el enfoque más eficiente.

Alexandre Vazquez: