# Kubectl Command line tool for communicating with a Kubernetes cluster's control plane using the Kubernetes API. Resource types are case **in**sensitive and can be specified in their singular, plural or abbreviated form for convenience: ```sh # The two commands below are equivalent. kubectl get deployment,replicasets,pods -A kubectl get deploy,rs,po -A ``` Use `kubectl api-resources` to check out the available resources and their abbreviations. Multiple resources types can be specified together, but only one resource name is accepted at a time. Resource names are case sensitive and will filter the requested resources; use the `-l`, `--selector` option to get around filtering: ```sh kubectl get deployments,replicasets -A kubectl get pod etcd-minikube -n kube-system kubectl get pods -l app=nginx,tier=frontend ``` ### Table of contents - [TL;DR](#tldr) - [Configuration](#configuration) - [Configure access to multiple clusters](#configure-access-to-multiple-clusters) - [Create resources](#create-resources) - [Output formatting](#output-formatting) - [Verbosity and debugging](#verbosity-and-debugging) - [Further readings](#further-readings) - [Sources](#sources) ## TL;DR ```sh # Enable shell completion. source <(kubectl completion bash) echo "[[ $commands[kubectl] ]] && source <(kubectl completion zsh)" >> ~/.zshrc # Shot the merged configuration. kubectl config view # Get specific values from the configuration. kubectl config view -o jsonpath='{.users[].name}' kubectl config view -o jsonpath='{.users[*].name}' kubectl config view -o jsonpath='{.users[?(@.name == "e2e")].user.password}' # Set configuration values. kubectl config set-context --current --namespace=keda kubectl config set-context gce --user=cluster-admin --namespace=foo kubectl config set-credentials \ kubeuser/foo.kubernetes.com --username=kubeuser --password=kubepassword # Delete configuration values. kubectl config unset users.foo # Use multiple config files at once. # This will temporarily merge them in one big configuration file. KUBECONFIG="path/to/config1:path/to/configN" # List contexts. kubectl config get-contexts kubectl config current-context # Set context as the default one. kubectl config use-context docker-desktop kubectl config use-context gce # Display addresses of the master and services. kubectl cluster-info # Dump the complete current cluster state. kubectl cluster-info dump kubectl cluster-info dump --output-directory=/path/to/cluster-state # List supported resources types along with their short name, API group, Kind, # and whether they are namespaced. kubectl api-resources kubectl api-resources --namespaced=true kubectl api-resources -o name kubectl api-resources -o wide kubectl api-resources --verbs=list,get # Show the documentation about resources or their fields. kubectl explain pods kubectl explain pods.spec.containers # List and filter resources. kubectl get pods kubectl get pod/coredns-845757d86-47np2 -n kube-system kubectl get namespaces,pods --show-labels kubectl get services -A -o wide kubectl get rs --sort-by=.metadata.name kubectl get pv --sort-by=.spec.capacity.storage --no-headers kubectl get po --sort-by='.status.containerStatuses[0].restartCount' kubectl get events --sort-by .metadata.creationTimestamp kubectl get pods --field-selector=status.phase=Running kubectl get node -l='!node-role.kubernetes.io/master' kubectl get replicasets -l 'environment in (prod, qa)' kubectl get deploy --selector 'tier,tier notin (frontend)' # Extract information from resources' definition. kubectl get deployment nginx -o yaml kubectl get cm kube-root-ca.crt -o jsonpath='{.data.ca\.crt}' kubectl get po -o=jsonpath='{.items..metadata.name}' kubectl get po -l app=redis -o jsonpath='{.items[*].metadata.labels.version}' kubectl get nodes \ -o jsonpath='{.items[*].status.addresses[?(@.type=="ExternalIP")].address}' # List all fields under '.metadata' regardless of their name. kubectl get pods -A -o=custom-columns='DATA:metadata.*' # List images being run in a cluster. kubectl get po -A -o=custom-columns='DATA:spec.containers[*].image' kubectl get po -A -o=custom-columns='DATA:spec.containers[?(@.image!="k8s.gcr.io/coredns:1.6.2")].image' # List all pods in status 'Shutdown'. kubectl get po -A \ -o jsonpath='{.items[?(@.status.reason=="Shutdown")].metadata.name}' # List ready nodes. kubectl get nodes \ -o jsonpath='{range .items[*]}{@.metadata.name}:{range @.status.conditions[*]}{@.type}={@.status};{end}{end}' \ | grep "Ready=True" # List all secrets currently in use by a Pod. kubectl get pods -o json \ | jq '.items[].spec.containers[].env[]?.valueFrom.secretKeyRef.name' \ | grep -v null | sort | uniq # List the name of Pods belonging to a particular RC. SELECTOR=${$(kubectl get rc my-rc --output=json | jq -j '.spec.selector | to_entries | .[] | "\(.key)=\(.value),"')%?} kubectl get pods -l=$SELECTOR \ -o=jsonpath='{.items..metadata.name}' # List the containerID of initContainers from all Pods. # Helpful when cleaning up stopped containers while avoiding the removal of # initContainers kubectl get pods --all-namespaces \ -o jsonpath='{range .items[*].status.initContainerStatuses[*]}{.containerID}{"\n"}{end}' \ | cut -d/ -f3 # Produce a period-delimited tree of all keys returned for nodes. # Helpful when trying to locate a specific key within a complex nested JSON # structure. kubectl get nodes -o json | jq -c 'path(..)|[.[]|tostring]|join(".")' # Show detailed information about resources. kubectl describe node pi kubectl describe deploy,rs,po -l app=redis # Create resources from manifests. kubectl apply -f manifest.yaml kubectl apply -f path/to/m1.yaml -f ./m2.yaml kubectl apply -f dir/ kubectl apply -f https://git.io/vPieo cat <<-EOF | kubectl apply -f - apiVersion: v1 kind: Secret metadata: name: mysecret type: Opaque data: password: $(echo -n "s33msi4" | base64 -w0) username: $(echo -n "jane" | base64 -w0) EOF # Compare the current state of the cluster against the state it would be in if # a manifest was applied kubectl diff -f ./manifest.yaml # Start a Pod. kubectl run nginx --image nginx kubectl run busybox --rm -it --image=busybox -n keda -- sh # Start a Pod and write its specs into a file. kubectl run nginx --image=nginx --dry-run=client -o yaml > pod.yaml # Create a single instance deployment of 'nginx'. kubectl create deployment nginx --image=nginx # Start a Job using an existing Job as template kubectl create job backup-before-upgrade-13.6.2-to-13.9.2 \ --from=cronjob.batch/backup -n gitlab # Wait for a pod to be 'ready'. kubectl wait --for 'condition=ready' --timeout 120s \ pod -l 'app.kubernetes.io/component=controller' # Update the 'image' field of the 'www' containers from the 'frontend' # Deployment. # This starts a rolling update. kubectl set image deployment/frontend www=image:v2 # Show the history of resources, including the revision. kubectl rollout history deployment/frontend # Rollback resources to the latest previous version. kubectl rollout undo deployment/frontend # Rollback resources to a specific revision. kubectl rollout undo deployment/frontend --to-revision=2 # Follow the rolling update status of the 'frontend' Deployment until its # completion. kubectl rollout status -w deployment/frontend # Start a rolling restart of the 'frontend' Deployment. kubectl rollout restart deployment/frontend # Replace a Pod based on the JSON passed into stdin. cat pod.json | kubectl replace -f - # Force replacement, deletion and recreation (in this order) of resources. # This Will cause a service outage. kubectl replace --force -f ./pod.json # Create a service for a replicated 'nginx'. # Set it to serve on port 80 and connect to the containers on port 8000. kubectl expose rc nginx --port=80 --target-port=8000 # Update a single-container Pod's image tag. kubectl get pod mypod -o yaml \ | sed 's/\(image: myimage\):.*$/\1:v4/' \ | kubectl replace -f - # Add Labels to resources. kubectl label pods nginx custom-name=awesome # Add Annotations. kubectl annotate pods alpine icon-url=http://goo.gl/XXBTWq # Autoscale resources. kubectl autoscale deployment foo --min=2 --max=10 # Partially update resources. kubectl patch node k8s-node-1 -p '{"spec":{"unschedulable":true}}' # Update a container's image. # 'spec.containers[*].name' is required to specify the path of the merged key. kubectl patch pod valid-pod \ -p '{"spec":{"containers": [{"name": "kubernetes-serve-hostname","image":"new image"}]}}' # Update a container's image using a JSONPatch with positional arrays. kubectl patch pod valid-pod --type='json' \ -p='[{"op": "replace", "path": "/spec/containers/0/image", "value":"new image"}]' # Disable a Deployment's livenessProbe using a JSONPatch with positional arrays. kubectl patch deployment valid-deployment --type json \ -p='[{"op": "remove", "path": "/spec/template/spec/containers/0/livenessProbe"}]' # Add a new element to a positional array. kubectl patch sa default --type='json' \ -p='[{"op": "add", "path": "/secrets/1", "value": {"name": "whatever" } }]' # Edit the service named docker-registry. kubectl edit svc/docker-registry KUBE_EDITOR="nano" kubectl edit svc/docker-registry # Scale a replicaset named 'foo' to 3 kubectl scale --replicas=3 rs/foo # Scale a resource specified in "foo.yaml" to 3 replicas. kubectl scale --replicas=3 -f foo.yaml # If the Deployment named 'mysql''s current size is 2, scale it to 3. kubectl scale --current-replicas=2 --replicas=3 deployment/mysql # Scale multiple ReplicationControllers at once. kubectl scale --replicas=5 rc/foo rc/bar rc/baz # Delete a Pod using the type and name specified in pod.json. kubectl delete -f ./pod.json # Delete Pods and Services named 'baz' and 'foo'. kubectl delete pod,service baz foo # Delete pods and services with Label name=myLabel. kubectl delete pods,services -l name=myLabel # Delete all pods and services in namespace my-ns. kubectl -n my-ns delete pod,svc --all # Delete all pods matching awk's pattern1 or pattern2. kubectl get pods --no-headers \ | awk '/pattern1|pattern2/{print $1}' \ | xargs -n1 kubectl delete pods # Delete non-default service accounts. kubectl get serviceaccounts \ -o jsonpath="{.items[?(@.metadata.name!='default')].metadata.name}" \ | xargs -n1 kubectl delete serviceaccounts # Attach to a running container. kubectl attach my-pod -i # Run command in existing Pods. kubectl exec my-pod -- ls / kubectl exec my-pod -c my-container -- ls / # Show metrics for a given Pod and its containers. kubectl top pod busybox --containers # Get logs from resources. kubectl logs redis-0 kubectl logs -l name=myLabel kubectl logs my-pod -c my-container # Follow logs. kubectl logs -f my-pod kubectl logs -f my-pod -c my-container kubectl logs -f -l name=myLabel --all-containers # Get logs for a previous instantiation of a container. kubectl logs nginx --previous # Get the logs of the first Pod matching ID. kubectl logs $(kubectl get pods --no-headers | grep $ID | awk '{print $2}') # Verify user's permissions on the cluster. kubectl auth can-i create roles kubectl auth can-i list pods # Taint a Node. kubectl taint nodes node1 key1=value1:NoSchedule # Taint all nodes in a certain nodepool (Azure AKS). kubectl get no -l "agentpool=nodepool1" -o jsonpath='{.items[*].metadata.name}' | xargs -n1 -I{} -p kubectl taint nodes {} key1=value1:NoSchedule # Remove a taint. # Notice the '-' sign at the end. kubectl taint nodes node1 key1=value1:NoSchedule- # If a taint with that key and effect already exists, replace its value. kubectl taint nodes foo dedicated=special-user:NoSchedule # Mark Nodes as unschedulable. kubectl cordon my-node # Mark my-node as schedulable. kubectl uncordon my-node # Drain my-node in preparation for maintenance. kubectl drain my-node # Show metrics for a given node. kubectl top node my-node # Listen on port 5000 on the local machine and forward connections to port 6000 # of my-pod kubectl port-forward my-pod 5000:6000 ``` ## Configuration The configuration files are loaded as follows: 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: ```sh kubectl config --kubeconfig config.local view ``` 2. If the `$KUBECONFIG` environment variable is set, then it is used as a list of paths following the normal path delimiting rules for your system; the files are merged: ```sh export KUBECONFIG="/tmp/config.local:.kube/config.prod" ``` 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 existing file; if no file in the chain exist, then the last file in the list is created with the configuration. 3. If none of the above happens, `~/.kube/config` is used, and no merging takes place. The configuration file can be edited, or acted upon from the command line: ```sh # Show the merged configuration. kubectl config view KUBECONFIG="~/.kube/config:config.local" kubectl config view # Show specific values only. kubectl config view -o jsonpath='{.users[].name}' kubectl config view -o jsonpath='{.users[?(@.name == "e2e")].user.password}' # Add a new user that supports basic auth. kubectl config set-credentials kubeuser/foo.kubernetes.com \ --username=kubeuser --password=kubepassword # Delete user 'foo'. kubectl config unset users.foo # List the available contexts. kubectl config get-contexts # Display the current default context name. kubectl config current-context # Set the default context. kubectl config use-context minikube # Permanently setup specific contexts. kubectl config set-context --current --namespace=ggckad-s2 kubectl config set-context gce --user=cluster-admin --namespace=foo ``` ### Configure access to multiple clusters See [configure access to multiple clusters] for details. ## Create resources The preferred way to create resources is to define them inside `manifest`s and then apply those: ```yaml --- # file manifest.yaml --- apiVersion: v1 kind: Pod metadata: name: busybox-sleep spec: containers: - name: busybox image: busybox args: - sleep - "1000000" --- apiVersion: v1 kind: Pod metadata: name: busybox-sleep-less spec: containers: - name: busybox image: busybox args: - sleep - "1000" ``` ```sh # Apply the manifest. kubectl apply -f manifest.yaml # Apply multiple manifests together. kubectl apply -f path/to/m1.yaml -f m2.yaml # Apply all manifests in a directory. kubectl apply -f ./dir # Apply a remote manifest. kubectl apply -f https://git.io/vPieo # Define a manifest using HEREDOC and apply it. cat < pod.yaml # Create a single instance deployment of 'nginx'. kubectl create deployment nginx --image=nginx # Start a Job using an existing Job as template kubectl create job backup-before-upgrade-13.6.2-to-13.9.2 \ --from=cronjob.batch/backup -n gitlab ``` ## Output formatting Add the `-o`, `--output` option to a command: Format | Description ----------------------------------- | ----------- `-o=custom-columns=` | Print a table using a comma separated list of custom columns `-o=custom-columns-file=` | Print a table using the custom columns template in the \ file `-o=json` | Output a JSON formatted API object `-o=jsonpath=