Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Tipp
Dieser Inhalt ist ein Auszug aus dem eBook, Architecting Cloud Native .NET Applications for Azure, verfügbar auf .NET Docs oder als kostenlose herunterladbare PDF, die offline gelesen werden kann.
Beenden Sie das, was Sie tun, und bitten Sie Ihre Kollegen, den Begriff "Cloud Native" zu definieren. Es gibt eine gute Chance, dass Sie mehrere verschiedene Antworten erhalten.
Beginnen wir mit einer einfachen Definition:
Cloudnative Architektur und Technologien sind ein Ansatz für das Entwerfen, Erstellen und Betreiben von Workloads, die in der Cloud integriert sind und das Cloud Computing-Modell vollständig nutzen.
Die Cloud Native Computing Foundation bietet die offizielle Definition:
Mit cloudeigenen Technologien können Organisationen skalierbare Anwendungen in modernen, dynamischen Umgebungen wie öffentliche, private und hybride Clouds erstellen und ausführen. Container, Dienstgitter, Microservices, unveränderliche Infrastruktur und deklarative APIs veranschaulichen diesen Ansatz.
Diese Techniken ermöglichen lose gekoppelte Systeme, die robust, verwaltbar und feststellbar sind. In Kombination mit robuster Automatisierung ermöglichen sie Entwicklern, häufig und vorhersehbare Änderungen mit minimalem Aufwand vorzunehmen.
Cloud Native geht es um Geschwindigkeit und Flexibilität. Geschäftssysteme entwickeln sich von der Aktivierung von Geschäftsfunktionen bis hin zu Waffen der strategischen Transformation, die die Geschäftsgeschwindigkeit und das Wachstum beschleunigen. Es ist zwingend erforderlich, sofort neue Ideen auf den Markt zu bringen.
Gleichzeitig sind Geschäftssysteme auch immer komplexer geworden, wenn die Nutzer mehr verlangen. Sie erwarten schnelle Reaktionsfähigkeit, innovative Features und null Ausfallzeiten. Leistungsprobleme, wiederkehrende Fehler und die Unfähigkeit, schnell zu navigieren, sind nicht mehr akzeptabel. Ihre Benutzer besuchen Ihren Konkurrenten. Cloudeigene Systeme sind so konzipiert, dass sie schnelle Veränderungen, große Mengen und Resilienz nutzen können.
Hier sind einige Unternehmen, die Cloud-native Techniken implementiert haben. Überlegen Sie sich die Geschwindigkeit, Flexibilität und Skalierbarkeit, die sie erreicht haben.
Firma | Erfahrung |
---|---|
Netflix | Verfügt über mehr als 600 Dienstleistungen im Betrieb. Die Bereitstellung erfolgt 100 Mal pro Tag. |
Uber | Verfügt über mehr als 1.000 Dienste in der Produktion. Die Bereitstellung erfolgt mehrere tausend Mal pro Woche. |
Verfügt über mehr als 3.000 Dienste in der Produktion. Die Bereitstellung erfolgt 1.000 Mal pro Tag. |
Wie Sie sehen können, machen Netflix, Uber und WeChat Cloud-native Systeme verfügbar, die aus vielen unabhängigen Diensten bestehen. Dieser Architekturstil ermöglicht es ihnen, schnell auf Marktbedingungen zu reagieren. Sie aktualisieren sofort kleine Bereiche einer Live-, komplexen Anwendung ohne vollständige erneute Bereitstellung. Sie skalieren Dienstleistungen nach Bedarf individuell.
Die Grundpfeiler von „cloudnativ“
Die Geschwindigkeit und Flexibilität von cloudnativen Lösungen ist auf viele Faktoren zurückzuführen. In erster Linie handelt es sich um cloudbasierte Infrastruktur. Aber es gibt mehr: Fünf weitere Säulen bilden, wie in Abbildung 1-3 gezeigt, die Grundlage für Cloud-native Systeme.
Abbildung 1-3. Cloud-native Basispfeiler
Nehmen wir uns etwas Zeit, um die Bedeutung jeder Säule besser zu verstehen.
Die Cloud
Cloudnative Systeme nutzen das Clouddienstmodell vollständig.
Diese Systeme wurden entwickelt, um in einer dynamischen, virtualisierten Cloudumgebung zu gedeihen und machen umfangreichen Gebrauch von Plattform als Dienst (PaaS)-Computeinfrastruktur und verwalteten Diensten. Sie behandeln die zugrunde liegende Infrastruktur als verwerfbar – sie wird in Minutenschnelle bereitgestellt und bei Bedarf durch Automatisierung in der Größe verändert, skaliert oder zerstört.
Berücksichtigen Sie den Unterschied zwischen der Behandlung von Haustieren und Rohstoffen. In einem herkömmlichen Rechenzentrum werden Server als Haustiere behandelt: eine physische Maschine, mit einem aussagekräftigen Namen und betreut. Sie skalieren, indem Sie demselben Computer weitere Ressourcen hinzufügen (Skalierung nach oben). Wenn der Server „krank“ wird, pflegen Sie ihn wieder gesund. Sollte der Server nicht mehr verfügbar sein, merkt jeder.
Das Rohstoffservicemodell unterscheidet sich. Sie stellen jede Instanz als virtuellen Computer oder Container bereit. Sie sind identisch und erhalten einen Systembezeichner wie Service-01, Service-02 usw. Sie skalieren, indem Sie weitere Instanzen erstellen (Verkleinern). Niemand bemerkt, wenn eine Instanz nicht verfügbar ist.
Das Rohstoffmodell umfasst unveränderliche Infrastruktur. Server werden nicht repariert oder geändert. Wenn einer fehlschlägt oder eine Aktualisierung erfordert, wird es zerstört und ein neues wird bereitgestellt – alles erfolgt automatisch.
Cloud-native Systeme nutzen das Rohstoffdienstmodell. Sie werden weiterhin ausgeführt, wenn die Infrastruktur ab- oder aufskaliert wird, ohne Rücksicht auf die Computer, auf denen sie ausgeführt werden.
Die Azure-Cloudplattform unterstützt diese Art von hochlastischer Infrastruktur mit automatischer Skalierung, Selbstheilung und Überwachung.
Modernes Design
Wie würden Sie eine cloudeigene App entwerfen? Wie würde Ihre Architektur aussehen? Welche Prinzipien, Muster und bewährten Methoden würden Sie einhalten? Welche Infrastruktur und operative Bedenken wären wichtig?
Die Zwölf-Faktoren-Anwendung
Eine weit akzeptierte Methode zum Erstellen cloudbasierter Anwendungen ist die Twelve-Factor Application. Es beschreibt eine Reihe von Prinzipien und Methoden, die Entwickler befolgen, um Anwendungen zu erstellen, die für moderne Cloudumgebungen optimiert sind. Besondere Aufmerksamkeit gilt der Portabilität zwischen Umgebungen und deklarativer Automatisierung.
Obwohl Twelve-Factor auf jede webbasierte Anwendung anwendbar ist, betrachten viele Praktiker es als solide Grundlage für den Aufbau von cloud-nativen Apps. Systeme, die auf diesen Prinzipien basieren, können schnell bereitgestellt und skaliert werden und Features hinzufügen, um schnell auf Marktänderungen zu reagieren.
In der folgenden Tabelle wird die Twelve-Factor Methodik hervorgehoben:
Faktor | Erklärung |
---|---|
1 – Codebasis | Eine einzelne Codebasis für jeden Microservice, der in einem eigenen Repository gespeichert ist. Mit Versionssteuerung nachverfolgt, kann sie in mehreren Umgebungen (QA, Staging, Produktion) bereitgestellt werden. |
2 – Abhängigkeiten | Jeder Microservice isoliert und verpackt seine eigenen Abhängigkeiten, wobei Änderungen ohne Auswirkungen auf das gesamte System angenommen werden. |
3 – Konfigurationen | Konfigurationsinformationen werden aus dem Microservice verschoben und über ein Konfigurationsverwaltungstool außerhalb des Codes externisiert. Dieselbe Bereitstellung kann sich mit der richtigen Konfiguration über Umgebungen hinweg ausbreiten. |
4 – Sicherungsdienste | Zusätzliche Ressourcen (Datenspeicher, Caches, Nachrichtenbroker) sollten über eine adressierbare URL verfügbar gemacht werden. Dadurch wird die Ressource von der Anwendung entkoppelt, sodass sie austauschbar ist. |
5 – Build, Release, Ausführung | Jede Version muss eine strikte Trennung zwischen Build-, Release- und Ausführungsphasen erzwingen. Jeder sollte mit einer eindeutigen ID markiert werden und die Möglichkeit zum Zurückrollen unterstützen. Moderne CI/CD-Systeme tragen dazu bei, diesen Grundsatz zu erfüllen. |
6 - Prozesse | Jeder Microservice sollte in einem eigenen Prozess ausgeführt werden, der von anderen ausgeführten Diensten isoliert ist. Externalisieren Sie den erforderlichen Zustand in einen Sicherungsdienst, z. B. einen verteilten Cache oder datenspeicher. |
7 – Portbindung | Jeder Microservice sollte mit seinen Schnittstellen und Funktionen eigenständig sein, die über einen eigenen Port verfügbar gemacht werden. Dadurch wird die Isolation von anderen Microservices gewährleistet. |
8 – Parallelität | Wenn die Kapazität erhöht werden muss, skalieren Sie Dienste horizontal über mehrere identische Prozesse (Kopien) hinweg, anstatt eine einzelne große Instanz auf dem leistungsstärksten Computer zu skalieren. Entwickeln Sie die Anwendung so, dass sie gleichzeitig ausgeführt werden kann, um die Skalierung in Cloud-Umgebungen nahtlos zu gestalten. |
9 - Verwertbarkeit | Dienstinstanzen sollten verwerfbar sein. Bevorzugen Sie einen schnellen Start, um Chancen für Skalierbarkeit zu erhöhen und einen ordnungsgemäßen Herunterfahren zu gewährleisten, damit das System in einem korrekten Zustand bleibt. Docker-Container zusammen mit einem Orchestrator erfüllen diese Anforderung inhärent. |
10 - Dev/Prod-Parität | Halten Sie Umgebungen im gesamten Anwendungslebenszyklus so ähnlich wie möglich, und vermeiden Sie kostspielige Verknüpfungen. Hier kann die Akzeptanz von Containern erheblich beitragen, indem die gleiche Ausführungsumgebung gefördert wird. |
11 - Protokollierung | Behandeln Sie Protokolle, die von Microservices generiert werden, als Ereignisdatenströme. Verarbeiten Sie sie mit einem Ereignisaggregator. Verteilen Sie Protokolldaten an Data Mining-/Protokollverwaltungstools wie Azure Monitor oder Splunk und schließlich an die Langzeitarchivierung. |
12 – Administratorprozesse | Führen Sie Verwaltungs-/Verwaltungsaufgaben wie Datenbereinigungen oder Computeranalysen als einmalige Prozesse aus. Verwenden Sie unabhängige Tools, um diese Aufgaben aus der Produktionsumgebung aufzurufen, jedoch separat von der Anwendung. |
Im Buch Jenseits der Twelve-Factor App beschreibt Autor Kevin Hoffman im Detail jeden der ursprünglichen 12 Faktoren (erschienen im Jahr 2011). Darüber hinaus erläutert er drei zusätzliche Faktoren, die das moderne Design von Cloudanwendungen widerspiegeln.
Neuer Faktor | Erklärung |
---|---|
13 – API Zuerst | Machen Sie alles zu einem Dienst. Gehen Sie davon aus, dass Ihr Code von einem Front-End-Client, einem Gateway oder einem anderen Dienst genutzt wird. |
14 – Telemetrie | Auf einer Arbeitsstation haben Sie tiefe Einblicke in Ihre Anwendung und ihr Verhalten. In der Cloud brauchen Sie das nicht. Stellen Sie sicher, dass Ihr Design die Sammlung von Überwachungs-, domänenspezifischen und Integritäts-/Systemdaten enthält. |
15 - Authentifizierung/ Autorisierung | Implementieren Sie die Identität von Anfang an. Berücksichtigen Sie RBAC-Features (rollenbasierte Zugriffssteuerung), die in öffentlichen Clouds verfügbar sind. |
Wir werden auf viele der 12+ Faktoren in diesem Kapitel und im gesamten Buch verweisen.
Azure Well-Architected Framework
Das Entwerfen und Bereitstellen von cloudbasierten Workloads kann schwierig sein, insbesondere bei der Implementierung der cloudeigenen Architektur. Microsoft bietet branchenübliche bewährte Methoden, mit denen Sie und Ihr Team robuste Cloudlösungen bereitstellen können.
Das Microsoft Well-Architected Framework bietet eine Reihe von leitenden Prinzipien, die verwendet werden können, um die Qualität einer Cloud-nativen Workload zu verbessern. Der Rahmen besteht aus fünf Säulen der Architektur-Exzellenz:
Grundsätze | BESCHREIBUNG |
---|---|
Kostenmanagement | Konzentrieren Sie sich frühzeitig auf das Generieren von inkrementellen Werten. Wenden Sie Build-Measure-Learn-Prinzipien an, um die Markteinführungszeit zu verkürzen und gleichzeitig kapitalintensive Lösungen zu vermeiden. Verwenden Sie eine nutzungsbasierte Bezahlungsstrategie und investieren Sie beim Aufskalieren, anstatt eine große Investition im Voraus zu tätigen. |
Operational Excellence | Automatisieren Sie die Umgebung und vorgänge, um die Geschwindigkeit zu erhöhen und menschliche Fehler zu reduzieren. Führen Sie schnell ein Rollback oder Rollforward für Problemupdates aus. Implementieren Sie die Überwachung und Diagnose von Anfang an. |
Effiziente Leistung | Erfüllen Sie die Anforderungen an Ihre Workloads effizient. Bevorzugen Sie die horizontale Skalierung (aufskalieren), und integrieren Sie sie in Ihre Systeme. Führen Sie kontinuierlich Leistungs- und Lasttests durch, um potenzielle Engpässe zu identifizieren. |
Zuverlässigkeit | Erstellen Sie Arbeitslasten, die sowohl robust als auch verfügbar sind. Resilienz ermöglicht es Arbeitslasten, sich von Ausfällen zu erholen und weiter zu funktionieren. Verfügbarkeit stellt sicher, dass Benutzer jederzeit auf Ihre Workload zugreifen können. Entwerfen Sie Anwendungen, um Fehler zu erwarten und sie wiederherzustellen. |
Sicherheit | Implementieren Sie Die Sicherheit über den gesamten Lebenszyklus einer Anwendung hinweg, von der Entwicklung und Implementierung bis hin zu Bereitstellung und Betrieb. Achten Sie auf Identitätsverwaltung, Infrastrukturzugriff, Anwendungssicherheit und Datenhoheit und Verschlüsselung. |
Um zu beginnen, bietet Microsoft eine Reihe von Onlinebewertungen , mit denen Sie Ihre aktuellen Cloudworkloads anhand der fünf gut durchdachten Säulen bewerten können.
Microservices
Cloudeigene Systeme nutzen Microservices, einen beliebten Architekturstil für die Erstellung moderner Anwendungen.
Erstellt als verteilter Satz kleiner, unabhängiger Dienste, die über eine freigegebene Fabric interagieren, teilen sich Microservices die folgenden Merkmale:
Jede implementiert eine bestimmte Geschäftsfunktion innerhalb eines größeren Domänenkontexts.
Jede wird autonom entwickelt und kann unabhängig eingesetzt werden.
Jeder ist eigenständig und kapselt seine eigene Datenspeichertechnologie, Abhängigkeiten und Programmierplattform.
Jede wird in einem eigenen Prozess ausgeführt und kommuniziert mit anderen mit Standardkommunikationsprotokollen wie HTTP/HTTPS, gRPC, WebSockets oder AMQP.
Sie fügen sich zu einer Anwendung zusammen.
Abbildung 1-4 kontrastiert einen monolithischen Anwendungsansatz mit einem Microservices-Ansatz. Beachten Sie, dass der Monolith aus einer mehrschichtigen Architektur besteht, die in einem einzigen Prozess ausgeführt wird. In der Regel verwendet sie eine relationale Datenbank. Der Microservice-Ansatz trennt Funktionalität in unabhängige Dienste, die jeweils über eigene Logik, eigenen Zustand und eigene Daten verfügen. Jeder Microservice hostt einen eigenen Datenspeicher.
Abbildung 1-4. Monolithische und microservices-Architektur
Beachten Sie, wie Microservices das Verfahrensprinzip aus der Twelve-Factor Anwendung fördern, die weiter oben im Kapitel erläutert wird.
Faktor #6 gibt an, "Jeder Microservice sollte in seinem eigenen Prozess ausgeführt werden, isoliert von anderen ausgeführten Diensten."
Warum Microservices?
Microservices bieten Flexibilität.
Weiter oben im Kapitel haben wir eine eCommerce-Anwendung, die als Monolith aufgebaut wurde, mit einer Anwendung mit Microservices verglichen. Im Beispiel haben wir einige klare Vorteile gesehen:
Jeder Microservice verfügt über einen autonomen Lebenszyklus und kann sich unabhängig entwickeln und häufig bereitstellen. Sie müssen nicht auf eine vierteljährliche Version warten, um ein neues Feature oder Update bereitzustellen. Sie können einen kleinen Bereich einer Live-Anwendung mit weniger Risiko aktualisieren, dass das gesamte System gestört wird. Das Update kann ohne vollständige erneute Bereitstellung der Anwendung erfolgen.
Jeder Microservice kann unabhängig voneinander skaliert werden. Anstatt die gesamte Anwendung als einzelne Einheit zu skalieren, skalieren Sie nur die Dienste auf, die mehr Rechenleistung benötigen, um die gewünschten Leistungsstufen und Service Level Agreements zu erfüllen. Feinkörnige Skalierung bietet eine bessere Kontrolle über Ihr System und trägt dazu bei, die Gesamtkosten zu reduzieren, während Sie Teile Ihres Systems skalieren, nicht alles.
Ein hervorragender Referenzleitfaden für das Verständnis von Microservices ist .NET Microservices: Architektur für containerisierte .NET-Anwendungen. Das Buch befasst sich eingehend mit dem Design und der Architektur von Microservices. Es ist ein Begleiter für eine Full-Stack-Microservice-Referenzarchitektur , die als kostenloser Download von Microsoft verfügbar ist.
Entwickeln von Microservices
Microservices können auf jeder modernen Entwicklungsplattform erstellt werden.
Die Microsoft .NET-Plattform ist eine ausgezeichnete Wahl. Frei und Open-Source, verfügt es über viele integrierte Funktionen, die die Entwicklung von Microservices vereinfachen. .NET ist plattformübergreifend. Anwendungen können unter Windows, macOS und den meisten Versionen von Linux erstellt und ausgeführt werden.
.NET ist sehr leistungsfähig und hat im Vergleich zu Node.js und anderen konkurrierenden Plattformen gut abgeschnitten. Interessanterweise führte TechEmpower eine umfangreiche Reihe von Leistungs-Benchmarks auf vielen Webanwendungsplattformen und Frameworks durch. .NET hat es in die Top 10 geschafft – weit vor Node.js und anderen konkurrierenden Plattformen.
.NET wird von Microsoft und der .NET-Community auf GitHub verwaltet.
Microservice-Herausforderungen
Während verteilte Cloud-native Microservices immense Flexibilität und Geschwindigkeit bieten können, stellen sie viele Herausforderungen dar:
Kommunikation
Wie kommunizieren Front-End-Clientanwendungen mit Backed-End-Kern-Microservices? Werden Sie die direkte Kommunikation zulassen? Oder können Sie die Back-End-Microservices mit einer Gatewayfassade abstrahieren, die Flexibilität, Kontrolle und Sicherheit bietet?
Wie kommunizieren Back-End-Kern-Microservices miteinander? Werden Sie direkte HTTP-Aufrufe zulassen, die die Kopplung erhöhen und die Leistung und Flexibilität beeinträchtigen können? Oder könnten Sie entkoppelte Nachrichten mit Warteschlangen- und Thementechnologien in Betracht ziehen?
Die Kommunikation wird im Kapitel " Cloud-native Kommunikationsmuster" behandelt.
Resilienz
Eine Microservices-Architektur verschiebt Ihr System von der In-Process-Netzwerkkommunikation in die Out-of-Process-Netzwerkkommunikation. Was geschieht in einer verteilten Architektur, wenn Service B nicht auf einen Netzwerkaufruf von Service A reagiert? Oder was geschieht, wenn Service C vorübergehend nicht verfügbar ist und andere Dienste, die sie aufrufen, blockiert werden?
Die Resilienz wird im Cloud-nativen Resilienzkapitel behandelt.
Verteilte Daten
Im Design kapselt jeder Microservice seine eigenen Daten, wodurch Vorgänge über die öffentliche Schnittstelle verfügbar werden. Wenn ja, wie fragen Sie Daten ab oder implementieren eine Transaktion über mehrere Dienste hinweg?
Verteilte Daten werden im Kapitel " Cloud-native Datenmuster" behandelt.
Geheimnisse
Wie werden Ihre Microservices geheime und vertrauliche Konfigurationsdaten sicher speichern und verwalten?
Geheimnisse werden im Detail in der cloud-nativen Sicherheit behandelt.
Verwalten der Komplexität mit Dapr
Dapr ist eine verteilte Open-Source-Anwendungslaufzeit. Durch eine Architektur modularer Komponenten vereinfacht es die Implementierung verteilter Anwendungen erheblich. Sie stellt einen dynamischen Klebestoff bereit, der Ihre Anwendung mit vordefinierten Infrastrukturfunktionen und -komponenten aus der Dapr-Laufzeit bindet. Abbildung 1-5 zeigt Dapr von 20.000 Fuß.
Abbildung 1-5. Dapr bei 20.000 Fuß.
Beachten Sie in der obersten Zeile der Abbildung, wie Dapr sprachspezifische SDKs für beliebte Entwicklungsplattformen bereitstellt. Dapr v1 umfasst Unterstützung für .NET, Go, Node.js, Python, PHP, Java und JavaScript.
Während sprachspezifische SDKs die Entwicklererfahrung verbessern, ist Dapr plattformunabhängig. Unter der Haube macht das Programmiermodell von Dapr Funktionen über standardmäßige HTTP/gRPC-Kommunikationsprotokolle verfügbar. Jede Programmierplattform kann Dapr über die nativen HTTP- und gRPC-APIs aufrufen.
Die blauen Kästchen in der Mitte der Abbildung stellen die Dapr-Bausteine dar. Jedes stellt vordefinierten Code für eine verteilte Anwendung zur Verfügung, den Ihre Anwendung nutzen kann.
Die Komponentenzeile stellt einen großen Satz vordefinierter Infrastrukturkomponenten dar, die Ihre Anwendung nutzen kann. Stellen Sie sich Komponenten als Infrastrukturcode vor, den Sie nicht schreiben müssen.
Die untere Zeile hebt die Portabilität von Dapr und die verschiedenen Umgebungen hervor, über die es ausgeführt werden kann.
Im Voraus hat Dapr das Potenzial, tief greifende Auswirkungen auf die Cloud-native Anwendungsentwicklung zu haben.
Behälter
Es ist selbstverständlich, dass der Begriff Container in jeder Cloud-native Unterhaltung erwähnt wird. In dem Buch Cloud Native Patterns stellt AutorIn Cornel Davis fest: "Container sind ein großartiger Enabler von Cloud-nativer Software." Die Cloud Native Computing Foundation platziert die Microservice-Containerisierung als ersten Schritt in ihrem Cloud-Native Trail Map – Anleitungen für Unternehmen, die ihre cloudeigene Reise beginnen.
Die Containerisierung eines Microservice ist einfach und unkompliziert. Der Code, seine Abhängigkeiten und die Laufzeit werden in eine Binärdatei verpackt, die als Containerimage bezeichnet wird. Bilder werden in einer Containerregistrierung gespeichert, die als Repository oder Bibliothek für Bilder fungiert. Eine Registrierung kann sich auf Ihrem Entwicklungscomputer, in Ihrem Rechenzentrum oder in einer öffentlichen Cloud befinden. Docker selbst verwaltet eine öffentliche Registrierung über Docker Hub. Die Azure-Cloud verfügt über eine private Containerregistrierung , um Containerimages in der Nähe der Cloudanwendungen zu speichern, die sie ausführen.
Wenn eine Anwendung gestartet oder skaliert wird, transformieren Sie das Containerimage in eine ausgeführte Containerinstanz. Die Instanz wird auf jedem Computer ausgeführt, auf dem eine Container-Runtime-Engine installiert ist. Sie können beliebig viele Instanzen des containerisierten Dienstes haben.
Abbildung 1-6 zeigt drei verschiedene Microservices, die jeweils in einem eigenen Container auf einem einzigen Host ausgeführt werden.
Abbildung 1-6. Mehrere Container, die auf einem Containerhost ausgeführt werden
Beachten Sie, dass jeder Container einen eigenen Satz von Abhängigkeiten und Laufzeiten verwaltet, die sich voneinander unterscheiden können. Hier sehen wir verschiedene Versionen des Product microservice, der auf demselben Host ausgeführt wird. Jeder Container teilt ein Segment des zugrunde liegenden Hostbetriebssystems, des Arbeitsspeichers und des Prozessors, ist jedoch voneinander isoliert.
Beachten Sie, wie gut das Containermodell das Abhängigkeitsprinzip aus der Twelve-Factor Application einschließt.
Faktor 2 gibt Folgendes an: „Jeder Microservice isoliert und verpackt seine eigenen Abhängigkeiten, sodass Änderungen ohne Auswirkungen auf das gesamte System möglich sind.“
Container unterstützen sowohl Linux- als auch Windows-Workloads. Die Azure-Cloud umfasst beides. Interessanterweise ist es Linux, nicht Windows Server, das in Azure zum populäreren Betriebssystem geworden ist.
Während mehrere Containeranbieter vorhanden sind, hat Docker den Löwenanteil des Marktes erfasst. Das Unternehmen treibt die Bewegung für Software-Container voran. Es ist zum de facto-Standard für das Packen, Bereitstellen und Ausführen von cloudeigenen Anwendungen geworden.
Warum Container?
Container bieten Portabilität und garantieren Konsistenz in allen Umgebungen. Indem Sie alles in ein einzelnes Paket kapseln, isolieren Sie den Microservice und dessen Abhängigkeiten von der zugrunde liegenden Infrastruktur.
Sie können den Container in jeder Umgebung bereitstellen, in der das Docker-Laufzeitmodul gehostet wird. Containerisierte Workloads vermeiden auch die Kosten für die Vorkonfiguration jeder Umgebung mit Frameworks, Softwarebibliotheken und Laufzeitmodulen.
Durch die gemeinsame Nutzung des zugrunde liegenden Betriebssystems und der Hostressourcen hat ein Container einen wesentlich geringeren Speicherbedarf als ein vollständiger virtueller Computer. Die kleinere Größe erhöht die Dichte oder Die Anzahl der Mikroservices, die ein bestimmter Host gleichzeitig ausführen kann.
Containerorchestrierung
Während Tools wie Docker Images erstellen und Container ausführen, benötigen Sie auch Tools zum Verwalten. Die Containerverwaltung erfolgt mit einem speziellen Softwareprogramm namens Container Orchestrator. Bei der Verwaltung vieler unabhängig laufender Container im großen Maßstab ist Orchestrierung entscheidend.
Abbildung 1-7 zeigt Verwaltungsaufgaben, die Container-Orchestratoren automatisieren.
Abbildung 1-7. Funktionsweise von Container-Orchestratoren
In der folgenden Tabelle werden allgemeine Orchestrierungsaufgaben beschrieben.
Aufgaben | Erklärung |
---|---|
Terminplanung | Automatische Bereitstellung von Containerinstanzen. |
Affinität/Antiaffinität | Bereitstellen von Containern in der Nähe oder weit voneinander entfernt, was zur Verfügbarkeit und Leistung beiträgt. |
Gesundheitsüberwachung | Automatisches Erkennen und Korrigieren von Fehlern. |
Ausfall | Automatische erneute Bereitstellung einer fehlerhaften Instanz auf einem fehlerfreien Computer. |
Skalierung | Automatisches Hinzufügen oder Entfernen einer Containerinstanz zur Erfüllung der Nachfrage. |
Vernetzung | Verwalten Sie ein Netzwerk-Overlay für die Containerkommunikation. |
Dienstentdeckung | Ermöglichen Sie Containern, sich gegenseitig zu finden. |
Laufende Upgrades | Koordinieren inkrementeller Upgrades mit Bereitstellung ohne Downtime. Automatisches Zurücksetzen problematischer Änderungen. |
Beachten Sie, wie Container-Orchestratoren die Prinzipien "Disposability " und "Concurrency " aus der Twelve-Factor Application nutzen.
Faktor #9 gibt an, dass "Dienstinstanzen verfügbar sein sollten und schnelle Startups bevorzugen, um Skalierbarkeitsmöglichkeiten zu erhöhen und einwandfreie Abschaltungen zu ermöglichen, um das System in einem korrekten Zustand zu hinterlassen". Docker-Container zusammen mit einem Orchestrator erfüllen diese Anforderung inhärent."
Faktor #8 gibt an, dass "Dienste über eine große Anzahl kleiner identischer Prozesse (Kopien) skaliert werden, anstatt eine einzelne große Instanz auf dem leistungsstärksten Computer zu skalieren."
Während mehrere Container-Orchestratoren vorhanden sind, ist Kubernetes zum de facto Standard für die cloud-native Welt geworden. Es ist eine tragbare, erweiterbare Open-Source-Plattform zum Verwalten von containerisierten Workloads.
Sie könnten Ihre eigene Instanz von Kubernetes hosten, aber dann würden Sie für die Bereitstellung und Verwaltung ihrer Ressourcen verantwortlich sein , was komplex sein kann. Die Azure-Cloud bietet Kubernetes als verwalteten Dienst. Sowohl Azure Kubernetes Service (AKS) als auch Azure Red Hat OpenShift (ARO) ermöglichen es Ihnen, die Features und Leistungsfähigkeit von Kubernetes als verwalteten Dienst vollständig zu nutzen, ohne sie installieren und verwalten zu müssen.
Die Containerorchestrierung wird in Skalieren cloudnativer Anwendungen ausführlich behandelt.
Sicherungsdienste
Cloudnative Systeme sind von vielen verschiedenen zusätzlichen Ressourcen abhängig, z. B. Datenspeicher, Nachrichtenbroker, Überwachung und Identitätsdienste. Diese Dienste werden als Sicherungsdienste bezeichnet.
Abbildung 1-8 zeigt viele gängige Sicherungsdienste, die cloudeigene Systeme nutzen.
Abbildung 1-8. Allgemeine Sicherungsdienste
Sie könnten Ihre eigenen Sicherungsdienste hosten, aber dann sind Sie für die Lizenzierung, Bereitstellung und Verwaltung dieser Ressourcen verantwortlich.
Cloudanbieter bieten eine umfangreiche Auswahl an verwalteten Sicherungsdiensten. Anstatt den Dienst zu besitzen, nutzen Sie ihn einfach. Der Cloudanbieter betreibt die Ressource in großem Umfang und trägt die Verantwortung für Performance, Sicherheit und Wartung. Überwachung, Redundanz und Verfügbarkeit sind in den Dienst integriert. Anbieter garantieren die Leistung auf Servicelevel und unterstützen ihre verwalteten Dienste vollständig – öffnen Sie ein Ticket, und sie beheben Ihr Problem.
Cloudnative Systeme bevorzugen verwaltete Sicherungsdienste von Cloudanbietern. Die Zeit- und Arbeitsersparnis kann erheblich sein. Das betriebliche Risiko, Ihre eigenen Systeme zu hosten und Probleme auftreten zu sehen, kann schnell teuer werden.
Eine bewährte Methode besteht darin, einen Sicherungsdienst als angefügte Ressource zu behandeln, die dynamisch an einen Microservice mit Konfigurationsinformationen (einer URL und Anmeldeinformationen) gebunden wird, die in einer externen Konfiguration gespeichert sind. Dieser Leitfaden wird in der Twelve-Factor Anwendung beschrieben, die weiter oben im Kapitel erläutert wird.
Factor #4 gibt an, dass Sicherungsdienste "über eine adressierbare URL verfügbar gemacht werden sollen. Dadurch wird die Ressource von der Anwendung entkoppelt, sodass sie austauschbar ist."
Faktor #3 gibt an, dass "Konfigurationsinformationen aus dem Microservice verschoben und über ein Konfigurationsverwaltungstool außerhalb des Codes extern verschoben werden."
Mit diesem Muster kann ein Sicherungsdienst ohne Codeänderungen angefügt und getrennt werden. Sie könnten einen Mikroservice von der QA in eine Staging-Umgebung verschieben. Sie aktualisieren die Microservice-Konfiguration, um auf die zusätzlichen Dienste im Staging zu verweisen und die Einstellungen mittels einer Umgebungsvariable in Ihren Container einzufügen.
Cloudanbieter bieten APIs für die Kommunikation mit ihren proprietären Sicherungsdiensten. Diese Bibliotheken kapseln die proprietäre Installation und die Komplexität. Durch die direkte Kommunikation mit diesen APIs wird Ihr Code jedoch eng mit diesem spezifischen Sicherungsdienst gekoppelt. Es ist eine allgemein akzeptierte Methode, die Implementierungsdetails der Anbieter-API zu isolieren. Stellen Sie eine Intermediationsschicht oder eine Zwischen-API vor, die generische Vorgänge für Ihren Dienstcode verfügbar macht, und umschließen Sie den Anbietercode darin. Diese lose Kopplung ermöglicht es Ihnen, einen Sicherungsdienst für einen anderen zu tauschen oder Ihren Code in eine andere Cloudumgebung zu verschieben, ohne Änderungen am Hauptzeilendienstcode vornehmen zu müssen. Dapr, früher diskutiert, folgt diesem Modell mit seinen vorgefertigten Bausteinen.
Zum Schluss fördern die unterstützenden Dienste auch das Prinzip der Staatenlosigkeit aus derTwelve-Factor-Applikation, wie weiter oben im Kapitel erörtert wurde.
Faktor #6 gibt an, dass "Jeder Microservice in seinem eigenen Prozess ausgeführt werden soll, isoliert von anderen ausgeführten Diensten. Externalisieren Sie den erforderlichen Zustand in einen Sicherungsdienst, z. B. einen verteilten Cache oder datenspeicher."
Sicherungsdienste werden in Cloud-nativen Datenmustern und Cloud-nativen Kommunikationsmustern erläutert.
Automatisierung
Wie Sie gesehen haben, nutzen cloudeigene Systeme Mikroservices, Container und modernes Systemdesign, um Geschwindigkeit und Flexibilität zu erzielen. Aber das ist nur ein Teil der Geschichte. Wie stellen Sie die Cloudumgebungen bereit, auf denen diese Systeme ausgeführt werden? Wie stellen Sie App-Features und -Updates schnell bereit? Wie runden Sie das vollständige Bild ab?
Geben Sie die allgemein akzeptierte Praxis der Infrastruktur als Code oder IaC ein.
Mit IaC automatisieren Sie die Plattformbereitstellung und Anwendungsbereitstellung. Im Wesentlichen wenden Sie Software engineering-Praktiken wie Tests und Versionsverwaltung auf Ihre DevOps-Praktiken an. Ihre Infrastruktur und Bereitstellungen sind automatisiert, konsistent und wiederholbar.
Automatisieren der Infrastruktur
Mit Tools wie Azure Resource Manager, Azure Bicep, Terraform von HashiCorp und der Azure CLI können Sie die erforderliche Cloudinfrastruktur deklarativ skripten. Ressourcennamen, Standorte, Kapazitäten und geheime Schlüssel sind parametrisiert und dynamisch. Das Skript wird mit Versionsangaben versehen und in die Quellcodeverwaltung als Artefakt Ihres Projekts eingecheckt. Sie rufen das Skript auf, um eine konsistente und wiederholbare Infrastruktur in systemübergreifenden Umgebungen bereitzustellen, z. B. QA, Staging und Produktion.
Unter der Haube ist IaC idempotent, was bedeutet, dass Sie dasselbe Skript über und über ohne Nebenwirkungen ausführen können. Wenn das Team eine Änderung vornehmen muss, bearbeiten und führen sie das Skript erneut aus. Nur die aktualisierten Ressourcen sind betroffen.
Im Artikel Was ist Infrastructure as Code, Autor Sam Guckenheimer, beschreibt, wie "Teams, die IaC implementieren, stabile Umgebungen schnell und in großem Umfang bereitstellen können. Sie vermeiden die manuelle Konfiguration von Umgebungen und erzwingen Konsistenz, indem sie den gewünschten Zustand ihrer Umgebungen über Code darstellen. Infrastrukturbereitstellungen mit IaC sind wiederholbar und verhindern Laufzeitprobleme, die durch Konfigurationsabweichungen oder fehlende Abhängigkeiten verursacht werden. DevOps-Teams können mit einer einheitlichen Reihe von Methoden und Tools zusammenarbeiten, um Anwendungen und ihre unterstützende Infrastruktur schnell, zuverlässig und in großem Umfang bereitzustellen."
Bereitstellungen automatisieren
Die zuvor erläuterte Twelve-Factor-Anwendung ruft beim Transformieren von abgeschlossenem Code in eine ausgeführte Anwendung separate Schritte auf.
Factor #5 gibt an, dass "Jede Version eine strikte Trennung zwischen Build-, Release- und Ausführungsphasen erzwingen muss. Jede Option sollte mit einer eindeutigen ID markiert werden und die Möglichkeit zum Rollback unterstützen.“
Moderne CI/CD-Systeme tragen dazu bei, diesen Grundsatz zu erfüllen. Sie stellen separate Build- und Übermittlungsschritte bereit, mit denen Konsistenter und Qualitätscode sichergestellt wird, der benutzern leicht zur Verfügung steht.
Abbildung 1-9 zeigt die Trennung im gesamten Bereitstellungsprozess.
Abbildung 1-9. Bereitstellungsschritte in einer CI/CD-Pipeline
Achten Sie in der vorherigen Abbildung besonders auf die Trennung von Aufgaben:
- Der Entwickler erstellt ein Feature in ihrer Entwicklungsumgebung und durchläuft die so genannte "innere Schleife" von Code, Ausführung und Debug.
- Nach Abschluss dieses Codes wird dieser Code in ein Code-Repository übertragen, z. B. GitHub, Azure DevOps oder BitBucket.
- Der Push löst eine Buildstufe aus, die den Code in ein binäres Artefakt transformiert. Die Arbeit wird mit einer Ci-Pipeline (Continuous Integration) implementiert. Sie erstellt, testet und packt die Anwendung automatisch.
- Die Releasephase nimmt das binäre Artefakt auf, wendet externe Anwendungs- und Umgebungskonfigurationsinformationen an und erzeugt ein unveränderliches Release. Das Release wird in einer angegebenen Umgebung bereitgestellt. Die Arbeit wird mit einer Continuous Delivery (CD)-Pipeline implementiert. Jede Version sollte identifizierbar sein. Sie können sagen: "Diese Bereitstellung läuft mit der Version 2.1.1 der Anwendung."
- Schließlich wird das veröffentlichte Feature in der Zielausführungsumgebung ausgeführt. Versionen sind unveränderlich, was bedeutet, dass jede Änderung eine neue Version erstellen muss.
Durch die Anwendung dieser Praktiken haben Organisationen radikal weiterentwickelt, wie sie Software versenden. Viele wurden von vierteljährlichen Versionen auf On-Demand-Updates umgestellt. Ziel ist es, Probleme frühzeitig im Entwicklungszyklus zu erfassen, wenn sie weniger teuer zu beheben sind. Je länger die Dauer zwischen Integrationen besteht, desto teurer werden probleme. Mit Konsistenz im Integrationsprozess können Teams Codeänderungen häufiger übernehmen, was zu einer besseren Zusammenarbeit und Softwarequalität führt.
Infrastruktur als Code- und Bereitstellungsautomatisierung sowie GitHub und Azure DevOps werden in DevOps ausführlich erläutert.