BLOG | NGINX

Ankündigung der Version 1.0.0 der NGINX Modern Apps Reference Architecture

NGINX-Teil-von-F5-horiz-schwarz-Typ-RGB
Jason Schmidt Miniaturbild
Jason Schmidt
Veröffentlicht am 28. April 2022

Wir waren mit unseren Designzielen offen, als wir im August 2021 bei Sprint 2.0 die NGINX Modern Applications Reference Architecture (MARA) vorstellten. Wir wollten ein Beispiel für eine moderne Anwendungsarchitektur erstellen, die in Kubernetes ausgeführt wird und Sicherheit, Skalierbarkeit, Zuverlässigkeit, Überwachung und Selbstbeobachtung unterstützt. Dieses Projekt musste über verschiedene Infrastrukturen hinweg einsetzbar sein und mithilfe eines „Plug-and-Play“-Ansatzes die Kombination funktionaler Komponenten ohne zeitaufwändigen Integrationsaufwand ermöglichen.

In den Monaten seit dem Sprint haben wir unseren Fahrplan weiterentwickelt. Wie bei jedem Projekt hatten wir unseren Anteil an Erfolgen und Misserfolgen und haben unsere Erfolge in MARA einfließen lassen, während gleichzeitig die Liste der gewonnenen Erkenntnisse immer länger wurde. Wir hoffen, dass wir andere vor denselben Problemen bewahren können, indem wir diese Probleme dokumentieren und die gewonnenen Erkenntnisse bei der Entwicklung berücksichtigen.

Wir haben kürzlich mit MARA Version 1.0.0 einen Meilenstein erreicht, der das Projektverzeichnis neu organisiert und den Prozess zum Instanziieren und Zerstören der Umgebung ändert. Wir haben doppelten Code eliminiert, eine Verzeichnisstruktur erstellt, die zukünftige Ergänzungen problemlos ermöglicht, und Verwaltungsskripte standardisiert. Da diese Version einen wichtigen Punkt in der Geschichte von MARA markiert, wollten wir innehalten und der Community von unseren Fortschritten berichten, die unserer Meinung nach wichtigsten Erkenntnisse festhalten und einige Informationen zu unserem Fahrplan für die Zukunft bereitstellen.

Topologiediagramm für Version 1.0.0 der NGINX Modern Apps Reference Architecture

Telemetrie – Metriken, Protokollierung und Ablaufverfolgung

Die Hauptbeitragenden bei MARA verfügen über Erfahrung im Ausführen von Software im großen Maßstab und wissen, was aus betrieblicher, technischer und Verwaltungsperspektive zur Bereitstellung von Diensten erforderlich ist. Sie kennen das mulmige Gefühl, das man hat, wenn eine Anwendung nicht richtig funktioniert und man nicht einfach feststellen kann, wo genau das Problem liegt. Ein in der DevOps-Welt kursierendes Zitat fasst das Problem prägnant zusammen: „Das Debuggen von Microservices ist wie das Lösen einer Reihe von Krimis.“

Vor diesem Hintergrund haben wir der Erweiterung der Beobachtbarkeit in unserem kurzfristigen Fahrplan höchste Priorität eingeräumt. Zur Beobachtbarkeit zählen in diesem Zusammenhang Protokollverwaltung, Metriken und Tracing-Daten. Allerdings reicht es nicht aus, einfach nur Daten zu sammeln. Sie müssen in der Lage sein, die Daten zu analysieren und sinnvolle Entscheidungen darüber zu treffen, was in der Umwelt geschieht.

Unsere Untersuchung von Optionen zur Ablaufverfolgung führte uns zu OpenTelemetry (OTEL), da es die gesamte Bandbreite an Telemetriedaten, Protokollen, Metriken und Ablaufverfolgungen unterstützt. Wir haben uns eine Implementierung vorgestellt, bei der der OTEL-Agent alle Tracing-Daten sammelt, verarbeitet und dedupliziert, bevor er sie zur Aggregation und zum Export an den OTEL-Collector weitergibt, mit einem Visualisierungssystem am Ende des Workflows, um die Daten nutzbar zu machen. Dieser Ansatz bietet den Benutzern die größte Auswahl an Möglichkeiten zur Anzeige und Analyse von Daten und nutzt gleichzeitig den OTEL-Standard, um die früheren Phasen (Erfassung, Aggregation usw.) zu vereinfachen.

Wir haben die Implementierung in zwei Phasen durchgeführt:

  1. Stellen Sie den OpenTelemetry Operator für Kubernetes bereit, um einen OTEL-Collector in der Umgebung zu verwalten

  2. Instrumentieren Sie die Bank of Sirius -Anwendung, um Spuren und Metriken auszugeben

Die ursprüngliche Version von MARA verwendete Elasticsearch mit Filebeat zur Protokollierung, und obwohl wir erwogen, sie durch Grafana Loki zu ersetzen, entschieden wir uns, vorerst die ursprüngliche Wahl beizubehalten. Was die Metriken betrifft, stellten wir fest, dass wir die ursprüngliche Bereitstellung auf Basis von Prometheus und Grafana überarbeiten mussten, indem wir die maßgeschneiderte Prometheus-Konfiguration, die wir ursprünglich verwendet hatten, durch das von der Community gepflegte Helm-Diagramm „kube-prometheus-stack“ ersetzten, das eine vollständige Prometheus-Umgebung einschließlich Grafana, Knoten-Exporteuren und einer Reihe vorkonfigurierter Dashboards und Scrape-Ziele enthält, die für die Verwaltung einer Kubernetes-Umgebung geeignet sind. Dazu haben wir einige zusätzliche Dashboards für den F5 NGINX Ingress Controller und die Bank of Sirius-Anwendung hinzugefügt.

Dies ist nur eine kurze Zusammenfassung des immensen Arbeitsaufwands, der für die Implementierung von OTEL erforderlich ist. Um anderen die Mühe zu ersparen, dieselbe steile Lernkurve zu bewältigen, haben wir den gesamten Prozess in unserem Blog unter „Integration von OpenTelemetry in die Referenzarchitektur für moderne Apps – Ein Fortschrittsbericht“ dokumentiert.

Bereitstellungsoptionen – Kubeconfig

In der ersten Version von MARA haben wir Amazon Elastic Kubernetes Service (EKS) als Bereitstellungsumgebung gewählt. Viele Benutzer haben uns inzwischen mitgeteilt, dass sie MARA aus Kostengründen in „lokalen“ Umgebungen ausführen möchten, die weniger Ressourcen erfordern, wie etwa einem Labor oder einer Workstation. Portabilität war (und ist) ein zentrales Ziel des ursprünglichen Projekts und dies war unsere Chance zu beweisen, dass wir es erreichen können. Um die Aufgabe zu vereinfachen, haben wir beschlossen, ein Bereitstellungsverfahren zu entwickeln, das auf jedem Kubernetes-Cluster ausgeführt werden kann, der bestimmte Mindestanforderungen erfüllt.

Als ersten Schritt haben wir MARA ein neues Pulumi-Projekt hinzugefügt, das eine Kubeconfig- Datei liest, um mit dem Kubernetes-Cluster zu kommunizieren. Dieses Projekt ist zwischen Pulumi Kubernetes-Projekten und Infrastrukturprojekten angesiedelt (Beispiele für letztere sind Projekte für AWS und Digital Ocean). In der Praxis senkt die Erstellung des Kubeconfig-Projekts die Hürde für die Integration eines neuen Infrastrukturprojekts. Wenn ein Infrastrukturprojekt eine Kubeconfig-Datei, einen Clusternamen und einen Clusterkontext an das Kubeconfig-Projekt übergeben kann, funktioniert der Rest des MARA-Bereitstellungsverfahrens nahtlos.

Für unsere Tests haben wir mehrere einfach zu installierende Kubernetes-Distributionen mit geringem CPU- und Speicherbedarf verwendet, darunter K3s , Canonical MicroK8s und minikube . Die Distributionen wurden alle auf einer virtuellen Maschine (VM) mit Ubuntu 21.10 mit 2 CPUs und 16 GB RAM bereitgestellt. Darüber hinaus wurden alle Distributionen so konfiguriert, dass sie persistente Volumes und Kubernetes LoadBalancer-Unterstützung bieten.

Der schwierigste Teil dieses Prozesses war die Arbeit mit dem privaten Register, das für den benutzerdefinierten NGINX Ingress Controller verwendet wird, der Teil des Projekts ist. (Beachten Sie, dass Sie beim Bereitstellen von MARA den standardmäßigen NGINX Ingress Controller basierend auf NGINX Open Source oder NGINX Plus sowie diesen benutzerdefinierten NGINX Ingress Controller verwenden können.) Wir haben festgestellt, dass wir unsere Registrierungslogik zugunsten eines plattformunabhängigeren Ansatzes vom Amazon Elastic Container Registry (ECR) entkoppeln müssen. Diese Aufgabe ist derzeit in Bearbeitung. Wir erkannten außerdem, dass unsere Logik zum Abrufen des Hostnamens der Ausgangsadresse sehr spezifisch für AWS Elastic Load Balancing (ELB) war und für die Anwendung auf andere Anwendungsfälle neu geschrieben werden musste.

Die MARA-Verwaltungsskripte und die Pulumi-Projekte verwenden derzeit eine spezielle Logik, um die oben beschriebenen Probleme zu umgehen. Derzeit müssen die konfigurationsbasierten Bereitstellungen von Kubernetes den NGINX Ingress Controller (basierend auf NGINX Open Source oder NGINX Plus) aus den offiziellen NGINX-Registern verwenden.

Wir haben den MARA-Konfigurationsdateien mehrere Optimierungsparameter hinzugefügt, um lokale Bereitstellungen zu ermöglichen, die nicht die für eine Cloud-basierte Bereitstellung erforderlichen Ressourcen bieten. Die meisten Parameter beziehen sich auf die Anzahl der angeforderten Replikate für die verschiedenen Komponenten des Elastic Stack . Im weiteren Verlauf der Tests werden zusätzliche Parameter zur Feinabstimmung von MARA basierend auf den Ressourcenbeschränkungen der Bereitstellungsumgebung verfügbar.

Mit diesen Änderungen können wir erfolgreich auf K3s, MicroK8s und Minikube bereitstellen und wir haben die Logik erfolgreich auf Azure Kubernetes Service (AKS), Digital Ocean , Google Kubernetes Engine , Linode und Rancher’s Harvester getestet. Weitere Informationen finden Sie auf der Seite „MARA-Anbieterstatus“ und bei MARA: Läuft jetzt auf einer Workstation in Ihrer Nähe auf unserem Blog.

Zusammenarbeit mit Partnern

Unsere Partner haben unsere Arbeit mit MARA sehr aufgeschlossen und unterstützend aufgenommen. Viele von ihnen haben sich an uns gewandt, um mehr über das Projekt zu erfahren, zu fragen, wie sie es für ihre Produkte nutzen oder sogar Funktionen hinzufügen können.

Wir haben Pulumi aufgrund seiner Benutzerfreundlichkeit und der Unterstützung von Python als Kernbestandteil von MARA ausgewählt. Python ist eine so beliebte Sprache, dass der MARA-Code dadurch von einer großen Community problemlos verstanden wird. Darüber hinaus waren Pulumis lebendige Gemeinschaft und ihr Engagement in dem Projekt ein Vorbild für die Einbindung der Gemeinschaft, die wir mit MARA erreichen möchten.

Ende 2021 haben wir mit Sumo Logic zusammengearbeitet, um MARA mit NGINX Ingress Controller zu einem Teil seiner Cloud-Überwachungslösung zu machen. Dies war eine Gelegenheit, unsere Behauptung, dass MARA steckbar ist, zu testen. Die Herausforderung bestand darin, Grafana, Prometheus und Elastic in MARA durch die Sumo Logic-Lösung zu ersetzen. Wir waren erfreut, dass wir die Lösung erfolgreich mit der gleichen Logik auf die Beine gestellt haben, die wir für andere Bereitstellungen verwenden, und sie nicht nur für die Verbindung mit Sumo Logic SaaS konfiguriert haben, sondern auch für das Abrufen von Messdaten aus unserer Umgebung.

Im Rahmen unserer Arbeit mit OpenTelemetry haben wir mit Lightstep zusammengearbeitet und unseren OTEL-Collector problemlos neu konfiguriert, um Traces und Metriken in das SaaS-Angebot von Lightstep zu exportieren. Dies ist ein Bereich, den wir gern näher untersuchen möchten, da wir der festen Überzeugung sind, dass OTEL die Zukunft der Beobachtbarkeit ist.

Gelernte Lektionen … bisher

Die wichtigste Lektion, die wir bisher gelernt haben, ist die Weisheit eines modularen Ansatzes. Die Arbeit mit Sumo Logic zeigt, dass wir MARA-Komponenten erfolgreich kombinieren können. Wir erwarten eine weitere Bestätigung, wenn wir OTEL vollständiger in die Umgebung integrieren. Wir haben bereits erwähnt, dass wir erwägen, Elasticsearch durch Grafana Loki als Protokollverwaltungsumgebung zu ersetzen, da dies den Ressourcenbedarf des Stacks reduziert. Allerdings plädieren wir für „pragmatische Modularität“, anstatt ins Extreme zu gehen und alles zu einem Microservice zu machen. Während es beispielsweise sinnvoll ist, einen spezialisierten Dienst zu haben, der Protokolle für viele Anwendungen verarbeiten kann, ist es weniger offensichtlich, dass Sie separate Mikrodienste für die Protokollerfassung, -speicherung und -visualisierung benötigen.

Wir haben auch gelernt, dass es hilfreich ist, Standardwerte festzulegen, indem man sie explizit in die Konfiguration einbezieht, anstatt den entsprechenden Parameter einfach wegzulassen. Dies ist für Administratoren in zweierlei Hinsicht praktisch: Sie müssen sich die Standardeinstellungen nicht merken und können diese ganz einfach ändern, indem sie einen Parameter ändern, der bereits mit der richtigen Syntax an der richtigen Stelle in der Konfiguration angezeigt wird.

Eine weitere schmerzliche Lektion, die wir gelernt haben, ist, dass manche Lösungen nicht deshalb beliebt sind, weil sie die besten sind, sondern weil sie am einfachsten zu installieren sind oder über das beste Tutorial verfügen. Aus diesem Grund ist es so wichtig, während des Designprozesses Ihre Annahmen zu hinterfragen und sich mit Kollegen zu beraten – eine Kultur der offenen Kommunikation trägt wesentlich dazu bei, Probleme frühzeitig zu erkennen und zu beheben.

Allerdings haben wir mehrmals eine Logik implementiert, die zwar funktionierte, uns jedoch in eine Sackgasse führte oder andere Probleme verursachte. Als wir beispielsweise begannen, Anwendungen über Pulumi bereitzustellen, verwendeten wir YAML-Manifeste für ConfigMaps und verließen uns auf Pulumi-Transformationen , um Variablen zu aktualisieren. Dies funktionierte, war jedoch aus mehreren Gründen nicht ideal, nicht zuletzt wegen der Wartbarkeit. In der nächsten Iteration haben wir die Lesbarkeit und Wartbarkeit des Codes verbessert, indem wir kube2pulumi verwendet haben, um die Manifeste in Pulumi-Code umzuwandeln, den wir dann zum Erstellen der ConfigMaps verwenden konnten.

Eine weitere Lektion begann, als durch eine Zusammenführung ungültige Einstellungen in die Bereitstellungs-YAML eingefügt wurden. Wir waren gezwungen, große Teile des YAML neu zu schreiben und sorgfältig zu überprüfen, um sicherzustellen, dass der Code sowohl syntaktisch korrekt war als auch das tat, was wir wollten – ein frustrierender und zeitaufwändiger Prozess. Um zukünftige Probleme zu vermeiden, haben wir jetzt sowohl das generische YAML als auch das Kubernetes-spezifische Linting und die Validierung während des GitHub-Push-Prozesses automatisiert .

Schließlich war es von Anfang an unser Ziel, sicherzustellen, dass unser Hauptzweig immer betriebsbereit ist. Es ist frustrierend, wenn Sie ein neues Projekt ausprobieren und ein Problem lösen müssen, das die Betreuer in die Hauptlinie eingeführt haben. Leider ist uns dies einige Male nicht gelungen, unter anderem in den folgenden Beispielen mit dem Untermodul „Bank of Sirius“:

  • Wir haben versehentlich vergessen, das URL-Schema von ssh:// in https:// zu ändern. Dies war für uns kein Problem, da wir alle SSH für die Verbindung mit GitHub verwenden. Benutzer, die keinen SSH-Schlüssel für GitHub hatten, wurden jedoch beim Versuch, das Untermodul zu initialisieren, mit Fehlermeldungen überschwemmt.
  • Eine Version der Verwaltungsskripte war von einem allgemeinen Paket abhängig, von dem wir fälschlicherweise annahmen, dass es auf allen Computern genauso installiert wäre wie auf unserem.
  • Wir haben beim Umschreiben der Startlogik vergessen, eine Prüfung auf die Submodulquelle einzufügen. Das Untermodul enthält die Manifeste, die zur Bereitstellung von Bank of Sirius erforderlich sind. Leider waren die Fehler und Warnungen, die ausgegeben wurden, wenn diese Manifeste nicht verfügbar waren, so obskur, dass wir uns auf eine mehrtägige Odyssee der Fehlerbehebung bei merkwürdigem Verhalten begeben mussten, bevor wir die Grundursache entdeckten.

Was kommt als nächstes

Wir haben für die nächsten Entwicklungsmonate Großes vor, unter anderem die Umgestaltung des NGINX Ingress Controller-Builds, Registry Push und der Ingress-Hostnamen-/IP-Adresslogik.

Bei jedem Standup von MARA ist uns aufgefallen, wie schnell wir Scans und Angriffe auf den NGINX Ingress Controller feststellen. Dies hat uns dazu veranlasst, mit der Integration von NGINX Ingress Controller mit NGINX App Protect WAF in MARA zu beginnen. Dies bringt die Herausforderung und Chance mit sich, zu bestimmen, wie die von App Protect erstellte Protokollierung am besten verwaltet werden kann.

Eine weitere Änderung, die wir in den kommenden Monaten planen, besteht darin, dass alle Module Geheimnisse aus Kubernetes und nicht sowohl aus Pulumi als auch aus Kubernetes abrufen. Dies bedeutet, dass alle Module ein gemeinsames Repository für Geheimnisse verwenden und dem Administrator Kontrolle über die Art und Weise der Auffüllung der Geheimnisse geben. Wir schreiben ein neues Modul, um Geheimnisse aus einem Repository nach Wahl des Benutzers zu lesen und die entsprechenden Kubernetes-Geheimnisse zu erstellen.

MARA enthält derzeit ein Tool zum Generieren von Last, bei dem es sich um eine verbesserte und leicht modifizierte Version des auf Locust basierenden Tools handelt, das mit der ursprünglichen Bank of Anthos-App geliefert wird, von der wir Bank of Sirius abgezweigt haben. Das neue Testtool, das wir gerade schreiben, Cicada Swarm, generiert nicht nur Last, sondern verfolgt und meldet auch, wenn Metriken von Ihnen festgelegte Schwellenwerte überschreiten, und stellt damit ein Framework für schnelle Leistungstests von Softwareprodukten in der Cloud bereit. Es verwendet Parallelisierungstechniken, um Testergebnisse mit dem von Ihnen benötigten Vertrauensniveau, höherer Präzision und anpassbaren Regressionsanalysen zu liefern, um den Erfolg oder Misserfolg von Builds in Ihren CI/CD-Pipelines zu bestimmen.

Abschließend können wir Belastungstests nicht erwähnen, ohne darüber zu sprechen, wie wir die Auswirkungen dieser Belastungstests messen werden, und damit kommen wir wieder zur Telemetrie. Wir sind vom Potenzial von OpenTelemetry begeistert und hoffen, bald eine umfassendere Implementierung bereitstellen zu können. Auch ohne eine vollständige Implementierung ist es unser Ziel, einen Test durchführen zu können, seine Auswirkungen zu messen und auf der Grundlage der Daten operative Entscheidungen zu treffen.

Wie immer freuen wir uns über Ihre Pull Requests , Probleme und Kommentare . Unser Ziel mit MARA ist es, die Community zur Zusammenarbeit zu inspirieren, um verschiedene potenzielle Lösungen zu diskutieren, auszuprobieren, zu testen und zu iterieren, um unser Verständnis dafür zu erweitern, wie eine moderne Anwendung am besten bereitgestellt und verwaltet werden kann.

Verwandte Artikel

Dieser Beitrag ist Teil einer Serie. Wenn wir MARA im Laufe der Zeit um neue Funktionen erweitern, veröffentlichen wir die Einzelheiten im Blog:


„Dieser Blogbeitrag kann auf Produkte verweisen, die nicht mehr verfügbar und/oder nicht mehr unterstützt werden. Die aktuellsten Informationen zu verfügbaren F5 NGINX-Produkten und -Lösungen finden Sie in unserer NGINX-Produktfamilie . NGINX ist jetzt Teil von F5. Alle vorherigen NGINX.com-Links werden auf ähnliche NGINX-Inhalte auf F5.com umgeleitet."