BLOG | NGINX

Tutorial de NGINX: Reducir la latencia de Kubernetes con el escalado automático

NGINX - Parte de F5 - horizontal, negro, tipo RGB
Miniatura de Daniele Polencic
Daniele Polencic
Publicado el 15 de marzo de 2022

Este tutorial es uno de los cuatro que ponen en práctica los conceptos de Microservicios de marzo de 2022: Redes de Kubernetes :

¿Quieres orientación detallada sobre el uso de NGINX para aún más casos de uso de redes Kubernetes? Descargue nuestro libro electrónico gratuito, Gestión del tráfico de Kubernetes con NGINX: Una guía práctica .

¡Su organización creó una aplicación en Kubernetes y ahora se está volviendo popular! Pasaste de tener unos pocos visitantes a cientos (y a veces miles) por día. Pero hay un problema… el aumento del tráfico está creando un cuello de botella, causando latencia y tiempos de espera para sus clientes. Si no puedes mejorar la experiencia, la gente dejará de usar la aplicación.

Usted, el valiente ingeniero de Kubernetes , tiene una solución. Implementa un controlador de Ingress para enrutar el tráfico y configura una política de escalamiento automático para que la cantidad de controladores de Ingress se expanda y contraiga instantáneamente para adaptarse a las fluctuaciones del tráfico. Ahora, sus controladores Ingress gestionan sin problemas los picos de tráfico – "¡Adiós, latencia!" – y reducen la escala para conservar recursos cuando el tráfico disminuye – "¡Hola, ahorro de costos!" Bien hecho, tú.

Descripción general del laboratorio y del tutorial

Este blog acompaña al laboratorio de la Unidad 1 de Microservicios de marzo de 2022: Arquitectura de clústeres de Kubernetes para sitios web de alto tráfico , y demuestra cómo usar el controlador de ingreso NGINX para exponer una aplicación y luego escalar automáticamente los pods del controlador de ingreso en respuesta al alto tráfico.

Para ejecutar el tutorial, necesitas una máquina con:

  • 2 CPU o más
  • 2 GB de memoria libre
  • 20 GB de espacio libre en disco
  • Conexión a Internet
  • Administrador de contenedores o máquina virtual , como Docker, Hyperkit, Hyper‑V, KVM, Parallels, Podman, VirtualBox o VMware Fusion/Workstation
  • minikube instalado
  • Timón instalado
  • Una configuración que le permite iniciar una ventana del navegador. Si eso no es posible, deberá averiguar cómo acceder a los servicios relevantes a través de un navegador.

Para aprovechar al máximo el laboratorio y el tutorial, le recomendamos que antes de comenzar:

Este tutorial utiliza estas tecnologías:

Las instrucciones para cada desafío incluyen el texto completo de los archivos YAML utilizados para configurar las aplicaciones. También puedes copiar el texto de nuestro repositorio de GitHub . Se proporciona un enlace a GitHub junto con el texto de cada archivo YAML.

Este tutorial incluye cuatro desafíos:

  1. Configurar una aplicación sencilla en un clúster de Kubernetes
  2. Utilice el controlador de ingreso NGINX para dirigir el tráfico a la aplicación
  3. Generar y monitorear tráfico
  4. Controlador de ingreso NGINX de escalado automático

Desafío 1: Configurar una aplicación sencilla en un clúster de Kubernetes

En este desafío, crearás un clúster de minikube e instalarás Podinfo como una aplicación de muestra.

Crear un clúster de Minikube

Crear un clúster de minikube . Después de unos segundos, un mensaje confirma que la implementación fue exitosa.

$ minikube start 🏄 ¡Listo! kubectl ahora está configurado para usar el clúster "minikube" y el espacio de nombres "default" de forma predeterminada. 

Instalar la aplicación Podinfo

Podinfo es una “ aplicação web creada con Go que muestra las mejores prácticas para ejecutar microservicios en Kubernetes”. Lo usamos como aplicación de muestra debido a su pequeño tamaño.

  1. Usando el editor de texto de su elección, cree un archivo YAML llamado 1-deployment.yaml con el siguiente contenido (o cópielo desde GitHub ). Define un Despliegue con una única réplica y un Servicio.

    apiVersion: apps/v1 tipo: Implementación
    Metadatos:
    Nombre: podinfo
    Especificación:
    Selector:
    Etiquetas de coincidencia:
    Aplicación: podinfo
    Plantilla:
    Metadatos:
    Etiquetas:
    Aplicación: podinfo
    Especificación:
    Contenedores:
    - Nombre: podinfo
    Imagen: stefanprodan/podinfo
    Puertos:
    - PuertoContenedor: 9898
    --- 
    Versión de API: v1 
    tipo: Servicio
    Metadatos:
    Nombre: podinfo
    Especificación:
    Puertos:
    - Puerto: 80
    Puerto de destino: 9898
    nodePort: 30001
    Selector:
    Aplicación: podinfo
    Tipo: Balanceador de carga 
    
  2. Implementar la aplicación:

    $ kubectl apply -f 1-deployment.yaml despliegue.apps/podinfo creado servicio/podinfo creado
    
  3. Confirme que el pod Podinfo se implementó, como lo indica el valor En ejecución en la columna ESTADO .

    $ kubectl get pods NOMBRE LISTO ESTADO REINICIO EDAD podinfo-5d76864686-rd2s5 1/1 Corriendo 0 3m38s
    
  4. Abra Podinfo en un navegador. Los saludos de la página podinfo indican que Podinfo se está ejecutando.

    $ minikube servicio podinfo
    

Desafío 2: Utilice el controlador de ingreso NGINX para dirigir el tráfico a la aplicación

En este desafío, implementa NGINX Ingress Controller y lo configura para enrutar el tráfico a la aplicación Podinfo .

Implementar el controlador de ingreso NGINX

La forma más rápida de instalar NGINX Ingress Controller es con Helm .

  1. Agregue el repositorio NGINX a Helm:

    $ helm repo agregar nginx-stable https://helm.nginx.com/stable 
    
  2. Descargue e instale el controlador de ingreso NGINX de código abierto, mantenido por F5 NGINX. La última línea de salida confirma la instalación.

    $ helm install main nginx-stable/nginx-ingress \ --set controller.watchIngressWithoutClass=true \ --set controller.service.type=NodePort \ --set controller.service.httpPort.nodePort=30005 NOMBRE: main ÚLTIMA IMPLEMENTACIÓN: mar 15 mar 09:49:17 2022 ESPACIO DE NOMBRES: predeterminado ESTADO: implementado REVISIÓN: 1 CONJUNTO DE PRUEBAS: Ninguna NOTAS: Se ha instalado el controlador de ingreso NGINX.
    
  3. Confirme que el pod del controlador de ingreso NGINX se haya implementado, como lo indica el valor En ejecución en la columna ESTADO (para facilitar la lectura, la salida se distribuye en dos líneas).

    $ kubectl get pods NOMBRE LISTO ESTADO ... main-nginx-ingress-779b74bb8b-mtdkr 1/1 En ejecución ... podinfo-5d76864686-fjncl 1/1 En ejecución ... ... REINICIO EDAD... 0 18s... 0 2m36s
    

Dirigir el tráfico a su aplicación

  1. Usando el editor de texto de su elección, cree un archivo YAML llamado 2-ingress.yaml con el siguiente contenido (o cópielo desde GitHub ). Define el manifiesto de ingreso necesario para enrutar el tráfico a Podinfo.

    apiVersion: networking.k8s.io/v1 tipo: Entrada
    Metadatos:
    Nombre: podinfo
    Especificación:
    NombreClaseIngress: nginx
    Reglas:
    - Host: "ejemplo.com"
    http:
    Rutas:
    - Backend:
    Servicio:
    Nombre: podinfo
    Puerto:
    Número: 80 
    ruta: / 
    tipoDeRuta: Prefijo 
    
  2. Implementar el recurso Ingress:

    $ kubectl apply -f 2-ingress.yaml ingress.networking.k8s.io/podinfo creado 
    

Desafío 3: Generar y monitorear tráfico

En este desafío, observará el rendimiento del controlador de ingreso NGINX bajo diferentes cargas de tráfico. Como pasos preparatorios, enumera las métricas disponibles en NGINX Ingress Controller, implementa Prometheus e instala Locust . Luego usa Locust para simular un aumento de tráfico y rastrear el efecto en el rendimiento en Prometheus.

Como ya descubrió, un controlador de Ingress es un pod de Kubernetes normal que incluye un proxy inverso (en nuestro caso, NGINX) con algún código para la integración con Kubernetes. Si su aplicación recibe mucho tráfico, probablemente necesite aumentar la cantidad de réplicas de pods de NGINX Ingress Controller para evitar la latencia generada cuando NGINX Ingress Controller se satura.

Enumere las métricas disponibles

Para saber cuándo y cuánto escalar, necesita información precisa sobre el rendimiento del controlador de ingreso NGINX. En este tutorial, la métrica NGINX utilizada para determinar cuándo escalar es la cantidad de conexiones activas ( nginx_connections_active ). Aquí verifica que su controlador de ingreso NGINX realice un seguimiento de esa métrica.

El controlador de ingreso NGINX expone múltiples métricas : 8 métricas con el modelo basado en código abierto NGINX que utilizamos en este tutorial y más de 80 métricas con el modelo basado en NGINX Plus .

  1. Obtenga la dirección IP del pod del controlador de ingreso NGINX para poder consultar su lista de métricas. La dirección aparece en el campo IP y aquí está172.17.0.4 . (Para facilitar la legibilidad, se omiten las columnas RESTARTS y AGE y la salida se distribuye en dos líneas).

    $ kubectl get pods -o wide NOMBRE LISTO ESTADO ... main-nginx-ingress-779b74bb8b-6hdwx 1/1 En ejecución ... podinfo-5d76864686-nl8ws 1/1 En ejecución ... ... Puertas de preparación de nodos designados por nodos IP
    ... 172.17.0.4   minikube <ninguno> <ninguno>
    ... 172.17.0.3 minikube
    
  2. Cree un pod BusyBox temporal con un shell en un host dentro del clúster de Kubernetes:

    $ kubectl run -ti --rm=true busybox --image=busybox Si no ve un símbolo del sistema, intente presionar Enter. / # 
    
  3. Enumere las métricas generadas por su controlador de ingreso NGINX y verifique que incluya nginx_connections_active . Para <dirección IP> Sustituya el valor del paso 1.

    /# wget -qO- <dirección IP>:9113/métricas
    
  4. Salga del shell para regresar al servidor Kubernetes.

    /# salida 
    

Implementar Prometheus

Ahora que sabe que su controlador de ingreso NGINX rastrea la métrica nginx_connections_active , necesita una herramienta para recopilar ("raspar") las métricas: este tutorial usa Prometheus .

En cuanto al controlador de ingreso NGINX, Helm es la forma más rápida de instalar Prometheus.

  1. Agregue el repositorio Prometheus a Helm:

    $ helm repo agregar prometheus-community https://prometheus-community.github.io/helm-charts
    
  2. Descargue e instale Prometheus:

    $ helm install prometheus prometheus-community/prometheus \ --set server.service.type=NodePort --set server.service.nodePort=30010
    
  3. Verificar la instalación, que suele tardar hasta 60 segundos en completarse. En el siguiente ejemplo de salida, el comando de verificación se ejecutó apenas unos segundos después del comando helm install y, por lo tanto, vemos que la instalación está en progreso, con ContainerCreating informado en el campo ESTADO para algunos pods de Prometheus. La instalación se completa cuando todos los pods tienen el estado En ejecución . (La salida se distribuye en dos líneas para facilitar su legibilidad).

    $ kubectl get pods NOMBRE LISTO ... main-nginx-ingress-779b74bb8b-mtdkr 1/1 ... podinfo-5d76864686-fjncl 1/1 ... prometheus-alertmanager-d6d94cf4b-85ww5 0/2 ... prometheus-kube-state-metrics-7cd8f95cb-86hhs 0/1 ... prometheus-node-exporter-gqxfz 1/1 ... prometheus-pushgateway-56745d8d8b-qnwcb 0/1 ... prometheus-server-b78c9449f-kwhzp 0/2 ... ... ESTADO REINICIO EDAD... Corriendo 0 3m23s... Corriendo 0 5m41s... ContenedorCreando 0 7s ... Corriendo 0 7s... Corriendo 0 7s... ContenedorCreando 0 7s ... ContenedorCreando 0 7s
    
  4. Abra Prometeo. En un entorno de minikube, ejecute el siguiente comando, que abre el panel de Prometheus en su navegador predeterminado.

    $ minikube servicio prometheus-server
    

    Una página como la siguiente confirma que el servidor está funcionando.

  5. Escriba nginx_ingress_nginx_connections_active en la barra de búsqueda para ver el valor actual de la métrica de conexiones activas. Verá una conexión activa, lo cual tiene sentido porque ha implementado un pod de controlador de ingreso NGINX.

Instalar Locust

En la siguiente sección, utilizará Locust , una herramienta de prueba de carga de código abierto, para simular un aumento de tráfico para que pueda observar el rendimiento del controlador de ingreso NGINX en Prometheus. Aquí se implementa Locust.

  1. Usando el editor de texto de su elección, cree un archivo YAML llamado 3-locust.yaml con el siguiente contenido (o cópielo desde GitHub ). Los objetos Implementación y Servicio definen el pod Locust. El objeto ConfigMap define un script llamado locustfile.py que genera solicitudes que se enviarán al pod, completas con los encabezados correctos.

    apiVersion: v1 
    tipo: Mapa de configuración
    Metadatos:
    Nombre: script de Locust
    Datos:
    ArchivoLocust.py: |-
    De Locust: import UsuarioHttp, tarea, entre
    
    Clase UsuarioRápido(UsuarioHttp):
    Tiempo_de_espera = entre(0.7, 1.3)
    
    @task
    Def Hola_Mundo(self):
    Self.Client.get("/", headers={"Host": "example.com"})
    ---
    VersiónAPI: apps/v1
    Tipo: Implementación
    Metadatos:
    Nombre: Locust
    Especificación:
    Selector:
    Etiquetas de coincidencia:
    Aplicación: Locust
    Plantilla:
    Metadatos:
    Etiquetas:
    Aplicación: Locust
    Especificación:
    Contenedores:
    - Nombre: Locust
    Imagen: Locustio/Locust
    Puertos:
    - PuertoContenedor: 8089
    volumenMontajes:
    - Ruta de montaje: /home/locust
    nombre: locust-script
    volumenes:
    - nombre: locust-script
    mapa de configuración:
    nombre: locust-script
    ---
    Versión de API: v1
    tipo: Servicio
    Metadatos:
    Nombre: Locust
    Especificación:
    Puertos:
    - Puerto: 8089
    Puerto de destino: 8089
    NodePort: 30015
    Selector:
    Aplicación: Locust
    Tipo: Balanceador de carga 
    
  2. Desplegar Locust:

    $ kubectl apply -f 3-locust.yaml configmap/locust-script created despliegue.apps/locust created servicio/locust created 
    

Simular un aumento repentino del tráfico y observar el efecto en el rendimiento

  1. Abra Locust en un navegador.

    $ minikube servicio locust
    

  2. Introduzca los siguientes valores en los campos:

    • Número de usuarios – 1000
    • Tasa de aparición – 10
    • Anfitrión : http://main-nginx-ingress
  3. Haga clic en el botón Iniciar enjambre para enviar tráfico a la aplicación Podinfo.

  4. Regrese al panel de Prometheus para ver cómo responde el controlador de ingreso NGINX. Es posible que tengas que realizar una nueva consulta para nginx_ingress_nginx_connections_active para ver algún cambio.

    Como se muestra en la siguiente salida de pantalla, el único módulo del controlador de ingreso NGINX tiene dificultades para procesar el aumento de tráfico sin latencia a medida que se establece una gran cantidad de conexiones. El gráfico de Prometheus revela que aproximadamente 100 conexiones activas por pod de controlador de ingreso NGINX es el punto de inflexión para un aumento en la latencia. Puede utilizar esta información para determinar cuándo necesita ampliar la cantidad de pods del controlador de ingreso NGINX para evitar una mayor latencia.

Desafío 4: Controlador de ingreso NGINX de escalado automático

En el desafío final, crea una configuración que escala automáticamente los recursos a medida que aumenta el volumen de tráfico. El tutorial utiliza KEDA para el escalamiento automático, por lo que primero lo instala y crea una política que define cuándo y cómo se produce el escalamiento. Al igual que en el Desafío 3, utiliza Locust para simular un aumento de tráfico y Prometheus para observar el rendimiento del controlador de ingreso NGINX cuando el escalado automático está habilitado.

Instalar KEDA

KEDA , un escalador automático basado en eventos de Kubernetes, integra un servidor de métricas (el componente que almacena y transforma las métricas para Kubernetes) y puede consumir métricas directamente desde Prometheus (así como otras herramientas). Crea un escalador automático de pods horizontal (HPA) con esas métricas, conecta las métricas recopiladas por Prometheus y las envía a Kubernetes.

Al igual que con NGINX Ingress Controller y Prometheus, el tutorial utiliza Helm para instalar KEDA.

  1. Agregue KEDA al repositorio de Helm:

    $ helm repo add kedacore https://kedacore.github.io/charts "kedacore" se ha agregado a sus repositorios 
    
  2. Instalar KEDA:

    $ helm install keda kedacore/keda NOMBRE: keda ESPACIO DE NOMBRES: predeterminado ESTADO: implementado REVISIÓN: 1 CONJUNTO DE PRUEBAS: Ninguno
    
  3. Verifique que KEDA se esté ejecutando como dos pods. (Para facilitar la legibilidad, algunos valores en la columna NOMBRE están acortados. Además, se omite la columna REINICIO ; el valor es0 para todas las vainas.)

    $ kubectl get pods NOMBRE LISTO ESTADO EDAD keda-operator-8644dcdb79-492x5 1/1 Ejecutando 59s keda-operator-metrics-apiserver-66d...  1/1 Ejecutando 59s locust-77c699c94d-dvb5n 1/1 Ejecutando 8m59s main-nginx-ingress-779b74bb8b-v7ggw 1/1 Ejecutando 48m podinfo-5d76864686-c98rb 1/1 Ejecutando 50m prometheus-alertmanager-d6d94cf4b-8...  2/2 Ejecutando 37m prometheus-kube-state-metrics-7cd8f...  1/1 Ejecutándose 37m prometheus-node-exporter-j4qf4 1/1 Ejecutándose 37m prometheus-pushgateway-56745d8d8b-9n4nl 1/1 Ejecutándose 37m prometheus-server-b78c9449f-6ktn9 2/2 Ejecutándose 37m
    

Crear una política de escalado automático

Ahora utilice la definición de recurso personalizado (CRD) de KEDA ScaledObject para definir los parámetros que determinan cómo se escala NGINX Ingress Controller. La siguiente configuración:

  • Activa el escalado automático según el valor de la métrica nginx_connections_active recopilada por Prometheus
  • Implementa un nuevo pod cuando los pods existentes alcanzan 100 conexiones activas cada uno
  • Escala automáticamente los pods del controlador de ingreso NGINX desde un único pod hasta 20 pods

Realice los siguientes pasos:

  1. Usando el editor de texto de su elección, cree un archivo YAML llamado 4-scaled-object.yaml con el siguiente contenido (o cópielo desde GitHub ). Define un KEDA ScaledObject .

    apiVersion: keda.sh/v1alpha1 tipo: Objeto escalado
    Metadatos:
    Nombre: nginx-scale
    Especificación:
    ReferenciaObjetivoEscala:
    Tipo: Implementación
    Nombre: main-nginx-ingress
    Mín.ReplicaCount: 1 
    Cantidad máxima de réplicas: 20 
    Periodo de enfriamiento: 30 
    Intervalo de sondeo: 1 
    Disparadores: 
    - Tipo: Prometheus 
    Metadatos: 
    Dirección del servidor: http://prometheus-server 
    Nombre de la métrica: nginx_connections_active_keda 
    Consulta: | 
    Suma(tiempo_superior_promedio(nginx_ingress_nginx_connections_active{app="main-nginx-ingress"}[1m])) 
    Umbral: "100" 
    
  2. Implementar el ScaledObject :

    $ kubectl apply -f 4-scaled-object.yaml scaledobject.keda.sh/nginx-scale creado 
    

Simular un aumento repentino del tráfico y observar el efecto del escalado automático en el rendimiento

Para probar realmente la eficacia del escalamiento automático, duplica la cantidad de conexiones en comparación con el Desafío 3.

  1. Regrese al servidor Locust en su navegador. Introduzca los siguientes valores en los campos y haga clic en el botón Iniciar enjambre :

    • Número de usuarios – 2000
    • Tasa de aparición – 10
    • Anfitrión : http://main-nginx-ingress
  2. Regresar a los paneles de Prometheus y Locust. El cuadro rosa debajo del gráfico de Prometheus representa la cantidad de pods del controlador de ingreso NGINX que aumentan o disminuyen su escala.

  3. Regrese a su terminal e inspeccione manualmente el KEDA HPA. El campo REPLICAS en la salida muestra la cantidad actual de réplicas de pod implementadas. (La salida se distribuye en dos líneas para facilitar su legibilidad).

    $ kubectl get hpa NOMBRE DE REFERENCIA ... keda-hpa-nginx-scale Implementación/main-nginx-ingress ... ... OBJETIVOS MINPODS MAXPODS RÉPLICAS EDAD... 101500 m/100 (promedio) 1 20 10 2 m 45 s
    

Próximos pasos

Existe una limitación potencial cuando el escalamiento automático se basa únicamente en la cantidad de conexiones activas. Si (incluso con escalamiento) el controlador de ingreso NGINX se ocupa tanto que tiene que descartar conexiones, el escalador automático ve menos conexiones activas, interpreta eso como que las solicitudes han disminuido y reduce la cantidad de réplicas. Eso puede empeorar el rendimiento, pero aprovechar una combinación de métricas puede garantizar que eso no suceda. Por ejemplo, nginxplus_connections_dropped (disponible con el controlador de ingreso NGINX basado en NGINX Plus) realiza un seguimiento de aquellas conexiones de cliente interrumpidas.

Para probar NGINX Ingress Controller con NGINX Plus y NGINX App Protect, comience hoy su prueba gratuita de 30 días o contáctenos para analizar sus casos de uso .

Para probar NGINX Ingress Controller con NGINX Open Source, puede obtener el código fuente de la versión o descargar un contenedor prediseñado desde DockerHub .


"Esta publicación de blog puede hacer referencia a productos que ya no están disponibles o que ya no reciben soporte. Para obtener la información más actualizada sobre los productos y soluciones F5 NGINX disponibles, explore nuestra familia de productos NGINX . NGINX ahora es parte de F5. Todos los enlaces anteriores de NGINX.com redirigirán a contenido similar de NGINX en F5.com.