Geschrieben von Thomas Kruse
am 7. Dezember 2018
In verteilten Systemen, zu denen etwa solche mit Microservice- und Cloud-Architekturen zählen, müssen in der Regel über Anwendungsgrenzen hinweg Funktionsaufrufe erfolgen.
Typischerweise kommt dabei für synchrone Aufrufe HTTP als Transportschicht zum Einsatz, das Format der ausgetauschten Daten kann XML, JSON oder eine andere spezifische Datenstruktur sein.
Welche HTTP-Verben und welche Adressen (URLs) wie zu verwenden sind, ist dabei eine fast schon in philosophische Bereiche ausufernde Debatte zwischen den verschiedenen Ansätzen.
Am häufigsten finden sich REST und Abwandlungen davon als Schnittstellenkonzept.
Im Gegensatz zu der reichhaltigen API-Oberfläche von REST findet sich SOAP als XML-basiertes RPC- (Remote-Procedure-Call-) Verfahren, bei dem lediglich HTTP POST-Requests zum Einsatz kommen.
Neben dem oft als schwerfällig bezeichneten Vorgehen von Design und Implementierung von SOAP-Schnittstellen hat XML als Transportformat auch deutliche Auswirkungen auf möglichen Durchsatz und erforderliche CPU- und Speicherresourcen bei der Verarbeitung.
Als Alternative zu diesen Ansätzen hat Google gRPC entwickelt:
gRPC setzt ebenfalls auf HTTP auf, verwendet jedoch Google Protocol Buffers als optimiertes Datenformat.
Wie der Einsatz im Kontext einer Java-Spring-Boot-Anwendung aussehen kann, wird im Folgenden dargestellt.
Geschrieben von Philipp Löpenhaus
am 20. November 2018
Debugging ist ein wichtiges Werkzeug in der Softwareentwicklung.
Aus klassischen Umgebungen, wie Java oder .net ist Debugging in Entwicklungsumgebung (IDEs) wie beispielsweise Visual Studio, NetBeans oder Eclipse bekannt.
Debugging bietet dem Entwickler...
Geschrieben von Thomas Kruse
am 6. November 2018
Angular ist ein vielversprechendes Framework, aber wie verwendet man es optimal? Welche Fallstricke gilt es zu vermeiden, damit auch in der Produktion alles reibungslos läuft? Dieser Vortrag basiert auf den Praxiserfahrungen aus rund zwei Jahren Entwicklung mit Angular: Vom Design bis zum produktiven Betrieb mehrerer Systeme. Neben Tipps zum API-Design geht es um Integration von Komponenten von Drittanbietern, Komponentenschnitt und Diagnose der Anwendung. Dieser Vortrag richtet sich an Softwareentwickler und Architekten, die an Best Practices und wertvollen Tipps und Tricks für eigene Projekte mit Angular interessiert sind.
— Angular im Projektalltag: Do's and Don'ts
Geschrieben von Thomas Kruse
am 3. November 2018
Kubernetes nutzt Container Images im OCI- oder Docker-Format, um Workload im Cluster zu verteilen und auszuführen.
Möchte man - zum Beispiel im Rahmen eines CI-Builds - in einem Kubernetes-Cluster auch Docker-Images bauen, gibt es im wesentlichen drei Ansätze:
-
Verwendung des außenliegenden Docker-Daemons
-
Verwendung eines Docker-Daemons in einem Container (Docker-in-Docker)
-
Verwendung eines alternativen Build Werkzeugs
Den Docker-Daemon, der im Cluster selbst Container bereitstellt, in einem Build-Container zu verwenden bringt vor allem den Nachteil mit sich, dass der Build die Stabilität der Cluster-Node beeinträchtigen kann.
Zudem ist nicht gesagt, dass überhaupt ein Docker-Daemon bereitsteht, schließlich könnte der Kubernetes-Cluster auch CRI-O als Runtime verwenden.
Diese Option scheidet somit in der Regel aus.
Docker-in-Docker (DinD) ist eine häufig gewählte Option, verlangt jedoch, dass der entsprechende Container priviligiert gestartet wird.
Aus Sicherheitsaspekten ist diese Option zwar nicht optimal, lässt sich jedoch in der Praxis gut einsetzen.
Das gilt selbst dann, wenn die Container-Engine des Clusters gar kein Docker verwendet.
Als letzte Optionen bleibt noch die Verwendung spezialisierter Werkzeuge zur Erstellung von Container-Images.
In diesem Beitrag wurde die Verwendung von Buildah beschrieben, in Spring Boot mit Jib die Verwendung von Jib.
Jib ist speziell auf Java-Anwendungen ausgerichtet, buildah benötigt zum Bauen von Images root-Berechtigungen - beide Werkzeuge bringen damit gewisse Einschränkungen mit.
Von Google kommt das Werkzeug Kaniko, das in diesem Beitrag vorgestellt wird, und speziell für den Einsatz in Kubernetes konzipiert wurde.
Geschrieben von Thomas Kruse
am 26. Oktober 2018
In diesem Beitrag wurde die Installation von Kubernetes auf ODROID unter Arch Linux ARM beschrieben.
Nachdem Kubernetes 1.12 veröffentlich wurde, ist es an der Zeit, sich auch mit dem Thema Kubernetes Update zu beschäftigen.
Das grundsätzliche Vorgehen bei einem Upgrade von Kubernetes erfolgt in mehreren Schritten:
-
Update der Kubernetes Binaries auf den Master Nodes (Control Plane)
-
Update der Kubernetes Pods auf den Master Nodes
-
Aktualisierung der Worker Nodes auf die neuesten Kubernetes Binaries
Kubernetes Upgrades werden jeweils zwischen Minor Versionen supported, d.h. ein Update von 1.10 zu 1.12 muss über den Zwischenschritt eines Updates auf Kubernetes 1.11 erfolgen.
Das konkrete Vorgehen hängt von dem gewählten Verfahren zur Kubernetes Einrichtung ab.
Da der Beispiel-Cluster mit kubeadm
eingerichtet wurde, wird auch das Update von Kubernetes mit kubeadm upgrade
durchgeführt.
Geschrieben von Thomas Kruse
am 16. Oktober 2018
Auch wenn mit Docker die Containertechnologie fast überall Einzug hält, gibt es immer wieder in der praktischen Arbeit Herausforderungen zu meistern.
Ganz besonders dann, wenn die Anwendung, die in einen Container verbracht werden soll, nicht dafür ausgelegt wurde, entsprechend betrieben zu werden.
Vor allem im PHP Umfeld finden sich oft Anwendungsarchitekturen, die der Docker Philosophie "Ein Container, eine Aufgabe" entgegen stehen.
Ein möglicher Ansatz zur Lösung ist die Nutzung von Docker lediglich zur Ausführung der PHP- und Webserverprozesse und separate Verwaltung der PHP Programmdateien.
Ein Host-Mount kann die Dateien in beliebige Container einbinden - doch verliert man dann gerade die Stärke von Docker, sowohl für Rollout als auch Rollback eine handhabbare Einheit bestehend aus Anwendungsserver und Programmdateien bereitzustellen.
Das Problem besteht bei PHP Anwendungen in Docker darin, dass diese typischerweise aus mehreren Komponenten bestehen:
-
PHP-FPM für die Ausführung von PHP als Resultat von Web-Anfragen
-
Cron Jobs, oft ebenfalls als Trigger von PHP Scripten für periodische und asynchrone Aufgaben
-
Memcached oder Redis als Cache
-
Eine Datenbank wie MySQL oder PostgreSQL
-
Ein Webserver (nginx, Apache httpd, …) zur Auslieferung statischer Dateien
Zumindest die ersten beiden Dienste benötigen Zugriff auf die selben PHP Programmdateien.
Einen Scheduler und PHP-FPM im selben Container auszuführen passt nicht so ganz zur reinen Lehre von Docker, ist aber solange leicht zu verschmerzen, wie lediglich eine Container-Instanz läuft.
Sowieso als externe Resourcen verwaltete Dienste wie die Datenbank oder einen Memcached in einem separaten Container laufen zu lassen ist naheliegen.
Doch wie geht mit man Software um, die für eine gänzlich andere Betriebsumgebung konzipiert wurde?
Am Beispiel typischer PHP Projekte kann man die unterschiedlichen Vorgehensweisen und damit einhergehende Eigenschaften betrachten.
Geschrieben von Thomas Kruse
am 3. Oktober 2018
Mit Docker haben sich Container als Auslieferungsformat (nicht nur) für Microservices zum Status Quo für Cloudanwendungen etabliert.
Zur Erstellung der Container-Images war lange Zeit Zugriff auf einen Docker-Daemon erforderlich.
Besonders in Umgebungen wie Kubernetes-Clustern oder Public-Clouds mit gemeinsam genutzter Infrastruktur soll auf privilegierte Container verzichtet werden.
Mit dem typischen Ansatz von Docker-in-Docker oder Docker-Outside-Docker erhält ein so ausgeführter Build nämlich relativ viele Rechte.
Dank der OCI Spezifikation für Image-Formate ist Docker mit einem Dockerfile jedoch nur noch eine Möglichkeit, zum auslieferbaren Image zu gelangen.
Ein weiterer Aspekt sind die oft schwer umzusetzenden Optimierungsmöglichkeiten für Docker Images:
Um vom Layer-Caching optimal zu profitieren und damit sowohl I/O-Operationen als auch Speicherplatz zu sparen, sollten die Daten, die sich weniger häufig ändern, in einem separaten Layer positioniert werden, als Daten, die sich regelmäßig ändern.
Bei einer Spring Boot Anwendung könnte man zum Beispiel zwischen allen Abhängigkeiten und den eigentlichen, zu der Anwendung selbst gehörenden Class-Dateien differenzieren:
Die Abhängigkeiten werden sich seltener ändern, als das Programm, das bei jedem Bugfix und jeder Erweiterung Änderungen erfährt.
Nur dieser geänderte Image-Layer muss dann verteilt werden.
Für beide Probleme soll das Google Projekt "Jib" eine Lösung liefert.
Am Beispiel einer Spring Boot Anwendung und Maven wird der Einsatz von Google Jib demonstriert.
Geschrieben von Thomas Kruse
am 26. September 2018
Das seit Angular 6 als Beta verfügbare Feature "Angular Elements" wird mit Angular 7 erweitert und für den produtkiven Einsatz stabilisiert.
Mit Angular Elements lassen sich mit dem Angular-Framework leichtgewichtige Web-Components entwickeln, die sich in unterschiedlichen Kontexten einsetzen lassen.
Karsten Sitterberg stellt in seinem Artikel "Architektur mit Angular Elements" vor, wie sich bereits mit Angular in Version 6 die Entwicklung von Web-Components gestalten lässt und welche Konsequenzen sich für die Architektur von Anwendungen durch die neuen Möglichkeiten ergeben.
Geschrieben von Thomas Kruse
am 20. September 2018
Qualität von Frontend-Anwendungen erhöhen und sicherstellen ist ein wichtiges Ziel.
Vor allem, wenn es um große Anwendungen mit hohen Investitionen geht, sollen diese oft langfristig gewartet und ausgebaut werden.
Wie das Thema Qualitätssicherung am Beispiel einer Angular Anwendung angegangen werden kann, stellte Karsten Sitterberg bei dem Meetup der "Frontend Freunde" in Münster vor.
Geschrieben von Thomas Kruse
am 6. September 2018
Docker-Images sind plattformabhängig:
Während früher Docker ausschließlich unter Linux auf x86 Plattformen ein Thema war, kamen mit der ARM-Architektur und Windows-Containern zusätzliche Varianten hinzu.
Die einzige Option, das jeweils richtige Image für die Plattform auszuwählen, war dann, mit Image Tags zu arbeiten, sofern von einem Projekt überhaupt mehrere Architekturen unterstützt wurden und nicht ein ganz anderes Repository genutzt werden musste.
Tags sind eindimensional und es gibt ggf. weitere Image-Varianten zu berücksichtigen.
Darum hat jedes Projekt eine eigene Namenskonvention erstellt, beispielsweise gibt es dann foo/mariadb:amd64
, foo/mariadb:arm
, foo/mariadb:alpine-amd64
und foo/mariadb:alpine-arm
.
Damit werden die zu verwendenen Image-Namen plattformabhängig und können nicht übergreifend verwendet werden, z.B. in Kubernetes-Deploymentmanifests.
Das Problem wurde erkannt und Docker hat in mehreren Schritten den "Multi-Architecture-Support" implementiert.