10 Februar 2020

kubectl - Eine Einführung

Kategorien: HowTos

Wer mit Kubernetes arbeitet, der kommt nicht umhin sich auch mit kubectl zu beschäftigen. Es ist das standard Command-Line-Interface zur Arbeit mit einem Kubernetes Cluster.

Dieser Blogpost soll dazu dienen, den initialen Start mit kubectl zu vereinfachen und den ein oder anderen Hinweis aufzuzeigen. Er orientiert sich dabei an Aufgaben und Problemstellungen, mit denen der reguläre Benutzer eines Clusters konfrontiert wird.

Kubeconfig

Zuerst wird eine sogenannte KUBECONFIG Konfigurationsdatei benötigt. Diese beinhaltet alle Parameter, die für eine oder mehrere Verbindung(en) zu Kubernetes benötigt werden.

Pfad

Standardmäßig prüft kubectl, ob sich unter ~/.kube/config eine Konfigurationsdatei findet. Um alternative Konfigurationsdateien zu nutzen, gibt es zwei Optionen diese zu definieren:

  • Command-Line-Argument --kubeconfig=<filepath> oder aber als
  • Environment Variable KUBECONFIG=<filepath>

Aufbau

Für eine Verbindung wird mindestens der Name des Clusters und der Benutzer innerhalb des Clusters benötigt. Diese Informationen werden in einem so genannten Context zusammengefasst. Optional kann an dieser Stelle der Namespace angegeben werden, der verwendet wird, sofern dieser beim Aufruf nicht angegeben wird.

Hier ein Beispiel:

contexts:
- context:
    cluster: my-k8s-cluster
    namespace: default
    user: system-admin
  name: default/my-k8s-cluster/system:admin

Der gezeigte Context alleine reicht allerdings noch nicht aus, um Kontakt zu unserem Cluster aufzunehmen. Es fehlen Detailinformationen für cluster und user.

Ein user-Eintrag könnte wie folgt aussehen:

users:
- user:
    token: eaBQIVe1jFDpsuD3NwsS6c2Qx7+eGDlat6BF2qlsgtY
  name: system-admin

Nun fehlen noch Detailinformationen zu unserem cluster:

clusters:
- cluster:
    server: https://my-k8s-cluster.example.com:8443
  name: my-k8s-cluster

Je nach Authentifikationsmethode des users und Konfiguration des clusters können sich die benötigten Konfigurationseinstellungen unterscheiden.

Werden alle Teile zusammengesetzt, ergibt sich der folgende Aufbau:

apiVersion: v1
kind: Config
current-context: default/my-k8s-cluster/system:admin
clusters:
- cluster:
    server: https://my-k8s-cluster.example.com:8443
  name: my-k8s-cluster
users:
- user:
    token: eaBQIVe1jFDpsuD3NwsS6c2Qx7+eGDlat6BF2qlsgtY
  name: system-admin
contexts:
- context:
    cluster: my-k8s-cluster
    namespace: default
    user: system-admin
  name: default/my-k8s-cluster/system:admin

Neben den bereits gezeigten Abschnitten definieren wir den ausgewählten Context.

Auch wenn der Name des Contexts frei gewählt werden kann, empfehlen sich eindeutige Bezeichnungen: default/my-k8s-cluster/system:admin

Dieser beinhaltet alle wichtigen Details zur Verbindung und ist damit eindeutig identifizierbar.

Zusätzliche Einträge wie cluster, user und context können ebenfalls definiert werden.
Somit ist es möglich, verschiedene Konstellationen in der Konfiguration zu hinterlegen, zwischen denen gewechselt werden kann.

Contexts

Die konfigurierten contexts können wir uns mit dem folgenden Befehl anzeigen lassen.

$ kubectl config get-contexts
CURRENT   NAME                                 CLUSTER         AUTHINFO      NAMESPACE
*         default/my-k8s-cluster/system:admin  my-k8s-cluster  system-admin  default

Der ausgewählte context wird durch einen * gekennzeichnet. Sofern mehrere contexts definiert wurden, können diese mit kubectl config use-context <context> gewechselt werden.

kubectl bietet neben der Anzeige und Auswahl der contexts auch die Möglichkeit die ausgewählte KUBECONFIG via Command-Line zu editieren.

Wie dies genau funktioniert, beschreibt die Hilfeausgabe:

$ kubectl config --help
Modify kubeconfig files using subcommands like "kubectl config set current-context my-context"

 The loading order follows these rules:

  1.  If the --kubeconfig flag is set, then only that file is loaded. The flag may only be set once and no merging takes
place.
  2.  If $KUBECONFIG environment variable is set, then it is used as a list of paths (normal path delimiting rules for
your system). These paths are merged. When a value is modified, it is modified in the file that defines the stanza. When
a value is created, it is created in the first file that exists. If no files in the chain exist, then it creates the
last file in the list.
  3.  Otherwise, ${HOME}/.kube/config is used and no merging takes place.

Available Commands:
  current-context Displays the current-context
  delete-cluster  Delete the specified cluster from the kubeconfig
  delete-context  Delete the specified context from the kubeconfig
  get-clusters    Display clusters defined in the kubeconfig
  get-contexts    Describe one or many contexts
  rename-context  Renames a context from the kubeconfig file.
  set             Sets an individual value in a kubeconfig file
  set-cluster     Sets a cluster entry in kubeconfig
  set-context     Sets a context entry in kubeconfig
  set-credentials Sets a user entry in kubeconfig
  unset           Unsets an individual value in a kubeconfig file
  use-context     Sets the current-context in a kubeconfig file
  view            Display merged kubeconfig settings or a specified kubeconfig file

Usage:
  kubectl config SUBCOMMAND [options]

Use "kubectl <command> --help" for more information about a given command.
Use "kubectl options" for a list of global command-line options (applies to all commands).

Anzeige

Das wohl meistgenutzte Feature von kubectl ist die Anzeige von Objekten innerhalb des Clusters und deren Status. Hierzu stehen gleich mehrere Methoden bereit, je nachdem welche Informationen wir uns anzeigen lassen wollen. Unter anderem:

  • get: Auflisten und Anzeigen von Objekten
  • describe: Beschreibung von Objekten und deren Status
  • logs: Anzeige der Logs eines Containers
  • explain: Anzeigen des Aufbaus von Ojekten

get

Mittels der get Methoden kann sich der User alle Objekte innerhalb des Clusters anzeigen lassen, auf die er Zugriff hat.

Hierzu muss mindestens ein Objekttyp angegeben werden, der angezeigt werden soll. Alternativ kann man sich mit all auch mehrere Objekttypen anzeigen lassen.

An dieser Stelle sollte angemerkt werden, dass all nicht all bedeutet. Es werden lediglich die gängigsten Objekte angezeigt.

$ kubectl get pods
NAME                               READY   STATUS    RESTARTS   AGE
nginx-deployment-6dd86d77d-5hldn   1/1     Running   0          47s
nginx-deployment-6dd86d77d-jr7hk   1/1     Running   0          47s
$ kubectl get all
NAME                                   READY   STATUS    RESTARTS   AGE
pod/nginx-deployment-6dd86d77d-5hldn   1/1     Running   0          100s
pod/nginx-deployment-6dd86d77d-jr7hk   1/1     Running   0          100s

NAME                               READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/nginx-deployment   2/2     2            2           100s

NAME                                         DESIRED   CURRENT   READY   AGE
replicaset.apps/nginx-deployment-6dd86d77d   2         2         2       100s

Die ausgabe des all Befehls kann in unserem konkreten Fall auch dadurch erreicht werden, dass mehrere Objekttypen gleichzeitig abgefragt werden.

Um alle Instanzen der Objekttypen pod, deployment und replicaset anzuzeigen, können wir auch folgenden Befehl verwenden:

$ kubectl get pods,deployments,replicasets
NAME                                   READY   STATUS    RESTARTS   AGE
pod/nginx-deployment-6dd86d77d-5hldn   1/1     Running   0          4m35s
pod/nginx-deployment-6dd86d77d-jr7hk   1/1     Running   0          4m35s

NAME                                     READY   UP-TO-DATE   AVAILABLE   AGE
deployment.extensions/nginx-deployment   2/2     2            2           4m35s

NAME                                               DESIRED   CURRENT   READY   AGE
replicaset.extensions/nginx-deployment-6dd86d77d   2         2         2       4m35s

Sobald die Antwort des Servers mehrere Objekttypen beinhaltet, werden die einzelnen Objektnamen mit ihrem Typ gepräfixt.

Soll nur der Status eines spezifischen Objekts ausgegeben werden, so geschieht dies durch Angabe des Objektnamens nach dem Objekttyp:

$ kubectl get pod nginx-deployment-6dd86d77d-5hldn
NAME                               READY   STATUS    RESTARTS   AGE
nginx-deployment-6dd86d77d-5hldn   1/1     Running   0          19m

Alternativ kann auch die Syntax <typ>/<name> verwendet werden.
Zum Beispiel: kubectl get pod/nginx-deployment-6dd86d77d-5hldn

Welche Informationen bei der Anzeige ausgegeben werden, hängt sowohl vom Ojekttyp selber, als auch vom Ausgabeformat ab. Neben dem Standardausgabeformat stehen unter anderem die folgenden Formate zur Verfügung:

  • wide: Darstellung zusätzlicher Informationen
  • yaml: Ausgabe des gesamten Objekts im YAML format
  • json: Ausgabe des gesamten Objekts im JSON format
  • jsonpath: Ausgabe definierter Bereiche

Eine vollständige Liste der Ausgabeformate kann der Ausgabe von kubectl get --help entnommen werden.

Schauen wir uns beispielsweise die Ausgabe der laufenden Pods mithilfe des Ausgabeformats wide an, dann werden neben den bereits bekannten Informationen zusätzliche Laufzeitinformationen angezeigt. Hierzu zählen unter anderem die IP-Adresse des Pods, sowie der Node auf dem der Pod ausgeführt wird.

$ kubectl get pods -o wide
NAME                               READY   STATUS    RESTARTS   AGE    IP              NODE                  NOMINATED NODE   READINESS GATES
nginx-deployment-6dd86d77d-5hldn   1/1     Running   0          112m   10.233.65.109   node-05.example.com   <none>           <none>
nginx-deployment-6dd86d77d-jr7hk   1/1     Running   0          112m   10.233.79.238   node-04.example.com   <none>           <none>

Die Formate yaml sowie json unterscheiden sich – abgesehen vom Format selbst – nicht in ihrem Inhalt. Beide liefern das ausgewählte Objekt und all seine Eigenschaften zurück.

Neben den manuell definierten Eigenschaften liefern die beiden Ausgabeformate zudem sehr detailierte Informationen über den Status des Objekts.

Ausklappen
$ kubectl get pod nginx-deployment-6dd86d77d-5hldn -o yaml
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: "2019-08-26T12:18:51Z"
  generateName: nginx-deployment-6dd86d77d-
  labels:
    app: nginx
    pod-template-hash: 6dd86d77d
  name: nginx-deployment-6dd86d77d-5hldn
  namespace: test
  ownerReferences:
  - apiVersion: apps/v1
    blockOwnerDeletion: true
    controller: true
    kind: ReplicaSet
    name: nginx-deployment-6dd86d77d
    uid: aa4125fe-c7fb-11e9-aa70-96000014cd55
  resourceVersion: "70713161"
  selfLink: /api/v1/namespaces/test/pods/nginx-deployment-6dd86d77d-5hldn
  uid: aa452873-c7fb-11e9-aa70-96000014cd55
spec:
  containers:
  - image: nginx:1.7.9
    imagePullPolicy: IfNotPresent
    name: nginx
    ports:
    - containerPort: 80
      protocol: TCP
    resources: {}
    terminationMessagePath: /dev/termination-log
    terminationMessagePolicy: File
    volumeMounts:
    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
      name: default-token-q2h6q
      readOnly: true
  dnsPolicy: ClusterFirst
  enableServiceLinks: true
  nodeName: node-05.example.com
  priority: 0
  restartPolicy: Always
  schedulerName: default-scheduler
  securityContext: {}
  serviceAccount: default
  serviceAccountName: default
  terminationGracePeriodSeconds: 30
  tolerations:
  - effect: NoExecute
    key: node.kubernetes.io/not-ready
    operator: Exists
    tolerationSeconds: 300
  - effect: NoExecute
    key: node.kubernetes.io/unreachable
    operator: Exists
    tolerationSeconds: 300
  volumes:
  - name: default-token-q2h6q
    secret:
      defaultMode: 420
      secretName: default-token-q2h6q
status:
  conditions:
  - lastProbeTime: null
    lastTransitionTime: "2019-08-26T12:18:51Z"
    status: "True"
    type: PodScheduled
  containerStatuses:
  - containerID: docker://52dfe6498a96a92ec118dbf18705237792c703be33a86498c53676b1028343b7
    image: nginx:1.7.9
    imageID: docker-pullable://nginx@sha256:e3456c851a152494c3e4ff5fcc26f240206abac0c9d794affb40e0714846c451
    lastState: {}
    name: nginx
    ready: true
    restartCount: 0
    state:
      running:
        startedAt: "2019-08-26T12:18:53Z"
  hostIP: 10.66.0.5
  phase: Running
  podIP: 10.233.65.109
  qosClass: BestEffort
  startTime: "2019-08-26T12:18:51Z"

 

Das Ausgabeformat jsonpath ist immer dann hilfreich, wenn Abschnitte der Ausgabe weiterverarbeitet werden sollen. Ein Beispiel stellt das Dekodieren eines base64 kodierten secrets dar.

Values innerhalb von secrets werden base64 kodiert gespeichert, was bedeutet, dass wir die Kodierung zunächst durch den Aufruf von base64 -d rückgängig machen müssen. Dank jsonpath können wir das in einem Aufruf bewerkstelligen.

Angenommen, wir wollen den Wert des Keys password als Plaintext darstellen und unser secret ist wie folgt aufgebaut. Dies können wir dann mithilfe des Befehls kubectl get secret mysecret -o jsonpath='{.data.password}' | base64 -d bewerkstelligen.

apiVersion: v1
data:
  password: c3VwZXJzZWN1cmUxMjM=
kind: Secret
metadata:
  creationTimestamp: "2019-08-26T14:38:05Z"
  name: mysecret
  namespace: test
  resourceVersion: "70750555"
  selfLink: /api/v1/namespaces/test/secrets/mysecret
  uid: 1d4a2224-c80f-11e9-8df3-96000014cd46
type: Opaque
$ kubectl get secret mysecret -o jsonpath='{.data.password}' | base64 -d
supersecure123

Auch ist es möglich, sich ausschließlich Objekte mit einem bestimmten Label anzeigen zu lassen. Hierzu bietet kubectl für den get Befehl die entsprechende Filteroption. Wollen wir uns beispielsweise alle deployments, replicasets und pods mit dem Label app=nginx anzeigen, so können wir dies mit dem folgenden Befehl bewerkstelligen:

kubectl get deployments,replicasets,pods -l app=nginx
NAME                                     READY   UP-TO-DATE   AVAILABLE   AGE
deployment.extensions/nginx-deployment   2/2     2            2           7d6h

NAME                                               DESIRED   CURRENT   READY   AGE
replicaset.extensions/nginx-deployment-6dd86d77d   2         2         2       7d6h

NAME                                   READY   STATUS    RESTARTS   AGE
pod/nginx-deployment-6dd86d77d-5hldn   1/1     Running   0          7d6h
pod/nginx-deployment-6dd86d77d-jr7hk   1/1     Running   0          7d6h

Welches Label ein Objekt besitzt, kann übrigens durch den zusätzlichen get-Parameter --show-labels angezeigt werden.

describe

Neben der einfachen Auflistung der Objekte ist es oftmals hilfreich, sich Objekte beschreiben zu lassen. Hierzu steht der Befehl describe zur Verfügung.

Die Ausgabe des describe-Befehls gibt eine relativ ausführliche Darstellung des Aufbaus und des Zustands des Objektes aus. Die describe-Ausgabe eines Pods gibt beispielsweise Aufschluss über:

  • Die priority-class des Pods
  • Container des Pods einschließlich:
    • Pod-ID
    • Image-Hash (sh256-Hash)
    • Status
  • QoS-Class
  • Node-Selectors
  • Tolerations
  • Events

Vor allem die Events eines Objekts sind oft ein wertvolles Mittel, um eventuellen Fehlern auf die Schliche zu kommen. Als Beispiel sei die Analyse der Fehlermeldung „ImagePullBackOff“ genannt. Oftmals bieten die Events einen Anhaltspunkt wo bei der Fehlanalyse anzusetzten ist.

$ kubectl describe pod nginx-deployment-6dd86d77d-9fm6w
Name:               nginx-deployment-6dd86d77d-9fm6w
Namespace:          test
Priority:           0
PriorityClassName:  <none>
Node:               node-05.example.com/10.66.0.5
Start Time:         Mon, 02 Sep 2019 20:44:29 +0200
Labels:             app=nginx
                    pod-template-hash=6dd86d77d
Annotations:        <none>
Status:             Running
IP:                 10.233.65.100
Controlled By:      ReplicaSet/nginx-deployment-6dd86d77d
Containers:
  nginx:
    Container ID:   docker://7a3e3b51987da42a421d6f965824bfe2ba5d553a9f1d2e93758207c34cd4e31b
    Image:          nginx:1.7.9
    Image ID:       docker-pullable://nginx@sha256:e3456c851a152494c3e4ff5fcc26f240206abac0c9d794affb40e0714846c451
    Port:           80/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Mon, 02 Sep 2019 20:44:31 +0200
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-q2h6q (ro)
Conditions:
  Type              Status
  Initialized       True 
  Ready             True 
  ContainersReady   True 
  PodScheduled      True 
Volumes:
  default-token-q2h6q:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-q2h6q
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type    Reason     Age   From                           Message
  ----    ------     ----  ----                           -------
  Normal  Scheduled  19s   default-scheduler              Successfully assigned test/nginx-deployment-6dd86d77d-9fm6w to node-05.example.com
  Normal  Pulled     18s   kubelet, node-05.example.com Container image "nginx:1.7.9" already present on machine
  Normal  Created    18s   kubelet, node-05.example.com  Created container nginx
  Normal  Started    17s   kubelet, node-05.example.com  Started container nginx

logs

Wird die Ausgabe eines Containers benötigt, so steht der Befehl logs zur Verfügung. Sollte sich ein Pod im Status „CrashLoopBackOff“ befinden, gibt die Anzeige der Logs des ensprechenden Containers meist Aufschluss über die Ursache des Problems.

Bei der Verwendung des logs-Befehls müssen wir explizit zwischen Pods und Containern unterscheiden. Da ein Pod mehrere Container beinhalten kann reicht es, dass einer der Container nicht richtig funktioniert, um den Pod in einen fehlerhaften Zustand zu bringen.

Sollen die Logs eines Pods mit ausschließlich einem Container angezeigt werden, so gestaltet sich die Ausgabe der Logs recht einfach:

$ kubectl logs nginx-deployment-6dd86d77d-9fm6w

Beinhaltet der zu analysierende Pod mehrere Container wird Kubernetes auf die gleiche Anfrage mit einem Fehler antworten.

Dabei ist Kubernetes allerdings so freundlich und liefert die entsprechende Lösung gleich mit.

Beinhaltet ein Pod mehrere Container, so muss neben dem Pod-Namen ebenfalls der Container-Name angegeben werden:

$ kubectl logs nginx-deployment-6dd86d77d-9fm6w -c nginx

Oftmals muss die Ausgabe des logs-Befehls allerdings nicht für die akute Fehlerbehebung herangezogen werden, sondern wird bei der Fehleranalyse vergangener Ereignisse benötigt.

Hierzu steht das zusätzliche Flag --previous zur Verfügung. Dabei werden nicht die aktuellen Logs des Containers angezeigt, sondern die der vorangegangenen Instanz des Containers / Pods.

Explain

Wer (wie ich) nicht immer den exakten Namen eines Parameters oder dessen Platzierung innerhalb der Objektstruktur im Kopf hat, kann sich mit Hilfe des explain-Befehls selbst helfen und sich den korrekten Aufbau eines Kubernetes-Objekts in der genutzten API-Version anzeigen zu lassen.

Er gibt neben dem Aufbau von Objekten auch eine kurze Beschreibung zu allen Parametern aus.

Wollen wir uns beispielsweise den Aufbau der Pod-Spezifiation anschauen, so könnnen wir dies mithilfe des folgenden Befehls bewerkstelligen:

$ kubectl explain pod
KIND:     Pod
VERSION:  v1

DESCRIPTION:
     Pod is a collection of containers that can run on a host. This resource is
     created by clients and scheduled onto hosts.

FIELDS:
   apiVersion   <string>
     APIVersion defines the versioned schema of this representation of an
     object. Servers should convert recognized schemas to the latest internal
     value, and may reject unrecognized values. More info:
     https://git.k8s.io/community/contributors/devel/api-conventions.md#resources

   kind <string>
     Kind is a string value representing the REST resource this object
     represents. Servers may infer this from the endpoint the client submits
     requests to. Cannot be updated. In CamelCase. More info:
     https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds

   metadata <Object>
     Standard object's metadata. More info:
     https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata

   spec <Object>
     Specification of the desired behavior of the pod. More info:
     https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status

   status   <Object>
     Most recently observed status of the pod. This data may not be up to date.
     Populated by the system. Read-only. More info:
     https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status

Wer eine rekursive Auflistung aller möglichen Parameter erhalten möchte erlangt diese mithilfe des folgenden Befehls:

kubectl explain --recursive pod.spec
KIND:     Pod
VERSION:  v1

RESOURCE: spec <Object>

DESCRIPTION:
     Specification of the desired behavior of the pod. More info:
     https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status

     PodSpec is a description of a pod.

FIELDS:
   activeDeadlineSeconds    <integer>
   .. Output Skipped ...
   automountServiceAccountToken <boolean>
   containers   <[]Object>
      args  <[]string>
      command   <[]string>
      env   <[]Object>
         name   <string>
         value  <string>
         valueFrom  <Object>
            configMapKeyRef <Object>
               key  <string>
               name <string>
               optional <boolean>
            fieldRef    <Object>
               apiVersion   <string>
               fieldPath    <string>
            resourceFieldRef    <Object>
               containerName    <string>
               divisor  <string>
               resource <string>
            secretKeyRef    <Object>
               key  <string>
               name <string>
               optional <boolean>
      .. Output Skipped ..
      name  <string>
      ports <[]Object>
      .. Output Skipped ...
   volumes  <[]Object>
      awsElasticBlockStore  <Object>
         fsType <string>
         partition  <integer>
         readOnly   <boolean>
         volumeID   <string>
      .. output Skipped ..
      vsphereVolume <Object>
         fsType <string>
         storagePolicyID    <string>
         storagePolicyName  <string>
         volumePath <string>

Die Ausgabe des explain-Befehls kann so eine Recherche innerhalb der Kubernetes-Dokumentation überflüssig machen. Das spart nicht nur Zeit, sondern oftmals auch Nerven.

Code-Completion

Wer regelmäßig mit der Konsole arbeitet, lernt das autocompletion-Feature zu lieben.

Oftmals ist die Syntax eines Befehles nicht 100 prozentig klar, oder es müssen Argumente vervollständigt werden, deren Namen man sich einfach nicht merken kann oder will. Viele Command-Line-Tools bringen deshalb so genannte completion-files mit und kubectl ist hier keine Ausnahme.

Wer die autocompletion-Funktionalität von kubectl verwenden will, muss dazu den Befehl kubectl completion ... bemühen. Der completion-Befehl gibt die entsprechenden completion-scripts sowohl für bash als auch für zsh aus. Wer die Autovervollständigung ad-hoc nutzten möchte, der kann sich mithilfe der folgenden Befehle behelfen:

bash: source <(kubectl completion bash)

zsh: source <(kubectl completion zsh)

Wer auch nach Beenden des Terminals in den Genuss der Auto-Completion kommen möchte, speichert sich die Ausgabe der Befehle kubectl completion bash/zsh innerhalb einer Datei ab und lädt diese wie gewohnt innerhalb seiner .bashrc oder .zshrc.

Anlegen / Ändern / Löschen

Zum Anlegen, Ändern oder Löschen von Objekten stehen via kubectl unterschiedliche Methoden zur Verfügung. Alle haben gemeinsam, dass sie das zu kontrollierende Objekt anhand ihres Namens und Namespaces (bei namespacesbehafteten Objekten) identifizieren.

Um ein neues Objekt im Cluster anzulegen, können sowohl die Befehle create als auch apply verwendet werden. Dabei setzt create voraus, dass das Zielobjekt noch nicht existiert. Das folgende Beispiel zeigt die Erzeugung eines Deplyoments, welcher den Webserver Nginx als einzigen Pod beinhaltet:

create

$ kubectl create deployment nginx --image=nginx
deployment.apps/nginx created

Versuchen wir nun das gleiche Deployment erneut anzulegen, erhalten wir eine Fehlermeldung, weil ein Deployment mit den namen nginx bereits exisiert.

kubectl create deployment nginx --image=nginx
Error from server (AlreadyExists): deployments.apps "nginx" already exists

Der create Befehl stellt somit eine konkrete Aktion dar und beschreibt nicht – wie andere Befehle – den Zielzustand.

Des Weiteren wurde die Definition des Objekts nicht lokal gespeichert, sondern lediglich dem Cluster mitgeteilt. Um das Objekt, in unserem Fall das Nginx Deployment, auch in anderen Cluster bereitzustellen, muss nun der gleiche Befehl gegen den neuen Cluster ausgeführt werden.

Oftmals ist es eine bessere Idee, Objekte nicht ad-hoc zu erstellen, sondern den Zwischenweg über eine YAML Datei zu gehen, welche die Definition des Selbigen beinhaltet.

kubectl create kann hierbei Hilfestellung leisten.

Der Parameter --output yaml erstellt nicht nur das Objekt, er generiert auch die Definition des Objekts im YAML Format und gibt diese auf der Konsole aus.
Soll die generierte Definition vor dem Einspielen in den Cluster bearbeitet werden, so kann zwischenzeitlich der Parameter --dry-run genutzt werden.

Beispiel:

$ kubectl create deployment nginx --image=nginx --output=yaml --dry-run
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: nginx
  name: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx
        name: nginx
        resources: {}
status: {}

Die Ausgabe des oben stehenden Befehls kann nun als Datei abgelegt und beispielsweise durch Git unter Versionskontrolle gestellt werden.
Wer die resultierende Definition via create gegen den Cluster anwenden will, der kann dies mit dem Befehl kubectl create -f nginx-deployment.yaml bewerkstelligen.

Eine Hilfestellung bietet create oft dann, wenn die Alternative zu fehleranfällig wäre. Als Beispiel sei hier die Erstellung eines secrets genannt, dass sowohl ein Serverzertifikat als auch den dazugehörigen Schlüssel beinhalten soll. Secrets enthalten base64 encodete Werte, weshalb eine manuelle Erstellung mehrere Schritte beinhalten würde.

Mit dem Befehl kubectl create secret tls certificate-pair --cert=certificate.pem --key=key.pem -o yaml --dry-run hingegen ist das gewünschte Secret in einem Befehl erstellt.

kubectl create secret tls certificate-pair --cert=certificate.pem --key=key.pem -o yaml --dry-run
apiVersion: v1
data:
  tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUQ2ekNDQXRPZ0F3SUJBZ0lVY3NtYWR5R29jRlEvZkVrRVRRM25kTjFxZVhrd0RRWUpLb1pJaHZjTkFRRUwKQlFBd2dZUXhDekFKQmdOVkJBWVRBa1JGTVF3d0NnWURWUVFJREFOT1VsY3hHVEFYQmdOVkJBY01FRTF2Wlc1agphR1Z1WjJ4aFpHSmhZMmd4RURBT0JnTlZCQW9NQjBWNFlXMXdiR1V4R1RBWEJnTlZCQU1NRUhSbGMzUXVaWGhoCmJYQnNaUzVqYjIweEh6QWRCZ2txaGtpRzl3MEJDUUVXRUhSbGMzUkFaWGhoYlhCc1pTNWpiMjB3SGhjTk1Ua3cKT1RJMk1UUXpNVEUyV2hjTk1qQXdPVEkxTVRRek1URTJXakNCaERFTE1Ba0dBMVVFQmhNQ1JFVXhEREFLQmdOVgpCQWdNQTA1U1Z6RVpNQmNHQTFVRUJ3d1FUVzlsYm1Ob1pXNW5iR0ZrWW1GamFERVFNQTRHQTFVRUNnd0hSWGhoCmJYQnNaVEVaTUJjR0ExVUVBd3dRZEdWemRDNWxlR0Z0Y0d4bExtTnZiVEVmTUIwR0NTcUdTSWIzRFFFSkFSWVEKZEdWemRFQmxlR0Z0Y0d4bExtTnZiVENDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQgpBTWtnSmtyd1U5UFhmRGhETW15cDlpblBFdmNiVkI5WUIvb3B6bHF3VzRybkkvbTJnbzFVeXFxZ3FLeDlEZWpWCnI0K3ZPcEtZcUcvTDJVZDlpS1o2bHdHUUZmWnNkaTJKVGRGdjVpSzVyejZPQVhwWTE1THYrTjN4TDRkMU5yN1gKT09DcVIwSmlFKzN0Q0tWN1l0Y1N4RUdsNWJlcStpOEJxK0w0bG1mQTZzS09vdjYwcWhpWi8wOUVUN3JoaXdCMApyYk80b2J4L0t5azZzbVhETW1SY2EvVVBXWk82L3hKSmhQeG9kY1dHOGJJcVE4SGtRM1NOaFpyWjdlekFMMmJoCjcxQSt2WFJOcXFJaHorOTdBRWZaSmozeGJZcm5vSVEwajZITkFZaHI1YzJSWmJ4WHVKL2J5QkUvL0U0Z1NPRmwKUU1EeitrS08rWlE1N25odkVXQWRFK01DQXdFQUFhTlRNRkV3SFFZRFZSME9CQllFRkZLK1JSNVBPVjVReENDOAp1UFM1a3lkMU9vcC9NQjhHQTFVZEl3UVlNQmFBRkZLK1JSNVBPVjVReENDOHVQUzVreWQxT29wL01BOEdBMVVkCkV3RUIvd1FGTUFNQkFmOHdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBSzdGbWFGYWRXei9hdkxxSmI1LzAxZ0UKNUxpNDVuSE5LbjZLa0lGZUdWT2RFS1F2ZWg5eWhyclRGaEJNUDk1aU43UEFVT2R6NVNMNC9tQ0V1QkRKd3dLKwpyc0N3OFJSS0hLaXYvcVdRU29BTDBkdU1LcXVIYU0rRTdINHFHOFVONDk2Q2YrQ3djU0paTjVSNGdROU1JTXp6CmFEL1dhek1qVHlJcFMwMFFaSTd5elBCYlFUMnRnbERLcjRRY0ROblFPNVNiVE5STDgraVR0QnBoZTRWWERjQ24KUTJpRkhweWVtZURvQ0l2YXBUU1k2VUxKM3JxNysrdmhRZmJIYmJtejJ4WHFCSUY5ZUV3RVFhM2NSd2hBeENlZQorMjJEVGoxaXdmeFpNWmRuSnR6UVM5QVRHeTQzSWh4dmJDQ2pxbTNCODBUblBTZGRrcFRDOVFKcEhPdkphTjg9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
  tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2d0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktrd2dnU2xBZ0VBQW9JQkFRREpJQ1pLOEZQVDEzdzQKUXpKc3FmWXB6eEwzRzFRZldBZjZLYzVhc0Z1SzV5UDV0b0tOVk1xcW9LaXNmUTNvMWErUHJ6cVNtS2h2eTlsSApmWWltZXBjQmtCWDJiSFl0aVUzUmIrWWl1YTgramdGNldOZVM3L2pkOFMrSGRUYSsxempncWtkQ1loUHQ3UWlsCmUyTFhFc1JCcGVXM3F2b3ZBYXZpK0pabndPckNqcUwrdEtvWW1mOVBSRSs2NFlzQWRLMnp1S0c4ZnlzcE9ySmwKd3pKa1hHdjFEMW1UdXY4U1NZVDhhSFhGaHZHeUtrUEI1RU4wallXYTJlM3N3QzltNGU5UVByMTBUYXFpSWMvdgpld0JIMlNZOThXMks1NkNFTkkraHpRR0lhK1hOa1dXOFY3aWYyOGdSUC94T0lFamhaVURBOC9wQ2p2bVVPZTU0CmJ4RmdIUlBqQWdNQkFBRUNnZ0VCQUxFV1JhRW1DaWswU29PZlp2NldoOUE0SzVLMzFWSGp5T0pUZlFZTTBnMXoKaHhHUHlWTjNuUnF2YXRTMUoxSWpFL21IYUNNN2x0TVl3YTlZc01Fa24yRVk1TDJjc2xGVjI5YlVsK1ZyYVFuRApMem55ajUwby9nOHRGWlJIZUhTQU8reFZBWGxKc2hLRDZtRUtTdlRqNlRtRVFNZC9HOW5YdHVpWnlKU0NJREk4CnBSSzJpQk9sRStPbHRScER3VnNDUDFtY0w2SjA2L0lWRjBnbjFyM3Q2S1o3NmIyMGlkSktPTjVpVmVLTDAxaUUKMWxmQmtKMXluUWgzR1dlSURDSXJyM2RoZ29qRVgvNjcxakJqRHVmcnBHUFpxNW02NXJLSTg4aENVNnVvMERPLwoyU0dqVG02VFNiRytPMUxPUmIzZXl0aFlMUXR2UVRuZHQ0Z3BIWTNoVklFQ2dZRUE2LzhMbEI0NTVwV1pkYTd6CmVKbTI1VWNxUXdjcUlmUzROZGlQWG5VTmxkWEdYVG5xdU1ST2JXd1JjbWtBUTh4aUxsaDJzYVNvQmNMN1ZYWWEKaTZyV081WXhSNjM3QktERjlOWTBxOHhoUDJlTVJ2ZUV2QkUzZkFFRjhvdCsrNUo0M05kbEI5M3lxOWIyUUs3TgpzRnhoVloyRDd3blM1bXRWekNWL3lHa2NNMGtDZ1lFQTJpeHZTeGxmUHpIZXM1THZpK1RseFhZTldsbFJiRVFvCko1amlEM2JDSG5oSENHQVJWU1V1NVVVTVd3b0pUQmxydldoNFczcWhzeDFoQkxmeDVQNVlOdVBBTDhhQlVQMUwKdUl2NlJtRUVFdXVPZ0MwMmhyRXIwNCtBYWIrbHM3SVpPUkZCMWd6M3FSdEUwQVo5UVF6YlJ4Q3ZUUnovS3lXaApjSHhRbk44RUljc0NnWUJPV0p5Q2JzcHdGNGdidnBvTGxwUldaNXJMSjh5Lyt4dFFuUFZ6dVU1cVNNOFMwaEJ2CmlKUTAxV1N4WTlSM3JabUdvMDI4U2RxU0Z4b1RWQ01aN1B3MFNmZFFRWjBNKzBiY3NtUklDSkRjV01jRUpGWUgKalh1ckNqZnNQbzFJZldic2dnR0RiQmFOSDg4ZXlDbDIvQ1JBSlF2UXhxVWlZODNXK1RnRDA0bE9LUUtCZ1FEVQpJMWlrQVN1bjJ1bmNXZ2NxVTR0SGtSNHl0NTZBVTFWb0N6UGtMV2xiRDBDaVdDY0NUNEZsMU5uS3U5dUdiMEZmCmpuRlpJY2lRelFSRS9rYnFqcFZmNmR3NW1CNnRqVjFQT0d4R2VwYm5mcnUwemtHeWZodExQc0Z5RWJNaEl3OTcKZWRnMk5hMnFkS1ZZVUxjQnhXcUJreXVoSTR6SmUzR2FXb1pYd2xIV09RS0JnUURXdjJmd2JTeVc0dkNEYm5rNgpxd1ZWaVVOV1drOHNYR1dDV3d5RXVxalRiYUlHMjVtbTNuWjRCRVJyUTB2Vmx2VWNsMmZwUVkweWxDdkRObTgxCk5jL243SUw0SnN3dU5XeThUWW1lZ0cxWThtcEUxTHo5UVVhWE1tRmpqZGc5TExwWElLM2xWSUVzYUtFRVNnM0sKN0hmUHpaV1h3dkZJUGlLTWRPaldmZ0xoS0E9PQotLS0tLUVORCBQUklWQVRFIEtFWS0tLS0tCg==
kind: Secret
metadata:
  creationTimestamp: null
  name: certificate-pair
type: kubernetes.io/tls

Da nicht alle Objekttypen oder Parameter als Argumente an create übergeben werden können, muss teilweise der Weg über eine Manifestdatei gegangen werden.

apply

Neben create können neue Objekte auch mithilfe des apply-Befehls erstellt werden. Hierbei unterscheidet sich apply jedoch leicht im Handling.

apply spielt seine Stärken im Umgang mit YAML-Manifesten aus. Nehmen wir die in create dargestellte Deployment-Definition und nehmen an, dass diese als nginx-deployment.yaml vorliegt. Dann können wir diese mit Hilfe des folgenden Befehls im Cluster einspielen:

kubectl apply -f nginx-deployment.yaml
deployment.apps/nginx created

Im Gegensatz zu create verhält sich apply bei erneuter Ausführung des Befehls unterschiedlich.

kubectl apply -f nginx-deployment.yaml
deployment.apps/nginx unchanged

Denn durch apply wird keine Aktion sondern ein Zielzustand definiert, welche vom Cluster berücksichtigt wird. In unserem Beispiel also die Existenz eines Deployment-Objekts namens nginx unter Verwendung des Image nginx und einem Replika.

Wollen wir die Anzahl der Replikas nun Beispielsweise auf 2 anheben, so genügt es, die Datei entsprechend zu aktualisieren und erneut den apply-Befehl auszuführen.

kubectl apply -f nginx-deployment.yaml
deployment.apps/nginx configured

Das definierte Ziel, unser Objekt, wird dabei immer anhand der apiVersion, Kind, name und namespace identifiziert.

Viele Eigenschafen eines Objekts können auf diese Weise geändert werden. Es gibt jedoch s.g. immutable Eigenschaften oder Felder, die nach der Erstellung des Objekts nicht mehr angepasst werden können. apply liefert dann eine entsprechende Fehlermeldung.

Weil keine Aktion, sondern ein Zielzustand definiert wird, eignet sich apply für mehrere Anwendungsfälle. Ferner ist es dazu geeignet, in Scripts oder Pipelines verwendet zu werden.

patch

Um Eigenschaften eines Objekts anzupassen, steht zusätzlich der Befehl patch zur Verfügung. Dieser enthält die Information, welches Objekt geändert werden soll und wie. Wollen wir z.B. die Anzahl der Replikas auf drei erhöhen, können wir dies mit dem folgenden patch-Befehl bewerkstelligen:

kubectl patch deployment nginx -p '{"spec": {"replicas": 3}}'
deployment.extensions/nginx patched

patch bietet sich vor allem dann an, wenn Objekte den eigenen Vorstellungen nach geändert werden sollen, aber automatisiert erstellt werden. Zum Beispiel node Objekte.

Spezifische Befehle

Neben den generischen Methoden wie apply oder patch stellt kubectl eine Reihe von spezifischen Befehlen bereit. Anhand dieser Befehle können beispielsweise Deployments oder StatefulSets skaliert werden, auf einen früheren Stand eines Deployments zurückgewechselt werden, oder aber der Status eines sogenannten rollouts überprüft werden.

Nachfolgend werden ein paar der gängigen Befehle und deren Verwendung grob skizziert:

  • label, annotate: Hinzufügen, ändern oder löschen von labels und annotations.
    Beispiel: kubectl label deployment nginx comment=awebserver
  • scale: Anpassen der Anzahl der replica-Eigenschaft.
  • rollout (history, pause, restart, undo): Steuerung von rollouts. Z.B. Rollback auf eine frühere Version eines Deployments.
  • expose: Erstellung ein Service zu einem gegebenen Objekt.

delete

Früher oder später kommt der Moment, in dem die angelegten Objekte auch wieder gelöscht werden sollen.

Hier kommt der Befehl delete zum Einsatz.

Wie auch bei create kann delete das Zielobjekt auf unterschiedliche Weise identifizieren. Entweder durch Angabe der Typs und des Namens oder aber indirekt über den Parameter -f und eine entsprechende Objektdefinition. Wollen wir unser Nginx Deployment löschen geschieht dies z.B. mit Hilfe des Befehls:

kubectl delete -f nginx-deployment.yaml
deployment.apps "nginx" deleted

Alternativ hätten wir das Deployment auch via kubectl delete deployment nginx löschen können.

Exec

Auch wenn keine manuellen Änderungen an Dateien oder Prozessen innerhalb eines Containers vorgenommen weden sollen, kann es manchmal durchaus hilfreich sein, in einen Container hineinzusehen. Besonders bei der Entwicklung bietet der Blick in einen Container oftmals schnelleren Einblick in die Situation als andere Lösungen.

Nehmen wir an, wir wollen unseren Nginx-Web-Service debuggen und prüfen, ob dieser auf bestimmte Requests reagiert, so kann der exec Befehl helfen.

kubectl exec führt den angegebenen Befehl innerhalb des Containers aus. Auch eine interaktive Shell innerhalb des Containers kann mit exec gestartet werden, sofern vorhanden.

Wollen wir beispielsweise sicherstellen, dass der Inhalt einer Datei innerhalb des Containers mit unseren Erwartungen übereinstimmt, dann können wir uns diese Datei mittels cat anzeigen lassen:

$ kubectl get pods
NAME                     READY   STATUS    RESTARTS   AGE
nginx-65f88748fd-lt2z5   1/1     Running   0          4m35s
nginx-65f88748fd-mmwl5   1/1     Running   0          4m35s
$ kubectl exec nginx-65f88748fd-lt2z5 cat /etc/nginx/nginx.conf

user  nginx;
worker_processes  1;
...

http {
    include       /etc/nginx/mime.types;
    ...
    include /etc/nginx/conf.d/*.conf;
}

Möchten wir eine interaktive Shell im Container starten, dann müssen wir neben dem Befehl selbst weitere Parameter angeben. Dabei handelt es sich um --stdin und --tty. Andernfalls wird die Shell zwar gestartet, sie beendet sich allerdings direkt wieder falls wir keine Argumente übergeben haben.

Dies ist bereits aus der Verwendung von docker exec bekannt. Das dort verwendete Kürzel -it kann auch bei kubectl exec verwendet werden. Ein vollständiges Beispiel sieht dann wie folgt aus:

kubectl exec -it nginx-65f88748fd-lt2z5 -- bash
root@nginx-65f88748fd-lt2z5:/#

Der auszuführende Befehl muss natürlich innerhalb des Containers vorhanden sein. Da die benutzten Images meist auf minimale Größe ausgelegt sind, ist die Auswahl der Tools innerhalb des Containers oft stark begrenzt. Aus Security-Sicht ist dies eine gute Sache.

Sofern der Zielpod mehrere Container beherbergt, oder gar Init-Container verwendet, kann mittels -c der ensprechende Containername angegeben werden.

Port Weiterleitung

Manchmal müssen Services analysiert werden, die nicht direkt der Außenwelt präsentiert werden, oder aber vorgelagerte Proxies und Loadbalancer bei einer Fehleranalyse ausgeschlossen werden sollen.

Hierzu ist es notwenig, dass direkt auf den entsprechenden Service zugegriffen werden kann. Auch wenn dies normalerweise nicht der Fall ist.

Um direkten Zugriff zu ermöglichen stellt kubectl den Befehl port-forward bereit. Dieser dient dazu, einen lokalen Port auf den Port eines Objekts innerhalb des Cluster weiterzuleiten. Als Ziel können unter Anderem Services, Pods auch auch ganze Deployments dienen.

Dabei wird das Ziel in der Form <typ-short>/ angegebenen. Als weiterer Parameter muss eine Kombination aus lokalem Port und Remoteport angegeben werden.

Wollen wir nun direkt auf einen unserer Nginx Pods zugreifen sieht die entsprechende Syntax wie folgt aus:

$ kubectl port-forward pod/nginx-65f88748fd-lt2z5 8080:80
Forwarding from 127.0.0.1:8080 -> 80
Forwarding from [::1]:8080 -> 80

Dabei gibt 8080 den lokal zu öffnenden Port, 80 den den Zielport. Ein Aufruf von http://localhost:8080 zeigt ob der Port-Forward funktioniert hat und wie erwartet unser Nginx antwortet:

$ curl http://localhost:8080
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
...
<p><em>Thank you for using nginx.</em></p>
</body>
</html>

kubectl port-forward bestätigt dabei den Request mit dem Output Handling connection for 8080. Sollte es kubectl aus irgendeinem Grund nicht möglich sein den Request weiterzuleiten, so wird eine entsprechende Fehlermledung ausgegeben.

Alternativ kann der lokale Port auch weggelassen werden, dann versucht kubectl lokal den gleichen Port zu öffnen, auf den weitergeleitet werden soll. Je nach Port-Range benötigt man dazu allerdings lokale Root-Berechtigungen. Wer einen zufälligen, lokalen Port öffnen möchte kann dies anhand der Syntax :<target-port> bewerkstelligen.

Wollen wir die Weiterleitung auf eine dedizierte IP-Adresse binden, dann kann dies mit Hilfe des Parameters --address geschehen. Diese nimmt im Zweifelsfall auch mehrere IP-Adressen als Argument auf.

Weiteres

diff

Anhand des diff Befehls ist es möglich, die Abweichungen des IST mit dem SOLL Zustand anzuzeigen.

Hierzu nimmt der diff Befehl den Parameter -f auf. Das folgende Beispiel zeigt die diff Ausgabe nach Aktualisieren unseres Nginx Deployment YAML und vor dem apply:

k diff -f nginx-deployment.yaml
diff -u -N /tmp/LIVE-265469814/apps.v1.Deployment.test.nginx /tmp/MERGED-783806045/apps.v1.Deployment.test.nginx
--- /tmp/LIVE-265469814/apps.v1.Deployment.test.nginx   2019-09-30 13:17:41.525469492 +0200
+++ /tmp/MERGED-783806045/apps.v1.Deployment.test.nginx 2019-09-30 13:17:41.541469584 +0200
@@ -6,7 +6,7 @@
     kubectl.kubernetes.io/last-applied-configuration: |
       {"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"labels":{"app":"nginx","version":"v1"},"name":"nginx","namespace":"test"},"spec":{"replicas":2,"selector":{"matchLabels":{"app":"nginx"}},"strategy":{},"template":{"metadata":{"labels":{"app":"nginx"}},"spec":{"containers":[{"image":"nginx","name":"nginx","resources":{}}]}}},"status":{}}
   creationTimestamp: "2019-09-26T16:04:43Z"
-  generation: 1
+  generation: 2
   labels:
     app: nginx
     comment: awebserver
@@ -18,7 +18,7 @@
   uid: 5a712cb7-e077-11e9-82d3-96000014cd46
 spec:
   progressDeadlineSeconds: 600
-  replicas: 2
+  replicas: 5
   revisionHistoryLimit: 10
   selector:
     matchLabels:
exit status 1

Copy

Wer Daten in oder aus einem laufenden Container kopieren möchte, dem steht mit kubectl cp ein Befehl zur Hand, der genau diese Aufgabe erfüllt. Voraussetzung ist allerdings ein installiertes tar innerhalb des Containers.

Wollen wir Beispielsweise die nginx.conf aus unserem Nginx Container kopieren, dann würde der entsprechende Befehl wie folgt aussehen:

$ kubectl get pods  
NAME                     READY   STATUS    RESTARTS   AGE
nginx-65f88748fd-lt2z5   1/1     Running   0          3d20h
nginx-65f88748fd-mmwl5   1/1     Running   0          3d20h

$ kubectl cp nginx-65f88748fd-lt2z5:/etc/nginx/nginx.conf nginx-65f88748fd-lt2z5_nginx.conf
tar: Removing leading `/' from member names

Falls innerhalb des Zielpods mehrere Container betrieben werden, so muss mithilfe des Parameter -c <container-name> der Zielcontainer angegeben werden.

wait

Manchmal könnte bestimmte Aktionen erst durchgeführt werden, nachdem andere erfolgreich abgeschlossen wurden. Oder man möchte einfach nur informiert werden sobald eine spezifische Aktion abgeschlossen wurde. Dies kann mit Hilfe des Befehls wait vollbracht werden.

wait nimmt ein Set an Argumenten auf, die sowohl das Zielobjekt als auch den Zielzustand beschreiben.

Wollen wir beispielsweise darauf warten, dass sich einer unserer Pods im Zustand Ready befindet, so sieht der Befehl wie folgt aus:

$ kubectl wait --for=condition=Ready pod/nginx-65f88748fd-lt2z5
pod/nginx-65f88748fd-lt2z5 condition met

Soll auf das endgültige Löschen eines Pods gewartet werden, so kann als Argument --for der Wert delete angegeben werden.

Dies ist insofern nützlich, als dass bei einem delete nicht der Löschvorgang selber durchgeführt wird, sondern das enstprechende Objekt nur als zu löschen makiert wird.

kubectl wait --for=delete pod/nginx-65f88748fd-49qv2 --timeout=120s
pod/nginx-65f88748fd-49qv2 condition met

Unterstützung

Falls Sie Unterstützung beim Einsatz von Kubernetes benötigen, steht Ihnen unser Open Source Support Center zur Verfügung – Falls gewünscht auch 24 Stunden am Tag, an 365 Tagen im Jahr.

Wir freuen uns auf Ihre Kontaktaufnahme.

Kategorien: HowTos


Beitrag teilen: