Skalierbares Software Deployment in der Cloud – Teil 1

Im ersten Teil unserer zweiteiligen Artikelserie berichten wir, wie wir mit der Verteilung von Quellcode (”Deployment”) auf automatisch skalierenden Cloud-Plattformen umgehen. Nach einem Exkurs zu den Besonderheiten von Cloud-Umgebungen, schauen wir uns die konkreten Anforderungen an Cloud-Deployment an, beleuchten den root360-Ansatz und zeigen Beispielszenarien auf, welche unabhängig von der eingesetzten Anwendung (Magento, Shopware, Symfony, PHP) funktionieren.

Was ist das Besondere beim Deployment in Cloud-Umgebungen?

Cloud-Umgebungen, wie root360 sie entwickelt, sind kein statisches Setup von Servern mehr, sondern eine Programmierung (“Infrastructure as Code”). Diese Programmierung legt fest, wie die einzelnen Komponenten der Umgebung zusammenspielen werden. Bei den Komponenten handelt es sich um Dienste wie z.B. Datenbanken, Web-Server, Caches, Firewalls oder CDNs. Diese Komponenten werden über APIs eingebunden und sollen austauschbar bleiben. Einige Dienste – z.B. Web-Server – sollen zudem automatisch skalieren können. Diese Anforderungen an flexible und elastische Cloud-Hosting-Umgebungen erfordern auch ein Neudenken der Deployment-Prozesse, schließlich gibt es nicht mehr “den einen” (Web-)Server sondern eine beliebige Anzahl von (Web-)Servern (Multi-Server), die zudem automatisch entstehen und auch wieder verschwinden können.

Welche Anforderungen ergeben sich daraus?

Wir haben in unserer Praxis vor allem folgende Anforderungen identifiziert:

  1. Unterstützung (Auto-)Skalierbarkeit
    Bei automatisch skalierenden Cloud-Hosting-Umgebungen stehen bei ansteigender oder abnehmender Last (z.B. durch Benutzerzahlen) entweder mehr oder weniger Server bereit. Das Deployment-System muss diese Skalierung unterstützen, damit neue Server schnell mit dem richtigen Softwarestand bereitgestellt sowie wegfallende Server sauber entfernt werden können.
  2. Unterstützung gängiger Protokolle
    Die Applikationen müssen auf die Server gelangen, sei es nun aus einem Versionsverwaltungssystem wie Git oder SVN, über Downloads via HTTP und FTP, eine vollständige Dateikopie via rsync oder aus einem Continuous Integration System wie Jenkins. Idealerweise sollte ein Deployment-System diese Quellen und weitere unterstützen können.
  3. Individualisierbare Deployment-Prozesse
    Jede Anwendung hat eigene Feinheiten. Ob es hierbei um das Nachinstallieren von Modulen geht, um die spezielle Konfiguration in der Datenbank oder dem Leeren bestimmter Caches: Das Deployment-System muss derartige (projekt-)spezifische Anpassungen unterstützen können.
  4. Unabhängigkeit vom Cloud-Provider
    Ein Deployment-System sollte unabhängig von einem konkreten Cloud-Provider wie AWS (Amazon Web Services) funktionieren. Somit ist es möglich, das System auch bei anderen Cloud-Anbietern oder ggf. sogar “on premise” einzusetzen.
  5. Unabhängigkeit von externen Quellen
    Eine Störung oder ein Ausfall der externen Systeme (z.B. Github, Kunden-Server), auf denen die Quellcodes liegen, darf die Stabilität der Applikation und die Skalierbarkeit der Systeme nicht beeinflussen. Daher muss das Deployment in hohem Maße Unabhängigkeit von dritten Systemen schaffen.
  6. Stabilität des Prozesses
    Generell müssen Deployment-Prozesse eine hohe Stabilität aufweisen, da sie gleichermaßen essentiell für die Stabilität der Cloud-Umgebung sind. Es muss für den Nutzer klar sein, “wie” er den Prozess auslöst und “welches” Ergebnis er erwarten kann.
  7. Hohe Geschwindigkeit des Deployments
    Zeit ist Geld – auch beim Deployment. Je schneller die Software aufgespielt ist, desto schneller geht der neue Software-Stand online oder wird der nächste Web-Server hinzugeschaltet.
  8. Sicherheit des Quellcodes
    Unabhängig davon, ob auf Cloud oder konventionelle Systeme deployed wird, muss ein Deployment-System bei Transfer und Lagerung des Quellcodes sicherstellen, dass kein unautorisierter Zugriff auf ebendiesen erfolgen kann.

Wie sieht die root360 Lösung für Cloud-Deployment aus?

Mit unserem skalierbaren Deployment stellen wir ein Verfahren bereit, welches sich in herkömmliche Deployment-Mechanismen integrieren lässt. Hierbei machen wir beim generellen Ansatz zunächst keine Unterschiede, ob es sich um Magento, Shopware oder um eine PHP/Symfony/Java Applikation handelt.

Schauen wir uns den Workflow eines Deployments für skalierbare Umgebungen an:

  1. Herunterladen und Vorbereiten des Quellcodes (z.B. Git über SSH)
  2. Zwischenspeichern des Quellcodes in Form eines Archivs in einem zentralen Speicher (z.B. AWS S3)
  3. Hochladen des Quellcodes auf die Web-Server
  4. Starten spezifischer Installations-Routinen und Aktivierung des neuen Quellcodes
  5. Hinzufügen der fertig installierten Server zum Loadbalancer (z.B. AWS ELB)

Dieser Workflow wird über ein Skript auf einem sogenannten “Jump-Server” gestartet. Der Server ist der Zugangspunkt zu den root360 Cloud-Umgebungen und über SSH erreichbar.

Technisch betrachtet durchläuft der Prozess jeden in sich geschlossenen Schritt durch, arbeitet dabei mit festgelegten Eingabedaten und erzeugt definierte Ausgabedaten. Dem Prozess liegt ein modularer Aufbau zugrunde. Dieser ermöglicht eine Anpassung des gesamten Prozesses an konkrete Gegebenheiten (weitere Prozessschritte, Quellen der Anwendung, Installationsprozesse). Mit dieser Flexibilität ist es z.B. möglich, Dienste wie AWS S3 oder den AWS Loadbalancer durch andere Mechanismen zu ersetzen, in dem der entsprechende Teilschritt angepasst wird.

Dieser gesamte Ablauf ist in der folgenden Grafik ersichtlich. Hinter dem Prozess steht eine Kombination aus python-basierten Tools und dem Konfigurationsmanagementsystem Saltstack. Besonders vom Saltstack-Returner-System wird durch eine spezielle python-Library umfassend Gebrauch gemacht.

root360 cloud deployment

Durch das Zwischenspeichern der Applikation an einem zentralen hochverfügbaren und sicheren Speicherort ist die (Auto-)Skalierbarkeit jederzeit gewährleistet und unabhängig von der externen Datenquelle (z.B. GitHub). Eine hohe Performance wird neben der systemtechnischen Nähe außerdem durch Komprimierung der Daten begünstigt.

Durch einen modularen Aufbau können verschiedene Protokolle unterstützt, ähnlich einem Plug-In-System erweitert sowie Software-spezifische Installationsroutinen realisiert werden. Des Weiteren wird durch weitgehend eigenständig funktionsfähige Module das Deployment-System von produktiven Komponenten entkoppelt. Eine Störung des Deployment-Systems stellt damit nicht zwingend auch eine Gefahr für den produktiven Betrieb der Software und ihrer Skalierbarkeit dar. Die Stabilität der Prozesse wird durch die Verwendung von Standard-Bibliotheken und hochverfügbare Konfigurationsmanagementsysteme (Saltstack) gewährleistet. Eine Unabhängigkeit von Cloud-Provider-spezifischen Systemen wird dadurch ebenfalls möglich und bietet sogar die Möglichkeit, das Verfahren in on-premise Rechenzentren oder bei anderen (Cloud/Hosting) Providern als Amazon AWS zur Anwendung zu bringen.

Neben einem konsequent verschlüsselten Datentransfer (z.B. Git über SSH, HTTPS und ZeroMQ) unterstützen auch Amazon AWS Technologien die Sicherheit des Quellcodes der Software. Umfangreiche Firewalling und Authentifizierungs-, sowie Autorisierungssysteme bilden die Grundlagen eines umfassenden Sicherheitkonzepts für alle Komponenten und Daten.

Beispielszenarien

Nachfolgend finden sich zwei Szenarien, bei denen wir uns beispielhaft  auf Amazon Web Services (AWS) beziehen. Das erste Beispiel zeigt einen einfachen Workflow mit Git, während das zweite Beispiel ein etwas komplexeres Szenario mit einem Continuous Integration System wie Jenkins zeigt.

Workflow für ein einfaches Setup mit Git

root360 cloud deployment workflow für einfaches Setup mit Git

  1. Entwickler checkt Code in Github ein
  2. Entwickler startet Deploymentprozess auf Jump-Server
  3. Quellcode wird von Github heruntergeladen
  4. heruntergeladener Quellcode wird für das Deployment vorbereitet und in zentralen Speicher (z.B. AWS S3) hochgeladen
  5. vorbereiteter Quellcode wird auf die Web-Server geladen
  6. kundenspezifische Installationsroutine wird gestartet und bei erfolgreichem Ende der neue Quellcode aktiviert
  7. fertig installierter Server aktiviert sich im Loadbalancer (z.B. AWS ELB)

Workflow für ein komplexeres Setup mit Jenkins

root360 cloud deployment workflow für komplexes Setup mit Jenkins

  1. Entwickler checkt Code in Github ein
  2. Git-Hook startet Jenkinsjob zum Testen und Bauen der Anwendung
  3. Jenkins baut die Anwendung erfolgreich zusammen und stellt sie zum Download bereit
  4. Jenkins startet Deployment-Prozess auf Jumpserver
  5. Quellcode wird vom Jenkins heruntergeladen
  6. heruntergeladener Quellcode wird für das Deployment vorbereitet und in zentralen Speicher (z.B. AWS S3) hochgeladen
  7. vorbereiteter Quellcode wird auf die Webserver geladen
  8. Kunden spezifische Installationsroutine wird gestartet und bei erfolgreichem Ende wird der neue Quellcode aktiviert
  9. fertig installierter Server aktiviert sich im Loadbalancer (z.B. AWS ELB)

Wie sieht die Zukunft aus?

Wir entwickeln das Deployment-System stetig weiter, wobei die Roadmap agil gehalten wird. So kam vor kurzem die Unterstützung von Pre- und Post-Deployment-Hooks dazu, wodurch sich z.B. das Leeren eines zentralen Varnish Caches direkt nach dem Deployment durchführen lässt. Desweiteren ist die Unterstützung weiterer Protokolle neben GIT oder HTTP geplant. Zusätzlich wird es zukünftig auch ein Dashboard über ein Webinterface geben, in dem Deployments durchgeführt und überwacht werden können.

Im zweiten Teil der Artikelserie geben wir einen Einblick in die technischen Details des Systems. Stay tuned :)!

Verpassen Sie keinen Cloud-Artikel mehr. Jetzt für unseren Newsletter anmelden!

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.