Dennis Hemeier

101 Series: Kubectl CheatSheet

101 Series
In dieser 101 Series beschäftigen wir uns mit kubectl. Einfache Funktionen wie get pods oder describe nodes kennt ihr sicherlich schon, aber mit kubectl könnt ihr wesentlich mehr machen. Heute zeige ich euch einige Funktionen und Möglichkeiten, die euch den Alltag bei der Bedienung von Kubernetes ernorm erleichtern können.
Kubectl CheatSheet

Kubectl Grundlagen

Die Kubernetes CLI kubectl könnt ihr lokal auf eurem Rechner nutzen und installieren. Die unterschiedlichen Wege der Installation findet ihr in der offiziellen Dokumentation. Mac User verwenden idealerweise den Paketmanager brew und den Befehl brew install kubernetes-cli.

Nach der Installation müsst ihr natürlich noch eine Konfiguration für euer Cluster anlegen. Dieses geschieht entweder über kubectl config Commands oder durch den Austausch der kubectl Konfigurationsdatei. Diese findet ihr unter $HOME/.kube/config. Habt ihr mehrere Cluster in einer Konfiguration, so könnt ihr über folgende Befehle die Cluster / Kontexte wechseln.

Liste alle hinterlegten Kontexte in deiner aktuellen Konfiguration auf

$ kubectl config get-contexts
CURRENT   NAME                 CLUSTER              AUTHINFO                NAMESPACE
*         cloudpirate          cloudpirate          cloudpirate-admin       my-namespace
          kind-kind            kind-kind            kind-kind
          minikube             minikube             minikube

Wechsel in einen bestimmten Kontext

$ kubectl config use-context minikube
Switched to context "minikube".

Alternativ könnt ihr auch temporär eine andere Konfigurationsdatei verwenden

$ kubectl get pods --kubeconfig MY-NEW-CONFIG

Generell ist auch der Parameter --help sehr nützlich. Diesen könnt ihr an jeden Befehl anhängen, um Beispiele und weitere Optionen einsehen zu können, die ihr in dem jeweiligen Bereich nutzen könnt.

$ kubectl --help
kubectl controls the Kubernetes cluster manager.

 Find more information at: https://kubernetes.io/docs/reference/kubectl/overview/

Basic Commands (Beginner):
  create        Create a resource from a file or from stdin.
  expose        Nehme einen Replication Controller, Service, Deployment oder Pod und biete ihn als neuen Kubernetes-Service an
  run           Starte ein bestimmtes Image auf dem Cluster
  set           Setze bestimmte Features auf Objekten

[ . . . ]

API und Ressource Versionen anzeigen

Über kubectl können wir alle Ressourcen einsehen und auflisten. Doch zunächst einmal sollte man Wissen, welche Ressourcen es in dem jeweiligen Cluster überhaupt gibt. Dazu gibt es zwei sehr nützliche Befehle.

Cluster API Versionen abrufen
Hiermit erfahrt ihr, welche API Versionen aktuell überhaupt in eurem API-Server aktiv sind.

$ kubectl api-versions
acme.cert-manager.io/v1alpha2
admissionregistration.k8s.io/v1
apiextensions.k8s.io/v1
apiregistration.k8s.io/v1
networking.k8s.io/v1
networking.k8s.io/v1beta1
node.k8s.io/v1beta1
[ . . . ]

Cluster API Ressourcen abrufen
Bei dieser Abfrage bekommt ihr direkt die möglichen Shortnames für kubectl genannt, seht auf einem Blick, welche Ressourcen innerhalb eines Namespaces vorkommen und wie der Kind innerhalb einer Definition auszusehen hat.

$ kubectl api-resources
NAME                              SHORTNAMES   APIGROUP                       NAMESPACED   KIND
bindings                                                                      true         Binding
componentstatuses                 cs                                          false        ComponentStatus
configmaps                        cm                                          true         ConfigMap
endpoints                         ep                                          true         Endpoints
events                            ev                                          true         Event
limitranges                       limits                                      true         LimitRange
namespaces                        ns                                          false        Namespace
nodes                             no                                          false        Node
persistentvolumeclaims            pvc                                         true         PersistentVolumeClaim
persistentvolumes                 pv                                          false        PersistentVolume
pods                              po                                          true         Pod
podtemplates                                                                  true         PodTemplate
replicationcontrollers            rc                                          true         ReplicationControl
[ . . . ]

Arbeiten mit Namespaces

Innerhalb von Kubernetes befinden sich einige Ressourcen innerhalb eines Namespaces. Um mit unterschiedlichen Namespaces zu arbeiten habt ihr verschiedene Möglichkeiten. So könntet ihr zum Beispiel in der Konfigurationsdatei in dem entsprechenden Context Eintrag einen weiteren Parameter namespace: MY-NAMESPACE einfügen, sodass ihr auf diesem Namespace arbeitet. Habt ihr solch einen Eintrag nicht gesetzt, so befindet ihr euch Standardmäßig im Namespace "default".

Ressourcen in allen Namespaces ausgeben (-A oder --all-namespaces)

$ kubectl get pods -A
NAMESPACE       NAME                                            READY   STATUS      RESTARTS   AGE
[ . . . ]
cloudpirate    cloudpirate-deployment-88dc64d88-w4hvs           1/1     Running     0          13d
[ . . . ]

Ressourcen in einem bestimmten Namespaces ausgeben (-n oder --namespace MY-NAMESPACE)

$ kubectl get pods -n cloudpirate
NAME                                     READY   STATUS    RESTARTS   AGE
cloudpirate-deployment-88dc64d88-w4hvs   1/1     Running   0          13d

Ressourcen auflisten und filtern

Nachdem wir nun Wissen, welche Ressourcen es in unserem Cluster gibt, können wir diese entsprechend ausgeben.

Allgemeine Ausgabe aller Ressourcen

$ kubectl get all

Ausgabe bestimmter Ressourcen

# Einfache Ausgabe
$ kubectl get pods

# Liste von Ressourcen
$ kubectl get pods,svc,deployments

Filterung der Ressourcen anhand eines oder mehrerer Label

$ kubectl get pods --selector KEY=VALUE [,KEY2=VALUE2]

Filtern nach Status
Besonders nützlich um zu sehen, ob aktuell Pods im Cluster vorhanden sind, die nicht laufen.

# alle Running Pods
$ kubectl get pods -A --field-selector status.phase=Running

# alle Pods, die nicht den Status Running haben
$ kubectl get pods -A --field-selector status.phase!=Running

Details von Ressourcen abrufen

Neben dem Auflisten von Ressourcen können wir uns natürlich auch entsprechend die Details einer einzelnen Ressource anzeigen lassen. Bei Pods kann es vorkommen, dass diese aus mehreren Containern bestehen. In diesem Fall kann mit dem Parameter -c CONTAINER-NAME der gewünschte Container ausgewählt werden.

Details anzeigen

$ kubectl describe deployment MY-DEPLOYMENT 

Pod Logs einsehen
Hierbei ist besonders der zusätzliche Parameter -f sinnvoll, mit dem wir einen Follow starten und neue Logs in Echtzeit angezeigt bekommen.

$ kubectl get logs MY-PODNAME [-c CONTAINER-NAME]

# Follow Mode
$ kubectl logs -f MY-PODNAME

# Logs des vorherigen Pods anzeigen (z.B. bei Neustart)
$ kubectl logs -p MY-PODNAME

Ausgabe einer Ressource im YAML Format
Möchte man eine bestehende Ressource z.B. als Datei in seinem VCS abspeichern, so eignet sich dazu der Parameter -o yaml

$ kubectl get deployment MY-DEPLOYMENT -o yaml > my-file.yaml

Befehl innerhalb eines Pods ausführen 

# Pod Shell öffnen
$ kubectl exec -ti MY-POD [-c CONTAINER-NAME] -- /bin/bash

Neue Ressourcen anlegen

Idealerweise habt ihr bereits alle gewünschten Ressourcen als YAML-Dateien in eurem VCS abgelegt. Diese könnt ihr einfach über ein apply ausführen. Kubectl bietete euch hier aber eine Unterstützung, sofern noch keine YAML-Dateien vorliegen.

$ kubectl apply -f MY-FILE.yaml

Neues Deployment anlegen
Bei diesem Command wird direkt ein neues Deployment angelegt und gestartet. Alternativ könnt ihr dieses Command auch nutzen, um euch eine Vorlage zu generieren, die ihr anschließend weiter bearbeiten könnt.

# Direktes anlegen
$ kubectl create deployment MY-DEPLOYMENT-NAME --image IMAGE [--port XX] [--replicas X]

# Vorlage erstellen und als Datei speichern
$ kubectl create deployment MY-DEPLOYMENT-NAME --image IMAGE --dry-run=client -o yaml > my-new-file.yaml

Service anlegen
Um für eine bestehende Ressource einen Service anzulegen, könnt ihr den Befehl expose verwenden. Auch hierbei könnt ihr über --dry-run in Verbindung mit -o yaml ein Template erzeugen.

$ kubectl expose deployment|pod|rs|xxxx MY-DEPLOYMENT [--port=XX] [--target-port=XX] [--name=XXXXXX]

Beschreibung einer Ressource
Wisst ihr nicht genau, wie eine bestimmte Ressource aufgebaut werden muss oder welche Felder es gibt, so könnt ihr euch die Details anzeigen und beschreiben lassen.

# Beschreibung der obersten Ebene
$ kubectl explain deployment

# Bestimmte Elemente innerhalb des Objektes beschreiben
$ kubectl explain deployment.spec.template.spec.containers

# Rekursive Ausgabe aller Felder (ohne Detailausgabe)
$ kubectl explain deployment --recursive

Kubectl CheatSheet & weitere Befehle

Alle häufig verwendeten Befehle habe ich euch als Auflistung erstellt. Neben den bereits bekannten und beschriebenen Befehlen findet ihr hier auch weitere Befehle und Funktionen. Den offiziellen Spickzettel findet ihr in der Kubernetes Dokumentation.

$ kubectl get pods              # List all pods
$ kubectl get pod MY-POD        # Get a single Pod

$ kubectl get svc               # List Services
$ kubectl get svc MY-SRV        # Get single Services

$ kubectl get deployment                 # List Deployments
$ kubectl get deployment MY-DEPLOYMENT   # Get single Deplyoment

$ kubectl describe svc          # Describe Services
$ kubectl describe deployment   # Describe Deployments
$ kubectl describe node         # Describe Nodes
$ kubectl describe node MY-NODE # Describe single Nodes

$ kubectl get services --sort-by=.metadata.name # List Services Sorted by Name

# List pods Sorted by Restart Count
$ kubectl get pods --sort-by='.status.containerStatuses[0].restartCount'

# Get the version label of all pods with label app=cassandra
$ kubectl get pods --selector=app=cassandra rc -o \
  jsonpath='{.items[*].metadata.labels.version}'

# Get ExternalIPs of all nodes
$ kubectl get nodes -o jsonpath='{.items[*].status.addresses[?(@.type=="ExternalIP")].address}'
$ kubectl rolling-update frontend-v1 -f frontend-v2.yaml           # Rolling update pods of frontend-v1
$ kubectl rolling-update frontend-v1 frontend-v2 --image=image:v2  # Change the name of the resource and update the image
$ kubectl rolling-update frontend --image=image:v2                 # Update the pods image of frontend
$ kubectl rolling-update frontend-v1 frontend-v2 --rollback        # Abort existing rollout in progress

$ kubectl rollout status frontend-v1          # Get the current Rollout status
$ kubectl rollout restart frontend-v1         # Restart an rollout
$ kubectl label pods my-pod new-label=awesome                      # Add a Label
$ kubectl annotate pods my-pod icon-url=http://goo.gl/XXBTWq       # Add an annotation
$ kubectl autoscale deployment foo --min=2 --max=10                # Auto scale a deployment "foo"
$ kubectl scale deployment my-deployment --replicas=10             # Scale a deployment
$ kubectl delete -f ./pod.yaml                      # Delete a pod using the type and name specified in pod.yaml
$ kubectl delete pod,service baz foo                # Delete pods and services with same names "baz" and "foo"
$ kubectl delete pods,services -l name=myLabel      # Delete pods and services with label name=myLabel
$ kubectl -n my-ns delete po,svc --all              # Delete all pods and services in namespace my-n
$ kubectl logs my-pod                                 # dump pod logs (stdout)
$ kubectl logs my-pod -c my-container                 # dump pod container logs (stdout, multi-container case)
$ kubectl logs -f my-pod                              # stream pod logs (stdout)
$ kubectl logs -f my-pod -c my-container              # stream pod container logs (stdout, multi-container case)
$ kubectl run -i --tty busybox --image=busybox -- sh  # Run pod as interactive shell
$ kubectl attach my-pod -i                            # Attach to Running Container
$ kubectl port-forward my-pod 5000:6000               # Forward port 6000 of Pod to your to 5000 on your local machine
$ kubectl exec my-pod -- ls /                         # Run command in existing pod (1 container case)
$ kubectl exec my-pod -c my-container -- ls /         # Run command in existing pod (multi-container case)
$ kubectl top pod POD_NAME --containers               # Show metrics for a given pod and its containers
$ kubectl cordon my-node                                                # Mark my-node as unschedulable
$ kubectl drain my-node                                                 # Drain my-node in preparation for maintenance
$ kubectl uncordon my-node                                              # Mark my-node as schedulable
$ kubectl top node my-node                                              # Show metrics for a given node
$ kubectl cluster-info                                                  # Display addresses of the master and services
$ kubectl cluster-info dump                                             # Dump current cluster state to stdout
$ kubectl cluster-info dump --output-directory=/cluster-state.          # Dump current cluster state to /cluster-state

# If a taint with that key and effect already exists, its value is replaced as specified.
$ kubectl taint nodes foo dedicated=special-user:NoSchedule