devops

Serverless-Deployment mit Docker vereinfachen

INTEGRTR Team · 26. August 2020

Dieser Beitrag wurde aus dem englischen Original übersetzt.

Serverless-Anwendungen und Docker sind seit einigen Jahren die Schlagworte schlechthin. Vor ein paar Jahren gab es im Grunde nur eine Möglichkeit, eine Produktivanwendung auszurollen: eine EC2-Instanz hochfahren und den Server hinter einem nginx oder einem Load Balancer betreiben, der den Traffic auf die einzelnen Anwendungsserver verteilt.

Dann kam Docker. Docker hat die Art, wie wir alle auf Deployment blicken, vollständig verändert.

Das nie endende Problem umgebungsspezifischer Bugs begann endlich zu verschwinden, denn der zentrale Anwendungsfall, den Docker gelöst hat, war dieser:

Nach Docker müssen Sie sich keine Gedanken mehr darüber machen, dass etwas auf Ihrer Maschine läuft, in der Produktionsumgebung aber nicht. Es ist exakt dieselbe Maschine mit exakt derselben Konfiguration, die in allen Umgebungen läuft. Ihr Code wird immer einmal gebaut, und dasselbe Image wandert anschließend ohne weitere Änderungen durch die verschiedenen Umgebungen. Das hat SREs und DevOps-Engineers ebenso wie Entwicklern beim Bauen einer Anwendung enorme Sicherheit gegeben.

Zeitgleich mit dem Aufkommen von Docker gewann eine weitere großartige Technologie enorm an Popularität: Serverless-Anwendungen. Serverless-Anwendungen, auch bekannt als FaaS (Function as a Service), sind einer dieser Pay-as-you-go-Dienste, bei denen Sie sich weder um die Kosten noch um die Skalierbarkeit Ihrer Anwendung sorgen müssen. Eine Serverless-Architektur bietet Ihnen eine Plattform, um ein bestimmtes Stück Code auszuführen; ist die Ausführung beendet, räumt sie sich selbst ab, ohne dass Sie an Geld denken müssen, das sie im Leerlauf verbrennt. Das gab Entwicklern die Freiheit, hochgradig skalierbare Services zu schreiben, ohne sich um horizontale Skalierung zu kümmern.

Deployment-Pipeline für Code

Mit coolen Technologien wie Docker war es plötzlich kinderleicht, beliebig viele Umgebungen hochzuziehen, ohne alles manuell einrichten zu müssen. Sie brauchen nur Docker auf dem System, und schon können Sie mit docker run loslegen.

Also fingen die Leute an, mehrere Umgebungen für ihre Anwendungen aufzusetzen. Häufig entstanden dev, staging, qa und production, wobei in jeder Stufe unterschiedliche Personen in der Organisation die Anwendung testen und für den nächsten Schritt freigeben.

Zum Beispiel:

  1. dev – Wird in der Regel intern von den Entwicklern genutzt. Sie pushen sehr häufig neue Codeänderungen und testen sie untereinander auf einem entfernten Server.
  2. staging – Sobald die Entwickler mit den Bugs zufrieden sind, die sie als Features verkaufen können, wandern die Dinge nach Staging. Dort können sich dann vermutlich die Produktmanager über die Farbe der Buttons beschweren.
  3. qa – Sind die Produktmanager mit den Farben zufrieden, geben sie frei und es geht in die QA-Umgebung, wo das QA-Team die Features auf die ungewöhnlichsten Arten testet, die man sich denken kann.
  4. production – Bestätigt die QA schließlich, dass alles auf Herz und Nieren geprüft ist, geht der neue Code in die Produktionsumgebung für die echten Nutzer.

Nun entwickeln verschiedene Unternehmen unterschiedliche Deployment-Pipelines, je nachdem, wie ihre Organisation aufgestellt ist. Ist das Team sehr schlank und gibt es kein QA-Team, kann diese Stufe einfach entfallen.

Diese Pipeline gibt große Sicherheit, dass alles, was die letzte Stufe erreicht, gründlich erprobt wurde. In Kombination mit Docker liefert die Deployment-Pipeline sogar doppelte Sicherheit, weil Sie immer wissen, dass dasselbe Image durch die Pipeline wandert und in allen Stufen exakt dieselbe Umgebung nachbildet.

Warum nicht Serverless mit Docker?

Da wir nun verstehen, wie viel Sicherheit uns Docker zusammen mit einer Deployment-Pipeline gibt, stellt sich die Frage: Warum nicht etwas Ähnliches auch für Serverless-Anwendungen? Nun, genau diese Frage kam vor ein paar Monaten in unseren internen Tech-Chats auf 😉

Es gibt dieses großartige Tool serverless, mit dem Sie Serverless-Anwendungen mit nur wenigen Befehlen ausrollen. Es bündelt Ihre Codebasis und deployt Ihre Serverless-Anwendung zu einem beliebigen Cloud-FaaS-Anbieter wie Google Cloud Function, AWS Lambda oder Azure Functions. Sie können sogar eine CI/CD-Pipeline einbinden, die Ihren Code deployt, sobald Sie auf einen bestimmten Branch pushen. Aber wäre es nicht großartig, denselben Pipeline-Mechanismus zu haben, um Änderungen in verschiedenen Stufen freizugeben? Natürlich wäre es das, und es gibt bereits einen Weg dorthin: das branch-basierte Deployment. Dabei pushen Sie Code in einen bestimmten Branch, und dieser Branch deployt in die zugehörige Stufe. Das funktioniert zwar, wirft aber eine Menge Probleme auf:

  1. Sie müssen stets im Blick behalten, wie die Pipeline durch die Branches fließt. Bei 4 Stufen brauchen Sie also immer diese 4 Branches in Ihrer Versionsverwaltung. Und Sie müssen manuell sicherstellen, dass immer der richtige Branch auf den passenden Branch gemergt wird, sonst entsteht ein Sprung in der Pipeline.
  2. Wer Zugriff hat, kann direkt in jeden beliebigen Branch pushen. Das führt zu inkonsistentem Code in den Stufen.
  3. Branch-basierte Deployments können immer wieder neue Merge-Konflikte hervorrufen. Es ist Aufgabe der mergenden Person, sicherzustellen, dass keine Konflikte bestehen.
  4. Für jemanden, der mit Versionsverwaltung nicht vertraut ist, ist das alles andere als selbsterklärend. Bei Pipelines kann selbst der Produktmanager einfach vorbeikommen, auf einen Knopf drücken, und es funktioniert wie von Zauberhand. Hier dagegen muss man wissen, wie Versionsverwaltung arbeitet.
  5. Je mehr Stufen, desto mehr Branches. Ohne enge Pflege wird daraus schnell ein unentwirrbares Durcheinander.

Wie Docker hilft

Da wir bereits besprochen haben, dass Docker immer sicherstellt, dass derselbe Code durch die verschiedenen Stufen wandert, können wir vermutlich beides zusammenführen: die Flexibilität von Serverless-Anwendungen und dieselbe Sicherheit beim Deployment über verschiedene Stufen.

Die Idee dahinter: Mit Docker sollten wir den Code einmal bündeln und denselben Code durch die verschiedenen Stufen bewegen können. Dazu gehen wir wie folgt vor:

  1. Ein Docker-Base-Image verwenden, auf dem serverless installiert ist.
  2. Den zu deployenden Code in ein Docker-Image kopieren und dieses speichern.
  3. Dasselbe Image für das Deployment in die verschiedenen Stufen verwenden.

Setup: serverless mit Docker

Base Image

Wir verwenden das obige Base Image, um unsere Lambda zu deployen. Um dieses Base Image in einem Ihrer Dockerfiles zu nutzen, gehen Sie wie folgt vor:

  • Legen Sie das obige Dockerfile in einem GitHub-Repository ab
  • Gehen Sie zu https://hub.docker.com
  • Legen Sie ein neues Repository an:
  • Tragen Sie die relevanten Angaben ein und halten Sie es öffentlich, um die Sache einfach zu halten
  • Wählen Sie das Repository aus, in das Sie Ihr Base Image gepusht haben
  • Klicken Sie auf Create and Build

Anlegen eines neuen Repositorys in DockerHub

Damit sollte Ihr Base Image gebaut und auf Docker Hub gehostet werden, sodass Sie es in jeder Ihrer Anwendungen nutzen können.

Unser neues serverless-docker-Repository

Über Ihren Benutzernamen und den Repository-Namen können Sie es dann in jedes Ihrer Dockerfiles ziehen.

Dockerfile für Ihre Lambda

Ein Dockerfile ist alles, was Sie brauchen, um Ihre Anwendung zu bündeln. Es sollte Ihre Codebasis kopieren und alle Abhängigkeiten installieren. Ist das Image gebaut, können Sie es in jede beliebige Docker-Image-Registry legen, etwa AWS Elastic Container Service, Docker Hub oder GCP Container Registry, je nachdem, auf welcher Cloud-Infrastruktur Sie unterwegs sind.

Images durch die Stufen befördern

Um es durch die verschiedenen Stufen zu befördern, muss es in eine Umgebung deployt werden, ohne den Code zu verändern oder anzufassen. Dazu müssen wir ihm einige Umgebungsvariablen mitgeben:

AWS_SECRET_ACCESS_KEY und AWS_ACCESS_KEY_ID geben dem Docker-Container die Zugriffsrechte, die er zum Deployen braucht. Die Variable STAGE hilft der serverless-Konfiguration, die Funktion passend zu benennen. So können Sie beim Deployment mehrerer Stufen diese auf der Übersichtsseite der Cloud Functions allein am Namen unterscheiden.

Wie Sie die Datei serverless.yml konfigurieren, erfahren Sie hier.

Um die Anwendung zu deployen, müssen Sie nun nur noch Folgendes tun:

Sobald Sie die Variablen durch die passenden Werte ersetzt haben, sollte Ihre Anwendung ausgerollt sein. Für das Deployment zu anderen Cloud-Anbietern wie GCP oder Azure brauchen Sie vermutlich anbieterspezifische Umgebungsvariablen, um die IAM-Rollenautorisierung herzustellen.

Die Integrität der Pipeline wahren

Nun stellt sich die Frage: Wenn man direkt in jede beliebige Stufe deployen kann, wie stellen wir dann sicher, dass alles in genau der Reihenfolge des ursprünglichen Entwurfs weitergereicht wird? Dafür müssen Sie einen Pipeline-Flow über Jenkins oder eine andere CI/CD-Plattform entwerfen, der das Weiterreichen des Images reglementiert. Dessen Konfiguration ist eine Geschichte für sich, über die wir bald in einem eigenen Blogbeitrag sprechen.

Fazit

So faszinierend das alles klingen mag: Man sollte sein Deployment und seine Codebasis nie überkonstruieren. Wenn Ihr aktuelles Setup in einem kleinen Team gut funktioniert, braucht es möglicherweise keine komplexe DevOps-Pipeline, deren Einarbeitung selbst wieder Zeit kostet. Jedes Team hat eigene Anforderungen und Bedürfnisse, und man sollte diese Technologien nicht einsetzen, nur um der coole Kid auf dem Block zu sein.

Die oben beschriebene Architektur und das Setup funktionieren für uns hervorragend, weil sie uns Folgendes ermöglichen:

  1. Die gesamte Pipeline aus der Vogelperspektive im Blick behalten, allein durch das Einloggen in unser Jenkins-Dashboard.
  2. Als schlankes Team war es für uns eine einmalige Einrichtung, die uns enorme Kontrolle darüber gibt, was in welche Stufe wandert, und ein sauberes Review und Weiterreichen ermöglicht.
  3. Als vollständig remote und asynchron arbeitendes Team kann selbst ein Produktmanager oder eine nicht-technische Person bei uns per Knopfdruck und ohne fremde Hilfe Dinge nach Produktion befördern.

Ähnliche Beiträge

Das könnte Sie auch interessieren

Aktualisieren Sie Ihre Unternehmensintegration.

Mit zunehmender Effizienz bei Digitalisierung und Datenfluss erwarten Sie einen höheren Unternehmenswert und eine bessere Wettbewerbsfähigkeit.