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 Objektendescribe: Beschreibung von Objekten und deren Statuslogs: Anzeige der Logs eines Containersexplain: 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 Informationenyaml: Ausgabe des gesamten Objekts im YAML formatjson: Ausgabe des gesamten Objekts im JSON formatjsonpath: 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=awebserverscale: Anpassen der Anzahl derreplica-Eigenschaft.rollout(history, pause, restart, undo): Steuerung vonrollouts. 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.
