diff --git a/Praxisbericht.tex b/Praxisbericht.tex index 0cd19f8..0c935e1 100644 --- a/Praxisbericht.tex +++ b/Praxisbericht.tex @@ -169,48 +169,52 @@ Sofern ein Produkt die Spitze des Backlogs erreicht, werden Eigenschaften über Täglich wird der aktuelle Stand dem Fachbetreuer mitgeteilt. Wöchentlich gibt es ein Meeting mit dem Fachbetreuer, dem organisatorischen Betreuer, meinem Gruppenleiter und weiteren Stakeholdern, um über ausprobierte Produkte, deren Eigenschaften und mögliche Integration in den Stack zu besprechen. Sofern Alternativen zu den Produkt bestehen erfolgt ein Vergleich mit diesen. Somit wird Techstack-Creep, welches mit übermäßiger Komplexitat, Ineffizienzen und Sicherheitsrisiken verbunden ist, verhindert. Gleichzeitig wird garantiert, dass wertschöpfende Produkte nicht ausgelassen werden. Bei grünem Licht wird das Produkt in die bestehende Testlandschaft integriert und weitere Optimierungen und Anpassungen für selektron erarbeitet. -\section{Vorgehensweise} +\section{Aufgabenbearbeitung} + +Nachdem Aufgabenstellung und Methodik geklärt sind, folgt nun die Bearbeitung der Aufgabe. Diese beschreibt den Hauptteil meiner Zeit der Praxisphase. \subsection{Distribution} -Initial wurde Forschung über die Funktionsweise von Kubernetes unternommen, da weder meine Betreuer, noch ich Wissen in diesem Bereich hatten. Dabei fiel zuerst Augenmerk darauf, dass es im Gegensatz zu Docker oder Podman nicht \glqq{}ein\grqq{} Kubernetes gibt, sondern verschiedene Distributionen\cite{distroList}, ähnlich wie bei Linux. Da die Logikcontroller der psb direkt im Lager On-Premise laufen, lassen sich schnell viele der Cloud-basierten Lösungen wie AWS EKS, Azure AKS oder Google GKE wegfiltern. Übrig bleiben die On-Premise oder Edge-Computing Distributionen. Diese Unterscheiden sich auch ähnlich wie Linux-Distributionen weniger darin, welche Software laufen kann, sondern in dem Standardumfang und bestimmten Unique Selling Points, wie einem einfachen Installationsprozess oder hohem Compliance-Grad out-of-the-box. Kandidaten sind Rancher k3s, eine Edge-Compute-Distribution mit Fokus auf Hauptspeichereffizienz auf Kosten einiger High-Availability-Funktionen, welche mit einem Befehl installierbar ist\cite{distroK3s}, Rancher RKE2, einer Distribution mit Fokus auf hohen Sicherheitsstandards, Compliance und Enterprise-Support\cite{distroRKE2}, RedHat OpenShift, eine allumfassende Plattform mit Kubernetes im Kern welche GitOps, CI/CD Pipelines, Infrastrukturmanagement, Monitoring und Enterprise-Support umfässt\cite{distroOpenShift}, OKD, die Communitygetriebene Version von OpenShift ohne Enterprise-Support\cite{distroOKD} und zuletzt kubeadm\cite{distroKubeadm}, welches den minimalen Kern von Kubernetes deployt und den Rest der Konfiguration dem Nutzer überlasst. +Initial wurde Forschung über die Funktionsweise von Kubernetes unternommen, da weder meine Betreuer, noch ich Wissen in diesem Bereich hatten. Dabei fiel zuerst Augenmerk darauf, dass es im Gegensatz zu Docker oder Podman nicht \glqq{}ein\grqq{} Kubernetes gibt, sondern verschiedene Distributionen\cite{distroList}, ähnlich wie bei Linux. In Anbetracht dessen, dass die Logikcontroller der psb direkt im Lager On-Premise laufen, lassen sich schnell viele der Cloud-basierten Lösungen wie AWS EKS, Azure AKS oder Google GKE wegfiltern. Übrig bleiben On-Premise oder Edge-Computing Distributionen. Diese Unterscheiden sich, auch ähnlich wie Linux-Distributionen, weniger darin, welche Software laufen kann, sondern in dem Standardumfang und bestimmten Unique Selling Points, wie einem einfachen Installationsprozess oder hohem Compliance-Grad out-of-the-box. Kandidaten sind Rancher k3s, eine Edge-Compute-Distribution mit Fokus auf Hauptspeichereffizienz auf Kosten einiger High-Availability-Funktionen, welche mit einem Befehl installierbar ist\cite{distroK3s}, Rancher RKE2, einer Distribution mit Fokus auf hohen Sicherheitsstandards, Compliance und Enterprise-Support\cite{distroRKE2}, RedHat OpenShift, eine allumfassende Plattform mit Kubernetes im Kern welche GitOps, CI/CD Pipelines, Infrastrukturmanagement, Monitoring und Enterprise-Support umfässt\cite{distroOpenShift}, OKD, die Communitygetriebene Version von OpenShift ohne Enterprise-Support\cite{distroOKD} und zuletzt kubeadm\cite{distroKubeadm}, welches den minimalen Kern von Kubernetes deployt und den Rest der Konfiguration dem Nutzer überlasst. Für das Evaluieren wurde entschlossen, eine möglichst Originalgetreue Distribution von Kubernetes zu benutzen, wodurch OpenShift und OKD mit ihren meinungsstarken Standardkonfigurationen sowie großen Zusatzkomponenten wegfallen und die Entwicklungen von Rancher als auch kubeadm übrig blieben. Da k3s mit einfacher Installation, besonders im Gegensatz zu kubeadm, überzeugt, wurde es als initiale Technische Grundlage ausgewählt, besonders mit dem Hintergedanken, dass für den Kubernetes-API-Kern geschriebene Komponenten auf jeder Distribution lauffähig sind. Diese Portabilität soll später ebenfalls erlauben, weitaus Kundensystem-agnostischer zu arbeiten. Im Verlauf wurde kubeadm sowie RKE2 geprüft. Falls die Migration zustande kommt, wird RKE2 als Produktionsumgebung mit Möglichkeit für High-Availability die Basis bilden. \subsection{Erste Berührungspunkte} -Nach der Wahl der Distribution folgte das Einarbeiten in Kubernetes. Dabei wurde mit den kompletten Grundlagen begonnen: wie bediene ich das Kommandozeilentool \texttt{kubectl}, was ist ein Pod, wie ist er definiert, wie binden Services sich an Pods, et cetera. Gleichzeitig wurde meiner ersten Aufgabe nachgegegangen, das Monitoring-Tool Graylog, welches selektron benutzt, um alle Logs der verschiedenen Services zusammenzuführen, auf Kubernetes zu portieren, um praktische Erfahrung zu sammeln. Währenddessen wurde ein Nachschlagewerk geschrieben und gepflegt, um diese Daten zusammengefasst an einer Stelle zu haben. +Nach der Wahl der Distribution folgte das Einarbeiten in Kubernetes. Dabei wurde mit den kompletten Grundlagen begonnen. Das \textit{Cluster}, welches ein vollständiges Kubernetes-System mit allen Komponenten beschreibt. Die \textit{Node}, welche einen einzelnen Rechner bzw. Server in einem Cluster abbildet, und das \textit{kubelet}, welches die Node mit dem Cluster verbindet. Den \textit{Pod}, der Basiseinheit in Kubernetes, bestehend aus Containern (Softwaremodulen), Speicheranbindungen und Rechten. \textit{Deployments}, welche den Lebenszyklus von einer Gruppe gleicher Pods verwalten, darunter Start, Neustart und Updates. \textit{Services}, welche Pods feste Adressen zuweisen, damit andere Pods diese ansprechen können. Verwaltet wird ein Cluster von der dazugehörigen \textit{Control-Plane}, bestehend aus \textit{kube-apiserver}, welcher Befehle annimmt und an das Cluster überträgt, \textit{kube-scheduler}, welcher Pods auf Nodes zuweist, \textit{etcd}, welches alle Konfigurationen des Clusters speichert, \textit{kube-controller-manager}, welcher die Hauptlogik von Kubernetes übernimmt und den \textit{cloud-controller-manager}, welcher das Cluster in der Cloud-Infrastrukturumgebung wiederspiegelt, sofern Verfügbar. Kommunikation mit dem Cluster verläuft über das Kommandozeilentool \texttt{kubectl}. Damit diese und weitere Informationen an einer zentralen Stelle für den späteren Gebrauch auffindbar sind, wurde ein Nachschlagewerk geschrieben und gepflegt, welches im Rahmen der Praxisphase weitere Ausarbeitungen erhalten hat. + +Nach dem initialen Einarbeiten wurde der Aufgabe nachgegegangen, das Monitoring-Tool Graylog, welches selektron benutzt, um alle Logs der verschiedenen Services zusammenzuführen, auf Kubernetes zu portieren, um praktische Erfahrung zu sammeln. \subsection{Helm} -Schnell wurde klar, das Kubernetes Komponenten manuell schreiben und verwalten möglich ist, jedoch Limitationen aufweist. Ein Kernnachteil ist, dass \texttt{kubectl apply} nur Komponenten hinzufügen, aber nicht löschen kann, und man somit nichtmehr definierte Komponenten selbst verwalten muss. Darauf folgt das benutzen von Helm als Paketmanager, welches Charts definiert. Charts sind Sammlungen an Komponentendefinitionsvorlagen, die mit einer Values-Datei zu vollwertigen Kubernetes-Komponentendefinitionen werden, um als konfigurierten Release auf das Cluster gespielt zu werden. Dies hat den Vorteil, dass Helm-Charts mit einem Befehl installiert, geupgraded und deinstalliert werden können und eine Versionierung zwischen den Releases existiert die Rollbacks ermöglicht. Glücklicherweise pflegen die Entwickler von Graylog ebenfalls solch einen Chart, wodurch ich von meiner spartanischen Erstimplementation auf eine allumfassend bessere Version wechseln konnte. Bei der Installation hatte ich gleichzeitig das erste mal Kontakt mit Operatoren, konkret dem vom Graylog-Helm-Chart genutzten MongoDB-Operator. Operatoren sind Kubernetes-Erweiterungen bestehend aus Custom-Resource-Definitions (kurz CRDs) und mindestens einem Pod, welcher Instanzen der definierten CRDs (Custom Resources, CRs) überwacht, und daraufhin das Cluster entsprechend bedient. Der MongoDB Operator überwacht z.B. das Cluster nach MongoDB-Komponenten, in welchen eine Datenbank definiert wird, und erstellt daraufhin dynamisch die Datenbank nach den Anforderungen. Falls die Komponente editiert oder gelöscht wird, wird die dadurch erstellte Datenbank dementsprechend editiert oder gelöscht. Somit Verwaltet der Operator den Lebenszyklus der angefragten Resource, und der anfragende Service muss sich nicht um die genaue Implementation, sondern nur den Finalzustand kümmern. Dieser Ansatz wird \glqq{}Infrastructure as Code\grqq{} genannt, in Anbetracht dessen, dass Infrastruktur (in diesem Fall Datenbanken) mithilfe von Code statt manueller Prozesse bereitgestellt wird, und somit Konsistenz, Auditierbarkeit, Transparenz und Skalierbarkeit gewährt. +Schnell wurde klar, das Kubernetes Komponenten manuell verwalten Limitationen aufweist. Ein Hauptgrund ist, dass der Befehl, um Komponenten aus einer Deklarationsdatei anzuwenden, sie hinzufügen, aber nicht löschen kann, und man somit aus der Deklarationsdatei entfernte Komponenten selbst zu löschen hat. Um diese Limitation zu umgehen, wurde zeitnah der Paketmanager Helm\cite{helm} benutzt. Pakete sind in Form von \textit{Charts} realisiert, welche konkret Sammlungen an Template-Deklarationsdateien darstellen, die mit einer Values-Datei zu vollwertigen Komponentendeklarationsdateien zusammengesetzt werden, um als \textit{Release} auf das Cluster gespielt zu werden. Dies hat den Vorteil, dass Helm-Charts mit einem Befehl installiert, geupgraded und deinstalliert werden können und eine Versionierung zwischen den Releases existiert die Rollbacks ermöglicht. Auch können Upgrades \textit{atomar} durchgeführt werden, das heißt dass im Falle einer Fehlgeschlagenen Komponente alles auf den vorherigen Zustand zurückgesetzt wird. Glücklicherweise pflegen die Entwickler von Graylog ebenfalls einen Helm-Chart, wodurch ich von meiner spartanischen Erstimplementation auf eine allumfassend bessere Version wechseln konnte. Bei der Installation hatte ich gleichzeitig das erste mal Kontakt mit Operatoren, konkret dem vom Graylog-Helm-Chart genutzten MongoDB-Operator. + +\subsection{Operatoren} +\textit{Operatoren} bilden einen der Hauptwege ab, Kubernetes zu erweitern. Sie bestehen aus \textit{Custom-Resource-Definitions} (kurz CRDs), mit welchen ein Wunschzustand definiert werden kann, und mindestens einem Pod, welcher Instanzen der \textit{Custom Resources} (CRs) überwacht, und daraufhin das Cluster entsprechend bedient. Der MongoDB-Operator als Beispiel überwacht das Cluster nach MongoDB-Komponenten, in welchen eine Datenbank definiert wird, und erstellt daraufhin dynamisch die Datenbank nach den in der CR angegebenen Anforderungen. Falls die CR-Komponente editiert oder gelöscht wird, wird die dadurch erstellte Datenbank dementsprechend editiert oder gelöscht. Somit Verwaltet der Operator den Lebenszyklus der angefragten Resource, wodurch sich der anfragende Service (in dem Fall der Graylog-Helm-Chart) nicht um die genaue Implementation, sondern nur den Finalzustand kümmern muss. Dieser Ansatz wird \glqq{}Infrastructure as Code\grqq{} bzw. \glqq{}Configuration as Code\grqq{} genannt, und zieht sich durch Kubernetes und das dazugehörige Ökosystem durch. In Anbetracht dessen, dass Infrastruktur (in diesem Fall Datenbanken) mithilfe von Code statt manueller Prozesse bereitgestellt wird, und somit Konsistenz, Auditierbarkeit, Transparenz und Skalierbarkeit gewährt wird, finde ich diesen Ansatz zukunftsorientiert. \subsection{GatewayAPI} -Nachdem Graylog auf dem Cluster lief, war es jedoch noch nicht von extern erreichbar. Dafür ist Ingress zuständig. Ingress ist ein Spec, verwaltet von dem Kubernetes-Team\cite{k8sIngress}, welcher Layer 7 HTTP/S Routing erlaubt. Dieser Spec wird von IngressControllern implementiert, z.B. nginx oder Traefik. Da selektron jedoch nicht nur Layer 7, sondern auch Layer 4 Routing benötigt, um mit der SPS im Lager zu kommunizieren, wurde auf Ingress' Nachfolger, GatewayAPI gesetzt\cite{k8sGatewayAPI}. GatewayAPI ist genau wie Ingress ein Spec, welcher von extern programmierten GatewayControllern, z.B. Istio oder Traefik, implementiert wird. Er lernt aus den Defiziten von Ingress und trennt Routen, Gateways und GatewayClasses voneinander. Ebenfalls erlaubt er nicht nur HTTP/S, sondern auch gRPC, TCP und UDP-Verbindungen. -Da Graylogs Chart aktuell nativ kein GatewayAPI unterstützt, wurde außerhalb des Charts die Notwendige HTTPRoute deklariert. Um abschließend Graylog mit einer externen Startroutine zu konfigurieren wurde ein Kubernetes Job geschrieben, welcher alle notwendigen Eingabequellen mit passendem Port einrichtet. +Nachdem Graylog auf dem Cluster lief, war es jedoch noch nicht von extern erreichbar. Dafür ist \textit{Ingress} zuständig. Ingress ist ein Spec, verwaltet von dem Kubernetes-Team\cite{k8sIngress}, welcher Layer 7 HTTP/S Routing verwaltet. HTTP/S ist das gleiche Protokoll, das ein Webbrowser verwendet um Webseiten zu öffnen. Implementationen wie nginx oder Traefik implementieren diesen Spec, und Stellen Controller bereit, welche das konkrete Routing verwalten. Da selektron jedoch nicht nur Layer 7, sondern auch für Kundenspezifische Lösungen Layer 4 Routing benötigt, wurde auf Ingress' Nachfolger, \textit{GatewayAPI} gesetzt\cite{k8sGatewayAPI}. GatewayAPI ist genau wie Ingress ein Spec, welcher von externen Implementationen mithilfe von Controllern verwaltet wird. Dabei wurde aus den Defiziten von Ingress gelernt, woraufhin \textit{Routen}, \textit{Gateways} und \textit{GatewayClasses} voneinander getrennt werden, um stärkere Trennung von Angelegenheiten (Seperation of Concerns) zu realisieren. Dazu unterstützt GatewayAPI nicht nur HTTP/S, sondern auch gRPC, TCP und UDP-Verbindungen. Zusätzlich kann mithilfe von GatewayAPI neben Nord-Süd-Datenverkehr (Nutzer mit Cluster) auch Ost-West-Datenverkehr (Pod zu Pod) geroutet werden. + +Da Graylogs Chart aktuell nativ kein GatewayAPI unterstützt, wurde außerhalb des Charts die Notwendige HTTPRoute deklariert. Um abschließend Graylog mit einer externen Startroutine zu konfigurieren, wurde ein Kubernetes Job geschrieben, welcher alle notwendigen Eingabequellen mit passendem Port einrichtet. \subsection{selektron} -Nachdem Graylog auf dem Cluster lief und ein initiales Verständnis für Kubernetes existierte, wurde sich der Portierung selektron auf einen Helm-Chart gewidmet. Als Grundlage für die Portierung wurde die Konfiguration eines Kundensystems übernommen. Während die Portierung schnell verlief, gab es eine Liste an Fehlern zu bewältigen. Da der selektron-Chart in einen anderen Namespace als Graylog deployed wird, war initiale Kommunikation zwischen den beiden Applikationen nicht möglich. Ein \texttt{ExternalName} Service wurde genutzt, um die Brücke zwischen den Namespaces zu bilden. Ebenfalls hat der Discovery- und Load-Balancing-Service, basierend auf Spring Boots Netflix Eureka, mit der Kubernetes Service-Schicht nicht kooperiert, da diese Domain-Namen und Container trennt, Eureka jedoch erwartet das jeder Container einen eigenen Domain-Namen hat. Glücklicherweise erlaubt Eureka für eine Entkopplung der beiden Komponenten. Grundsätzlich ist jedoch Eureka im Falle der Portierung von selektron auf Kubernetes nichtmehr von Nöten, da der komplette Aufgabenbereich von Kubernetes Service-Schicht bereits übernommen wird. Da es sich um einen Prototypen handelt, bleibt dieses Modul jedoch bestehen. +Nachdem Graylog auf dem Cluster lief und ein initiales Verständnis für Kubernetes, Helm und GatewayAPI existierte, wurde sich der Portierung selektron auf einen Helm-Chart gewidmet. Als Grundlage für die Portierung wurde die Konfiguration eines Kundensystems übernommen. Während die initiale Portierung schnell verlief, gab es eine Liste an Fehlern zu bewältigen. Da der selektron-Chart in einen anderen \textit{Namespace} als Graylog deployed wird, war Kommunikation zwischen den beiden Applikationen nicht möglich. Namespaces sind logisch getrennte Abschnitte innerhalb eines Clusters, um deren Inhalte nicht zu vermischen. Ein \textit{ExternalName}-Service wurde genutzt, um die Brücke zwischen den Namespaces zu bilden. Ebenfalls hat der Discovery- und Load-Balancing-Container von selektron, basierend auf Spring Boots Netflix Eureka, mit der Kubernetes Service-Schicht nicht kooperiert, da diese Domain-Namen und Container trennt, Eureka jedoch erwartet, dass jeder Container einen eigenen Domain-Namen hat. Glücklicherweise erlaubt Eureka für eine Entkopplung der beiden Komponenten. Grundsätzlich ist jedoch Eureka im Falle der Portierung von selektron auf Kubernetes nichtmehr von Nöten, da der komplette Aufgabenbereich von Kubernetes' Service-Schicht bereits übernommen wird. Da es sich um einen Prototypen handelt, bleibt dieses Modul jedoch bestehen. -Generell ist der selektron-Chart Modular aufgebaut und erlaubt in einer Zentralen Datei das Ändern aller relevanten Parametern. Durch die hohe Konfigurabilität und Helms Unterstützung von \glqq{}Overlays\grqq{}, partiellen Konfigurationsdateien welche mit der Kern-Konfiguration zusammengeführt werden, um Wiederholungen zu vermeiden, können Änderungen einfach und gezielt vorgenommen werden. +Generell ist der selektron-Chart Modular aufgebaut und erlaubt in einer zentralen Datei das Ändern aller relevanten Parametern. Durch die hohe Konfigurabilität und Helms Unterstützung von \textit{Overlays}, partiellen Konfigurationsdateien, welche mit der Kern-Konfiguration zusammengeführt werden, um Wiederholungen zu vermeiden, können Änderungen einfach und gezielt vorgenommen werden. \subsection{Nutzeroberfläche} -Eine weitere Anforderung ist eine Verwaltungsübersicht für das Kubernetes-Cluster, da Werkzeuge wie \texttt{kubectl} und \texttt{Helm} zwar alle Funktionalitäten von Kubernetes abdecken, sich jedoch Personalschulung als aufwändig erweist und der Aufwand für simple und repetetive Aufgaben größer ist als Notwendig. Als Visualisierung wurde sich auf Headlamp\cite{uiHeadlamp}, den offiziellen Nachfolger des Kubernetes-Dashboards\cite{uiHeadlampDeprecated}, Radar\cite{uiRadar}, ein Plugin-loses modular reaktives Dashboard als ersatz für Headlamp, und k9s\cite{uiK9s}, ein grafisches Kommandozeilentool geeinigt. k9s ist dabei besonders auf Geschwindigkeit und Tastaturbasiertes bedienen getrimmt, vergleichbar mit dem Text-Editor vim, und umfässt eher Aufgaben im Bereich des Developments von einzelnen Komponenten auf dem Cluster (Komponenten anzeigen \& editieren, Logs durchforsten). Headlamp bringt dagegen mehr Bedienkomfort, eine Standardmäßige Auflistung aller existierenden Kubernetes-Komponenten und CRDs (anstatt k9s' Such-basiertes Modell zur Komponentenauswahl), eine Map, welche existierende Komponenten miteinander Verbindet um sie Logisch zu gruppieren, und Plugin-Support. Radar bringt ähnlich wie Headlamp hohen Bedienkomfort und von sich aus viele Module für klassische Cluster-Plugins wie Helm, FluxCD, ArgoCD und Auditing, ist jedoch mit seinen Features eher auf Infrastrukturbereitsteller und DevSecOps als auf Anwendungsentwicklung ausgelegt. Da alle mit Kubeconfigs arbeiten, sind sie sofern \texttt{kubectl} eingerichtet ist, ohne weiteren Konfigurationsaufwand benutzbar. Besonders Headlamp hat für Überzeugung im Team gesorgt, da es auch ohne Kubernetes-Grundlagen vergleichsweise sehr einfach zu bedienen ist. - -Eine klassische Serviceaufgabe wäre das Neustarten und Stoppen von Containern. Was mit dem originalen Setup mit einer Ansammlung fehleranfälliger Skripte ablief, kann somit über eine Nutzerfreundliche Oberfläche mit wenigen Clicks realisiert werden. - -\todo{TODO: VIELLEICHT PANEL FÜR RESTART ETC IN HEADLAMP / RADAR} +Eine weitere Anforderung ist eine Verwaltungsübersicht für das Kubernetes-Cluster, da Kommandozeilenwerkzeuge wie \texttt{kubectl} und \texttt{helm} zwar alle Funktionalitäten von Kubernetes abdecken, sich jedoch Personalschulung für den Support als aufwändig erweist und der Aufwand für simple und repetetive Aufgaben größer ist als notwendig. Als Haupt-Visualisierung wurde sich auf \textit{Headlamp}\cite{uiHeadlamp}, den offiziellen Nachfolger des Kubernetes-Dashboards\cite{uiHeadlampDeprecated} geeignet. Zusatz-Visualisierungen für Entwickler und Cluster-Operatoren bilden \textit{Radar}\cite{uiRadar}, ein modulares Dashboard als Ersatz für Headlamp, und \textit{k9s}\cite{uiK9s}, ein grafisches Kommandozeilentool. k9s ist dabei besonders auf Geschwindigkeit und Tastaturbasiertes bedienen getrimmt, vergleichbar mit dem Text-Editor vim, und umfässt eher Aufgaben im Bereich des Developments von einzelnen Komponenten auf dem Cluster (Komponenten anzeigen \& editieren, Logs durchforsten). Headlamp bringt dagegen mehr Bedienkomfort, eine Standardmäßige Auflistung aller existierenden Kubernetes-Komponenten und CRDs (im Gegensatz zu k9s' Such-basiertes Modell zur Komponentenauswahl), eine Map, welche existierende Komponenten in einem Graph miteinander verbindet um sie Logisch zu gruppieren, sowie Plugin-Support. Radar bringt ähnlich wie Headlamp hohen Bedienkomfort und von sich aus Module für klassische Cluster-Erweiterungen wie Helm, FluxCD, ArgoCD und GatewayAPI, ist jedoch mit seinen Features eher auf Infrastrukturbereitsteller und DevSecOps als auf Anwendungsentwicklung ausgelegt. Da alle der genannten Übersichten auf Basis von \textit{Kubeconfig}s mit dem Cluster kommunizieren, sind sie sofern \texttt{kubectl} eingerichtet ist, ohne weiteren Konfigurationsaufwand benutzbar. Kubeconfig beschreibt dabei den offiziellen Weg, Authentifikationsdaten innerhalb einer Datei zu speichern, um sich gegenüber einem Cluster zu Authentifizieren. Besonders Headlamp hat für Überzeugung im Team gesorgt, da es auch ohne Kubernetes-Grundlagen vergleichsweise sehr einfach zu bedienen ist, und man mögliche defizite mithilfe von Plugins ausmerzen kann. Klassische Serviceaufgaben, wie das Neustarten und Stoppen von Containern, oder das Ausführen von Kommandos innerhalb eines Containers, können somit über eine nutzerfreundliche Oberfläche mit wenigen Clicks realisiert werden, anstatt auf Skripte die auf einem Server versteckt liegen, zurückgreifen zu müssen. \subsection{Windows} -Kernbestandteil der mir initial gegebenen Anforderungsliste war die Evaluation der Nutzbarkeit von Kubernetes auf Windows-basierten Systemen. Während Kubernetes unterstützt, Worker-Nodes auf Windows laufen zu lassen, gibt es keine Control-Plane die für Windows konzipiert ist, da Windows im Umfeld der Containerisierung keine Vorteile gegenüber Linux bietet, und der Mehraufwand nicht rechtfertigbar ist. Die Problemstellung lässt sich trotzdem lösen, da der Windows-Kernel seit Windows 10 bzw. Windows-Server 2016 Hyper-V mitliefert\cite{windowsHyperVIntro}. Hyper-V ist Microsofts Type-1 (Bare-Metal) Hypervisor, vergleichbar mit Linux' KVM. Hypervisor sind Software, die es erlauben, auf Host-Systemen mehrere Virtuelle Maschinen (VMs), sogenannte Guest-Systeme, laufen zu lassen. Dabei unterscheidet man zwischen Type-1 und Type-2 Hypervisorn. Der Vorteil von Type-1 Hypervisorn ist, dass diese parallel zum Kernel laufen und unabhängig Userspace des Host-Systems sind, während Type-2 Hypervisor auf dem Host-Betriebssystem laufen. Damit sind Type-2 Hypervisor einfacher zu bedienen, jedoch langsamer und unsicherer. Der Clou ist, mithilfe von Hyper-V eine Linux-VM aufzusetzen auf welcher das Cluster läuft. Nachteil bei dieser Konfiguration ist, dass durch die Virtualisierung ein Performance-Overhead, besonders in I/O-Operationen entsteht, sowie dass Networking innerhalb Hyper-V sehr fragil ist, weswegen nur externe Switches wie erwartet funktionieren. Diese müssen jedoch innerhalb der Kundenfirewall als externes Gerät eingerichtet werden, was die Kundentoleranz maßgeblich senkt. Da ein nicht zu unterschätzender Anteil der Kunden auf Windows-basierte Serversysteme setzt, könnte dies eine große Einschränkung bei Portierung von selektron erweisen. +Kernbestandteil der mir initial gegebenen Anforderungsliste war die Evaluation der Nutzbarkeit von Kubernetes auf Windows-basierten Systemen. Während Kubernetes es unterstützt, Worker-Nodes auf Windows laufen zu lassen, gibt es keine Control-Plane die für Windows konzipiert ist, da Windows im Umfeld der Containerisierung keine Vorteile gegenüber Linux bietet, und der Mehraufwand nicht rechtfertigbar ist. Die Problemstellung lässt sich trotzdem lösen, da der Windows-Kernel seit Windows 10 bzw. Windows-Server 2016 \textit{Hyper-V} mitliefert\cite{windowsHyperVIntro}. Hyper-V ist Microsofts Type-1 (Bare-Metal) \textit{Hypervisor}, vergleichbar mit Linux' KVM. Hypervisor sind Software, die es erlauben, auf Host-Systemen mehrere Virtuelle Maschinen (VMs), sogenannte Guest-Systeme, laufen zu lassen. Dabei unterscheidet man zwischen Type-1 und Type-2 Hypervisorn. Der Vorteil von Type-1 Hypervisorn ist, dass diese parallel zum Betriebssystem laufen und daher unabhängig von dem Geschehen auf dem Host-Systems sind, während Type-2 Hypervisor auf dem Host-Betriebssystem laufen. Damit sind Type-2 Hypervisor trivialer zu installieren und bedienen, jedoch langsamer. Der Clou ist, mithilfe von Hyper-V eine Linux-VM aufzusetzen auf welcher das Cluster läuft. Nachteil bei dieser Konfiguration ist, dass durch die Virtualisierung von Hardware ein Performance-Verlust, sogenannter \textit{Overhead}, entsteht. Dieser ist besonders in I/O-Operationen, also dem Lesen und Schreiben von Daten, spürbar. Auch ist Networking innerhalb Hyper-V sehr fragil, sofern keine Hyper-V External Switches verwendet werden. Diese müssen jedoch innerhalb der Kundenfirewall als externes Gerät eingerichtet werden, was die Kundentoleranz maßgeblich senkt. Da ein nicht zu unterschätzender Anteil der Kunden auf Windows-basierte Serversysteme setzt, könnte dies eine große Einschränkung bei der vollständigen Migration von selektron erweisen. Somit bleibt die Hyper-V Lösung eine Zwischenlösung. \subsection{GitOps \& FluxCD} -Um zu verhindern, dass die Server-Konfiguration undokumentiert Verändert wird, existiert das Konzept von GitOps: eine oder mehrere Git-Repositories zählen als Wahrheitsquelle und definieren den Wunschzustand der gesamten Infrastruktur, und Operatoren synchronisieren die laufende Umgebung ständig mit diesem Zustand. Dieser Vorgang ist dabei Teil der CI/CD (Continous Integration, Continous Delivery) Pipeline, konkret übernimmt es den CD-Teil. Anders als bei einer klassischen CD-Pipeline, bei der Push-basiert von einem Build-Server auf den Deployment-Server deployt wird, wird bei der GitOps-Pipeline Pull-basiert von einem auf dem Deployment-Server laufenden Operator in Intervallen die Git-Repo nach Änderungen überwacht, und im Falle einer Differenz zwischen Repository-Zustand und Server-Zustand die notwendigen Änderungen vorgenommen. Diesen Prozess nennt man reconciliation. Somit sind Serverzustand und Git-Zustand synchronisiert, Änderungen am Server auditierbar (Wer hat etwas geändert), differenzierbar (Was wurde genau geändert), rollbackbar im Falle eines Problems und reproduzierbar. Dabei setzen wir auf FluxCD, eine CNCF Graduated\cite{fluxCNCF} GitOps Implementation für Kubernetes. Eine Mögliche Alternative ist ArgoCD, welches von Haus aus eine UI bietet, jedoch ist FluxCD nativer in das Kubernetes-Tooling integriert, benutzt Kubernetes-natives RBAC und integriert mit Headlamp-Plugin\cite{fluxHeadlampPlugin} nativ in die gewünschte Übersicht. Dabei hat Flux zwei für selektron relevante Pipelines: die GitOps Pipeline und die Image-Controller-Pipeline. +\textit{Drift} beschreibt Änderungen an der Server-Konfiguration, welche undokumentiert sind, ähnlich wie bei der Bootsfahrt, bei der ungeplante Änderungen vom Kurs als Drift bezeichnet werden. Um zu verhindern, dass Drift entsteht, benötigt man eine Wahrheitsquelle. Das Konzept von \textit{GitOps} verfolgt den Ansatz, eine Git-Repository als Wahrheitsquelle zu definieren. Diese Git-Repository beschreibt den Wunschzustand der gesamten Infrastruktur. Operatoren auf dem Cluster synchronisieren die laufende Umgebung in definierten Abständen mit diesem Wunschzustand. Dieser Vorgang ist dabei Teil des \textit{CI/CD-Prozess} (Continous Integration, Continous Delivery), konkret übernimmt es den Delivery-Aspekt. Anders als bei einer klassischen CD-Pipeline, bei der Push-basiert von einem Build-Server auf den Deployment-Server (hier das Cluster) deployt wird, wird bei der GitOps-Pipeline Pull-basiert von einem auf dem Deployment-Server laufenden Operator intervallbasiert die Git-Repository nach Änderungen überwacht, und im Falle einer Differenz zwischen Repository-Zustand und Server-Zustand die notwendigen Änderungen vorgenommen. Diesen Prozess nennt man \textit{Reconciliation}. Somit sind Serverzustand und Git-Zustand synchronisiert, Änderungen am Server auditierbar (Wer hat etwas geändert), differenzierbar (Was wurde genau geändert), rollbackbar im Falle eines Problems und reproduzierbar. Dabei wurde sich für \textit{FluxCD}\cite{fluxCNCF} entschieden, eine der GitOps-Implmentationen für Kubernetes. Eine Mögliche Alternative ist \textit{ArgoCD}, welches von Haus aus eine Nutzeroberfläche und weitere fortgeschrittene Features bietet, jedoch ist FluxCD weniger resourcenintensiv, nativer in das Kubernetes-Tooling verzahnt und integriert mit einem existierenden Headlamp-Plugin\cite{fluxHeadlampPlugin} nativ in die gewünschte Übersicht. Dabei hat FluxCD zwei für selektron relevante Pipelines: die GitOps-Pipeline und die Image-Controller-Pipeline. -Die GitOps Pipeline besteht aus \texttt{source-controller}, \texttt{kustomize-controller} und \texttt{helm-controller}.\\ -Der \texttt{source-controller}\cite{fluxSourceController} überprüft in Gegebenem Intervall Angegebene Quellen wie \texttt{GitRepository}, \texttt{HelmRepository} oder \texttt{OCIRepository} und speichert sie als Cluster-lokales Artifact.\\ -Der \texttt{kustomize-controller}\cite{fluxKustomizeController} sucht nach auf dem Cluster existierenden Komponenten des Typs \texttt{Kustomization}. Sofern das in der Komponente definierte Intervall abgelaufen ist oder die Quelle, die vom Source-Controller überwacht wird, sich geändert hat, führt der Controller auf dem gegebenen Pfad einen Kustomize-Befehl aus, produziert .yaml Dateien, checkt diese gegen den aktuellen Stand, und wendet sie bei Änderungen an. Damit wird nach jedem Intervall jeglicher Drift überschrieben. Die Kustomization-Komponente kann mit Parameter \texttt{prune} alle unter das Kustomization fallenden nichtmehr existierenden Komponenten automatisch aufräumen. Mit Parameter \texttt{wait} oder \texttt{healthChecks} wartet die Kustomization bis alle bzw. die unter \texttt{healthChecks} definierten Komponenten bereit sind, bevor die Kustomization selbst als Bereit gilt. Somit fallen Fehlkonfigurationen schneller auf.\\ +Die \textit{GitOps Pipeline} besteht aus \texttt{source-controller}, \texttt{kustomize-controller} und \texttt{helm-controller}.\\ +Der \texttt{source-controller}\cite{fluxSourceController} überprüft in gegebenem Intervall angegebene Quellen Git-, Helm- oder OCI-Repositories und speichert sie als Cluster-lokales Artefakt.\\ +Der \texttt{kustomize-controller}\cite{fluxKustomizeController} sucht nach auf dem Cluster existierenden Komponenten des Typs \texttt{Kustomization}, einer CR von FluxCD. In Abständen die in der Komponente definiert sind, führt der Controller auf dem gegebenen Pfad einen \textit{Kustomize}-Befehl aus, produziert, ähnlich wie Helm, Komponentendeklarationsdateien, vergleicht diese mit den aktuellen Stand, und wendet sie bei Änderungen an. Damit wird nach jedem Intervall jeglicher Drift in den Konfigurationsdateien überschrieben. Die Kustomization-Komponente kann mit Parameter \texttt{prune} alle unter das Kustomization fallenden nichtmehr existierenden Komponenten automatisch aufräumen. Mit weiteren Parametern ist es möglich, die Kustomization so zu gestalten, dass alle Komponenten bereit sein müssen, bevor die Kustomization selbst als Bereit gilt. Somit fallen Fehlkonfigurationen schneller auf.\\ Der \texttt{helm-controller}\cite{fluxHelmController} greift analog zum Kustomize-Controller bei \texttt{HelmRelease}s statt \texttt{Kustomization}s, und setzt dabei Helm-Charts automatisch mit den gegebenen Values auf. -Die Image-Automation-Pipeline\cite{fluxImagePipeline} besteht aus dem \texttt{image-reflector-controller}, welcher \texttt{ImageRepository}s überwacht und deren Metadaten speichert. Er wertet mit einer \texttt{ImagePolicy} die gespeicherten Metadaten aus, und entscheidet welches der zu benutzende Tag ist. Mithilfe des \texttt{image-automation-controller}s und einer \texttt{ImageUpdateAutomation}-Komponente wird in einer Angegebenen Git-Repository der zu benutzende Tag committed. Somit übernimmt im Falle von Image-Updates FluxCD automatisch die Migration. +Die \textit{Image-Automation-Pipeline}\cite{fluxImagePipeline} besteht aus dem \texttt{image-reflector-controller}, welcher Container-Images überwacht und deren Metadaten speichert. Er wertet mit nutzerdefinierten Regeln die gespeicherten Metadaten aus, und entscheidet welches das zu benutzende Image ist. Mithilfe des \texttt{image-automation-controller}s und einer \texttt{ImageUpdateAutomation}-Komponente wird in einer Angegebenen Git-Repository der zu benutzende Tag committed. Somit übernimmt im Falle von Image-Updates FluxCD automatisch die Migration. -Mithilfe der beiden Pipelines kann FluxCD einen massiven Teil des Deployments übernehmen und gleichzeitig die Synchronisation der wunschkonfiguration aus einer gewählten Quelle und dem Clusterstatus übernehmen, um undokumentierte Zugriffe zu verhindern und einen höheren Transparenzgrad zu gewährleisten. +Mithilfe der beiden Pipelines kann FluxCD einen massiven Teil des Deployments automatisieren und gleichzeitig die Synchronisation der Wunschkonfiguration aus einer gewählten Quelle und dem Clusterstatus übernehmen, um undokumentierte Zugriffe zurückzusetzen und einen höheren Transparenzgrad zu gewährleisten. \subsection{High Availability, Longhorn und CloudNativePG}