Grundlegender Aufbau
Eine Kubernetes Umgebung besteht aus mehreren Komponenten.
System-Basis einer Kubernetes-Umgebung
Auf System-Ebene (also was die benötigten Systeme/Server angeht) wird zunächst nur zwischen Control-Plane und Worker-Nodes unterschieden.
- Control-Plane Hier werden die Basis-Komponenten zur Verwaltung und Steuerung einer Kubernetes-Umgebung zusammen gefasst.
- Worker-Node Auf diesen Nodes werden die eigentlichen Pods und Container betrieben.
Auf einem Single-System (z.B. bei einer Standard-Installation des K3s) laufen die Contraol-Plane und ein Worker-Node auf dem einen System.
In einem Cluster sollte aber gerade die Control-Plane auf eigenen Systemen (zumeist mindestens 3) abgetrennt von den Worker-Nodes betrieben werden.
Die Worker-Nodes können mit Hilfe von Taints in eigene Rollen unterteilt werden. Beispielsweise kann es Sinn machen die Ingress-Gateways auf gesonderten Systemen zu halten und diese von den eigentlichen Applikationen (ggf. in einem separaten Subnet) zu trennen.
Basis-Komponenten einer Kubernetes-Umgebung
Die folgenden Beschreibungen sollen vor allem dem Verständnis dienen und sind ggf. technisch nicht ganz korrekt ausgeführt - weiterführende und genauere Informationen sollten vor allem in der Dokumentation zu Kubernetes entnommen werden können.
Folgende Basis Komponenten werden für eine Kubernetes Plattform benötigt und sind immer vorhanden:
- etcd - die Datenbank mit Secrets, Konfigurationen und Definitionen der Umgebung
- coredns - der Cluster-interne DNS
Folgende Komponenten sind in Abhängigkeit der verwendeten Kubernetes-Plattform vorhanden:
- kube-apiserver - dies ist die API-Schnittstelle zur Kubernetes-Umgebung (zumeist auf Port 6443)
- kube-controller-manager - in Clustern eine Komponente um die Funktionalitäten wie Deployments und deren Ressourcen an die darunter liegenden Controller zu koordinieren
- kube-scheduler - Komponente um die Erstellung und Verteilung der Pods auf den Nodes abzuhandeln
Anmerkung: Bei K3s sind diese Komponenten nicht ersichtlich aber dennoch im System-Service vorhanden. Alle Kubernetes-Umgebungen sind über ihre API standardmäßig auf Port 6443 (HTTPS) erreichbar unabhängig ob es hierfür eine eigene Komponente gibt, oder nicht.
Folgende Komponenten werden benötigt, sind aber zumeist individuell einzurichten:
- CNI / Container Network Interface - diese Komponente stellt das Netzwerk innerhalb des Clusters bereit. Einerseits für die Pods und deren Containers, andererseits auch für die Services.
- Loadbalancer
- Ingress Gateway(s) - eine Art Reverse-Proxy um die Pods nach "Außen" erreichbar zu machen. Zumeist wird hier auf externe IPs zurück gegriffen, die über den darunter liegenden Loadbalancer zur Verfügung gestellt werden.
Folgende Komponenten sind zwar Bestandteil in vielen Umgebungen, aber auch von dieser abhängig:
- metrics-server - Komponente um Leistungsdaten aufzunehmen
- snapshot-controller - Bestandteil seit Kubernetes v1.27 aber bsplw. in K3s nicht vorhanden
- cloud-controller-manager - von der verwendeten Umgebung und ggf. dessen Provider abhängig. Es kann auch mehrere/verschiedene Cloud-Controller geben (teilweise auch abhängig der Netzwerk-Struktur für den Zugriff von Außen/den Internet her)
weitere empfohlene Komponenten:
- cert-manager - Zertifikats-Handling mit verschiedenen Möglichkeiten (zur Projekt-Site)
- trust-manager - Zusatz-Komponente vom Cert-Manager gerade für Trusts einer internen PKI / Root-CA
- stakater/reloader - Komponente um bei geänderten Objekten (Secrets, ConfigMaps usw.) ein Deployment oder Pods neu zu starten ( Projekt)
- Kubernetes NFS Subdir External Provisioner - Komponente um dynamische PVs von einem NFS-Server zu erzeugen ( Projekt Helm)
- Kyverno - zum Durchsetzen von Policies (zur Projekt-Site)
systemischer Aufbau
Innerhalb einer Kubernetes Umgebung bestehen verschiedene Layer zur Kommunikation, die die systemischen Komponenten miteinander verbinden.
In dem ersten Schaubild wird als Sidecar Container eine Datenbank betrieben, das zumeist nicht geeignet dafür ist. Sidecar Container werden zumeist nur für "kleinere" Sachen beispielsweise für Logging oder Monitoring eingesetzt. Bezüglich Datenbanken wird über einen Sidecar Container aber auch die Synchronisation geregelt.
Diese erste Darstellung soll aber auch die Möglichkeit veranschaulichen, dass bei mehreren Containern innerhalb eines
Pods mit localhost gearbeitet werden kann.
In folge ein etwas besseres Beispiel für ein entsprechendes Deployment:
Man achte auf die Namen beim Datenbank-Service (unterstrichen) und in den Commands (fettgedruckt) - hier wird der direkte Zusammenhang innerhalb eines Namespaces dargestellt.
schematische Darstellung der Komponenten
Es soll hier im Groben versucht werden das Zusammenspiel der Komponenten in einer Kubernetes Umgebung darzustellen.
grobe Beschreibung der Darstellung (des Ablaufs):
- ein DevOp definiert ein Deployment1 in einem (oder mehreren) Manifest(s) mit allen Angaben zu den benötigten Ressourcen
- das Deployment wird über die Kubernetes-API an den API-Manager übergeben
- der API-Manager prüft an Hand von RBAC-Regeln inwieweit alles ausgeführt werden darf (gibt ggf. eine Fehlermeldung aus) und übergibt die zugelassenen "Tasks" an dahinter liegende Komponenten (wie den Controller)
- der Controller steuert die Erstellung (bzw. Änderungen) an weiteren Ressourcen mithilfe des Schedulers
- mit dem lokal auf den Nodes vorhandenen kubelet werden dann die eigentlichen Ressourcen durch den Scheduler koordiniert erzeugt - der Scheduler entscheidet dabei auch auf welchen Nodes etwas erzeugt werden muss/soll
grobe Beschreibung eines Deployments
In einem (oder auch mehreren zusammen gelegten) Manifest zu einem Deployment gehören mehrere Komponenten. Hierzu gehören einerseits Ressourcen, die direkt von den Containern in einem Pod benötigt, aber auch Ressourcen die benötigt werden um auf den/die Pods als Service innerhalb, aber auch von außerhalb (durch einen Ingress-Gateway) des Clusters zugegriffen werden zu können.
Bei den Ressourcen für einen Pod können in Secrets und/oder ConfigMaps Environment-Variablen oder auch ganze Konfigurationsdateien eingebunden werden - diese werden im etcd gespeichert und nicht lokal auf den Platten des Nodes.
Hingegen können Daten in einem persistenten Volume (sog. PV) tatsächlich auch lokal auf einem Node (was in einem Cluster nicht unbedingt Sinn macht) oder in einem entfernten Speicher (z.B. via NFS) abgelegt werden. Ein PV wird über eine Storage Class (SC) definiert und über ein persistentes Volume Claim (PVC) als Volume in einen Pod eingebunden. Dabei können auch Sidecar- oder Init-Container innerhalb des Pods das Volume verwenden.
Eine weitere wichtige Ressource ist die Definition eines Services. Erst durch diese Definition können die Pods zu dem Deployment definiert angesprochen werden ohne die genauen (generierten) Namen der einzelnen Pods wissen zu müssen.
-
ein Deployment bezeichnet hier nicht den API Call im technischen Kontext, sondern die Beschreibung aller benötigten Ressourcen zum Aufbau einer Applikation im Kontext von DevOps-Arbeiten ↩