BLOG | NGINX

Anuncio de la versión 1.0.0 de la arquitectura de referencia de aplicaciones modernas de NGINX

NGINX - Parte de F5 - horizontal, negro, tipo RGB
Miniatura de Jason Schmidt
Jason Schmidt
Publicado el 28 de abril de 2022

Fuimos sinceros con nuestros objetivos de diseño cuando presentamos la Arquitectura de referencia de aplicações modernas (MARA) de NGINX en Sprint 2.0 en agosto de 2021. Queríamos crear un ejemplo de una arquitectura de aplicação moderna que se ejecute en Kubernetes y esté diseñada para soportar seguridad, escalabilidad, confiabilidad, monitoreo e introspección. Este proyecto debía poder implementarse en diferentes infraestructuras con un enfoque “plug and play” para combinar componentes funcionales sin esfuerzos de integración que consumieran mucho tiempo.

En los meses transcurridos desde Sprint, hemos ido avanzando con nuestra hoja de ruta. Como en cualquier proyecto, hemos tenido nuestra cuota de éxitos y fracasos y hemos incorporado nuestros éxitos a MARA mientras mantenemos una lista creciente de lecciones aprendidas. Esperamos poder evitar que otros enfrenten los mismos problemas al documentar estos asuntos y diseñar teniendo estas lecciones en mente.

Recientemente hemos alcanzado un hito con la versión 1.0.0 de MARA , que reorganiza el directorio del proyecto y cambia el proceso de creación de instancias y destrucción del entorno. Eliminamos código duplicado, creamos una estructura de directorio que acomoda fácilmente futuras incorporaciones y estandarizamos los scripts de administración. Como esta versión marca un punto importante en la historia de MARA, queríamos detenernos e informar a la comunidad sobre nuestro progreso, destacar lo que creemos que son algunas de las lecciones aprendidas más importantes y brindar información sobre nuestra hoja de ruta para avanzar.

Diagrama de topología para la versión 1.0.0 de la arquitectura de referencia de aplicaciones modernas NGINX

Telemetría: métricas, registro y seguimiento

Los principales contribuyentes de MARA tienen experiencia en la ejecución de software a gran escala y comprenden lo que se necesita para brindar servicios desde perspectivas operativas, de ingeniería y de gestión. Conocen la sensación de hundimiento que se siente cuando una aplicação funciona mal y no se tiene una forma sencilla de determinar exactamente cuál es el problema. Una cita que circula en el mundo de DevOps resume el problema sucintamente: “Depurar microservicios es como resolver una serie de misterios de asesinatos”.

Con esto en mente, hicimos de la incorporación de la observabilidad una prioridad máxima en nuestra hoja de ruta a corto plazo. La observabilidad en este contexto incluye la gestión de registros, métricas y datos de seguimiento. Sin embargo, simplemente recopilar datos no es suficiente: es necesario poder analizarlos en profundidad y tomar decisiones significativas sobre lo que sucede en el entorno.

Nuestra exploración de opciones de rastreo nos llevó a OpenTelemetry (OTEL) porque admite todo el espectro de datos de telemetría, registros, métricas y rastreos. Visualizamos una implementación donde el agente OTEL recopila, procesa y deduplica todos los datos de seguimiento antes de pasarlos al recopilador OTEL para su agregación y exportación, con un sistema de visualización al final del flujo de trabajo para hacer que los datos sean utilizables. Este enfoque ofrece a los usuarios la gama más amplia de opciones para visualizar y analizar datos, al tiempo que aprovecha el estándar OTEL para simplificar las etapas iniciales (recopilación, agregación, etc.).

Construimos la implementación en dos etapas:

  1. Implementar el operador OpenTelemetry para Kubernetes para administrar un recopilador OTEL en el entorno

  2. Instrumentar la aplicação del Banco de Sirius para emitir trazas y métricas

La versión original de MARA usaba Elasticsearch con Filebeat para el registro, y aunque consideramos reemplazarlos con Grafana Loki , decidimos mantener la opción original por el momento. En cuanto a las métricas, nos dimos cuenta de que necesitábamos revisar la implementación original basada en Prometheus y Grafana reemplazando la configuración personalizada de Prometheus que habíamos usado inicialmente con el diagrama Helm kube-prometheus-stack mantenido por la comunidad, que establece un entorno Prometheus completo que incluye Grafana, exportadores de nodos y una serie de paneles preconfigurados y objetivos de raspado adecuados para administrar un entorno de Kubernetes. A esto agregamos algunos paneles adicionales para el controlador de ingreso F5 NGINX y la aplicação Bank of Sirius.

Este es sólo un breve resumen de la inmensa cantidad de trabajo que se requiere para implementar OTEL. Para ahorrarles a otros el esfuerzo de tener que escalar la misma curva de aprendizaje empinada, hemos documentado todo el proceso en Integración de OpenTelemetry en la arquitectura de referencia de aplicaciones modernas: un informe de progreso en nuestro blog.

Opciones de implementación – Kubeconfig

En la versión inicial de MARA elegimos Amazon Elastic Kubernetes Service (EKS) como entorno de implementación. Desde entonces, muchos usuarios nos han dicho que, por razones de costo, desean ejecutar MARA en entornos “locales” que requieren menos recursos, como un laboratorio o una estación de trabajo. La portabilidad fue un objetivo clave del proyecto original (y sigue siéndolo), por lo que esta fue nuestra oportunidad de demostrar que podíamos lograrlo. Para facilitar la tarea, decidimos diseñar un procedimiento de implementación que pudiera ejecutarse en cualquier clúster de Kubernetes que cumpliera algunos requisitos mínimos.

Como primer paso, agregamos un nuevo proyecto Pulumi a MARA que lee un archivo kubeconfig para comunicarse con el clúster de Kubernetes. Este proyecto se encuentra entre los proyectos de Kubernetes de Pulumi y los proyectos de infraestructura (ejemplos de estos últimos son los proyectos para AWS y Digital Ocean). En términos prácticos, la creación del proyecto kubeconfig reduce la barrera para la integración de un nuevo proyecto de infraestructura. Si un proyecto de infraestructura puede pasar un archivo kubeconfig, un nombre de clúster y un contexto de clúster al proyecto kubeconfig, el resto del procedimiento de implementación de MARA funciona sin problemas.

Para nuestras pruebas, utilizamos varias distribuciones de Kubernetes fáciles de instalar con pequeños requisitos de CPU y memoria, incluidas K3s , Canonical MicroK8s y minikube . Todas las distribuciones se implementaron en una máquina virtual (VM) que ejecuta Ubuntu 21.10 con 2 CPU y 16 GB de RAM . Además, todas las distribuciones se configuraron para proporcionar volúmenes persistentes y compatibilidad con Kubernetes LoadBalancer.

La parte más difícil de este proceso fue trabajar con el registro privado utilizado para el controlador de ingreso NGINX personalizado que forma parte del proyecto. (Tenga en cuenta que al implementar MARA puede utilizar el controlador de ingreso NGINX estándar basado en NGINX Open Source o NGINX Plus, así como este controlador de ingreso NGINX personalizado). Descubrimos que necesitábamos desacoplar nuestra lógica de registro de Amazon Elastic Container Registry (ECR) en favor de un enfoque más independiente de la plataforma, una tarea que actualmente está en progreso. También nos dimos cuenta de que nuestra lógica para extraer el nombre de host de la dirección de salida era muy específica de AWS Elastic Load Balancing (ELB) y debía reescribirse para aplicarla a otros casos de uso.

Los scripts de gestión de MARA y los proyectos Pulumi utilizan actualmente una lógica específica para solucionar los problemas descriptos anteriormente. Por ahora, las implementaciones basadas en configuración de Kubernetes deben usar NGINX Ingress Controller (basado en NGINX Open Source o NGINX Plus) de los registros oficiales de NGINX.

Hemos agregado varios parámetros de ajuste a los archivos de configuración de MARA para adaptarlos a las implementaciones locales que no ofrecen los recursos necesarios para la implementación basada en la nube. La mayoría de los parámetros están relacionados con la cantidad de réplicas solicitadas para los distintos componentes de Elastic Stack . A medida que avancen las pruebas, habrá parámetros adicionales para ajustar MARA en función de las limitaciones de recursos del entorno de implementación.

Con estos cambios implementados, podemos implementar con éxito en K3s, MicroK8s y Minikube, y hemos probado con éxito la lógica en Azure Kubernetes Service (AKS), Digital Ocean , Google Kubernetes Engine , Linode y Rancher's Harvester . Para obtener más información, consulte la página Estado del proveedor de MARA y MARA: Ahora ejecutándose en una estación de trabajo cerca de usted en nuestro blog.

Colaboración con socios

Nuestros socios han sido muy receptivos y solidarios con nuestro trabajo con MARA; muchos de ellos se acercaron para conocer más sobre el proyecto, preguntar cómo pueden aprovecharlo con sus productos o incluso agregar funciones.

Elegimos Pulumi como parte central de MARA por su facilidad de uso y soporte de Python, siendo este último un lenguaje tan popular que hace que el código MARA sea fácilmente comprendido por una gran comunidad. Además, la vibrante comunidad de Pulumi y su compromiso con el proyecto fueron un modelo de la participación comunitaria que esperamos lograr con MARA.

A fines de 2021, trabajamos con Sumo Logic para hacer de MARA parte de su solución de monitoreo en la nube con NGINX Ingress Controller. Esta fue una oportunidad para poner a prueba nuestra afirmación de que MARA es conectable. El desafío fue sustituir la solución Sumo Logic por Grafana, Prometheus y Elastic en MARA. Nos complace haber implementado con éxito la solución utilizando la misma lógica que usamos para otras implementaciones y haberla configurado no solo para conectarse a Sumo Logic SaaS sino también para extraer métricas de nuestro entorno.

Como parte de nuestro trabajo con OpenTelemetry, colaboramos con Lightstep y reconfiguramos fácilmente nuestro recopilador OTEL para exportar rastros y métricas a la oferta SaaS de Lightstep. Esta es un área que estamos interesados en investigar más a fondo, ya que creemos firmemente que OTEL es el futuro de la observabilidad.

Lecciones aprendidas…hasta ahora

La lección más importante que hemos aprendido hasta ahora es la sabiduría de un enfoque modular. El trabajo con Sumo Logic demuestra que podemos mezclar y combinar con éxito los componentes de MARA. Esperamos más confirmaciones a medida que integremos más plenamente OTEL en el entorno. Anteriormente mencionamos que estamos considerando reemplazar Elasticsearch con Grafana Loki como entorno de administración de registros, porque reduce la huella de recursos de la pila. Dicho esto, abogamos por la “modularidad pragmática” en lugar de llegar a los extremos y convertir todo en un microservicio. Por ejemplo, si bien tiene sentido tener un servicio especializado que pueda procesar registros para muchas aplicações, es menos obvio que se necesiten microservicios separados para la recopilación, el almacenamiento y la visualización de registros.

También hemos aprendido que es útil establecer valores predeterminados incluyéndolos explícitamente en la configuración en lugar de simplemente omitir el parámetro relevante. Esto es conveniente para los administradores de dos maneras: no tienen que recordar los valores predeterminados y pueden cambiarlos fácilmente simplemente modificando un parámetro que ya aparece con la sintaxis correcta en el lugar correcto en la configuración.

Otra lección dolorosa que aprendimos es que algunas soluciones son populares no porque sean las mejores, sino porque son las más fáciles de instalar o tienen el mejor tutorial. Por eso es tan importante cuestionar sus suposiciones y consultar con colegas durante el proceso de diseño: una cultura de comunicación abierta ayuda mucho a identificar y solucionar problemas desde el principio.

Dicho esto, en varias ocasiones implementamos una lógica que funcionó pero que nos dejó en un callejón sin salida o causó otros problemas. Por ejemplo, cuando comenzamos a implementar aplicações a través de Pulumi, usamos manifiestos YAML para ConfigMaps , confiando en las transformaciones de Pulumi para actualizar las variables. Esto funcionó, pero no fue ideal por varias razones, una de las cuales, y una de las menos importantes, fue la facilidad de mantenimiento. En la siguiente iteración, mejoramos la legibilidad y el mantenimiento del código al usar kube2pulumi para transformar los manifiestos en código Pulumi que luego podríamos usar para construir los ConfigMaps.

Otra lección comenzó cuando una fusión insertó configuraciones no válidas en el YAML de implementación. Nos vimos obligados a reescribir y revisar cuidadosamente grandes partes del YAML para asegurarnos de que el código fuera sintácticamente correcto y hiciera lo que queríamos, un proceso frustrante y que llevó mucho tiempo. Para evitar problemas futuros, ahora hemos automatizado el análisis y la validación de YAML genérico y específicos de Kubernetes durante el proceso de envío a GitHub.

Por último, nuestro objetivo desde el principio ha sido asegurarnos de que nuestra rama principal siempre esté ejecutable. Es frustrante cuando revisas un nuevo proyecto y tienes que resolver un problema que los mantenedores introdujeron en la línea principal. Lamentablemente, hemos fallado en esto algunas veces, incluidos estos ejemplos con el submódulo del Banco de Sirio:

  • Olvidamos por error cambiar el esquema de URL de ssh:// a https:// . Esto no fue un problema para nosotros, porque todos usamos ssh para conectarnos a GitHub. Sin embargo, los usuarios que no tenían una clave SSH para GitHub se vieron inundados de mensajes de error cuando intentaron inicializar el submódulo.
  • Una versión de los scripts de administración tenía una dependencia de un paquete común que asumimos erróneamente que se instalaría en las máquinas de todos como en las nuestras.
  • Olvidamos poner una verificación para la fuente del submódulo durante una reescritura de la lógica de inicio. El submódulo incluye los manifiestos necesarios para implementar Bank of Sirius y, desafortunadamente, los errores y las advertencias que aparecieron cuando estos manifiestos no estaban disponibles fueron lo suficientemente oscuros como para llevarnos a una odisea de varios días de depuración de comportamientos extraños antes de descubrir la causa raíz.

¿Qué sigue?

Tenemos grandes planes para los próximos meses de desarrollo, incluida la refactorización de la compilación del controlador de ingreso NGINX, el envío de registro y la lógica de dirección IP/nombre de host de ingreso.

Una cosa que hemos notado con cada puesta en marcha de MARA es la rapidez con la que empezamos a ver escaneos y ataques al controlador de ingreso NGINX. Esto nos ha impulsado a comenzar a integrar NGINX Ingress Controller con NGINX App Protect WAF en MARA. Esto conlleva el desafío y la oportunidad de determinar cuál es la mejor manera de gestionar el registro producido por App Protect.

Otro cambio que planeamos realizar en los próximos meses es que todos los módulos extraigan secretos de Kubernetes en lugar de Pulumi y Kubernetes. Esto significa que todos los módulos utilizan un repositorio de secretos común y le otorga al administrador control sobre cómo se completan los secretos. Estamos escribiendo un nuevo módulo para leer secretos de un repositorio elegido por el usuario y crear los secretos de Kubernetes correspondientes.

MARA actualmente incluye una herramienta para generar carga que es una versión mejorada y ligeramente modificada de la herramienta basada en Locust que viene con la aplicación original Bank of Anthos de la cual bifurcamos Bank of Sirius. La nueva herramienta de prueba que estamos escribiendo, Cicada Swarm, no solo genera carga sino que también rastrea e informa cuando las métricas superan los umbrales que usted ha establecido, lo que la convierte en un marco para pruebas rápidas de rendimiento de productos de software en la nube. Utiliza técnicas de paralelización para ofrecer resultados de pruebas con el nivel de confianza que necesita, mayor precisión y análisis de regresión personalizable para determinar el éxito o el fracaso de las compilaciones en sus pipelines de CI/CD.

Por último, no podemos mencionar las pruebas de carga sin hablar de cómo vamos a medir el impacto de esas pruebas de carga, lo que nos lleva de nuevo a la telemetría. Estamos entusiasmados con el potencial de OpenTelemetry y esperamos tener una implementación más completa pronto. Incluso sin una implementación completa, nuestro objetivo es poder ejecutar una prueba, medir su impacto y tomar decisiones operativas sobre lo que nos dicen los datos.

Como siempre, agradecemos sus solicitudes de extracción , problemas y comentarios . Nuestro objetivo con MARA es inspirar a la comunidad a trabajar en conjunto para discutir, probar, evaluar e iterar a través de diferentes soluciones potenciales para aumentar nuestra comprensión de cómo implementar y administrar mejor una aplicação moderna.

Publicaciones relacionadas

Esta publicación es parte de una serie. A medida que vayamos añadiendo capacidades a MARA, publicaremos los detalles en el blog:


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