Skip to content
Alle Beiträge

Fünfzehn vor zwölf: Der Gang in die Cloud

Design ohne Titel-2

Viele unserer Kunden unterstützen wir dabei, die ersten Schritte nach vorne in wenig bekanntes Territorium, nämlich den Weg in die Cloud zu beschreiten.

Was das konkret heißt, ist sehr unterschiedlich und richtet sich nach den spezifischen Bedürfnissen, Assets, technischen Fähigkeiten (https://dora.dev/devops-capabilities/) und Kernkompetenzen der jeweiligen Unternehmen.

Wir durften bei einigen dieser Reisen aktiv dabei sein als Begleiter und Mitgestalter. Wie sehen diese unterschiedlichen Reisen im Einzelnen aus?

Erfahrungen sammeln

Eine gut gemeinte Cloud-Initiative kann nach wenigen Monaten schon für Ernüchterung bei den Beteiligten sorgen

  • wenn schnell gefasste Ziele als vermeintliche "low hanging fruit" gesteckt werden ("wir gehen mit der Legacy-Anwendung in <viel zu eng gestecktem Ziel in Monaten> in die Cloud"),
  • lediglich ein Lift-and-Shift angewendet wird („packt die Anwendung so wie sie ist einfach mal in einen Container rein")

weil die erhofften Effekte (bessere Skalierung, Verfügbarkeit oder Resilienz) nicht eintreffen. Die alte IT-Weisheit gilt nach wie vor: es gibt keine Silver Bullets. Punkt.

Am Anfang der Reise steht stets eine Bestandsaufnahme, welche Anwendungen sich bereits als Piloten für die Cloud eignen und mit geringem Aufwand in die Cloud transferiert werden können. In vielen Fällen gilt es dann aber auch, eine schrittweise Modernisierung der bestehenden Anwendungslandschaft anzustoßen, um sukzessive ihre Eignung für Cloud-Umgebungen zu verbessern und weitere, gegebenenfalls auch zuvor „sperrigere“ Anwendungen nachzuziehen. Oft ist dies mit Refactoring und architekturellen Änderungen verbunden.

Anders als vielleicht gemeinhin angenommen und häufig irreführend beworben, fallen Skalierung und Verfügbarkeit in der Cloud nicht plötzlich vom Himmel. Damit unsere Kunden nicht nach einer anfänglichen Euphorie buchstäblich „aus allen Wolken fallen“, stehen wir ihnen auf dem Weg in die Cloud mit unserer Expertise rund um die Herausforderungen und Anforderungen einer Cloud-Transformation zur Verfügung. Einige dieser Heraus- und Anforderungen wollen wir in diesem Artikel näher erläutern.

Erfolgsfaktoren für die Cloud-Transformation

Ob es tatsächlich gelingt, Anwendungen gut zu skalieren und weitere Vorteile der Cloud-Transformation zu ernten, hängt entscheidend vom Anwendungsdesign ab. Viele Anwendungen wurden anfangs nicht unter der Prämisse entwickelt, in der Cloud betrieben zu werden und deren Eigenschaften optimal zu nutzen. Im Fachjargon bezeichnet man solche Anwendungen als nicht „cloud-native“.

Im Gegensatz dazu stehen die cloud-nativen Anwendungen, die etablierten Kriterien und Empfehlungen für Cloud-Anwendungen folgend entwickelt werden. Eine weithin anerkannte Aufstellung solcher Empfehlungen stellt die von Heroku eingeführte Methodik der "Twelve-Factor Apps" dar, welche Entwicklern, Architekten und Betrieb bzw. DevOps als Leitfaden dient und ihnen dabei hilft, cloud-native Anwendungen zu entwerfen, zu entwickeln und zu betreiben.

Kurz zusammengefasst sind die (ursprünglichen) zwölf Faktoren:

  1. Codebase
    Die Codebase der Anwendung ist in einem Versionsmanagementsystem wie Git versioniert. Alle Deployments werden aus dieser einen, versionierten Codebase erzeugt.
  2. Abhängigkeiten
    Die Anwendung definiert ihre Abhängigkeiten explizit und eindeutig. Sie verlässt sich nicht auf die Existenz systemweit verfügbarer Pakete. Zur Laufzeit wird die Anwendung isoliert betrieben, um versteckte implizite Abhängigkeiten zu unterbinden.
  3. Konfiguration
    Die Anwendung erlaubt eine Konfiguration hinsichtlich verschiedener Deployments, Stages oder Installationsumgebungen „von außen“, also aus ihrer Umgebung, beispielsweise durch Umgebungsvariablen. Die Konfiguration ist strikt vom Code getrennt, welcher zwar Standardwerte vorgeben, jedoch keine umgebungsspezifischen, realen Konfigurationswerte enthalten darf. Dies gilt insbesondere für Anmeldeinformationen und andere Geheimnisse.
  4. Dienstabhängigkeiten
    Die Anwendung definiert lediglich, welche unterstützenden Dienste sie benötigt, für die Bereitstellung und Bindung dieser Dienste ist die Betriebsumgebung (also die Cloud-Umgebung) zuständig. Dies erfolgt konfigurativ wie durch den dritten Faktor „Konfiguration“ beschrieben. Ein Austausch einer Dienstabhängigkeit, beispielsweise durch eine alternative Implementierung, ist ohne ein neues Deployment der abhängigen Anwendung möglich, vorausgesetzt, die Schnittstelle bleibt kompatibel und die konfigurierte Dienstbindung bleibt weiterhin gültig.
  5. Bauen, freigeben, betreiben
    Die Anwendung durchläuft einen klar definierten Build-Prozess, der aus dem Quellcode ein Build-Artefakt erzeugt. Erst im nächsten Schritt wird dann das Build-Artefakt kombiniert mit der Konfiguration zu einem lauffähigen Release, das wiederum versioniert wird, sodass jederzeit nachvollziehbar ist, welches Release aus welchem Build und welchen Konfigurationswerten zusammengesetzt ist und bei Bedarf auch jederzeit ein Release aus der Historie wiederhergestellt werden kann. Nach dem Start der Anwendung beginnt die Betriebsphase, in der die Cloud-Umgebung betriebliche Aufgaben, wie Health-Monitoring, Skalierung, etc. wahrnimmt, die Anwendung selbst jedoch bis zum nächsten Deployment nicht mehr verändert wird.
  1. Prozesse
    Die Anwendung wird als ein oder mehrere, funktional zustandslose Prozesse ausgeführt. Zustand wird über wohldefinierte Persistenzlösungen wie beispielsweise eine Datenbank abgebildet. Für die Prozesse selbst ist lediglich ein transparenter Zustand, beispielsweise ein Cache zur Performanzoptimierung, zulässig, dessen Verlust (etwa durch Abbruch oder Neustart des Anwendungsprozesses) keine funktionalen Auswirkungen hat. Die Anwendung ist insbesondere nicht auf sogenannte „Sticky Sessions“ angewiesen.
  2. Socket-Bindung
    Analog zum vierten Faktor „Dienstabhängigkeiten“ und zum dritten Faktor „Konfiguration“ sind auch die Sockets, die die Anwendung selbst anbietet, von außen konfigurierbar, sodass sie auch selbst als Dienstabhängigkeit für andere Zwölf-Faktor-Anwendungen dienen kann.
  3. Nebenläufigkeit
    Während auch eine vertikale Skalierbarkeit der Anwendung wünschenswert ist, um mittels nebenläufiger Threads die einem Anwendungsprozess zur Verfügung stehenden Ressourcen auszunutzen, ist die vertikale Skalierung eben auch durch die auf einer Maschine zur Verfügung stehenden Ressourcen begrenzt. Daher muss eine Anwendung auch horizontal skalierbar sein durch die nebenläufige Ausführung mehrere Prozesse auf (potenziell) verschiedenen Maschinen. Dafür ist neben der Einhaltung des sechsten Faktors „Prozesse“ auch sicherzustellen, dass geteilte Ressourcen vermieden werden (siehe dazu beispielsweise den elften Faktor „Logging“) oder zumindest ein definiertes Verhalten bei nebenläufigen Zugriffen sichergestellt ist (wie beispielweise bei Datenbankzugriffen).
  4. Einweggebrauch
    Die Anwendung kann zügig gestartet und beendet werden, jeweils innerhalb weniger Sekunden, besser noch in weniger als einer Sekunde, denn nur so kann die Cloud-Umgebung kurzfristige Lastspitzen durch dynamische Skalierung abfangen. In der Cloud-Umgebung gibt es keine Sonderbehandlung für bestimmte Prozessinstanzen, sodass die Homogenität sichergestellt bleibt.
  5. Dev-Prod-Vergleichbarkeit
    Die Ausführungsumgebungen der Anwendung sind zwischen Entwicklung, Staging und Produktion so ähnlich wie möglich zu halten. Die sogenannten „drei Lücken“ Zeit-Lücke (d.h. die Zeit zwischen Entwicklung und Deployment), Personal-Lücke (unterschiedliche Zuständigkeiten für Entwicklung und Deployment) und Werkzeug-Lücke (unterschiedliche Werkzeuge und Abhängigkeiten, wie beispielsweise Datenbank- oder Betriebssyteme zwischen verschiedenen Umgebungen) sind möglichst zu minimieren. Hierfür ist auch die Umsetzung des Konzepts DevOps
  6. Logs
    Die Anwendung schreibt ihre Logs direkt in ihren Ausgabestrom (stdout bzw. stderr), nicht in eine Datei oder Datenbank. Für das Sammeln der Logs und ihre Übertragung in eine zentrale Logging-Lösung ist die Cloud-Umgebung zuständig, nicht die Anwendung. Des Weiteren werden Logs nicht als „write-only“-Prosa betrachtet, sondern als Strom von auch maschinenlesbaren Ereignissen.
  7. Admin-Prozesse
    Sollten „einmalige“ administrative Aufgaben, wie beispielsweise die Durchführung bestimmter Migrationen oder das Bereinigen von Datensätzen durchgeführt werden müssen, so geschieht dies mittels gemeinsam mit dem Anwendungscode versionierter Skripte (siehe dazu auch den ersten Faktor „Codebase“) bzw. als Teil der Anwendungsfunktionalität. Die Durchführung dieser Aufgaben ist automatisierbar, sodass sie auch im Rahmen von Deployments stattfinden kann. Des Weiteren erfolgt die Durchführung in einer Umgebung, die identisch ist zur Umgebung, in der die langlaufenden Prozesse der Anwendung laufen und verwendet die Artefakte und Konfiguration eines definierten und versionierten Release.

Wenig überraschend decken sich viele der Empfehlungen mit bereits für die klassische Anwendungsentwicklung anerkannten Best Practices wie Versionierung, Trennung des Codes von der Konfiguration und klar definierten Deployment-Prozessen, sodass sich für Anwendungen, die bisher bereits unter Berücksichtigung etablierter Entwicklungsleitlinien entwickelt wurden, in jedem Fall eine günstige Ausgangsposition ergibt. Für alle anderen ist nun der Zeitpunkt gekommen, einige technische Schulden zu tilgen.

Die zwölf Faktoren für cloud-native Anwendungen haben in den letzten Jahren große Bekanntheit erhalten und ihre Sinnhaftigkeit und Notwendigkeit sind kaum von Hand zu weisen. Allerdings zeigt die Erfahrung der letzten Jahre gleichzeitig auch, dass diese Faktoren, wie zu erwarten, noch nicht hinreichend sind. Insbesondere drei weitere Faktoren haben sich als ebenfalls beachtenswert herauskristallisiert, sodass man heute gemeinhin nicht mehr von nur zwölf, sondern von insgesamt fünfzehn Faktoren spricht.

  1. API First
    Dem Entwurf der APIs der Anwendung ist eine hohe Wertschätzung entgegenzubringen, denn cloud-native Anwendungen sind in der Regel Teil eines Ökosystems verteilter Dienste. Wenn APIs nicht wohldefiniert sind, kann dies zu Integrationsfehlern führen. Daher hat sich Consumer-getriebenes Contract-Testing beispielsweise mittels Pact, bewährt. Auch der Lebenszyklus einer API ist zu berücksichtigen und nicht als unwichtige Nebentätigkeit abzutun: API-Economy und API-Management, wie beispielsweise der Umgang mit Breaking-Changes, Versionierung und Parallelbetrieb sind anspruchsvolle Tätigkeiten. Die Verwendung von Standardmodellen von Spezifikationen (vorrangig OpenAPI) ermöglicht klare API-Definitionen.
  1. Telemetrie
    Gemäß der geflügelten Aussage „Was man nicht messen kann, kann man nicht verbessern“ von Peter Drucker, gilt es, konsistentes Monitoring und Tracing über verteilte Anwendungen zu etablieren. Eine cloud-native Anwendung muss Health-Checks, sowie system- und domänenspezifische Metriken bieten, um schnelles Feedback aus dem Live-System und damit auch eine professionelle Bearbeitung von Incidents zu ermöglichen.
  2. Authentifizierung (AuthN) und Autorisierung (AuthZ)
    Eine cloud-native Anwendung sichert ihre Endpunkte mit rollenbasierter Zugriffssteuerung ab („role-based access control“, RBAC). Token-basierte Authentifizierungsmechanismen haben sich bewährt und durchgesetzt. Dabei gilt es, Standards wie beispielsweise OAuth2 und JWT einzuhalten bzw. einzusetzen, denn das NIH-Syndrom („not invented here“, „nicht von uns erfunden“), das Organisationen dazu verleitet, „ihr eigenes Ding“ zu bauen, ist nirgends gefährlicher als im Bereich Security.

    Diese zusätzlichen drei Faktoren sind gleichzustellen mit den ursprünglichen zwölf Faktoren, sodass für eine reibungslose Cloud-Transformation das Prinzip „fünfzehn vor zwölf“ gilt: die Beachtung aller fünfzehn Faktoren ist gegenüber der Beschränkung auf die bekannteren, ursprünglichen zwölf Faktoren unbedingt vorzuziehen.

Ausblick: Neue Perspektiven mit Serverless

Die klassischen Cloud-Modelle wie IaaS, PaaS, CaaS, SaaS etc. sind bereits weit verbreitet. Bei einigen Kunden durften wir mit an der Speerspitze dabei sein, wenn es hieß, Blueprints und Beispiele für Serverless-Anwendungen zu gestalten, damit die Entwicklerteams schneller in der Cloud durchstarten können. Tatsächlich nutzen die wenigsten Unternehmen schon FaaS als Betriebskonzept, welches eine konsequent (und extrem) weitergedachte Entwicklung des Plattformgedankens widerspiegelt: eine maximale Elastizität unter Extrembedingungen erfordert, dass Anwendungen bei Nicht-Verwendung auch auf null runterskalieren können/sollen. Auch eine rasche Skalierung nach oben ist gefordert die Mini-Anwendungen/Functions müssen deutlich unter dem Sekundenbereich starten, wie auch schon durch den neunten Faktor „Einweggebrauch“ nahegelegt.

Allerdings muss bei klarer Betrachtung eingeräumt werden, dass auch der Anwendungsfall entscheidend für die Sinnhaftigkeit des Einsatzes des Serverless-Modells ist: Für bestimmte Anwendungsfälle, in denen fachlich eine Elastizität gefordert ist (Naturereignisse oder wiederkehrende, aber vorhersehbare Lastspitzen, wie z.B. End-of-Day, End-of-Year, und sportliche Ereignisse wie eine Weltmeisterschaft oder der Superbowl) eignet sich der Serverless-Betrieb hervorragend. Letztlich sollte die Entscheidung für ein Cloud-Modell auch stets einer Kostenrechnung standhalten. Hier zeigt sich, ob sich ein Serverless- oder Container-Betrieb je nach Auslastung (sporadische Anfragen und Lastspitzen gegenüber 24/7 mehr oder weniger konstanter Auslastung) eher rechnet oder nicht. Serverless wäre im Prinzip auch eine interessante Alternative für Batchprozesse, funktioniert jedoch nur wenn sich Letztere gut in kleinere unabhängige Teilschritte zerstückeln lassen, denn Serverless-Funktionen sind oft zeitlich limitiert (beispielsweise 15 Minuten bei AWS Lambdas).

Fazit

Während manche Organisationen sicherlich mutmaßen, dass es bei ihnen bereits „fünf(zehn) vor zwölf“ ist hinsichtlich des Gangs in die Cloud oder der Alternative, den Anschluss an die Konkurrenz zu verlieren, hoffen wir, dass wir hier darlegen konnten, dass es bei allen Vorteilen der Cloud wichtig ist, nicht den zweiten Schritt vor dem ersten zu machen, sondern nüchtern zu analysieren, welche potenziellen Hindernisse einer erfolgreichen Cloud-Transformation im Weg stehen und welches Modell das geeignetste ist. Glücklicherweise existieren etablierte Empfehlungen und Kriterien, die dafür zu Rate gezogen werden, allen voran die fünfzehn Faktoren für cloud-native Anwendungen. Zugegebenermaßen ist die Umsetzung dieser Empfehlungen nicht immer einfach und selbst die Beachtung aller fünfzehn Faktoren kann nicht sämtliche Komplexität einer Cloud-Transformationen auflösen. Hier stehen wir unseren Kunden zur Seite und unterstützen Sie auf dem Weg in die Cloud.

Weitere Beiträge