Cloud Native Development – Das ist doch nur für die Cloud? – Technologie & Philosophie

Viele glauben, dass Cloud-Native-Entwicklung nicht mit der Entwicklung im On-Premises-Bereich kompatibel ist. Diese Haltung kann aber nicht allgemeingültig bestätigt werden, da sich über die letzten Jahre viele Technologien und Szenarien entwickelt haben, die genau diese beiden Welten vereinen und so ganz neue Möglichkeiten schaffen.

Nur, was ist Cloud Native genau?

Wo fängt es an und wo hört es auf? Wie auch im Bereich der Softwarearchitektur, beispielsweise sehr prägnant im Fall „Monolith vs. Microservices“, ist es nahezu unmöglich eine Grenze zu ziehen, weshalb die Ansichten sehr stark variieren. Versucht man die Abgrenzungen in Gänze zu verstehen, ideologisch anzuwenden und recherchiert hierzu im Internet, findet man so viele unterschiedliche Ansätze, dass es schwer wird, den eigenen Weg zu definieren.

Am einfachsten lässt sich Cloud Native damit beschreiben, dass Applikationen so konzipiert sind, dass einzelne Module bzw. Bestandteile austauschbar und nahezu beliebig skalierbar in der Cloud und im eigenen Rechenzentrum laufen können. Sie nutzen all das, was die Cloud zur Verfügung stellt und haben daher keine Abhängigkeiten zu den Ressourcen und Services der eigenen Hardware- und Serverlandschaft. 

Nun kann es aber passieren, dass auf Grund einer Priorisierung der On-Premises-Ressourcen, durch unterschiedlichste Gründe, die Cloud grundsätzlich ausgeschlossen wird und die Entwicklung auch nur auf bzw. mit On-Premises-Ressourcen durchgeführt wird.

Die offizielle Definition der Cloud Native Computing Foundation zu Cloud Native Technologien, die hier Licht ins Dunkle bringt, lautet:

„Cloud Native Technologien ermöglichen es Firmen skalierbare Applikationen in Public- Private, und Hybrid-Clouds in Form von APIs, Microservices, Containern und Infrastruktur zu beschreiben und zu betreiben. Hierdurch lassen sich Änderungen schneller und mit weniger Aufwand realisieren.“

Wendet man diese Definition also an, stellt sich direkt heraus, dass sich On-Premises-Umgebungen und die Cloud annähern und nicht ausschließen.  Was viele nicht wissen: Beide Umgebungen sind auch jetzt schon technisch betrachtet ein Verbund, ohne dass man die Beziehung auf Anhieb sieht.

Fallbeispiel: Entwicklung von APIs mit C#

Traditionell wurden APIs mit C# in .NET mit dem .NET Full Framework entwickelt. Die hiermit entstandenen APIs konnten nur auf Microsoft Windows Systemen als Dienst oder innerhalb eines Internet Information Services (IIS)-Webservers ausgeführt werden. Durch den Wechsel von .NET Full Framework zu .NET Core – in der letzten Evolutionsstufe nur noch .NET genannt – ist es nun möglich, die eigens entwickelten APIs nicht nur auf Microsoft Windows Systemen zu hosten, sondern auch auf Linux oder MacOS. Dieser Wechsel des Hostings hat bereits den Grundpfeiler gesetzt, um Cloud-Native-Szenarien auf Basis von .NET zu ermöglichen. 

Sofern nicht Features, z.B. die im IIS (Internet Information Services) nativ vorhandene Integration in das Active Directory, für die Authentifizierung genutzt werden müssen, fällt in dem Fall die Hürde zu Cloud Native von Haus aus weg. Moderne Authentifizierungsmechanismen, die einen Token-basierten Ansatz nutzen, machen dies möglich.

Was ist der Status Quo?

Mit dem aktuellen Tech-Stack im Bereich C# ist man nun an einem Punkt angelangt, an dem das zugrundeliegende Betriebssystem keine eklatante Rolle mehr spielt, da die Entwicklung unter Windows, Linux und MacOS gleichermaßen lauffähig ist. Abhängigkeiten hinsichtlich direkter Integration von Funktionalitäten aus dem Web-Server wurden weg abstrahiert und hindern daher nicht mehr daran, die APIs beliebig umzuziehen.

Doch widerspricht dies nicht der Aussage, die anfänglich gedanklich Cloud Native Technologien ausschließt: „Es ist notwendig alles On-Premises zur Verfügung zu stellen, also fallen Technologien und Praktiken in der Public Cloud weg“. Dem ist aber definitiv nicht so. 

Das grundsätzliche Prinzip, eine API zur Verfügung zu stellen, funktioniert beim Hosting über Web-Server, wie auch in Containern gleichermaßen. Bei der Nutzung von Container-Technologien kristallisiert sich der Vorteil gegenüber der traditionellen Bereitstellung aber deutlicher heraus. Die Container Images können ohne Anpassungen in jeder dafür konzipierten Umgebung ausgeführt werden. Außerdem ist eine Installation des darunterliegenden Betriebssystems nicht mehr notwendig. Eine Skalierung der Container- bzw. API-Instanzen kann einfach durchgeführt werden, während zusätzlich eine Streuung, sogar über Rechenzentren bzw. Clouds hinweg, möglich ist. Durch die Nutzung von .NET in Version 6 und 7 ist man bestens gewappnet, um APIs über Container zur Verfügung zu stellen und die Vorteile von Cloud Native Technologien zu nutzen.

Doch wie geht man nun vor? Welche Herausforderungen oder Fragestellungen gilt es zu lösen? Nur weil es notwendig ist, die Container und darin laufende Services On-Premises zu hosten, müssen diese nicht zwangsläufig dort entwickelt werden. Auch um Services für den Einsatz in der On-Premises-Umgebung zu testen, muss kein extra Test-System installiert und zur Verfügung gestellt werden. Für die Bereitstellung von realistischen Entwicklungsumgebungen für Developer ist es daher nicht nötig Aufwand auf On-Premises Seite zu betrieben oder ggf. teure Ressourcen vorzuhalten.

Ressourcen-Engpässe auf den Entwicklermaschinen

In der Entwicklung benötigen APIs auch entsprechend Ressourcen auf den Laptops der Entwickler:innen. Hat man sich dafür entschieden, die alten Monolithen zu modernisieren und aufzubrechen oder entwickelt neue Applikationen direkt nach dem Microservice-Prinzip, sieht man sich mit den nächsten Herausforderungen konfrontiert. Diese sind aber einfacher zu lösen, als man zunächst denkt – vor allem, wenn Ressourcen aus der Cloud hierfür genutzt werden können bzw. diese nicht grundsätzlich ausgeschlossen sind. 

Mit der Komplexität der Anwendungen, dem Zusammenspiel der APIs und der Verwendung von nicht selbst entwickelten Open-Source-Technologien, wie z.B. Messaging-Systemen, steigen die Anforderungen an CPU und Arbeitsspeicher. Der Footprint bei der Nutzung von C# und dem ASP .NET Framework ist weiterhin größer als bei der Nutzung von vielen anderen Programmiersprachen und Frameworks, auch wenn hier eine stetige Verbesserung stattfindet. Je nachdem, wie groß die Lösung wird, reicht ein einzelner Laptop ggf. nicht mehr für die Entwicklung und das Testen aus. Bei Bedarf müssen Ressourcen bereits bei der Entwicklung durch mehrere Personen oder Teams geteilt werden. Für die Lösung dieses Problems ist es notwendig zunächst noch über die Bereitstellung zu sprechen.

Das Hosting der Umgebung(en)

Der nächste zu betrachtende Themenkomplex ist die Bereitstellung bzw. das Hosting der Container. Diese Thematik hat vermutlich den größten Einfluss auf die Klärung der Frage “On-Premises, Cloud oder beides?”.  Das beste Beispiel hierfür ist die Container-Orchestrierung Kubernetes, der de-facto Standard für das ausfallsichere und stark automatisierbare Hosting von Container-Services. Auf einem Kubernetes-Cluster können die entwickelten Services gehostet und veröffentlicht werden. Vom Kubernetes-Cluster selbst oder von Services, die innerhalb des Clusters laufen, existieren im Idealfall mehrere Instanzen, jeweils für die Entwicklung und das Testing, die Qualitätssicherung sowie die Produktionsumgebung.

Nun zur wichtigsten Erkenntnis bzw. dem Grundstein für die weiteren Überlegungen: “Der Kubernetes-Cluster selbst ist eine Cloud Native Technologie”.

Eine entwickelte API in C# und .NET ist also von Grund auf plattformunabhängig. Diese API kann containerisiert und somit auf einem Kubernetes-Cluster ausgeführt werden. Wurden beim Design entsprechende Grundprinzipien der Entwicklung von Microservices eingehalten, sind die APIs beliebig skalierbar. Sie können als Gesamtlösung entweder auf einem Kubernetes-Cluster im eigenen Rechenzentrum laufen oder auch auf einem Kubernetes-Cluster in der Cloud. Die Beschreibung der Kubernetes-Cluster selbst, mitsamt Funktionsumfang und Konfiguration, kann währenddessen auf jedem Cluster, unabhängig vom Betriebsort, angewandt werden. Genau dies führt dazu, dass man in der Cloud entwickeln kann und die entwickelte Lösung trotzdem auch im eigenen Rechenzentrum lauffähig ist – ohne Codeanpassungen und in mehreren Umgebungen.

Automatisierung & Einsparpotenzial

Die entwickelten Lösungen werden irgendwann so komplex, dass diese nicht mehr auf der Maschine der Developer in Gänze ausgeführt werden können. Für den Prozess der Entwicklung wird sogar ein vollständiges Kubernetes-Cluster zur Ausführung der Services notwendig – im schlimmsten Fall für jeden einzelnen Developer. Müssen diese Ressourcen im eigenen Rechenzentrum vorgehalten werden, kommt man hier ggf. an einen Engpass.

Benötigen die Developer also aufgrund der hohen Komplexität eine komplette Umgebung, können alle Abhängigkeiten durch z.B. Infrastructure-as-Code-Technologien automatisiert provisioniert werden. Diese müssen allerdings nur für den Zeitraum, in dem sie wirklich benötigt werden, existieren. Die gleiche Vorgehensweise kann automatisiert innerhalb der CI/CD-Pipeline für das Testing oder die Abnahme von Entwicklungen verwendet werden. Werden die Ressourcen nicht mehr benötigt, werden diese automatisiert gelöscht und erst wieder bei Bedarf erstellt. Zusätzlich kann sichergestellt werden, dass jede Entwicklung innerhalb oder mit diesen Technologien auch gleichermaßen in der On-Premises-Umgebung funktioniert.

Abschließend noch ein paar Worte zum Thema Serverless oder grundsätzlich Software as a Service. Nicht alle Bereiche einer selbst entwickelten Lösung müssen auch selbst gehostet werden. Obwohl die Lösung im eigenen Rechenzentrum läuft, ist man nicht zwangsweise verpflichtet z.B. die Datenbank dort unterzubringen. Vollständige Bereiche der Applikation, sei es die Verwaltung der Identitäten, der Daten oder die Kommunikation zwischen den Services kann in der Cloud provisioniert und genutzt werden. Neben den genannten Technologien bzw. Technologiebereichen reden wir hier aber noch über viel mehr. Vollständig gemanagte Services, Storage, Functions, ermöglichen es verteilte, performante und ausfallsichere Applikationen zu entwickeln und bereitzustellen.

Fazit

Betrachtet man alle Technologien, die in der Cloud zur Verfügung stehen, und konzipiert Software nach modernen Standards, ist es möglich vollständig in der Cloud zu entwickeln und zu testen, das Endergebnis in der On-Premises-Umgebung auszurollen und eine viel schnellere und kosteneffizientere Release-Strategie zu fahren. Die beiden Welten schließen sich also definitiv nicht aus, sondern ergänzen sich perfekt.  Mit hoher Wahrscheinlichkeit ist man bereits im Cloud Native Bereich bzw. in der Cloud Native Entwicklung angekommen, geht aber auf Grund der unterschiedlichen Definitionen nicht davon aus. Somit fällt auch die Einarbeitungszeit in die unterschiedlichen Services und Methodiken weitaus kürzer aus, als man zunächst denkt. Das fehlende Knowhow, sei es aus Entwicklungs- oder Infrastruktur, im Idealfall aus “DevOps”-Sicht, kann sich schnell angeeignet werden.