# 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 ``` One possible output format is [JSONpath]. ## Table of contents 1. [TL;DR](#tldr) 1. [Configuration](#configuration) 1. [Configure access to multiple clusters](#configure-access-to-multiple-clusters) 1. [Create resources](#create-resources) 1. [Output formatting](#output-formatting) 1. [Verbosity and debugging](#verbosity-and-debugging) 1. [Further readings](#further-readings) 1. [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 configuration files at once. # This will *merge* all files in one big temporary configuration file. KUBECONFIG="path/to/config1:path/to/configN" # List Contexts. kubectl config get-contexts kubectl config current-context # Set given Contexts as the default one. kubectl config use-context 'docker-desktop' kubectl config use-context 'gce' # Display the cluster's state with FQDNs. 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 the 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. # Also includes the latest events involving them. kubectl describe node pi kubectl describe deploy,rs,po -l 'app=redis' # Create or update resources from manifests. # Missing resources will be created. Existing resources will be updated. 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 kubectl run 'alpine' --restart=Never -it --image 'alpine' -- sh kubectl run 'ephemeral' --image=registry.k8s.io/pause:3.1 --restart=Never # 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 printing "Hello World". kubectl create job 'hello' --image 'busybox:1.28' -- echo "Hello World" # 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' # Start a CronJob printing "Hello World" every minute. kubectl create cronjob 'hello' --image=busybox:1.28 --schedule="*/1 * * * *" \ -- echo "Hello World" # 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. kubectl label pods 'nginx' 'custom-name=awesome' kubectl label ns 'default' 'pod-security.kubernetes.io/enforce=privileged' # 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 resources of a single type. # Also deletes the resources managed by the specified ones. kubectl delete deployment 'bar' # 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 all Completed Jobs and all Pods in a failed state. kubectl delete pods --field-selector 'status.phase=Failed' # Delete all Pods and Services with Label 'name=myLabel'. kubectl delete pods,services -l name=myLabel # Delete all Pods and Services in the 'my-ns' Namespace. kubectl -n my-ns delete pod,svc --all # Delete all Pods matching '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 the current 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 given node pool (Azure AKS). kubectl get no -l "agentpool=nodepool1" -o jsonpath='{.items[*].metadata.name}' | xargs -n1 -I{} -p kubectl taint nodes {} key1=value1:NoSchedule # Remove Taints. # 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 # Execute debug Containers. # Debug Containers are privileged. kubectl debug -it 'node/docker-desktop' --image 'busybox:1.28' # Mark Nodes as unschedulable. kubectl cordon my-node # Mark Nodes as schedulable. kubectl uncordon my-node # Drain Nodes in preparation for maintenance. kubectl drain my-node # Show metrics for given Nodes. 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 # Show Containers' status, properties and capabilities from the inside. # Run the command from *inside* the container. cat /proc/1/status # Check a container's capabilities. # Run the command from *inside* the container. grep 'Cap' /proc/1/status ``` ## 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=