Architektur: Kubernetes
Workshop-Unterlage für Architektur, Betrieb und Troubleshooting von Kubernetes.
Stand: 13. Juni 2026
1. Ziel
Dieses Dokument beschreibt die fachliche Architektur von Kubernetes für einen praxisorientierten Workshop. Es erklärt nicht nur Begriffe, sondern verbindet Konzepte mit Betriebsentscheidungen, typischen Fehlerbildern und konkreten Manifesten.
Nach dem Workshop sollst du Kubernetes nicht als Sammlung einzelner YAML-Dateien sehen, sondern als zustandsbasiertes Steuerungssystem: Du beschreibst einen Zielzustand, Kubernetes validiert ihn, speichert ihn in der API und lässt Controller kontinuierlich daran arbeiten, den tatsächlichen Zustand an diesen Zielzustand anzugleichen.
Dieses Dokument dient als:
- Referenz für Workshop-Module und Übungen.
- Grundlage für Diskussionen über Plattformarchitektur.
- Einstieg in Troubleshooting und Betriebsverantwortung.
- Entscheidungshilfe bei Workload-, Netzwerk-, Storage- und Sicherheitsdesign.
Nicht Ziel dieses Dokuments ist eine vollständige Installationsanleitung für einen bestimmten Cloud-Anbieter oder eine konkrete Distribution wie AKS, EKS, GKE, OpenShift, Rancher oder k3s. Die Architekturprinzipien gelten clusterübergreifend; einzelne Implementierungen können sich im Detail unterscheiden.
2. Lernziele
Nach dem Durcharbeiten dieser Unterlage kannst du:
- erklären, welche Aufgaben Control Plane, Worker Nodes und Add-ons übernehmen,
- den Weg von einem Manifest bis zum laufenden Pod nachvollziehen,
- Deployments, ReplicaSets, Services, ConfigMaps, Secrets, PersistentVolumeClaims und Ingress/Gateway-Ressourcen fachlich einordnen,
- beurteilen, wann du welches Kubernetes-Objekt verwendest,
- typische Fehlerzustände wie
ImagePullBackOff,CrashLoopBackOff,Pending, fehlgeschlagene Readiness oder Netzwerkprobleme systematisch untersuchen, - Ressourcenanforderungen, Limits, Probes und Rollout-Strategien sinnvoll setzen,
- Sicherheitsmechanismen wie RBAC, ServiceAccounts, Admission Control, Pod Security und NetworkPolicies architektonisch einordnen,
- Betriebsentscheidungen dokumentieren, statt sie implizit in verstreuten YAML-Dateien zu verstecken.
3. Architekturüberblick
3.1. Grundidee
Kubernetes ist eine Plattform für den Betrieb containerisierter Anwendungen. Du beschreibst Anwendungen, Konfiguration, Netzwerkzugriff, Persistenz und Zugriffsrechte über API-Objekte. Kubernetes nimmt diese Objekte entgegen und koordiniert die Ausführung auf einem Cluster aus Maschinen.
Wichtig ist: Kubernetes startet nicht einfach Container. Kubernetes verwaltet Workloads. Ein Workload besteht aus gewünschtem Zustand, Scheduling-Entscheidung, Container-Laufzeit, Netzwerkidentität, Konfiguration, Sicherheit, Health Checks und Statusinformationen.
flowchart LR user[Du: Manifest, CLI oder GitOps] --> api[Kubernetes API Server] api --> store[(etcd: Cluster-Zustand)] api --> controllers[Controller] controllers --> scheduler[Scheduler] scheduler --> nodes[Worker Nodes] nodes --> pods[Pods und Container] pods --> services[Services, DNS, Ingress/Gateway] pods --> obs[Logs, Events, Metriken] obs --> user
Kubernetes trennt dabei mehrere Verantwortungsbereiche:
| Bereich | Kernfrage | Beispiele |
|---|---|---|
| API und Zustand | Was soll existieren? | Deployment, Service, Secret, Namespace |
| Scheduling | Wo soll ein Pod laufen? | Scheduler, Requests, Affinity, Taints |
| Laufzeit | Wie wird der Container gestartet? | Kubelet, containerd, CRI-O |
| Netzwerk | Wie erreichen sich Workloads? | CNI, Service, DNS, Ingress, Gateway API |
| Persistenz | Wo bleiben Daten erhalten? | PVC, PV, StorageClass, CSI |
| Sicherheit | Wer darf was und unter welchen Bedingungen? | RBAC, Admission Control, Pod Security, NetworkPolicy |
| Betrieb | Wie erkennst du Zustand und Fehler? | Events, Logs, Metriken, Traces, Alerts |
3.2. Control Plane, Worker Nodes und Add-ons
Ein Kubernetes-Cluster besteht aus einer Control Plane und einem oder mehreren Worker Nodes.
Die Control Plane hält den Clusterzustand, validiert API-Anfragen und trifft zentrale Steuerungsentscheidungen. Worker Nodes führen Pods aus. Add-ons ergänzen Funktionen, die Kubernetes als Plattform braucht, aber nicht zwingend als monolithischen Kernbestandteil mitbringt.
flowchart TB
subgraph CP[Control Plane]
api[kube-apiserver]
etcd[(etcd)]
sched[kube-scheduler]
cm[kube-controller-manager]
ccm[cloud-controller-manager]
end
subgraph W1[Worker Node]
kubelet1[kubelet]
proxy1[kube-proxy oder eBPF-Dataplane]
runtime1[Container Runtime]
pod1[Pods]
end
subgraph ADD[Add-ons]
dns[CoreDNS]
ingress[Ingress/Gateway Controller]
cni[CNI Plugin]
csi[CSI Driver]
metrics[Metrics/Logging]
end
api <--> etcd
cm --> api
sched --> api
kubelet1 <--> api
kubelet1 --> runtime1
runtime1 --> pod1
pod1 --> dns
pod1 --> cni
pod1 --> csi
ingress --> api
3.3. Reconciliation Loop
Der zentrale Betriebsmechanismus von Kubernetes ist der Reconciliation Loop. Controller beobachten die API, vergleichen gewünschten und tatsächlichen Zustand und führen Korrekturmaßnahmen aus.
Beispiel: Du definierst ein Deployment mit replicas: 3. Wenn nur zwei Pods laufen, erstellt der zuständige Controller einen weiteren Pod. Wenn vier Pods laufen, wird ein Pod entfernt. Kubernetes arbeitet also nicht primär befehlsorientiert, sondern zustandsorientiert.
flowchart LR desired[Gewünschter Zustand\nManifest in der API] --> compare[Controller vergleicht] actual[Tatsächlicher Zustand\nPods, Nodes, Netzwerk, Storage] --> compare compare --> action[Korrekturaktion] action --> actual
Für den Betrieb bedeutet das:
- Du untersuchst nicht nur, was du ausgeführt hast, sondern auch, welcher Zustand in der API gespeichert ist.
- Viele Probleme entstehen nicht durch einen einzelnen Befehl, sondern durch widersprüchliche Zielzustände.
- Controller erzeugen abgeleitete Objekte. Ein Deployment erzeugt ReplicaSets; ReplicaSets erzeugen Pods.
- Manuelle Änderungen an abgeleiteten Objekten sind meist nicht dauerhaft, weil der übergeordnete Controller sie wieder überschreibt.
4. Kubernetes-Denkmodell
4.1. Desired State
Der Desired State ist der gewünschte Zielzustand einer Ressource. Du beschreibst ihn in YAML oder JSON, meistens in YAML. Kubernetes speichert diesen Zustand in etcd und versucht, den tatsächlichen Zustand damit in Übereinstimmung zu bringen.
Beispiel:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: nginx
image: nginx:1.27
Damit sagst du nicht: „Starte jetzt drei Container.“ Du sagst: „Sorge dauerhaft dafür, dass drei passende Pod-Replikate existieren.“ Das ist ein wesentlicher Unterschied.
4.2. Deklarative API
Kubernetes verwendet eine deklarative API. Du beschreibst das Ergebnis, nicht jeden Zwischenschritt. Das passt gut zu GitOps und Infrastructure as Code, weil der gewünschte Zustand versionierbar und überprüfbar wird.
Typischer Workflow:
kubectl apply -f deployment.yaml
kubectl get deployment web
kubectl rollout status deployment/web
Wichtige Konsequenzen:
kubectl applyist für wiederholbares Anwenden von Manifesten gedacht.kubectl createeignet sich eher für einmaliges Erzeugen.kubectl editist praktisch im Labor, aber riskant im produktiven Betrieb, weil Änderungen nicht automatisch versioniert werden.- GitOps-Controller wie Argo CD oder Flux erwarten, dass Git der autoritative Zielzustand ist.
4.3. Ressourcen, Objekte und Controller
Eine Ressource ist ein Typ in der Kubernetes API, zum Beispiel Pod, Deployment oder Service. Ein Objekt ist eine konkrete Instanz dieser Ressource, zum Beispiel deployment/web.
Fast jedes Objekt enthält:
| Feld | Bedeutung |
|---|---|
apiVersion |
API-Gruppe und Version, zum Beispiel apps/v1 |
kind |
Ressourcentyp, zum Beispiel Deployment |
metadata |
Name, Namespace, Labels, Annotations, OwnerReferences |
spec |
Gewünschter Zustand |
status |
Beobachteter Zustand, meist von Controllern gesetzt |
Du änderst in der Regel spec, nicht status. Der status ist Ergebnis der Controllerarbeit und zeigt dir, was Kubernetes beobachtet.
4.4. Namen, Labels, Selectors und Annotations
Namen identifizieren Objekte innerhalb ihres Gültigkeitsbereichs. Ein Deployment-Name muss innerhalb eines Namespace eindeutig sein.
Labels sind strukturierte Schlüssel-Wert-Paare zur Auswahl und Gruppierung von Objekten. Services, ReplicaSets, NetworkPolicies und viele andere Ressourcen verwenden Label Selectors.
Annotations speichern zusätzliche Metadaten, die nicht primär für Selektion gedacht sind. Viele Controller verwenden Annotations für Konfiguration, Integrationen oder Tooling-Hinweise.
Beispiel:
metadata:
name: web
labels:
app.kubernetes.io/name: web
app.kubernetes.io/component: frontend
app.kubernetes.io/part-of: shop
environment: workshop
annotations:
owner: platform-team
documentation: "https://example.invalid/runbooks/web"
Empfehlung für den Workshop:
- Nutze ein konsistentes Label-Schema.
- Verwende Labels für Selektion und Gruppierung.
- Verwende Annotations für beschreibende oder tool-spezifische Zusatzinformationen.
- Plane Selectors vor der Erstellung. Bei Deployments ist der Selector praktisch eine grundlegende Identität der Ressource und sollte nicht nachträglich geändert werden.
4.5. Namespaces
Namespaces teilen einen Cluster logisch in Bereiche. Damit organisierst du Ressourcen, Berechtigungen, Quotas, NetworkPolicies und Namensräume. Ein Namespace ist aber keine vollständige Sicherheitsgrenze wie ein getrennter Cluster.
Typische Namespace-Strategien:
| Strategie | Beispiel | Bewertung |
|---|---|---|
| Nach Umgebung | dev, test, prod |
Einfach, aber bei vielen Teams schnell unübersichtlich |
| Nach Team | team-a, team-b |
Gut für Ownership und RBAC |
| Nach Anwendung | shop, billing, identity |
Gut bei klar getrennten Produkten |
| Nach Tenant | customer-a, customer-b |
Nur sinnvoll mit sauberer Isolation, Quotas und Policies |
Für produktive Workloads solltest du den Namespace default vermeiden. Lege explizite Namespaces an und dokumentiere, wem sie gehören, welche Quotas gelten und welche Zugriffe erlaubt sind.
Beispiel:
apiVersion: v1
kind: Namespace
metadata:
name: workshop
labels:
pod-security.kubernetes.io/enforce: baseline
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/warn: restricted
5. Komponenten
5.1. Control Plane
| Komponente | Aufgabe | Betriebsrelevanz |
|---|---|---|
kube-apiserver |
Zentrale API-Schicht. Nimmt Anfragen entgegen, authentifiziert, autorisiert, validiert und speichert Objekte. | Wenn die API nicht erreichbar ist, kannst du den Cluster nicht steuern. Fast alle Werkzeuge sprechen mit dem API Server. |
etcd |
Stark konsistenter Key-Value-Store für den Clusterzustand. | Backup, Restore, Performance und Sicherheit sind kritisch. Verlust von etcd bedeutet Verlust des autoritativen Clusterzustands. |
kube-scheduler |
Wählt geeignete Nodes für neue Pods anhand von Ressourcen, Constraints, Affinity, Taints und Policies. | Pods im Status Pending hängen oft mit Scheduling-Bedingungen zusammen. |
kube-controller-manager |
Führt integrierte Controller aus, zum Beispiel Deployment-, ReplicaSet-, Node- und Job-Controller. | Verantwortlich für Selbstheilung und Abgleich zwischen gewünschtem und tatsächlichem Zustand. |
cloud-controller-manager |
Integriert Kubernetes mit Cloud-Anbietern, zum Beispiel Load Balancer, Routen, Node-Metadaten und Volumes. | Relevant in Cloud-Clustern. Fehler zeigen sich oft bei LoadBalancer-Services, Node-Erkennung oder Cloud-Volumes. |
5.2. Worker Node
| Komponente | Aufgabe | Betriebsrelevanz |
|---|---|---|
kubelet |
Node-Agent. Registriert den Node, beobachtet PodSpecs und startet Container über die Container Runtime. | Zentrale Fehlerquelle bei Pod-Start, Volume-Mounts, Probes und Node-Zustand. |
| Container Runtime | Führt Container aus, zum Beispiel containerd oder CRI-O. | Image Pulls, Container-Start, Logs und Runtime-Fehler hängen hiermit zusammen. |
kube-proxy oder alternative Dataplane |
Setzt Service-Regeln auf Node-Ebene um, klassisch über iptables/ipvs; manche CNIs ersetzen dies durch eBPF. | Relevant bei Service-Erreichbarkeit, Load Balancing und Node-Port-Verhalten. |
| CNI Plugin | Stellt Pod-Netzwerk bereit. | Ohne funktionierendes CNI bleiben Pods oft in ContainerCreating, oder Pod-zu-Pod-Kommunikation scheitert. |
| CSI Node Plugin | Bindet Storage auf dem Node ein. | Relevant bei PVCs, Volume-Attach, Mount-Problemen und Storage-Performance. |
5.3. Cluster-Add-ons
| Add-on | Aufgabe | Typische Beispiele |
|---|---|---|
| DNS | Namensauflösung für Services und Pods. | CoreDNS |
| Ingress/Gateway Controller | Setzt externe HTTP(S)-Routen um. | NGINX Ingress, HAProxy, Traefik, Envoy Gateway, cloud-native Controller |
| Metrics | Liefert Ressourcennutzung für kubectl top und HPA. |
metrics-server, Prometheus Adapter |
| Logging | Sammelt und speichert Container-Logs. | Fluent Bit, Vector, Loki, Elasticsearch/OpenSearch |
| Monitoring | Metriken, Dashboards und Alerts. | Prometheus, Grafana, Alertmanager |
| Policy Engine | Validiert oder mutiert Ressourcen nach Organisationsregeln. | Kyverno, OPA Gatekeeper, ValidatingAdmissionPolicy |
| Certificate Management | Automatisiert Zertifikate. | cert-manager |
| GitOps | Synchronisiert Git-Zustand in den Cluster. | Argo CD, Flux |
6. Zentrale Kubernetes-Objekte
| Objekt | Zweck | Wann du es verwendest | Typische Fehler |
|---|---|---|---|
Namespace |
Logische Gruppierung von Ressourcen. | Team-, App-, Tenant- oder Umgebungsgrenzen. | Falscher Namespace-Kontext, fehlende Quotas, unklare Ownership. |
Pod |
Kleinste ausführbare Einheit. Enthält einen oder mehrere Container. | Meist indirekt über Controller wie Deployment oder Job. | Pending, CrashLoopBackOff, ImagePullBackOff, Probe-Fehler. |
ReplicaSet |
Hält eine gewünschte Anzahl identischer Pods. | Meist durch Deployments erzeugt, selten direkt. | Manuelle Änderungen werden vom Deployment überschrieben. |
Deployment |
Verwaltet stateless Anwendungen, Rollouts und Rollbacks. | Standardobjekt für Webservices, APIs und Worker ohne stabile Identität. | Falsche Selectors, fehlerhafte Images, zu aggressive Probes. |
StatefulSet |
Verwaltet Pods mit stabiler Identität und geordneter Skalierung. | Datenbanken, Broker, verteilte Systeme mit Identität. | Falsche Storage-Klasse, blockierende PVCs, ungeeignete Update-Strategie. |
DaemonSet |
Startet genau einen Pod pro passendem Node. | Node-Agenten, Logging, Monitoring, CNI/CSI-Komponenten. | Taints/Tolerations fehlen, Node-Selector passt nicht. |
Job |
Führt eine Aufgabe bis zum Abschluss aus. | Migrationen, Batch-Verarbeitung, einmalige Tasks. | RestartPolicy falsch, BackoffLimit zu hoch oder zu niedrig. |
CronJob |
Startet Jobs nach Zeitplan. | Regelmäßige Tasks, Backups, Reports. | Zeitzonen, Parallelität, verpasste Starts. |
Service |
Stabile virtuelle Adresse für wechselnde Pods. | Interne Kommunikation, Load Balancing innerhalb des Clusters. | Selector passt nicht, Endpoints fehlen, falscher Port. |
Ingress |
HTTP(S)-Routing von außen zu Services. | Klassisches Web-Ingress mit Host- und Pfadregeln. | Kein Ingress Controller, falsche Klasse, TLS-Fehler. |
Gateway / HTTPRoute |
Erweiterbares, rollenorientiertes Routing. | Moderne Alternative für komplexeres Traffic-Routing. | Gateway Controller fehlt, Listener und Route passen nicht zusammen. |
ConfigMap |
Nicht vertrauliche Konfiguration. | Feature Flags, URLs, Konfigurationsdateien. | Vertrauliche Daten versehentlich in ConfigMaps, Updates kommen nicht wie erwartet im Pod an. |
Secret |
Vertrauliche kleine Datenmengen. | Passwörter, Tokens, Zertifikate, Registry-Zugänge. | Base64 mit Verschlüsselung verwechselt, zu breite RBAC-Rechte. |
PersistentVolumeClaim |
Anforderung von persistentem Storage. | Daten, die Pod-Neustarts überleben müssen. | PVC bleibt Pending, StorageClass falsch, AccessMode passt nicht. |
StorageClass |
Beschreibt dynamische Storage-Provisionierung. | Standardisierung von Performance-, Reclaim- und Provisioner-Eigenschaften. | Falscher Default, unerwartete Löschsemantik. |
ServiceAccount |
Identität für Pods gegenüber der Kubernetes API. | Workloads mit API-Zugriff oder cloud-nativen Berechtigungen. | Zu viele Rechte, Default-ServiceAccount unkontrolliert genutzt. |
Role / RoleBinding |
Namespace-bezogene Berechtigungen. | Team- und App-spezifische Rechte. | Wildcards, falscher Namespace, zu breite Bindings. |
ClusterRole / ClusterRoleBinding |
Clusterweite Berechtigungen. | Cluster-Admin, Controller, clusterweite Reader. | Privilege Escalation durch zu breite Rechte. |
NetworkPolicy |
Erlaubt oder verbietet Pod-Netzwerkverkehr. | Segmentierung zwischen Apps, Namespaces und Datenbanken. | CNI unterstützt Policies nicht, Default-Allow bleibt aktiv. |
HorizontalPodAutoscaler |
Skaliert Replikate anhand von Metriken. | Lastabhängige Skalierung stateless Workloads. | Metrics fehlen, Requests fehlen, Skalierung oszilliert. |
PodDisruptionBudget |
Begrenzt gleichzeitige freiwillige Unterbrechungen. | Hochverfügbare Deployments bei Node-Drain oder Upgrades. | Zu strikte PDBs blockieren Wartung. |
7. Von Manifest zu laufendem Pod
Wenn du ein Manifest anwendest, laufen mehrere Schritte ab. Diese Schritte sind für Troubleshooting entscheidend.
sequenceDiagram participant Du participant API as kube-apiserver participant Etcd as etcd participant Ctrl as Controller participant Sched as Scheduler participant Kubelet as kubelet participant Runtime as Container Runtime Du->>API: kubectl apply -f deployment.yaml API->>API: Authentifizierung, Autorisierung, Admission, Validierung API->>Etcd: Objekt speichern Ctrl->>API: Deployment beobachten Ctrl->>API: ReplicaSet und Pods erzeugen Sched->>API: unscheduled Pods beobachten Sched->>API: Node-Binding setzen Kubelet->>API: PodSpec für eigenen Node abrufen Kubelet->>Runtime: Images ziehen, Container starten Runtime-->>Kubelet: Status und Logs Kubelet->>API: PodStatus aktualisieren
Wichtige Diagnosepunkte:
| Phase | Was du prüfst | Beispielkommando |
|---|---|---|
| API-Annahme | Wurde das Objekt akzeptiert? | kubectl apply -f file.yaml --dry-run=server |
| Admission | Wurde das Objekt durch Policies abgelehnt oder verändert? | kubectl describe und Events prüfen |
| Controller | Wurden abgeleitete Objekte erzeugt? | kubectl get rs,pods -l app=web |
| Scheduling | Wurde ein Node ausgewählt? | kubectl describe pod <pod> |
| Image Pull | Kann das Image geladen werden? | kubectl describe pod <pod> |
| Container Start | Startet der Prozess? | kubectl logs <pod> |
| Readiness | Wird der Pod in Services aufgenommen? | kubectl get endpointslice |
| Netzwerk | Ist Service/DNS erreichbar? | Debug-Pod mit curl, nslookup, dig |
8. Workloads, Deployment und Updates
8.1. Pods als kleinste Einheit
Ein Pod ist die kleinste Einheit, die Kubernetes direkt ausführen kann. Ein Pod enthält einen oder mehrere Container, die Netzwerk-Namespace, IP-Adresse und optional Volumes teilen.
In der Praxis besteht ein Pod meistens aus genau einem Applikationscontainer. Mehrere Container in einem Pod solltest du nur verwenden, wenn sie eng gekoppelt sind und gemeinsam auf demselben Node laufen müssen.
Typische Mehr-Container-Muster:
| Muster | Beschreibung | Beispiel |
|---|---|---|
| Sidecar | Ergänzt den Hauptcontainer dauerhaft. | Log-Forwarder, Service-Mesh-Proxy |
| Init Container | Läuft vor dem Start der Hauptcontainer. | Migration, Konfigurationsvorbereitung |
| Adapter | Übersetzt Formate oder Protokolle. | Metriken von proprietärem Format nach Prometheus |
| Ambassador | Vermittelt zu externen Diensten. | Proxy für ausgehende Verbindung |
Pods sind grundsätzlich kurzlebig. Wenn ein Pod gelöscht wird, erhält ein Ersatz-Pod eine neue UID und meistens eine neue IP. Deshalb solltest du Pods nicht direkt adressieren, sondern über Services, Labels und Controller arbeiten.
8.2. ReplicaSets und Deployments
Ein ReplicaSet sorgt dafür, dass eine bestimmte Anzahl identischer Pods läuft. Ein Deployment verwaltet ReplicaSets und bietet zusätzliche Funktionen wie Rollouts, Rollbacks und Rollout-Historie.
Im Workshop arbeitest du für stateless Anwendungen fast immer mit Deployments, nicht direkt mit ReplicaSets.
flowchart TB dep[Deployment] --> rs1[ReplicaSet Revision 1] dep --> rs2[ReplicaSet Revision 2] rs1 --> oldpods[alte Pods] rs2 --> newpods[neue Pods]
Grundregeln:
- Ändere das Pod Template eines Deployments, wenn du ein neues Rollout auslösen willst.
- Skaliere über
spec.replicasoder einen Autoscaler. - Bearbeite Pods eines Deployments nicht manuell als dauerhafte Lösung.
- Wähle Labels und Selectors bewusst, da sie die Verbindung zwischen Deployment, ReplicaSet, Pods und Service herstellen.
8.3. Rolling Updates und Rollbacks
Ein Rolling Update ersetzt alte Pods schrittweise durch neue Pods. Dadurch kann eine Anwendung verfügbar bleiben, während eine neue Version ausgerollt wird.
Wichtige Parameter:
| Feld | Bedeutung |
|---|---|
maxUnavailable |
Wie viele gewünschte Pods während des Rollouts nicht verfügbar sein dürfen. |
maxSurge |
Wie viele zusätzliche Pods temporär über die Zielanzahl hinaus erstellt werden dürfen. |
minReadySeconds |
Wie lange ein Pod bereit sein muss, bevor er als verfügbar zählt. |
progressDeadlineSeconds |
Wie lange ein Rollout ohne Fortschritt laufen darf. |
Nützliche Kommandos:
kubectl rollout status deployment/web -n workshop
kubectl rollout history deployment/web -n workshop
kubectl rollout undo deployment/web -n workshop
kubectl describe deployment web -n workshop
Wenn ein Rollout hängen bleibt, prüfst du zuerst die neuen Pods:
kubectl get pods -n workshop -l app=web
kubectl describe pod <pod-name> -n workshop
kubectl logs <pod-name> -n workshop
8.4. Beispiel: Deployment mit Ressourcen und Probes
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
namespace: workshop
labels:
app.kubernetes.io/name: web
app.kubernetes.io/component: frontend
spec:
replicas: 3
revisionHistoryLimit: 5
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
selector:
matchLabels:
app.kubernetes.io/name: web
app.kubernetes.io/component: frontend
template:
metadata:
labels:
app.kubernetes.io/name: web
app.kubernetes.io/component: frontend
spec:
containers:
- name: web
image: nginx:1.27
ports:
- name: http
containerPort: 80
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 256Mi
startupProbe:
httpGet:
path: /
port: http
failureThreshold: 30
periodSeconds: 2
readinessProbe:
httpGet:
path: /
port: http
initialDelaySeconds: 3
periodSeconds: 5
livenessProbe:
httpGet:
path: /
port: http
initialDelaySeconds: 10
periodSeconds: 10
Bewertung dieses Beispiels:
requestsgeben dem Scheduler eine belastbare Planungsgrundlage.limitsverhindern unbegrenzte Ressourcennutzung, können bei CPU aber auch zu Throttling führen.startupProbeschützt langsam startende Anwendungen vor zu frühen Liveness-Restarts.readinessProbesteuert, ob der Pod Traffic erhalten soll.livenessProbesollte nur echte Deadlocks oder nicht selbst heilbare Zustände erkennen.
9. Netzwerkarchitektur
9.1. Kubernetes-Netzwerkmodell
Kubernetes geht von einem flachen Pod-Netzwerk aus: Jeder Pod kann grundsätzlich jeden anderen Pod über dessen Pod-IP erreichen, ohne Network Address Translation auf Pod-Ebene. Wie dieses Modell technisch umgesetzt wird, hängt vom CNI-Plugin ab.
Wichtige Netzwerkebenen:
| Ebene | Zweck | Typische Komponenten |
|---|---|---|
| Pod-Netzwerk | Pod-zu-Pod-Kommunikation. | CNI, Routing, Overlay oder native Cloud-Routen |
| Service-Netzwerk | Stabile virtuelle Adresse für dynamische Pods. | Service, EndpointSlice, kube-proxy/eBPF |
| DNS | Namensauflösung für Services und teilweise Pods. | CoreDNS |
| Ingress/Gateway | Externe HTTP(S)-Routen in den Cluster. | Ingress Controller, Gateway Controller |
| NetworkPolicy | Segmentierung und Zugriffskontrolle. | CNI mit Policy-Unterstützung |
9.2. Services und Service Discovery
Pods sind kurzlebig und erhalten neue IP-Adressen. Services bieten eine stabile Abstraktion über eine Gruppe von Pods.
Beispiel:
apiVersion: v1
kind: Service
metadata:
name: web
namespace: workshop
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: web
app.kubernetes.io/component: frontend
ports:
- name: http
port: 80
targetPort: http
Service-Typen:
| Typ | Zweck | Verwendung |
|---|---|---|
ClusterIP |
Interne stabile Adresse im Cluster. | Standard für interne Kommunikation. |
NodePort |
Öffnet einen Port auf jedem Node. | Labor, einfache externe Zugriffe, Basis für manche LoadBalancer-Implementierungen. |
LoadBalancer |
Beauftragt externe Load-Balancer-Infrastruktur. | Cloud-Umgebungen oder Bare-Metal mit passender Integration. |
ExternalName |
DNS-Alias auf externen Namen. | Abstraktion externer Dienste. |
| Headless Service | Kein ClusterIP, direkte DNS-Antworten für Endpoints. | StatefulSets, direkte Pod-Adressierung, Service Discovery für Stateful Workloads. |
DNS-Namen folgen typischerweise diesem Muster:
<service>.<namespace>.svc.cluster.local
Für einen Service web im Namespace workshop also:
web.workshop.svc.cluster.local
Innerhalb desselben Namespace reicht oft web, weil die DNS-Suchliste des Pods ergänzt wird.
9.3. Ingress und Gateway API
Ingress beschreibt HTTP- und HTTPS-Routing von außerhalb des Clusters zu Services im Cluster. Ein Ingress-Objekt wirkt nur, wenn ein passender Ingress Controller installiert ist.
Beispiel:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web
namespace: workshop
spec:
ingressClassName: nginx
rules:
- host: web.example.invalid
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web
port:
number: 80
Für neue Plattformarchitekturen solltest du auch die Gateway API prüfen. Diese API ist rollenorientierter und ausdrucksstärker als klassisches Ingress, insbesondere wenn mehrere Teams Infrastruktur, Routing und Anwendungen getrennt verantworten.
Konzeptioneller Unterschied:
| Thema | Ingress | Gateway API |
|---|---|---|
| Fokus | HTTP(S)-Routing über ein einzelnes Objektmodell. | Rollenorientiertes Modell mit GatewayClass, Gateway und Routes. |
| Erweiterbarkeit | Häufig über controller-spezifische Annotations. | Als API-Modell stärker auf Erweiterbarkeit ausgelegt. |
| Teamgrenzen | Weniger explizit. | Bessere Trennung zwischen Plattformteam und App-Team. |
| Status | Stabil, aber funktional eingefroren. | Moderne Weiterentwicklung über Gateway API Ressourcen. |
9.4. NetworkPolicies
Ohne NetworkPolicies erlauben viele Cluster standardmäßig Kommunikation zwischen Pods. Eine NetworkPolicy definiert, welcher Ingress- und/oder Egress-Traffic für ausgewählte Pods erlaubt ist. Die Durchsetzung hängt vom CNI-Plugin ab.
Beispiel: Nur Pods mit Label app.kubernetes.io/name: web dürfen eine Datenbank auf Port 5432 erreichen.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-web-to-db
namespace: workshop
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: db
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app.kubernetes.io/name: web
ports:
- protocol: TCP
port: 5432
Betriebsregeln:
- Prüfe, ob dein CNI NetworkPolicies tatsächlich unterstützt.
- Beginne mit klaren Default-Deny-Policies, aber plane Ausnahmen bewusst.
- Denke an DNS-Egress, wenn du Egress-Policies einführst.
- Dokumentiere erlaubte Kommunikationsbeziehungen als Teil der Anwendungsarchitektur.
10. Storage und Persistenz
Container-Dateisysteme sind kurzlebig. Wenn ein Pod ersetzt wird, darfst du nicht davon ausgehen, dass lokale Daten erhalten bleiben. Kubernetes trennt deshalb Workload und Storage über Volumes, PersistentVolumes und PersistentVolumeClaims.
Wichtige Begriffe:
| Begriff | Bedeutung |
|---|---|
emptyDir |
Temporärer Speicher für die Lebensdauer eines Pods. Wird gelöscht, wenn der Pod entfernt wird. |
PersistentVolume |
Clusterweite Repräsentation eines Storage-Volumes. |
PersistentVolumeClaim |
Namespace-bezogene Anforderung von Storage durch eine Anwendung. |
StorageClass |
Definiert dynamische Provisionierung, Provisioner, Parameter und Reclaim-Verhalten. |
| CSI | Standardisierte Schnittstelle, über die Storage-Anbieter Volumes bereitstellen. |
Beispiel für einen PVC:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: data
namespace: workshop
spec:
accessModes:
- ReadWriteOnce
storageClassName: standard
resources:
requests:
storage: 10Gi
Typische Architekturfragen:
- Ist die Anwendung stateless oder stateful?
- Muss Storage zonen- oder regionenübergreifend verfügbar sein?
- Welcher
accessModeist erforderlich:ReadWriteOnce,ReadOnlyMany,ReadWriteManyoderReadWriteOncePod? - Was passiert beim Löschen eines PVCs?
- Wie werden Backups, Restores und Migrationen getestet?
- Welche Latenz und IOPS braucht die Anwendung wirklich?
Für Datenbanken im Kubernetes-Cluster brauchst du deutlich mehr Architekturarbeit als für stateless Webservices. StatefulSets lösen Identität und geordnete Starts, ersetzen aber kein Backup-Konzept, keine Replikationsstrategie und kein Disaster-Recovery-Verfahren.
11. Konfiguration und Secrets
Konfiguration gehört nicht fest ins Container-Image. Kubernetes trennt Anwendungscode, nicht vertrauliche Konfiguration und vertrauliche Daten.
| Objekt | Geeignet für | Nicht geeignet für |
|---|---|---|
ConfigMap |
Nicht vertrauliche Konfiguration, URLs, Feature Flags, Textdateien. | Passwörter, Tokens, private Schlüssel. |
Secret |
Kleine vertrauliche Daten wie Passwörter, Tokens, Zertifikate. | Große Dateien, vollständige Secret-Management-Strategie ohne Zusatzschutz. |
Beispiel ConfigMap:
apiVersion: v1
kind: ConfigMap
metadata:
name: web-config
namespace: workshop
data:
LOG_LEVEL: "info"
FEATURE_CHECKOUT: "enabled"
Beispiel Secret:
apiVersion: v1
kind: Secret
metadata:
name: database-credentials
namespace: workshop
type: Opaque
stringData:
username: app
password: change-me-in-real-life
Verwendung im Pod:
envFrom:
- configMapRef:
name: web-config
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: database-credentials
key: password
Betriebshinweise:
- Secrets sind nicht automatisch gleichbedeutend mit starker Verschlüsselung. Plane Verschlüsselung ruhender Daten, RBAC, Audit und gegebenenfalls externe Secret Stores.
- ConfigMap- und Secret-Updates verhalten sich unterschiedlich je nach Einbindung. Umgebungsvariablen werden erst bei Pod-Neustart neu gesetzt; gemountete Dateien können aktualisiert werden, aber nicht in jedem Sonderfall sofort.
- Vermeide Secrets in Logs, Events, Kommandozeilenargumenten und CI-Ausgaben.
- Nutze getrennte Secrets pro Anwendung und Zweck, nicht ein globales Sammel-Secret.
12. Ressourcenmanagement und Scheduling
12.1. Requests, Limits und QoS
Kubernetes plant Pods anhand ihrer Requests. Limits begrenzen die maximale Nutzung.
| Feld | Wirkung |
|---|---|
resources.requests.cpu |
CPU-Menge, die der Scheduler für die Platzierung berücksichtigt. |
resources.requests.memory |
Memory-Menge, die der Scheduler für die Platzierung berücksichtigt. |
resources.limits.cpu |
Maximale CPU-Nutzung; kann zu CPU-Throttling führen. |
resources.limits.memory |
Maximale Speichernutzung; Überschreitung führt typischerweise zu OOMKill. |
Beispiel:
resources:
requests:
cpu: 250m
memory: 256Mi
limits:
cpu: 1000m
memory: 512Mi
QoS-Klassen:
| QoS-Klasse | Bedingung | Bedeutung |
|---|---|---|
Guaranteed |
Für alle Container sind CPU und Memory Request gleich Limit. | Höchste Stabilität bei Ressourcendruck. |
Burstable |
Mindestens ein Request ist gesetzt, aber nicht alles ist Guaranteed. | Häufiger Standard für Anwendungen. |
BestEffort |
Keine Requests und Limits gesetzt. | Höchstes Risiko bei Ressourcendruck. |
Workshop-Regel: Setze für produktionsnahe Beispiele immer Requests. Ohne Requests kann der Scheduler keine realistische Kapazitätsentscheidung treffen.
12.2. Node-Auswahl, Affinity und Taints
Der Scheduler wählt Nodes anhand vieler Kriterien. Du kannst diese Auswahl beeinflussen.
| Mechanismus | Zweck | Beispiel |
|---|---|---|
nodeSelector |
Einfache harte Node-Auswahl über Labels. | Nur Linux-Nodes, nur GPU-Nodes. |
| Node Affinity | Ausdrucksstärkere Node-Auswahl mit harten und weichen Regeln. | Zone, Hardwareklasse, Compliance-Label. |
| Pod Affinity | Pods in die Nähe anderer Pods bringen. | Cache neben App. |
| Pod Anti-Affinity | Pods voneinander trennen. | Replikate über Nodes oder Zonen verteilen. |
| Taints und Tolerations | Nodes weisen Pods ab, sofern Pods keine passende Toleration haben. | Dedizierte Nodes für Datenbanken oder GPU-Workloads. |
| Topology Spread Constraints | Gleichmäßige Verteilung über Topologien. | Replikate über Zonen verteilen. |
Beispiel Toleration:
tolerations:
- key: "workload"
operator: "Equal"
value: "platform"
effect: "NoSchedule"
Beispiel Node Affinity:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: topology.kubernetes.io/zone
operator: In
values:
- eu-central-1a
- eu-central-1b
12.3. Quotas und Limits pro Namespace
ResourceQuotas begrenzen den aggregierten Ressourcenverbrauch eines Namespace. LimitRanges können Default-Werte oder Mindest- und Höchstwerte für Pods und Container setzen.
Beispiel ResourceQuota:
apiVersion: v1
kind: ResourceQuota
metadata:
name: workshop-quota
namespace: workshop
spec:
hard:
requests.cpu: "4"
requests.memory: 8Gi
limits.cpu: "8"
limits.memory: 16Gi
pods: "20"
Architekturhinweis: Quotas schützen nicht vor jeder Form von Überlastung, aber sie verhindern, dass ein Namespace unbegrenzt Ressourcen verbraucht oder Objekte erzeugt.
12.4. Autoscaling und Disruption Budgets
Der Horizontal Pod Autoscaler skaliert Replikate anhand beobachteter Metriken. Dafür brauchst du passende Metrikquellen und sinnvolle Requests.
Beispiel HPA:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web
namespace: workshop
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
Ein PodDisruptionBudget begrenzt freiwillige Unterbrechungen, zum Beispiel bei Node-Wartung:
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: web
namespace: workshop
spec:
minAvailable: 2
selector:
matchLabels:
app.kubernetes.io/name: web
app.kubernetes.io/component: frontend
Wichtig: Ein PDB schützt nicht vor allen Ausfällen. Es wirkt vor allem bei freiwilligen Disruptions wie kubectl drain, nicht bei ungeplanten Node-Abstürzen.
13. Health Checks und Lifecycle
Kubernetes kennt verschiedene Probes. Du solltest sie nicht austauschbar verwenden.
| Probe | Zweck | Fehlwirkung bei falscher Nutzung |
|---|---|---|
startupProbe |
Prüft, ob eine langsam startende Anwendung überhaupt initial hochgefahren ist. | Ohne sie kann livenessProbe zu früh neu starten. |
readinessProbe |
Prüft, ob ein Pod Traffic erhalten soll. | Falsch konfigurierte Readiness nimmt gesunde Pods aus dem Service. |
livenessProbe |
Prüft, ob ein Container neu gestartet werden muss. | Zu aggressive Liveness erzeugt Crash-Loops. |
Pod-Lifecycle vereinfacht:
stateDiagram-v2 [*] --> Pending Pending --> Running Running --> Succeeded Running --> Failed Running --> Terminating Terminating --> [*]
Betriebsregeln:
- Readiness sollte Abhängigkeiten prüfen, die für Traffic-Annahme relevant sind.
- Liveness sollte nur Zustände prüfen, die durch Neustart wahrscheinlich behoben werden.
- Startup-Probes sind sinnvoll bei langsamen Anwendungen, JVMs, Migrationen oder großem Cache-Aufbau.
- Probes dürfen die Anwendung nicht selbst überlasten.
- Probe-Endpunkte sollten schnell, deterministisch und möglichst ohne teure Abfragen sein.
14. Sicherheit
14.1. Zugriff auf die Kubernetes API
Der API Server ist der zentrale Kontrollpunkt. Jede Anfrage durchläuft mehrere Phasen:
- Authentifizierung: Wer stellt die Anfrage?
- Autorisierung: Darf diese Identität die Aktion ausführen?
- Admission Control: Wird das Objekt akzeptiert, abgelehnt oder verändert?
- Persistenz: Wird der neue Zustand in
etcdgespeichert?
flowchart LR req[API Request] --> authn[Authentifizierung] authn --> authz[Autorisierung] authz --> adm[Admission Control] adm --> val[Validierung] val --> etcd[(etcd)]
Für deinen lokalen Zugriff nutzt kubectl eine kubeconfig. Eine kubeconfig enthält Cluster-, Benutzer- und Kontextinformationen. Behandle kubeconfig-Dateien wie sensible Zugangsdaten.
14.2. RBAC und ServiceAccounts
RBAC definiert, welche Subjekte welche Verben auf welchen Ressourcen ausführen dürfen.
| Begriff | Bedeutung |
|---|---|
| Subject | Benutzer, Gruppe oder ServiceAccount. |
| Verb | Aktion wie get, list, watch, create, update, patch, delete. |
| Resource | API-Ressource wie pods, deployments, secrets. |
| Role | Berechtigungen innerhalb eines Namespace. |
| ClusterRole | Clusterweite oder wiederverwendbare Berechtigungen. |
| RoleBinding | Bindet Role oder ClusterRole an Subjects in einem Namespace. |
| ClusterRoleBinding | Bindet ClusterRole clusterweit. |
Beispiel: Ein ServiceAccount darf Pods im Namespace lesen.
apiVersion: v1
kind: ServiceAccount
metadata:
name: pod-reader
namespace: workshop
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-reader
namespace: workshop
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: pod-reader
namespace: workshop
subjects:
- kind: ServiceAccount
name: pod-reader
namespace: workshop
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: pod-reader
Betriebsregeln:
- Vergib minimale Rechte.
- Vermeide Wildcards wie
*, wenn sie nicht zwingend nötig sind. - Prüfe Rechte mit
kubectl auth can-i. - Gib Workloads eigene ServiceAccounts statt den Default-ServiceAccount unkontrolliert zu verwenden.
- Sei besonders vorsichtig mit Rechten auf
secrets,nodes,pods/exec,pods/attach,roles,rolebindings,clusterrolesundclusterrolebindings.
14.3. Admission Control und Pod Security
Admission Controller prüfen API-Anfragen nach Authentifizierung und Autorisierung, aber vor dem Speichern. Damit lassen sich Objekte validieren oder verändern.
Typische Einsatzfälle:
- Erzwingen von Labels und Ownership-Metadaten.
- Verhindern privilegierter Container.
- Erzwingen von Resource Requests.
- Verhindern von Images aus nicht freigegebenen Registries.
- Setzen von Default-Werten.
- Prüfung von Pod Security Standards.
Pod Security Admission kann Namespaces mit Sicherheitsstufen versehen:
| Level | Zweck |
|---|---|
privileged |
Wenig Einschränkungen, für hochprivilegierte System-Workloads. |
baseline |
Verhindert bekannte riskante Einstellungen, bleibt aber relativ kompatibel. |
restricted |
Stärker gehärtet, für sicherheitskritische Workloads empfohlen. |
Beispiel Namespace-Labels:
metadata:
labels:
pod-security.kubernetes.io/enforce: baseline
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/warn: restricted
14.4. Secret-Schutz
Secrets brauchen technische und organisatorische Schutzmaßnahmen.
Checkliste:
- Aktiviere Verschlüsselung ruhender Daten für Secrets im Cluster.
- Beschränke
get,listundwatchauf Secrets sehr streng. - Vermeide Secret-Werte in Umgebungsvariablen, wenn Prozesslisten, Dumps oder Debugging sie offenlegen könnten.
- Bevorzuge externe Secret Stores, wenn Organisation, Rotation und Audit dies erfordern.
- Prüfe, ob Backup-Systeme Secrets verschlüsselt speichern.
- Rotiere Secrets und dokumentiere Rotation als Betriebsprozess.
14.5. Image- und Supply-Chain-Sicherheit
Kubernetes führt Images aus, die du referenzierst. Die Plattform löst nicht automatisch alle Risiken rund um Image-Herkunft und Inhalt.
Empfehlungen:
- Nutze vertrauenswürdige Registries.
- Verwende möglichst unveränderliche Image-Referenzen über Digests statt nur Tags.
- Scanne Images auf bekannte Schwachstellen.
- Signiere Images oder prüfe Signaturen, wenn deine Plattform dies unterstützt.
- Vermeide
latestin produktiven Manifesten. - Setze
imagePullPolicybewusst. - Verwende schlanke Basisimages und entferne unnötige Tools.
15. Beobachtbarkeit
Kubernetes liefert mehrere Beobachtungsebenen. Keine einzelne Ebene reicht alleine aus.
| Ebene | Zweck | Beispiele |
|---|---|---|
| Objektstatus | Aktueller Zustand von Kubernetes-Objekten. | kubectl get, kubectl describe |
| Events | Zeitliche Hinweise auf Scheduling, Pulls, Mounts und Probe-Fehler. | kubectl get events |
| Logs | Ausgabe von Containern. | kubectl logs |
| Metriken | Ressourcen, Latenzen, Fehlerraten, Sättigung. | Prometheus, metrics-server |
| Traces | Anfragepfade über Services hinweg. | OpenTelemetry, Jaeger, Tempo |
| Audit Logs | API-Zugriffe und administrative Aktionen. | API Server Audit Logging |
Minimaler Beobachtungsansatz im Workshop:
kubectl get all -n workshop
kubectl get events -n workshop --sort-by=.lastTimestamp
kubectl describe deployment web -n workshop
kubectl describe pod <pod-name> -n workshop
kubectl logs <pod-name> -n workshop
kubectl top pods -n workshop
Für Produktion brauchst du zusätzlich:
- zentrale Log-Ablage,
- Metriken mit Alerts,
- Dashboards nach Service-Level-Indikatoren,
- Audit Logs,
- Runbooks,
- klare Ownership pro Namespace und Anwendung.
16. Troubleshooting
16.1. Systematische Vorgehensweise
Nutze eine feste Reihenfolge, damit du nicht zufällig suchst.
Kontext prüfen
kubectl config current-context kubectl config view --minify kubectl get nsObjekte im Namespace prüfen
kubectl get all -n workshop kubectl get deploy,rs,pods,svc,endpointslice -n workshopEvents lesen
kubectl get events -n workshop --sort-by=.lastTimestampBetroffenes Objekt beschreiben
kubectl describe pod <pod-name> -n workshopLogs prüfen
kubectl logs <pod-name> -n workshop kubectl logs <pod-name> -n workshop --previousOwner-Kette verstehen
kubectl get pod <pod-name> -n workshop -o yaml | grep -A 10 ownerReferencesNetzwerk isoliert testen
kubectl run debug -n workshop --rm -it --image=curlimages/curl -- sh
16.2. Typische Fehlerbilder
| Symptom | Wahrscheinliche Ursache | Diagnose | Korrektur |
|---|---|---|---|
Pod bleibt Pending |
Keine passenden Nodes, zu hohe Requests, fehlende PVCs, Taints ohne Toleration. | kubectl describe pod Events lesen. |
Requests anpassen, Nodes bereitstellen, Tolerations/Affinity korrigieren, PVC prüfen. |
ImagePullBackOff |
Image existiert nicht, Registry nicht erreichbar, fehlendes ImagePullSecret. | Pod Events, Image-Name prüfen. | Image-Referenz korrigieren, Secret setzen, Registry-Zugang prüfen. |
CrashLoopBackOff |
Prozess beendet sich wiederholt, Konfiguration fehlt, Secret falsch, Startkommando fehlerhaft. | kubectl logs --previous, Exit Code. |
App-Konfiguration korrigieren, Startkommando prüfen, Ressourcen prüfen. |
CreateContainerConfigError |
Referenzierte ConfigMap oder Secret fehlt. | kubectl describe pod. |
Objekt erstellen oder Referenz korrigieren. |
ContainerCreating bleibt hängen |
CNI, Volume Mount oder Image-Download hängt. | Pod Events, Node-Zustand, kubelet-Logs. | CNI/CSI/Registry prüfen. |
| Readiness schlägt fehl | Endpoint falsch, App noch nicht bereit, Probe zu streng. | Pod Events, App-Logs, Probe-Endpunkt testen. | Readiness-Definition korrigieren, App-Fertigmeldung verbessern. |
| Liveness startet Pod ständig neu | Probe zu aggressiv oder prüft falsche Abhängigkeit. | Restart Count, Events, Logs. | Startup-Probe ergänzen, Liveness entschärfen. |
| Service hat keine Endpoints | Service-Selector passt nicht zu Pod-Labels oder Pods sind nicht ready. | kubectl get endpointslice, Labels vergleichen. |
Selector oder Labels korrigieren, Readiness prüfen. |
| DNS funktioniert nicht | CoreDNS gestört, falscher Namespace, NetworkPolicy blockiert DNS. | nslookup, CoreDNS-Logs, Egress-Policy. |
DNS-Service prüfen, FQDN nutzen, Policy anpassen. |
| Ingress liefert 404 | Host/Path-Regel falsch, falsche IngressClass, Backend-Service leer. | Ingress describe, Controller-Logs. | Regeln, Klasse und Service prüfen. |
PVC bleibt Pending |
Keine passende StorageClass, Provisioner fehlt, Zone passt nicht. | PVC Events, StorageClass, CSI-Controller. | StorageClass korrigieren, CSI prüfen, Kapazität bereitstellen. |
| Zugriff wird verweigert | RBAC fehlt oder falscher ServiceAccount. | kubectl auth can-i, PodSpec prüfen. |
Role/Binding korrigieren, ServiceAccount setzen. |
16.3. Nützliche kubectl-Kommandos
# Überblick
kubectl get nodes -o wide
kubectl get pods -A -o wide
kubectl get all -n workshop
# Status und Events
kubectl describe pod <pod-name> -n workshop
kubectl get events -n workshop --sort-by=.lastTimestamp
# Logs
kubectl logs <pod-name> -n workshop
kubectl logs <pod-name> -n workshop --previous
kubectl logs deployment/web -n workshop
# Rollouts
kubectl rollout status deployment/web -n workshop
kubectl rollout history deployment/web -n workshop
kubectl rollout undo deployment/web -n workshop
# Labels und Selectors
kubectl get pods -n workshop --show-labels
kubectl get pods -n workshop -l app.kubernetes.io/name=web
# Services und Endpoints
kubectl get svc,endpointslice -n workshop
kubectl describe svc web -n workshop
# YAML anzeigen
kubectl get deployment web -n workshop -o yaml
kubectl explain deployment.spec.template.spec.containers.resources
# Berechtigungen prüfen
kubectl auth can-i get pods -n workshop
kubectl auth can-i list secrets -n workshop --as=system:serviceaccount:workshop:pod-reader
# Debug-Pod starten
kubectl run debug -n workshop --rm -it --image=busybox:1.36 -- sh
17. Architekturentscheidungen
Dokumentiere Architekturentscheidungen explizit. Kubernetes-Manifestdateien zeigen, was konfiguriert ist, aber nicht immer, warum es so konfiguriert wurde.
Leitfragen:
Zielzustand und Ownership
- Wo liegt der autoritative Zielzustand: Git, CI/CD-System, Helm-Repository, GitOps-Controller oder manuelle API?
- Wer darf produktive Manifeste ändern?
- Wie werden Änderungen reviewed, getestet und ausgerollt?
- Wie werden Rollbacks durchgeführt?
Namespace- und Tenant-Modell
- Welche Namespaces gibt es und wem gehören sie?
- Sind Namespaces nach Team, Anwendung, Umgebung oder Tenant geschnitten?
- Welche Quotas und LimitRanges gelten?
- Welche NetworkPolicies gelten standardmäßig?
Workload-Modell
- Ist die Anwendung stateless oder stateful?
- Reicht ein Deployment, oder brauchst du StatefulSet, DaemonSet, Job oder CronJob?
- Welche Replikatanzahl ist minimal erforderlich?
- Welche Update-Strategie ist akzeptabel?
- Wie wird Verfügbarkeit während Wartung sichergestellt?
Ressourcen
- Welche Requests und Limits sind realistisch?
- Wie wird Last getestet?
- Gibt es HPA, VPA oder Cluster Autoscaler?
- Wie erkennst du CPU-Throttling, OOMKills und Node-Druck?
Netzwerk
- Welche Services müssen intern erreichbar sein?
- Welche externen Endpunkte gibt es?
- Wird Ingress oder Gateway API verwendet?
- Welche TLS-Strategie gilt?
- Welche Kommunikationsbeziehungen werden durch NetworkPolicies erlaubt?
Storage
- Welche Daten müssen persistent sein?
- Welche StorageClass wird verwendet?
- Welche Backup- und Restore-Prozesse sind getestet?
- Was passiert bei Zonen- oder Node-Ausfall?
- Welche Daten dürfen gelöscht werden und welche nicht?
Sicherheit
- Welche ServiceAccounts verwendet die Anwendung?
- Welche RBAC-Rechte sind wirklich nötig?
- Welche Admission-Policies gelten?
- Wie werden Secrets erzeugt, gespeichert, rotiert und auditiert?
- Welche Images dürfen verwendet werden?
Beobachtbarkeit und Betrieb
- Welche Logs, Metriken und Traces sind verpflichtend?
- Welche Alerts zeigen echte Nutzerwirkung statt nur technische Symptome?
- Gibt es Runbooks?
- Wer reagiert auf Incidents?
- Wie wird nach Incidents gelernt?
18. Workshop-Übungen
Die folgenden Übungen passen zu dieser Unterlage. Du kannst sie nacheinander durchführen oder einzelne Module auswählen.
Übung 1: Namespace und Baseline erstellen
Ziel: Du erstellst einen dedizierten Namespace und prüfst deinen Kontext.
kubectl create namespace workshop
kubectl config set-context --current --namespace=workshop
kubectl get ns
Diskussion:
- Warum ist ein eigener Namespace besser als
default? - Welche Labels würdest du für Ownership und Pod Security setzen?
Übung 2: Deployment ausrollen
Ziel: Du erstellst ein Deployment mit drei Replikaten und beobachtest die Controller-Kette.
kubectl apply -f deployment.yaml
kubectl get deploy,rs,pods -n workshop
kubectl rollout status deployment/web -n workshop
Diskussion:
- Welche Objekte hast du direkt erstellt?
- Welche Objekte hat Kubernetes daraus abgeleitet?
- Was passiert, wenn du einen Pod manuell löschst?
Übung 3: Service Discovery testen
Ziel: Du legst einen Service an und testest DNS aus einem Debug-Pod.
kubectl apply -f service.yaml
kubectl run debug --rm -it --image=curlimages/curl -- sh
curl http://web.workshop.svc.cluster.local
Diskussion:
- Warum adressierst du den Service und nicht Pod-IPs?
- Wie erkennst du, ob ein Service Endpoints hat?
Übung 4: Fehler absichtlich erzeugen
Ziel: Du änderst das Image auf einen nicht vorhandenen Tag und analysierst den Fehler.
kubectl set image deployment/web web=nginx:does-not-exist -n workshop
kubectl rollout status deployment/web -n workshop
kubectl get pods -n workshop
kubectl describe pod <pod-name> -n workshop
Diskussion:
- Wo steht die eigentliche Fehlermeldung?
- Warum bleibt das Deployment möglicherweise teilweise verfügbar?
- Wie führst du ein Rollback durch?
Übung 5: Readiness und Liveness verstehen
Ziel: Du setzt absichtlich eine falsche Readiness-Probe und beobachtest Service-Endpunkte.
kubectl get endpointslice -n workshop
kubectl describe pod <pod-name> -n workshop
Diskussion:
- Warum läuft der Container, erhält aber keinen Traffic?
- Was unterscheidet Readiness von Liveness?
Übung 6: RBAC prüfen
Ziel: Du erstellst einen ServiceAccount mit minimalen Rechten und prüfst Zugriff.
kubectl auth can-i list pods -n workshop --as=system:serviceaccount:workshop:pod-reader
kubectl auth can-i list secrets -n workshop --as=system:serviceaccount:workshop:pod-reader
Diskussion:
- Warum ist
list secretsbesonders sensibel? - Wann brauchst du eine Role und wann eine ClusterRole?
Übung 7: NetworkPolicy einführen
Ziel: Du beschränkst Kommunikation und prüfst, ob dein CNI Policies durchsetzt.
kubectl apply -f networkpolicy.yaml
kubectl get networkpolicy -n workshop
Diskussion:
- Was passiert in einem CNI ohne NetworkPolicy-Unterstützung?
- Welche Egress-Ausnahmen brauchst du für DNS?
19. Abgrenzung
Kubernetes ist nicht identisch mit den Werkzeugen und Plattformen um Kubernetes herum. Eine saubere Architektur trennt Verantwortlichkeiten.
| Werkzeug oder Konzept | Verhältnis zu Kubernetes |
|---|---|
| Docker Image | Paketformat und Build-Ergebnis für Container. Kubernetes führt Images aus, baut sie aber nicht selbst. |
| containerd / CRI-O | Container Runtime auf dem Node. Kubernetes spricht über CRI mit ihr. |
| Helm | Paketierungs- und Templating-Werkzeug für Kubernetes-Manifeste. Helm ersetzt kein Architekturmodell. |
| Kustomize | Overlay-Mechanismus für YAML-Manifeste. Gut für Umgebungsvarianten. |
| GitOps | Betriebsmodell, bei dem Git den Zielzustand beschreibt. Kubernetes bleibt Ausführungsplattform. |
| Prometheus | Monitoring-System. Kubernetes liefert Ziele und Metadaten, Prometheus sammelt Metriken. |
| Ingress Controller | Implementierung für Ingress-Ressourcen. Ohne Controller bewirkt ein Ingress-Objekt nichts. |
| Gateway Controller | Implementierung für Gateway API Ressourcen. |
| CSI Driver | Storage-Integration. Kubernetes definiert das Modell, der Treiber bindet konkreten Storage an. |
| CNI Plugin | Netzwerk-Integration. Kubernetes definiert Anforderungen, das Plugin setzt Netzwerk und Policies um. |
| Cloud Provider | Stellt Infrastruktur wie Nodes, Load Balancer, Volumes und Identitäten bereit. |
| Service Mesh | Zusätzliche Ebene für Traffic-Management, mTLS, Telemetrie und Policies. Nicht Voraussetzung für Kubernetes. |
20. Glossar
| Begriff | Erklärung |
|---|---|
| API Server | Zentrale Kubernetes API. Alle Steuerungswerkzeuge sprechen mit ihr. |
| Controller | Prozess, der gewünschten und tatsächlichen Zustand abgleicht. |
| Desired State | Gewünschter Zustand einer Ressource in der API. |
| Actual State | Tatsächlich beobachteter Zustand im Cluster. |
| etcd | Persistenter Speicher für den Kubernetes-Zustand. |
| Kubelet | Agent auf jedem Node, der Pods startet und überwacht. |
| Node | Maschine im Cluster, auf der Pods laufen. |
| Pod | Kleinste ausführbare Kubernetes-Einheit. |
| ReplicaSet | Controller für eine gewünschte Anzahl gleichartiger Pods. |
| Deployment | Controller für stateless Workloads mit Rollout- und Rollback-Funktionen. |
| Service | Stabile Netzwerkabstraktion über wechselnde Pods. |
| EndpointSlice | API-Objekt, das Service-Endpunkte skalierbarer beschreibt als klassische Endpoints. |
| Ingress | API-Objekt für HTTP(S)-Routing in den Cluster. |
| Gateway API | Erweiterbares API-Modell für Service Networking und Traffic-Routing. |
| ConfigMap | Nicht vertrauliche Konfiguration. |
| Secret | Vertrauliche kleine Datenmenge. |
| PVC | Anforderung von persistentem Storage durch eine Anwendung. |
| StorageClass | Definition dynamischer Storage-Provisionierung. |
| CNI | Schnittstelle für Container-Netzwerk-Plugins. |
| CSI | Schnittstelle für Container-Storage-Plugins. |
| RBAC | Rollenbasierte Zugriffskontrolle. |
| Admission Control | Prüfung oder Veränderung von API-Anfragen vor Speicherung. |
| Probe | Health-Check-Mechanismus für Container. |
| HPA | Horizontal Pod Autoscaler, skaliert Replikate anhand von Metriken. |
| PDB | PodDisruptionBudget, begrenzt freiwillige gleichzeitige Ausfälle. |
21. Offizielle Referenzen
Diese Unterlage orientiert sich an der offiziellen Kubernetes-Dokumentation. Für Details und versionsspezifische Unterschiede prüfst du die Dokumentation deiner eingesetzten Kubernetes-Version.
- Kubernetes Components: https://kubernetes.io/docs/concepts/overview/components/
- Pods: https://kubernetes.io/docs/concepts/workloads/pods/
- Pod Lifecycle: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/
- Deployments: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/
- Services: https://kubernetes.io/docs/concepts/services-networking/service/
- DNS for Services and Pods: https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/
- Ingress: https://kubernetes.io/docs/concepts/services-networking/ingress/
- Gateway API: https://kubernetes.io/docs/concepts/services-networking/gateway/
- Network Policies: https://kubernetes.io/docs/concepts/services-networking/network-policies/
- ConfigMaps: https://kubernetes.io/docs/concepts/configuration/configmap/
- Secrets: https://kubernetes.io/docs/concepts/configuration/secret/
- Resource Management for Pods and Containers: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
- Labels and Selectors: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/
- Namespaces: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/
- RBAC Good Practices: https://kubernetes.io/docs/concepts/security/rbac-good-practices/
- Pod Security Admission: https://kubernetes.io/docs/concepts/security/pod-security-admission/
- Good practices for Kubernetes Secrets: https://kubernetes.io/docs/concepts/security/secrets-good-practices/
- Horizontal Pod Autoscaling: https://kubernetes.io/docs/concepts/workloads/autoscaling/horizontal-pod-autoscale/
- Pod Disruption Budgets: https://kubernetes.io/docs/tasks/run-application/configure-pdb/