Serverless - Hat der klassische Webserver ausgedient?

Den meisten Entwicklern ist der Begriff serverless sicherlich schon mal über den Weg gelaufen. Doch was bedeutet er eigentlich? Ins Deutsche übersetzen kann man den Begriff etwa mit Serverlos oder ohne Server. Doch das ist eigentlich nicht ganz zutreffend. Denn auch bei einer serverlosen Anwendung werden weiterhin Server für den Betrieb und das Bereitstellen benötigt.

In diesem ersten Teil der Blog-Serie zum Thema Serverless möchte ich euch die Grundlagen von Cloud und Serverless Computing vorstellen. Falls du also planst deine nächste Applikation serverless umzusetzen, eine bestehende App migrieren willst oder einfach nur wissen willst, was es mit serverless auf sich hat, bist du hier genau richtig!

Die Zukunft heißt Cloud

Die Cloud ist heutzutage eng mit der Entwicklung von Webanwendungen verknüpft. Kaum eine Software kommt heute noch ohne eine Verbindung zum Internet aus. Meist werden hierfür eigene Backend-APIs implementiert, um z.B. das Speichern und Tracking von Benutzerdaten oder das Laden bestimmter Inhalte zu ermöglichen. Die Architektur des Backends hängt dabei maßgeblich vom jeweiligen Einsatzzweck ab und verwendet dementsprechend geeignete Programmiersprachen und Frameworks.

Bis Anfang des 21. Jahrhunderts wurden die Backend-Systeme typischerweise über dedizierten Rechenzentren bereitgestellt (engl. on premise, also “vor Ort” betrieben). Doch seitdem Amazon mit den Amazon Web Services (AWS) im Jahr 2006 die Dienste AWS EC2, S3 und SQS vorstellte, sind Cloud-Lösungen unaufhaltsam auf dem Vormarsch. Auch andere namhafte Unternehmen wie Microsoft, IBM und Google bieten ihren Kunden mittlerweile passgerechte Lösungen in der Cloud an.

Die Vorteile liegen auf der Hand: Anstatt sich selbst um das Betreiben und die Instandhaltung der notwendigen Netzwerk- und Serverkomponenten zu kümmern, überlässt man diese meist zeit- und kostenintensiven Aufgaben dem Cloud-Anbieter. Das bietet - insbesondere auch für kleine Unternehmen und Start-Ups - die Möglichkeit auf eine professionelle und erschwingliche IT-Infrastruktur zurückgreifen zu können, die nach den eigenen Bedürfnissen konfiguriert und bei Wachstum nahezu beliebig skaliert werden kann. Wie wir aber gleich noch sehen werden, bietet die Cloud weit mehr als nur Netzwerk- und Serverkomponenten.

Was bedeutet Cloud eigentlich?

Der Begriff Cloud kann leider nicht klar definiert werden. Im Consumer-Bereich wird er meist synonym für eine externe, über das Internet verbundene Datenablage verwendet. Als Beispiele seien hier Dienste wie iCloudOneDriveDropbox oder Google Drive genannt, die es dem Nutzer ermöglichen von überall auf seine Daten zuzugreifen und diese bei Bedarf auch für einzelne Personengruppen oder frei zugänglich zu machen. Im weiteren Sinne beschreibt der Begriff Cloud ein Netzwerk aus Servern, das sich über mehrere Rechenzentren an verschiedenen Standorten der Erde verteilt und somit eine globale Erreichbarkeit sicherstellt.

Cloud Computing hingegen lässt sich sehr wohl definieren:

Cloud computing is a model for enabling ubiquitous, convenient, on-demand network access to a shared pool of configurable computing resources (e.g. networks, servers, storage, applications, and services) that can be rapidly provisioned and released with minimal management effort or service provider interaction.

(Quelle:NIST)

Cloud Computing - Anything-as-a-Service?

Um die diversen Angebote und Dienstleistungen voneinander abgrenzen zu können kann man diese in drei Dienstleistungsmodelle (engl. service model) aufteilen, die wie Schichten aufeinander aufbauen. In Funktion und Umfang unterscheiden sich diese aber teilweise sehr deutlich.

  1. Software-as-a-Service (SaaS): Die erste und wohl auch den meisten Endanwendern vertrauteste Schicht nennt sich Software-as-a-Service. Typischerweise handelt es sich hierbei um eine Softwarekomponente die als leichtgewichtige App auf dem Endgerät des Anwenders oder direkt im Webbrowser läuft. Ein aufwändiges Installieren und Konfigurieren der App entfällt vollständig und der Endbenutzer kann direkt durchstarten. Auch die zugehörigen Programmierschnittstellen (APIs) können unter den Begriff SaaS fallen. Bekannte Beispiele hierfür sind die bereits erwähnten Cloud-Dienste wie Dropbox und Co. Aber auch anderer Softwareangebote wie Slack, Microsoft 365 und Netflix ebenso wie spezialisierte Tools wie AWS Rekognition für Objekt- und Gesichtserkennung und Google Analytics zur Analyse des Datenverkehrs auf der eigenen Website können als SaaS klassifiziert werden.
  2. Platform-as-a-Service (PaaS): Diese Schicht richtet sich in erster Linie an Entwickler und Betreiber webbasierter Software. Paas bietet Lösungen für die unkomplizierte Bereitstellung und den Betrieb von Applikationen auf Basis einer virtuellen Platform die bereits eine voll funktionsfähige Laufzeitumgebung sowie die wichtigsten Komponenten mitbringt. Hierbei werden gängige Programmiersprachen unterstützt und darüber hinaus lassen sich teilweise auch ganze Server-Stacks aus Load-Balancer-, Server- und Datenbank-Instanzen per Knopfdruck bereitstellen. Beispiele für PaaS Angebote sind AWS Elastic Beanstalk, Azure App Service und Heroku.
  3. Infrastructure-as-a-Service (IaaS): Die letzte Schicht liefert die Basis für alle darüber liegenden Cloud Computing Angebote. IaaS richtet sich eher an Systemadministratoren und umfasst die Provisionierung und Bereitstellung von (virtuellen) Netzwerkkomponenten, Servern und Netzwerkspeicher. Die tatsächlich darunter liegende Cloud-Infrastruktur wird hierbei durch eine weitere Abstraktionsebene vom Benutzer getrennt und vom Cloud-Anbieter selbst verwaltet und instand gehalten. AWS Elastic Compute Cloud (EC2) ist sicherlich eines der bekannteren Beispiele. Aber auch Dienste wie Google Compute Engine, IBM Cloud Virtual Servers und DigitalOcean Droplets zählen als IaaS.

Allen drei Schichten gemein ist, dass sich der Benutzer nicht um das jeweils darunter liegende Dienstleistungsmodell kümmern muss. Diese Aufgabe wird vollständig vom Cloud-Anbieter übernommen. Ein weiteres Merkmal ist, dass der Benutzer nur für die tatsächlich konsumierten Leistungen zahlen muss (engl. pay as you go).

Um dem Endanwender also eine digitale, Cloud-basierte Softwarelösung anbieten zu können, müssen unterm Strich alle drei Schichten implementiert sein. Es hängt letztendlich von verschiedenen Faktoren ab, auf welche der drei Dienstleistungsmodelle man die eigene Applikation aufsetzt und was man lieber dem Cloud-Anbieter überlassen möchte. Hierzu zählen unter anderem die internen Kenntnisse und Fähigkeiten des Projektteams, der geplante Zeitaufwand und der gewünschte Grad an Flexibilität.

Oftmals kann allerdings auch eine Kombination der verschiedenen Dienstleistungsmodelle der richtige Weg für die eigene Softwareanwendung sein.

Function-as-a-Service als neues Dienstleistungsmodell

PaaS-Angebote sind oftmals die erste Wahl, wenn es um die Entwicklung einer konventionellen Webanwendungen geht. Sie bringen bereits alle Werkzeuge mit die zum Bauen, Bereitstellen, Betreiben und Skalieren notwendig sind. Dennoch gibt es einige Kritikpunkte an diesem Ansatz:

Egal ob Container, ausführbare Datei oder Skript: Alle Varianten basieren auf einer oder mehreren Instanzen, die zuvor reserviert und hochgefahren werden müssen. Das reicht von der einzelnen Serverinstanz bis hin zum ausgewachsenen Kubernetes-Cluster. Trotz Autoscaling führt dies im Allgemeinen zu einer gewissen Trägheit. Insbesondere bei selbstverwalteten Systemen kann diese Trägheit zu erheblichen Kosten führen, wenn z.B. auf Nachfrage-Maxima Leerlaufzeiten folgen, in denen zuvor bereitgestellte Instanzen nicht mehr ausgelastet sind oder im schlimmsten Fall gänzlich überflüssig werden. Dieses Problem entsteht ebenso durch eine übermäßige Bereitstellung von Ressourcen (engl. over-provisioning), um im Falle von unvorhergesehenen Ereignissen kurzfristig noch genügend Reserven zu haben oder um die generelle Ausfallsicherheit des Systems zu erhöhen.

Um eben diesen Problemen entgegenzuwirken, hat Amazon mit AWS Lambda im Jahr 2014 ein neues Dienstleistungsmodell vorgestellt, welches als Function-as-a-Service (FaaS) bezeichnet werden kann. Die entscheidende Neuheit hierbei war, dass der Quellcode nur als unmittelbare Reaktion auf ein zuvor festgelegtes Ereignis ausgeführt wird (ereignisbasiert). Ereignisse können z.B. HTTP-Anfragen, Datenbankänderungen, Nachrichten in einer Queue oder ein manuelles Auslösen der Funktion sein. Damit ist es also nicht mehr notwendig dauerhaft eine Serverinstanz zu betreiben, die auf eingehende Anfragen wartet, um diese dann zu bearbeiten (instanzbasiert).

Technisch gesehen wird bei FaaS ein zustandsloser, kurzlebiger Container gestartet, in dem der Code ausgeführt wird. Der Container wird jedoch vollständig vom Cloud-Anbieter verwaltet. Der Entwickler hat damit zwar auch keinen Einfluss mehr auf den Lebenszyklus des Containers, er bekommt jedoch eine isolierte Laufzeitumgebung bereitgestellt, in der er den Anwendungscode nach Belieben ausführen lassen kann.

Die Abrechnung erfolgt üblicherweise ebenso auf Ereignisebene, wodurch Kosten nur durch die Anzahl der tatsächlich verarbeiteten Anfragen und der damit direkt verbundenen Rechenzeit bzw. benötigter Kapazität verursacht werden (engl. pay per request).

Die Anwendungsgebiete von FaaS reichen von der Auslagerung einzelner Funktionen die wiederum als SaaS von anderen Diensten konsumiert werden können bis hin zur Implementierung vollständiger APIs, die die Verarbeitung sämtlicher Benutzerinteraktionen für ein System übernehmen.

Ist FaaS die Lösung aller Probleme?

Nein, denn auch FaaS hat seine Grenzen und Fallstricke. So ist beispielsweise die maximale Ausführungsdauer einer Lambda Funktion auf aktuell 15 Minuten beschränkt. Länger andauernde Prozesse müssen entweder aufgeteilt oder anderweitig verarbeitet werden.

Ein weiterer Nachteil besteht in der tendenziell höheren Latenz im Vergleich zu instanzbasierten Lösungen. Denn bevor die Funktion ausgeführt werden kann müssen noch weitere Schritte unternommen werden. Anwendungscode und -konfiguration existieren zunächst nur als Dateien in einem Cloud-Speicher. Das heißt der Code muss heruntergeladen werden und auf einem Server mit freier Rechenkapazität muss ein Container entsprechend der hinterlegten Konfiguration gestartet werden. Anschließend muss auch noch die Laufzeitumgebung für den Code initialisiert werden bevor schlussendlich der Code ausgeführt werden kann. Diese Latenz ist auch als “Kaltstart” (engl. cold start problem) bekannt.

Damit dieser Prozess nicht bei jeder Ausführung einer Funktion wiederholt werden muss, werden einmal initialisierte Instanzen für einen kurzen Zeitraum zurückgehalten. Diese “warmen” Instanzen können dann ohne Latenz direkt ausgeführt werden. Demnach steigt also die Wahrscheinlichkeit eine warme Instanz für die Verarbeitung eines Ereignisses zu bekommen, wenn kurz zuvor bereits eine Instanz benötigt wurde.

Letztendlich übernimmt allerdings der Cloud-Anbieter hierbei die volle Kontrolle darüber, wann genau eine Instanz gestartet und wieder gestoppt wird. Zusätzliche Kosten fallen für dieses “warmhalten” im Allgemeinen nicht an. Die meisten Cloud-Anbieter bieten darüber hinaus aber auch die Möglichkeit, eine bestimmte Anzahl an Instanzen ständig warm zu halten - das dann allerdings gegen Aufpreis.

Für die meisten Anwendungsfälle wird dieser Kaltstart nicht nennenswert ins Gewicht fallen. Für zeitkritische Anwendungen, die in Echtzeit auf ein Ereignis reagieren müssen, sind diese Latenzen aber ggf. bereits zu hoch. Hier sollte besser auf instanzbasierte Lösungen zurückgegriffen werden.

Ein letzter Hinweis, den es bei FaaS zu beachten gilt, bezieht sich auf die Zustandslosigkeit der Funktionen (engl. stateless): Anders als bei Containern wird keine Gewähr dafür übernommen, dass bestimmte Daten und Werte über den Ausführungszeitraum der eigentlichen Funktion hinweg verfügbar sind. Dadurch können z.B. Probleme bei der Anbindung von SQL-Datenbanken entstehen. Der initiale Aufbau einer Datenbankverbindung ist im Vergleich zur Anfrage deutlich aufwändiger. Daher werden beim Starten der Anwendung meist direkt mehrere Datenbankverbindungen hergestellt, um diese dann bei nachfolgenden Anfragen verwenden zu können (engl. connection pooling). Wird die Funktionsinstanz allerdings nicht warmgehalten, lohnt sich auch der Aufwand des Connection Poolings meist nicht.

Serverless Computing - Mehr als nur Marketing?

Die Cloud-Anbieter haben daher spezielle Dienste im Angebot, die sich nahtlos in eine FaaS-Implementierung integrieren lassen. Meist werden diese Dienste dann unter der Bezeichnung serverless oder serverless computing angepriesen. Bei genauerer Betrachtung stellt sich aber heraus, dass auch serverless computing nichts anderes, als eine spezialisierte Form von PaaS darstellt die Zwecks Marketing gesondert vertrieben wird.

Es gibt aber auch einige Eigenschaften die typisch für Serverless Computing sind. So ist der Cloud-Anbieter hierbei insbesondere verantwortlich für das Bereitstellen der Cloud-Infrastruktur, sowie für operative Aufgaben. Diese umfassen die Bearbeitung und Weiterleitung von Netzwerkanforderungen ebenso wie das automatische Skalieren, Wiederherstellen und Überwachen des Systems.

Die Kosten werden üblicherweise auch hier wieder auf Basis der anfallenden Anfragen berechnet. Leerlaufzeiten können demnach gänzlich vermieden werden und die Anwendung skaliert sich selbst linear zur eintreffenden Last. Aus Sicht des Anwenders ist es somit nicht mehr notwendig dauerhaft laufende Serverinstanzen bereitzustellen, da sich der Cloud-Anbieter mit den verschiedenen Diensten um alles Notwendige kümmert.

Typischerweise beinhaltet eine serverlose Architektur folgende Dienste:

  • mehrere Recheneinheiten des FaaS-Dienstes
  • Content Delivery Networks (CDNs), Load Balancer und HTTP-APIs zum Entgegennehmen externer Anfragen
  • Event-Busse und Message Queues für eine asynchrone Kommunikation zwischen Komponenten
  • dokumentenorientierte Datenbanken und Cloud-Speicher für die Speicherung der Anwendungsdaten
  • Zustandsautomaten für die Orchestrierung mehrerer Funktionen

Na dann, weg mit den Servern!

Die Vorteile einer serverlosen Systemarchitektur sind vielseitig: Neben teilweise deutlich reduzierten Betriebskosten fallen auch Instandhaltungskosten weg, da sich der Cloud-Anbieter um Patches und Updates kümmert. Ferner werden dadurch auch Sicherheitslücken schneller und ohne weitere Benutzerinteraktion geschlossen. Darüber hinaus kann auch die Entwicklerproduktivität gesteigert und gleichzeitig die Veröffentlichungszyklen verkürzt werden. Daher ist es nicht verwunderlich, dass Serverless Computing in den letzten Jahren zunehmend an Fahrt aufgenommen hat und mittlerweile eine deutlich höhere Wachstumsrate als herkömmliche PaaS-Ansätze hat.

In den nächsten Teilen der Blog-Serie werde ich dann ein konkretes Beispiel vorstellen bei dem die Migration einer Anwendung von AWS Elastic Beanstalk auf das Serverless Application Model (SAM) vollzogen wurde. Hierbei werde ich insbesondere auf die Architektur und die Erkenntnisse der Migration eingehen.

Holger Janßen-Kroll

Technology Lead: Architectureholger.janssenkroll@aleri.de
Stephan Lotter, Aleri

Stephan Lotter

IT Specialiststephan.lotter@aleri.de
Seite teilen