DevOps und Container – Umgebungen und Unveränderlichkeit

Liebe – Nach einer wahren Begebenheit

DevOps an sich ist nicht an eine Technologie gebunden, jedoch haben sich Container-Technologien und DevOps als Verwandte im Geiste gefunden. Dies geht soweit, dass namhafte Autoren diese als zusammengehörend betrachten, obwohl beide Komponente völlig unabhängig voneinander nützlich sind.

Dieser Ansatz hat sich insbesondere im Web-Umfeld etabliert, da oftmals die Client- und Server-Komponenten getrennt sind und so entsprechend einzeln skaliert und installiert werden können. In den nachfolgenden Beispielen werden daher folgende Technologien verwendet:

  • Docker
  • Angular
  • Net Core

​Doch wieso passen überhaupt ein hippes Prozess-Kunstwort ohne genaue Definition und eine Virtualisierungsstechnologie so gut zusammen? Dies hat diverse Gründe, wobei nachfolgend einige gute Argumente zu finden sind.

Kein “works on my machine” mehr

Ein Image, eine Vorlage für ein Container, ist nach der Erstellung unveränderbar. Wir haben somit eine Garantie, dass wir dieselben Artefakte von der Test-Umgebung bis in die Produktion verwenden. Dies ist im DevOps Umfeld besonders wichtig, da durch den Anspruch, dass Installationen zeitnah und in kurzen Abständen erfolgen müssen, keine größeren Probleme oder Unterbrechungen auftreten dürfen.

Bildnachweis Foliensatz Berner Fachhochschule CAS Application Lifecycle Management

It’s magic – Automatisierung im großen Stil

Docker setzt auf deklarative Automatisierung: Wir definieren anhand von versionierbaren und lesbaren Dateien sowohl was wir in unseren Containern haben möchten, als auch wohin, wie und in welcher Anzahl diese installiert werden sollen. Bekannte DevOps Tools wie Azure DevOps lesen und verwenden diese Dateien, um diese Container zu erstellen und auf beliebige Systeme zu installieren. Da eine hohe Automatisierung einer der Grundpfeiler von DevOps ist, haben wir so das Risiko von Fehlern bei der Erstellung oder dem Verteilen von Artefakten praktisch entfernt.

Sie werden so schnell groß – Umgebungen auf Zuruf

Agilität im DevOps Umfeld bedeutet auch, dass wir Umgebungen bei Bedarf innerhalb von Minuten initialisieren, verwenden und wieder herunterfahren wollen. Auch sollten diese Umgebungen bitte einfach skalierbar sein, permanent überwacht werden, nichts kosten und das Ganze in Grün!

Dies ist genau der Anwendungszweck von Containern: Diese sind in sich geschlossene Einheiten, die durch einzelne Kommandos skaliert, gestoppt und gestartet werden können. Dazu kommen Überwachungstools, die Probleme feststellen, Container bei Bedarf starten, die Lasten verteilen und viele weitere Tasks durchführen.

Teil 2: Die Realität schlägt zurück

Die oben genannten Punkte klingen großartig, doch gibt es in der Praxis einige Probleme und zusätzliche Komplexitäten, die zu berücksichtigen sind.

Einer der interessanten Punkte ist der konzeptuelle Gegensatz zwischen Umgebungen und der Unveränderbarkeit von Containern: URL-Adressen, Datenbank-Verbindungen und jegliche andere Konfigurationen unterscheiden sich zwischen den jeweiligen Umgebungen, also haben wir einen dynamischen Teil, den die Applikationen in den Containern kennen müssen, die Container selber jedoch nicht kennen dürfen.

Der einfache Teil: Die Server-Seite

Dienste zur Container-Orchestrierung wie Kubernetes oder Docker Swarm bieten Möglichkeiten an, entsprechende Umgebungsvariablen zu konfigurieren, die wiederum von Server-Komponenten wie ASP.Net Core ausgelesen werden können. Dieser Teil wird ausführlich in diesem Beitrag beschrieben und hat sich in der Praxis bewährt.

Der schwierige Teil: Die Webclient-Seite

Aus Gründen der Sicherheit dürfen JavaScript Applikationen den Prozess des Browsers nicht verlassen, wir haben also keine Möglichkeit von einer Angular Applikation aus die von Docker zur Verfügung gestellten Umgebungsvariablen auszulesen.

Bildnachweis Wiki

Hier ist daher wiederum Kreativität gefragt, wobei wir in diversen Projekten drei unterschiedliche Lösungsansätze angewendet haben:

ASP.Net Core Settings Middleware

Wie wir bereits festgestellt haben, arbeitet ASP.Net Core sehr gut mit Docker zusammen, da wir die Umgebungsvariablen und somit das eingebaute ASP.Net Core Konfigurationsmanagement verwenden können. Dieser Ansatz macht sich diese Tatsache zu Nutze, indem im Container vom Webclient aus eine ASP.Net Core Applikation mitgeliefert wird, die dem Angular Client die benötigte Konfiguration liefert.

Der Vorteil ist hierbei, dass wir keine infrastrukturellen Maßnahmen treffen müssen und die Kommunikation sehr transparent ist. Der Nachteil ist wiederum, dass wir eine eigene Komponente pflegen müssen, welche “nur” als Adapter dient und entsprechend zusätzliche Komplexität mit sich bringt.

Redirect des Client-Servers

Die Lösung Marke Eigenbau: Generell ist der Teil, der das initiale HTML zur Verfügung stellt, so minimal, dass wir oft vergessen, dass hier auch ein Web-Server am Werk ist. Doch auch diese bieten Lösungsansätze. So gewährt beispielsweise der Web-Server LightTPD Zugriff auf Umgebungsvariablen, die wir verwenden, um auf die jeweilige Konfigurations-Datei umzuleiten:

Somit haben wir bei Aufrufen dieses Pfades immer die jeweilige umgebungsspezifische Konfigurations-Datei, doch müssen wir dies Angular ebenfalls noch beibringen. Hier müssen wir selbst Hand anlegen, da das von Angular mitgelieferte Konfigurationsmanagement bereits zur Erstellung wissen muss, welche Umgebung zu verwenden ist, was wir möglichst vermeiden wollen.

Daher liefern wir alle appsettings.json Dateien mit und lassen die konfigurierte Umleitung entscheiden, welche wir verwenden. Der Angular Service, der diese ausliest, ist ein klassischer HTTP-Server, der anstatt einen Web-Server aufzurufen, auf den Pfad zugreift und so die Konfiguration lädt:

Der Vorteil dieser Lösung ist, dass wir keine weiteren Komponenten anbinden müssen und die bestehende Funktionalität der Web-Services verwenden können. Die Nachteile wiederum sind, dass wir uns vom jeweiligen Web-Server abhängig machen. Auch haben wir durch die zusätzliche Umleitung Komplexität und Fehlerquellen geschaffen, die allenfalls schwierig nachvollziehbar sind. Des Weiteren müssen wir unsere eigene Konfigurationslogik bauen, da Angular solche Szenarien nicht unterstützt.

Umbiegen der Settings beim Start des Containers

Ähnlich wie beim vorher genannten Vorgehen verwenden wir einen eigenen Angular HTTP-Service und laden alle appsetting.jsons mit. Wir fügen jedoch kein Redirect hinzu, sondern biegen die Settings beim Start des Containers um. Docker erlaubt hierzu das Mitgeben eines Commands beim Start eines Containers:

Dieser sehr kompliziert aussehende Befehl beinhaltet folgende Schritte:

  1. Ersetze appsettings.json mi der Umgebungs-spezifischen Datei
  2. Lösche alle Dateien, die mit json enden, aber nicht appsettings.json heißen
  3. Starte den Web-Server

Somit enden wir mit genau einer appsettings.json, angepasst auf die jeweilige Umgebung, welche wir wiederum mit einem Angular HTTP-Service auslesen können.

Der Vorteil dieser Lösung ist, dass wir keine Abhängigkeit von dem Web-Server haben und auch keine zusätzliche Komponente benötigen, da wir reine Docker- und Linux-Infrastruktur verwenden. Des Weiteren wird dieser Schritt nur beim Starten des Containers ausgeführt, wir haben also keine unnötigen Aufrufe zur Laufzeit.

Allerdings benötigen wir auch hier einen eigenen Angular-Service und sind weniger flexibel, da wir vom Release-Management abhängig sind.

Fazit

Containerisierung bietet viele Vorteile und ergänzt sich exzellent mit DevOps, doch ist die zusätzliche Komplexität nicht zu unterschätzen.

Auch stellt diese neue Welt andere Anforderungen an Entwickler: Themen wie YAML, Linux Bash, Docker-Stack, Dockerfile, Azure DevOps und viele weitere Komponenten werden für Entwickler wichtiger, da sie diese Infrastruktur pflegen und bei Problemen zurechtkommen müssen.

Auch wird für unerwartete Probleme, wie das oben beschriebene Konfigurationsmanagement für Web-Clients, kreative Lösungsfindung immer wichtiger, was wiederum bedeutet, dass die Basics sitzen und oftmals längere Recherchen durchgeführt werden müssen. Jedoch zahlt sich die initiale Komplexität aus, da wir so hochgradig stabile, automatisierte und flexible Installationen erreichen.

Bildnachweise

  • DevOps Container 1: Foliensatz Berner Fachhochschule CAS Application Lifecycle Management
  • DevOps Container 2: Wiki
  • DevOps Container Titelbild: meetup.com
By |2018-12-14T08:30:42+02:00December 14th, 2018|Allgemein, ASP.net, Azure, Office 365|0 Comments

About the Author:

Senior Developer

Leave a Reply

%d bloggers like this:

novaCapta verwendet Cookies, um die Funktionalität dieser Website zu verbessern. Durch die Nutzung dieser Seite stimmen Sie der Verwendung von Cookies zu. Weiterlesen

The cookie settings on this website are set to "allow cookies" to give you the best browsing experience possible. If you continue to use this website without changing your cookie settings or you click "Accept" below then you are consenting to this.

Close