Select Page

Kubernetes 101: So installierst und verwaltest du Anwendungen

by | Apr 24, 2023 | NETWAYS, Cloud Native

This entry is part 4 of 7 in the series Alles rund um Kubernetes

Nachdem wir uns vergangene Woche damit befasst haben, welche Mittel und Wege existieren, um sich ein Cluster für Tests oder die Produktion zu installieren, sind wir nun (hoffentlich) an dem Punkt angekommen, an dem wir erste Anwendungen auf Kubernetes portieren oder neu installieren möchten. Da sich Kubernetes als Containerorchestrator deutlich von “althergebrachten” Betriebsumgebungen für Anwendungen unterscheidet, ist es nur logisch, dass sich auch Best Practices für die Installation und den Betrieb von Anwendungen unterscheiden. Grob lassen sich die zu beachtenden Gesichtspunkte in 5 Felder unterteilen:

  • Dateisystem vs. Container
  • Monolithen vs. Microservices
  • Stateful vs. Stateless
  • Blackbox vs. Whitebox
  • Monitoring vs. Observability

Diese Felder und ihre Implikationen bedingen einander teilweise. Fangen wir also mit dem evtl. offensichtlichsten an – der Installationsmethodik.

Dateisystem vs. Container

Der größte und für viele auch folgenschwerste Unterschied zwischen Anwendungen, die in Kubernetes laufen ,und solchen, die auf VMs oder physischen Servern installiert werden, ist Containerisierung der Workloads. Jede Anwendung muss als Containerimage definiert, gebaut, gesichert und verteilt werden – dies erfordert oftmals eine Umstellung bestehender Abläufe für Tests, Bau und Verteilung der Software, bspw. in den CI/CD-Pipelines der Entwickler- und DevOps-Teams. Des Weiteren muss oftmals neue Infrastruktur eingerichtet werden, um etwa Imagescans oder eine eigene Container- und Artefaktregistry für das Unternehmen bereitstellen zu können.

Des Weiteren gilt es natürlich, entsprechendes Know-How in den Teams aufzubauen – nicht jede/r Entwickler/in hat in der Vergangenheit mit Docker und containerisierten Anwendungen gearbeitet, geschweige denn entwickelt. Auch wenn Tools wie Docker Desktop oder Podman Desktop den Einstieg heutzutage erleichtern, müssen Mindset, Praktiken und Routinen oftmals erst aufgebaut werden. Gleiches gilt für die Handhabe der Containerimages nach dem Bau: Wie werden Sie gespeichert und für Pipelines und Cluster verfügbar gemacht? Nutzt man hierfür eine offene Plattform (GitHub Container Registry, DockerHub), eine SaaS-Lösung (Artifactory), oder baut eigene Infrastruktur auf (Harbor)?
Mit diesen möglichen Problematiken sollte man sich im Bestfall bereits im Vorfeld befassen und aufkommende Fragen initial klären, um einen möglichst reibungslosen Umstieg auf Kubernetes für alle beteiligten Teams zu gewährleisten.

Monolithen vs. Microservices

Eine direkte Folge der Containerisierung von Anwendungen ist die Transition von sog. Monolithen zu Microservices. Der Grund hierfür ist klar: In einer Umgebung, in der Softwarereleases oft mehrmals täglich stattfinden und ein Orchestrator installierte Anwendungen nach Belieben skalieren, verwerfen oder an anderer Stelle erneut initialisieren kann, sind Anwendungen mit einer Paketgröße von mehreren Gigabyte nicht praktikabel – man möchte schmale Pakete im Bereich von maximal einigen Hundert Megabyte, um flexibel und schnell in Sachen Verteilung und Installation zu sein.

Hierfür ist es gängige Praxis, bestehende Anwendungen umzustrukturieren bzw. bei der Entwicklung neuer Anwendungen bereits in der Designphase auf die spätere Installation als Microservices hinzuwirken, um Monolithen zu vermeiden. Unter einem Monolithen versteht man ein einzelnes Softwarepaket, das sich von Operatoren nur als eine Einheit installieren lässt und keinerlei Flexibilität und Unabhängigkeit seiner Komponenten bietet – alle Bestandteile sind unter der Haube fest miteinander “verdrahtet”. Hat man nun Probleme mit der Performanz eines bestimmten Features (ein sog. Bottleneck) bleibt einem keine andere Wahl, als den gesamten Monolithen zu skalieren – in den meisten Fällen Ressourcenverschwendung.

Viel sinniger wäre es doch, die einzelnen Bestandteile zu trennen – das Ergebnis sind viele verschiedene Microservices, die im Bestfall jeweils nur eine Aufgabe übernehmen. Ein solcher Ansatz ermöglicht die Skalierung einzelner Bestandteile der Anwendung, bspw. des viel frequentierten Webshops, anstatt direkt die gesamte Anwendung skalieren zu müssen. Die Kommunikation der einzelnen Microservices untereinander geschieht in solchen Szenarien über das (clusterinterne) Netzwerk bspw. via HTTP oder gRPC.

Stateful vs. Stateless

Eine direkte Folge der Umsetzung von Anwendungen als Microservices wiederum ist eine Transition von zustandsabhängigen (stateful) zu größtenteils zustandslosen (stateless) Anwendungen – während die meisten Monolithen zustandsabhängig sind (fast jede nennenswerte Anwendung muss an irgendeinem Punkt Daten persistent speichern können), müssen nur die wenigsten Microservices Daten persistent speichern. In vielen Fällen reicht ein lokaler Cache, bspw. zum Speichern von Nutzersitzungen oder dem Vorhalten von oft angefragten Daten.

Wirkliche Persistenz benötigen nur die Microservices, die sich unmittelbar mit der Verarbeitung und Speicherung von Daten befassen und hierfür bspw. mit rückgelagerten Datenbanken oder Dateisystemen kommunizieren. Mittlerweile gibt es allerdings genug Fallstudien, in denen auch Services wie Blockspeicher oder Datenbanken direkt auf Kubernetes betrieben werden.

Blackbox vs. Whitebox

Neben der Umstellung von “Stateful” auf “Stateless” betrifft eine weitere große Veränderung im Design von Anwendungen bestehend aus Microservices den Ansatz ihrer Überwachung: Anstatt lediglich von außen auf die Anwendung zu blicken und evtl. auftretende Symptome einer Fehlfunktion zu erkennen, bspw. durch HTTP-Anfragen an für Nutzer angebotene Webendpunkte (sog. Blackbox-Monitoring), instrumentalisiert man seine Microservices von vornherein so dass man tatsächliche Metriken aus den im Service ablaufenden Prozessen erhält (sog. Whitebox-Monitoring).

Beliebt für die Umsetzung ist hierbei Prometheus, was einen etablierten Standard für Metriken liefert, weit verbreitet ist und Funktionsbibliotheken für die Instrumentalisierung von Code in verschiedenen Programmiersprachen bietet. Prometheus sammelt die Metriken der Services über Webendpunkte ab und speichert sie in einer internen Timeseriesdatenbank (TSDB) ab. Ist Prometheus für euch ein gänzlich unbekannter Begriff, kann ich euch an dieser Stelle wärmstens unser Prometheus Fundamentals Training ans Herz legen, mit dem man in kürzester Zeit relativ vertraut mit Prometheus und seinem Funktionsumfang wird.
Verfolgt man also Whitebox- statt Blackboxmonitoring, hat man die tatsächlichen Metriken seiner Microservices zur Verfügung und kann bei aufkommenden Komplikationen Ursachen statt Symptomen bekämpfen. Des Weiteren können die Metriken zur permanenten Weiterentwicklung und Verbesserung der Serviceperformanzen genutzt werden – eine Win-Win-Situation!

Monitoring vs. Observability

Aufbauend auf dem letzten Absatz zu Blackbox- vs. Whiteboxmonitoring lässt sich die Monitoring-Philosophie im Hinblick auf K8s oder “Cloud-Native” generell noch vertiefen und erweitern: Man spricht von den Three pillars of observability (Drei Säulen der Beobachtbarkeit/Observability) Metrics, Traces und LogsMetriken werden von Anwendungen und Services selbst bereitgestellt und bieten wie bereits erklärt einen ungetrübten Einblick in das Innenleben einzelner Services. Traces erlauben es, Prozessketten über Servicegrenzen hinweg zu verfolgen und bspw. zu ermitteln, in welchen Stadien der Verarbeitung besonders hohe Latenzen entstehen. Logs ermöglichen die Verarbeitung von Events o.Ä., die von den einzelnen Anwendungen protokolliert werden.

Aus der Fülle an verschiedenen Datentypen und den dafür benötigten Praktiken entsteht die Entwicklung von Monitoring hin zu Observability – es ist nicht mehr ausreichend, lediglich “von außen” auf seine monolithische Anwendung zu blicken, sondern es gilt, stattdessen in den Services selbst anzusetzen und soviel Informationen wie möglich abzugreifen.
Für alle drei Arten an Beobachtungen gibt es umfangreiches Tooling in der Opensource-Gemeinschaft, das einem hilft, den Überblick über seine Cluster und die darauf betriebenen Anwendungen zu behalten, diese nach und nach zu optimieren und bei Fehlern schnell oder sogar proaktiv reagieren zu können. Auch bei der Einhaltung von Service Level Agreements (SLAs) gegenüber den Kunden oder internen Service Level Agreements (SLAs) hilft eine lückenlose Observability-Strategie.

 

Sollten diese Punkte etwas viel auf einmal gewesen sein oder du bereits absehbare Probleme bei der Umsetzung auf dich zukommen siehst, kann ich euch erneut auf unsere Services rund um Container, DevOps und Kubernetes verweisen – wir sind in vielen der genannten Bereichen bereit, dir mit Rat und Tat zur Seite zu stehen und bei der Umsetzung zu unterstützen. Ansonsten bleibt mir für heute nur, “bis zum nächsten Mal” zu sagen, wenn wir uns genauer anschauen, wie man Anwendungen auf Kubernetes denn nun im Detail verwaltet und skaliert.

Daniel Bodky
Daniel Bodky
Platform Advocate

Daniel kam nach Abschluss seines Studiums im Oktober 2021 zu NETWAYS und beriet zwei Jahre lang Kunden zu den Themen Icinga2 und Kubernetes, bevor es ihn weiter zu Managed Services zog. Seitdem redet und schreibt er viel über cloud-native Technologien und ihre spannenden Anwendungsfälle und gibt sein Bestes, um Neues und Interessantes rund um Kubernetes zu vermitteln. Nebenher schreibt er in seiner Freizeit kleinere Tools für verschiedenste Einsatzgebiete, nimmt öfters mal ein Buch in die Hand oder widmet sich seinem viel zu großen Berg Lego. In der wärmeren Jahreszeit findet man ihn außerdem oft auf dem Fahrrad oder beim Wandern.

0 Comments

Submit a Comment

Your email address will not be published. Required fields are marked *

More posts on the topic NETWAYS | Cloud Native