Einführung
Im Kurs „Kubernetes für Einsteiger“ hast du kubectl get, describe und Labels verwendet, um zu prüfen, ob eine Anwendung funktioniert. In realen Clustern gibt es jedoch zahlreiche Objekte. Deshalb besteht der nächste wichtige Schritt darin, gezieltere Fragen zu stellen und nur die benötigten Informationen herauszufiltern.
In diesem Lab stellst du eine kleine Anwendung für einen Onlineshop bereit und untersuchst sie aus verschiedenen Blickwinkeln: Namespace, Labels, strukturierte Felder, Controller-Besitzverhältnisse und Events. Am Ende verwendest du einen kompakten Befehl, der ein Deployment mit den von ihm verwalteten Pods verknüpft.
Du musst dir nicht jedes Ausgabeformat merken. Übe stattdessen, eine Frage in eine präzise Abfrage zu übersetzen: „Welche Objekte existieren?“, „Welche Pods passen zu diesem Service?“, „Wem gehört dieser Pod?“ oder „Was ist zuletzt passiert?“ Jeder Schritt ergänzt ein weiteres Werkzeug für diesen Untersuchungs-Workflow.
Einen abgegrenzten Arbeitsbereich erstellen
In diesem Schritt erstellst du einen Namespace und stellst die vorbereiteten Ressourcen darin bereit. Ein Namespace schränkt den Bereich späterer Abfragen ein und verhindert, dass gleichnamige Objekte verwechselt werden.
Wechsle in den Lab-Arbeitsbereich und überprüfe anschließend den aktuellen Kontext, bevor du den Cluster-Zustand änderst. cd ändert das aktuelle Arbeitsverzeichnis der Shell. Dadurch beziehen sich spätere relative Dateinamen wie storefront.yaml auf den vorbereiteten Arbeitsbereich.
cd /home/labex/project/resource-inspection
kubectl config current-context
Die Ausgabe sollte labex-v135 lauten. Erstelle den Namespace und wende das vorbereitete Multi-Dokument-Manifest an:
kubectl create namespace practice-observe
kubectl apply -f storefront.yaml
kubectl rollout status deployment/storefront -n practice-observe --timeout=60s
Die letzten Zeilen sollten ungefähr so aussehen. Während die beiden Pods gestartet werden, können zwischendurch weitere Rollout-Meldungen erscheinen:
namespace/practice-observe created
deployment.apps/storefront created
service/storefront created
deployment "storefront" successfully rolled out
-n practice-observe beschränkt den Befehl auf diesen Namespace. Der Rollout-Befehl wartet, bis beide Replikate des Deployments verfügbar sind, statt sich auf eine beliebige Wartezeit zu verlassen.
Du wirst -n practice-observe wiederholt verwenden. Ohne diese Angabe nutzen Kubernetes-Befehle den im aktuellen Kontext konfigurierten Namespace – normalerweise default. Dadurch kann ein funktionsfähiges Objekt scheinbar „fehlen“, wenn du versehentlich im falschen Bereich suchst.
Ressourcen und ihren Gültigkeitsbereich ermitteln
In diesem Schritt verwendest du zunächst die API-Erkennung, bevor du Objekte abfragst. kubectl api-resources listet die Ressourcennamen auf, die der aktuelle API-Server kennt, einschließlich Kurzformen und der Information, ob eine Ressource an einen Namespace gebunden ist. Die Weiterleitung an head begrenzt die erste umfangreiche Liste auf zehn Zeilen, damit das Terminal nicht mit Ausgabe überflutet wird.
kubectl api-resources | head
kubectl api-resources --namespaced=true | grep -E 'pods|deployments|services'
Die Weiterleitung übergibt die Ressourcenliste an grep. -E aktiviert die Alternative mit |, sodass ein einzelner Befehl mehrere Ressourcennamen finden kann. Beachte, dass Pods, Deployments und Services an Namespaces gebunden sind.
Liste die Anwendungsobjekte zunächst mit ihren vollständigen Namen auf und wiederhole die Abfrage anschließend mit den gebräuchlichen Kurzformen:
kubectl get pods,deployments,services -n practice-observe
kubectl get po,deploy,svc -n practice-observe
Beide Befehle greifen auf dieselben API-Ressourcen zu. Kurzformen sparen Tipparbeit, während die vollständigen Namen in Skripten und Dokumentationen verständlicher sind.
Du solltest ein Deployment, zwei automatisch erzeugte Pods und einen Service sehen. Die durch Kommas getrennte Ressourcenliste ist lediglich eine praktische Schreibweise für die Abfrage. Die Objekte haben weiterhin unterschiedliche Rollen und API-Schemata.
Die Typpräfixe erleichtern die Interpretation der kombinierten Ausgabe. Die erzeugten Namenssuffixe, Adressen und Altersangaben unterscheiden sich:
NAME READY STATUS RESTARTS AGE
pod/storefront-... 1/1 Running 0 ...
pod/storefront-... 1/1 Running 0 ...
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/storefront 2/2 2 2 ...
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/storefront ClusterIP ... <none> 80/TCP ...
Mit Labels und Selektoren filtern
In diesem Schritt verwendest du Labels als durchsuchbare Metadaten. --show-labels zeigt alle Labels an, während -l nur Objekte auswählt, deren Labels einem Ausdruck entsprechen.
kubectl get pods -n practice-observe --show-labels
kubectl get pods -n practice-observe -l app=storefront
kubectl get pods -n practice-observe -l 'app=storefront,tier=web'
Ein Komma zwischen Selektorbedingungen bedeutet eine logische Verknüpfung mit UND. Die letzte Abfrage liefert daher nur Pods, die beide Labels tragen.
Vergleiche den Selektor des Services mit den Labels der ausgewählten Pods:
kubectl get service storefront -n practice-observe -o jsonpath='Service selector: {.spec.selector.app}{"\n"}'
kubectl get pods -n practice-observe -l app=storefront -o custom-columns='NAME:.metadata.name,TIER:.metadata.labels.tier,IP:.status.podIP,READY:.status.containerStatuses[0].ready'
kubectl get endpointslices -n practice-observe -l kubernetes.io/service-name=storefront
JSONPath extrahiert ein einzelnes Feld aus dem Service. -o custom-columns erzeugt aus mehreren Pod-Feldern eine kompakte Tabelle. Das ist zuverlässiger, als ein großes YAML-Dokument visuell zu durchsuchen.
Der letzte Befehl fragt nach EndpointSlices, deren automatisch verwaltetes Label kubernetes.io/service-name den Wert storefront trägt. Ein EndpointSlice speichert die Netzwerkendpunkte, die für einen Service ausgewählt wurden. Eine nicht leere Spalte ENDPOINTS bestätigt, dass die passenden Labels erreichbare Backends hervorgebracht haben.
Der Selektor des Services sollte storefront ausgeben, und beide Zeilen der Pod-Tabelle sollten tier=web enthalten. Das übereinstimmende app-Label stellt die Verbindung her: Ein Service findet Pods über Labels, nicht über die Besitzverhältnisse des Deployments.
Service selector: storefront
NAME TIER IP READY
storefront-... web 10.244... true
storefront-... web 10.244... true
NAME ADDRESSTYPE PORTS ENDPOINTS AGE
storefront-... IPv4 80 10.244...,10.244... ...
Besitzverhältnisse der Controller nachverfolgen
In diesem Schritt verfolgst du die Besitzkette von Kubernetes: vom Deployment über das ReplicaSet bis zu den Pods. Controller fügen ownerReferences hinzu, damit Kubernetes weiß, welches übergeordnete Objekt die jeweiligen abhängigen Objekte verwaltet.
kubectl get replicasets -n practice-observe -l app=storefront
kubectl get replicasets -n practice-observe -l app=storefront -o custom-columns='REPLICASET:.metadata.name,OWNER_KIND:.metadata.ownerReferences[0].kind,OWNER_NAME:.metadata.ownerReferences[0].name'
kubectl get pods -n practice-observe -l app=storefront -o custom-columns='POD:.metadata.name,OWNER_KIND:.metadata.ownerReferences[0].kind,OWNER_NAME:.metadata.ownerReferences[0].name'
Als Besitzer des ReplicaSets sollte das Deployment storefront angezeigt werden. Besitzer jedes Pods ist das erzeugte ReplicaSet, nicht direkt das Deployment:
Deployment/storefront -> ReplicaSet/storefront-... -> Pod/storefront-...
Verwende kubectl describe, wenn du diese Beziehung gemeinsam mit Zuständen und aktuellen Events untersuchen möchtest:
kubectl describe deployment storefront -n practice-observe
Lies die Ausgabe von describe nicht jedes Mal vollständig von oben bis unten. Konzentriere dich für diese Fragestellung auf Selector, Replikazahlen, Zustände und Events. Der beste Untersuchungsbefehl ist derjenige, der die aktuelle Frage mit möglichst wenig überflüssiger Ausgabe beantwortet.
Events als Zeitlinie lesen
In diesem Schritt untersuchst du Events als zeitlich geordnete Belege. Events beschreiben Aktionen der Planung, des Image- und Container-Managements sowie der Controller. Sie sind jedoch nur vorübergehende Diagnoseinformationen und keine dauerhaften Audit-Protokolle.
kubectl get events -n practice-observe --sort-by=.metadata.creationTimestamp
--sort-by sortiert Objekte anhand eines Feldpfads. Schränke die Zeitlinie zunächst auf das Deployment und anschließend auf einen ausgewählten Pod ein:
kubectl events -n practice-observe --for deployment/storefront
POD_NAME=$(kubectl get pods -n practice-observe -l app=storefront -o jsonpath='{.items[0].metadata.name}')
echo "$POD_NAME"
kubectl events -n practice-observe --for "pod/${POD_NAME}"
$(...) ist eine Befehlsersetzung: Die Shell führt den inneren Befehl aus und speichert dessen Ausgabe in POD_NAME. Damit hast du nun einen wiederholbaren Untersuchungsweg: Namespace eingrenzen, nach Labels auswählen, Felder extrahieren, Besitzer verfolgen und mit der relevanten Event-Zeitlinie abschließen.
Von Controllern erzeugte Pod-Namen ändern sich, wenn Pods ersetzt werden. Daher ist es sicherer, den aktuellen Namen anhand eines Labels auszuwählen, als einen veralteten Wert zu kopieren. Dieses Muster wird in den Troubleshooting-Labs noch häufiger vorkommen.
Der erfolgreiche Lebenszyklus umfasst normalerweise Scheduled, Pulled, Created und Started. In einem gerade gestarteten lokalen Cluster kann außerdem noch eine frühere Warnung wie FailedCreatePodSandBox vorhanden sein, während Calico bereitgestellt wird. Schließe nicht allein aufgrund einer alten Warnung darauf, dass die Anwendung weiterhin fehlerhaft ist: Vergleiche ihren Zeitstempel mit den späteren regulären Events und überprüfe anschließend den aktuellen READY-Zustand des Pods. Zeitstempel und automatisch erzeugte Pod-Namen werden absichtlich weggelassen, da sie sich bei jedem Durchlauf ändern.
Zusammenfassung
Du hast eine Kubernetes-Anwendung untersucht, ohne irrelevante Objekte durchsuchen zu müssen. Durch die Kombination aus Namespaces, Labels, JSONPath, benutzerdefinierten Spalten, Besitzreferenzen und Events bist du von einer allgemeinen Bestandsaufnahme zu präzisen betrieblichen Informationen gelangt. Im nächsten Lab wendest du diesen Untersuchungs-Workflow auf fehlerhafte Pods und Container an.


