BLOG | NGINX

Controles de seguridad y equilibrio de carga dinámicos de múltiples clústeres de Kubernetes A/B con NGINX Plus

NGINX - Parte de F5 - horizontal, negro, tipo RGB
Miniatura de Chris Akker
Chris Akker
Publicado el 15 de febrero de 2024

Eres un ingeniero moderno de Platform Ops o DevOps. Utiliza una biblioteca de herramientas de código abierto (y quizás algunas comerciales) para probar, implementar y administrar nuevas aplicaciones y contenedores para tu equipo de desarrollo. Ha elegido Kubernetes para ejecutar estos contenedores y pods en entornos de desarrollo, prueba, preparación y producción. Has adoptado las arquitecturas y los conceptos de los microservicios y, en su mayor parte, funcionan bastante bien. Sin embargo, a lo largo de este viaje te has topado con algunos obstáculos.

Por ejemplo, a medida que crea e implementa nuevos clústeres, servicios y aplicações, ¿cómo integra o migra fácilmente estos nuevos recursos a producción sin perder tráfico? Los dispositivos de red tradicionales requieren recargas o reinicios al implementar cambios de configuración en registros DNS, balanceadores de carga, firewalls y servidores proxy. Estos ajustes no se pueden reconfigurar sin causar tiempo de inactividad porque se requiere una “interrupción del servicio” o una “ventana de mantenimiento” para actualizar las reglas de DNS, balanceador de carga y firewall. A menudo, tienes que enviar un temido ticket de servicio y esperar a que otro equipo apruebe y realice los cambios.

Las ventanas de mantenimiento pueden llevar a su equipo a un callejón sin salida, detener la entrega de aplicação y hacerle declarar: "¡Debe haber una mejor manera de gestionar el tráfico!". Entonces, exploremos una solución que le permita volver al carril rápido.

Equilibrio de carga multiclúster activo-activo

Si tiene varios clústeres de Kubernetes, lo ideal es enrutar el tráfico a ambos clústeres al mismo tiempo. Una opción aún mejor es realizar una división del tráfico A/B, canario o azul-verde y enviar un pequeño porcentaje de su tráfico como prueba. Para hacer esto, puede utilizar NGINX Plus con ngx_http_split_clients_module .

Diagrama de K8s con NGINX Plus

El módulo HTTP Split Clients está escrito por NGINX Open Source y permite distribuir la proporción de solicitudes en función de una clave. En este caso de uso, los clústeres son los "upstreams" de NGINX. Por lo tanto, a medida que llegan las solicitudes del cliente, el tráfico se divide entre dos clústeres. La clave que se utiliza para determinar la solicitud del cliente es cualquier variable de cliente NGINX disponible. Dicho esto, para controlar esto para cada solicitud, utilice la variable $request_id , que es un número único asignado por NGINX a cada solicitud entrante.

Para configurar las proporciones de división, determine qué porcentajes desea asignar a cada grupo. En este ejemplo, utilizamos el Cluster1 de K8s como un “clúster grande” para producción y el Cluster2 como un “clúster pequeño” para pruebas de preproducción. Si tuviera un clúster pequeño para pruebas, podría usar una proporción de 90:10 y probar el 10 % de su tráfico en el clúster pequeño para asegurarse de que todo esté funcionando antes de implementar nuevos cambios en el clúster grande. Si esto parece demasiado arriesgado, puedes cambiar la proporción a 95:5. La verdad es que puedes elegir cualquier proporción que quieras entre 0 y 100%.

Para la mayor parte del tráfico de producción en tiempo real, probablemente desee una proporción 50:50 donde los dos clústeres tengan el mismo tamaño. Pero puedes proporcionar fácilmente otras proporciones, en función del tamaño del clúster u otros detalles. Puede establecer fácilmente la relación a 0:100 (o 100:0) y actualizar, parchar, reparar o incluso reemplazar un clúster completo sin tiempo de inactividad. Deje que NGINX split_clients enrute las solicitudes al clúster en vivo mientras usted aborda los problemas en el otro.

# Balanceo de carga multiclúster de Nginx
# Configuración de clientes divididos HTTP para las relaciones Clúster1:Clúster2
# Proporcionar relaciones de 100, 99, 50, 1 y 0 % (añadir o modificar según sea necesario)
# Basado en
# https://www.nginx.com/blog/dynamic-a-b-testing-with-nginx-plus/
# Chris Akker – Enero de 2024
#

split_clients $request_id $split100 {
* cluster1-cafe; # Todo el tráfico al clúster1
} 

split_clients $request_id $split99 {
99 % cluster1-cafe; # 99 % cluster1, 1 % cluster2
* cluster2-cafe;
} 

split_clients $request_id $split50 {
50 % cluster1-cafe; # 50% clúster1, 50% clúster2
* clúster2-cafe;
}

split_clients $request_id $split1 { 
1.0% clúster1-cafe; # 1% al clúster1, 99% al clúster2
* clúster2-cafe;
}

split_clients $request_id $split0 { 
* clúster2-cafe; # Todo el tráfico al clúster2
}

# Seleccionar el clúster ascendente según la proporción

map $split_level $upstream { 
100 $split100; 
99 $split99; 
50 $split50; 
1.0 $split1; 
0 $split0;
default $split50;
}

Puede agregar o editar la configuración anterior para que coincida con las relaciones que necesita (por ejemplo, 90:10, 80:20, 60:40, etc.).

Nota:  NGINX también tiene un módulo de Clientes Divididos para conexiones TCP en el contexto de flujo, que se puede utilizar para tráfico que no sea HTTP. Esto divide el tráfico en función de las nuevas conexiones TCP, en lugar de las solicitudes HTTP.

Almacén de clave-valor NGINX Plus

La siguiente característica que puede utilizar es el almacén de clave-valor NGINX Plus. Este es un objeto clave-valor en una zona de memoria compartida NGINX que se puede utilizar para muchos casos de uso diferentes de almacenamiento de datos. Aquí lo usamos para almacenar el valor de relación de división mencionado en la sección anterior. NGINX Plus permite modificar cualquier registro clave-valor sin tener que recargar NGINX. Esto permite modificar este valor de división mediante una llamada a la API, creando así la función de división dinámica.

Basándonos en nuestro ejemplo, se vería así:

{“cafe.ejemplo.com”:90}

Este registro de KeyVal dice:
La clave es el nombre de host “cafe.example.com”
El valor es “90” para la relación de división

En lugar de codificar la relación de división en los archivos de configuración de NGINX, puede utilizar la memoria clave-valor. Esto elimina la recarga de NGINX necesaria para cambiar un valor de división estático en NGINX.

En este ejemplo, NGINX está configurado para utilizar 90:10 para la relación de división con el Cluster1 grande para el 90 % y el Cluster2 pequeño para el 10 % restante. Dado que se trata de un registro clave-valor, puede cambiar esta relación utilizando la API NGINX Plus de forma dinámica sin necesidad de recargar la configuración. El módulo Clientes divididos utilizará este nuevo valor de proporción tan pronto como lo cambie, en la próxima solicitud.

Crea el registro KV, comienza con una proporción 50/50:

Agregue un nuevo registro al almacén KeyValue, enviando un comando API a NGINX Plus:

curl -iX POST -d '{"cafe.example.com":50}' http://nginxlb:9000/api/8/http/keyvals/split

Cambie el registro KV, cambie a la relación 90/10:

Cambie la relación de división de KeyVal a 90, utilizando un método HTTP PATCH para actualizar el registro de KeyVal en la memoria:

curl -iX PARCHE -d '{"cafe.example.com":90}' http://nginxlb:9000/api/8/http/keyvals/split

A continuación, el equipo de pruebas de preproducción verifica que el nuevo código de la aplicação esté listo, lo implementa en el Cluster1 grande y cambia la proporción al 100%. Esto envía inmediatamente todo el tráfico al Cluster1 y su nueva aplicação está "activa" sin interrupciones de tráfico, sin cortes de servicio, sin ventanas de mantenimiento, reinicios, recargas o muchos tickets. Solo se necesita una llamada a la API para cambiar esta relación de división en el momento que usted elija.

Por supuesto, ser tan fácil de pasar del 90% al 100% significa que tienes una forma sencilla de cambiar la relación de 100:0 a 50:50 (o incluso 0:100). Por lo tanto, puede tener un clúster de respaldo activo o puede escalar sus clústeres horizontalmente con nuevos recursos. A toda máquina, incluso puedes construir un nuevo clúster con los últimos parches de software, hardware y software, implementando la aplicação y migrando el tráfico durante un período de tiempo sin perder una sola conexión.

CASOS DE USO

El uso del módulo HTTP Split Clients con el almacén de clave-valor dinámico puede generar los siguientes casos de uso:

  • Equilibrio de carga activo-activo : para equilibrar la carga en múltiples clústeres.
  • Equilibrio de carga activo-pasivo : para equilibrar la carga en clústeres y aplicações principales, de respaldo y de recuperación ante desastres.
  • Pruebas A/B, azul-verde y canarias : se utilizan con nuevas aplicações de Kubernetes.
  • Escalamiento de clúster horizontal : agrega más recursos de clúster y cambia la proporción cuando esté listo.
  • Actualizaciones de clúster sin interrupciones : capacidad de usar un clúster mientras actualiza, parchea o repara el otro clúster.
  • Conmutación por error instantánea : si un clúster tiene un problema grave, puede cambiar la proporción para utilizar el otro clúster.

Ejemplos de configuración

A continuación se muestra un ejemplo de la configuración clave-valor:

# Definir el almacén de valores clave, el archivo de estado de la copia de seguridad, el tiempo de espera y habilitar la sincronización
keyval_zone zone=split:1m state=/var/lib/nginx/state/split.keyval timeout=365d sync;

keyval $host $split_level zone=split;

Y este es un ejemplo de la configuración de la aplicação cafe.example.com:

# Defina bloques de servidor y ubicación para cafe.example.com, con TLS server { listen 443 ssl; server_name cafe.example.com; status_zone https://cafe.example.com; ssl_certificate /etc/ssl/nginx/cafe.example.com.crt; ssl_certificate_key /etc/ssl/nginx/cafe.example.com.key; location / { status_zone /; proxy_set_header Host $host; proxy_http_version 1.1; proxy_set_header "Connection" ""; proxy_pass https://$upstream; # tráfico dividido en bloques ascendentes } # Defina 2 bloques ascendentes: uno para cada clúster # Servidores administrados dinámicamente por NLK, copia de seguridad del archivo de estado # Cluster1 upstreams upstream cluster1-cafe { zone cluster1-cafe 256k; least_time last_byte; keepalive 16; #servidores administrados por el estado del controlador NLK /var/lib/nginx/state/cluster1-cafe.state; } # Cluster2 upstreams upstream cluster2-cafe { zone cluster2-cafe 256k; least_time last_byte; keepalive 16; #servidores administrados por el estado del controlador NLK /var/lib/nginx/state/cluster2-cafe.state; }

Los puertos IP del servidor ascendente son administrados por NGINX Loadbalancer para Kubernetes , un nuevo controlador que también utiliza la API NGINX Plus para configurar NGINX Plus dinámicamente. Los detalles se encuentran en la siguiente sección .

Echemos un vistazo al tráfico dividido HTTP a lo largo del tiempo con Grafana , una popular herramienta de monitoreo y visualización. Utilice el exportador NGINX Prometheus (basado en njs ) para exportar todas sus métricas NGINX Plus, que luego son recopiladas y graficadas por Grafana. Los detalles para configurar Prometheus y Grafana se pueden encontrar aquí .

Hay cuatro servidores ascendentes en el gráfico: Dos para el Cluster1 y dos para el Cluster2 . Utilizamos una herramienta de generación de carga HTTP para crear solicitudes HTTP y enviarlas a NGINX Plus.

En los tres gráficos a continuación, puede ver que la proporción de división es 50:50 al comienzo del gráfico.

Diagrama de solicitudes ascendentes de LB

Luego, la relación cambia a 10:90 a las 12:56:30.

Diagrama de solicitudes ascendentes de LB

Luego cambia a 90:10 a las 13:00:00.

Diagrama de solicitudes ascendentes de LB

Puede encontrar configuraciones funcionales de Prometheus y Grafana en el repositorio de GitHub NGINX Loadbalancer para Kubernetes .

Upstreams HTTP dinámicos: Balanceador de carga NGINX para Kubernetes

Puede cambiar la configuración estática de NGINX Upstream a configuraciones de clúster dinámicas mediante la API NGINX Plus y el controlador NGINX Loadbalancer para Kubernetes . Este proyecto gratuito es un controlador de Kubernetes que observa el controlador de ingreso NGINX y actualiza automáticamente una instancia externa NGINX Plus configurada para el equilibrio de carga TCP/HTTP. Tiene un diseño muy sencillo y es fácil de instalar y operar. Con esta solución, puede implementar el equilibrio de carga TCP/HTTP en entornos de Kubernetes, lo que garantiza que las nuevas aplicaciones y servicios se detecten de inmediato y estén disponibles para el tráfico, sin necesidad de recarga.

Arquitectura y flujo

NGINX Loadbalancer para Kubernetes se encuentra dentro de un clúster de Kubernetes. Está registrado en Kubernetes para monitorear el servicio NGINX Ingress Controller ( nginx-ingress ). Cuando hay un cambio en los controladores de Ingress, NGINX Loadbalancer for Kubernetes recopila las IP de Worker y los números de puerto TCP de NodePort y luego envía las IP:puertos a NGINX Plus a través de la API de NGINX Plus .

Los servidores ascendentes de NGINX se actualizan sin necesidad de recarga, y NGINX Plus equilibra la carga del tráfico hacia los servidores ascendentes y los NodePorts de Kubernetes correctos. Se pueden agregar instancias NGINX Plus adicionales para lograr una alta disponibilidad .

Diagrama del balanceador de carga NGINX en acción

Una instantánea de NGINX Loadbalancer para Kubernetes en acción

En la captura de pantalla a continuación, hay dos ventanas que muestran NGINX Loadbalancer para Kubernetes implementado y haciendo su trabajo:

  1. Tipo de servicio : Balanceador de carga para nginx-ingress
  2. IP externa : se conecta a los servidores NGINX Plus
  3. Puertos : NodePort se asigna a 443:30158 con servidores ascendentes NGINX coincidentes (como se muestra en el panel de control en tiempo real de NGINX Plus)
  4. Registros : indica que NGINX Loadbalancer para Kubernetes está enviando datos correctamente a NGINX Plus

Ventana de NGINX Plus

Nota : En este ejemplo, los nodos de trabajo de Kubernetes son 10.1.1.8 y 10.1.1.10

Agregar funciones de seguridad de NGINX Plus

A medida que más y más aplicações que se ejecutan en Kubernetes quedan expuestas a Internet abierta, la seguridad se vuelve necesaria. Afortunadamente, NGINX Plus tiene funciones de seguridad de clase empresarial que pueden usarse para crear una arquitectura de defensa en capas y en profundidad.

Con NGINX Plus al frente de sus clústeres y realizando la función split_clients , ¿por qué no aprovechar esa presencia y agregar algunas funciones de seguridad beneficiosas? Aquí se presentan algunas de las características de NGINX Plus que podrían usarse para mejorar la seguridad, con enlaces y referencias a otra documentación que puede usarse para configurarlas, probarlas e implementarlas.

Empieza hoy

Si está frustrado con los desafíos de red en el borde de su clúster de Kubernetes, considere probar esta solución de múltiples clústeres NGINX. Pruebe el software NGINX Loadbalancer para Kubernetes y díganos qué piensa. El código fuente es de código abierto (bajo la licencia Apache 2.0) y todas las instrucciones de instalación están disponibles en GitHub .

Para brindar comentarios, déjenos un comentario en el repositorio o envíenos un mensaje en el Slack de la comunidad NGINX .


"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.