--- title: "Essential kubectl Commands: A Practical Cheat Sheet" description: "A practical kubectl reference: manage contexts and namespaces, inspect and change resources, debug pods with logs and exec, and run safe rollouts and rollbacks." category: "Docker Kubernetes" language: en source: https://cubepath.com/docs/docker-kubernetes/kubectl-essential-commands updated: 2026-09-25 --- # Essential kubectl Commands: A Practical Cheat Sheet `kubectl` is the command-line client for the Kubernetes API. Almost everything you do on a cluster, from deploying an application to reading its logs, goes through it. This guide collects the commands you will use every day, grouped by task, with what each one is for and what to look at in the output. ## Prerequisites To use the commands in this guide you need: - Access to a Kubernetes cluster, for example one you built on a CubePath VPS with [kubeadm](/docs/docker-kubernetes/kubernetes-installation-with-kubeadm). - `kubectl` installed on your workstation or on the control plane node, within one minor version of the cluster. - A kubeconfig file in `~/.kube/config`, or referenced by the `KUBECONFIG` environment variable. Check that the client can reach the cluster: ```bash kubectl version kubectl cluster-info ``` ```output Kubernetes control plane is running at https://10.0.0.10:6443 CoreDNS is running at https://10.0.0.10:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy ``` ## Command structure and built-in help Every command follows the same pattern: ```text kubectl [name] [flags] ``` For example `kubectl get pods web-1 -n shop -o yaml`. Resource types accept short names (`po` for pods, `svc` for services, `deploy` for deployments, `ns` for namespaces). List all types with their short names and API groups: ```bash kubectl api-resources ``` `kubectl explain` documents every field of a resource straight from the cluster's API schema, which is faster and more accurate than searching the web when writing YAML: ```bash kubectl explain deployment.spec.strategy kubectl explain pod.spec.containers.readinessProbe --recursive ``` ## Contexts and namespaces A **context** combines a cluster, a user and a default namespace. If you manage more than one cluster, always check which one you are talking to before changing anything: ```bash kubectl config get-contexts kubectl config current-context ``` ```output CURRENT NAME CLUSTER AUTHINFO NAMESPACE * prod-admin prod prod-admin default staging-admin staging staging-admin default ``` Switch context: ```bash kubectl config use-context staging-admin ``` Set the default namespace for the current context, so you do not need `-n` on every command: ```bash kubectl config set-context --current --namespace=shop ``` To use several kubeconfig files at once, list them in `KUBECONFIG` separated by colons. `kubectl config view --flatten` merges them into a single file: ```bash export KUBECONFIG=~/.kube/config:~/.kube/staging.yaml kubectl config view --flatten > ~/.kube/merged.yaml ``` ## Viewing resources `get` lists resources. Add `-n ` for a specific namespace or `-A` for all of them: ```bash kubectl get pods kubectl get pods -A kubectl get deploy,svc,pods -n shop ``` `-o wide` adds the node and Pod IP; `--show-labels` shows labels: ```bash kubectl get pods -o wide --show-labels ``` Filter by label with `-l`, and by field with `--field-selector`: ```bash kubectl get pods -l app=web kubectl get pods -l 'environment in (staging,prod)' kubectl get pods -A --field-selector status.phase!=Running ``` The last command is a quick way to find everything that is not healthy in the cluster. Watch changes live with `-w` (press `Ctrl+C` to stop): ```bash kubectl get pods -w ``` `describe` shows the full state of an object plus its recent events. It is the first command to run when something does not work: ```bash kubectl describe pod web-5d4f8c7b9d-8xk2m kubectl describe node worker-1 ``` ### Extracting fields Use `-o yaml` to see an object exactly as stored, and `jsonpath` or `custom-columns` to extract specific values in scripts: ```bash kubectl get deploy web -o yaml kubectl get pods -o jsonpath='{.items[*].metadata.name}' kubectl get nodes -o custom-columns=NAME:.metadata.name,IP:.status.addresses[0].address ``` Sort output by a field, for example to see the most recent events last: ```bash kubectl get events --sort-by=.lastTimestamp ``` ## Creating and changing resources The recommended workflow is declarative: keep YAML files in version control and apply them. `apply` creates the objects if they do not exist and updates them if they do: ```bash kubectl apply -f deployment.yaml kubectl apply -f manifests/ ``` Before applying, see exactly what would change on the live cluster: ```bash kubectl diff -f deployment.yaml ``` `kubectl diff` prints a unified diff and exits with status `1` when there are differences, so it works in CI pipelines too. Generate a starting manifest instead of writing it from scratch. `--dry-run=client -o yaml` prints the object without creating it: ```bash kubectl create deployment web --image=nginx:1.28 --replicas=3 --dry-run=client -o yaml > deployment.yaml kubectl create service clusterip web --tcp=80:80 --dry-run=client -o yaml > service.yaml ``` For quick one-off changes, `edit` opens the live object in your editor and `patch` changes specific fields: ```bash kubectl edit deployment web kubectl patch deployment web -p '{"spec":{"replicas":4}}' ``` > Note: `edit`, `patch`, `scale` and `set` change the live object only. The next `kubectl apply` of your file overwrites them, so update the file too. Labels and annotations: ```bash kubectl label pod web-5d4f8c7b9d-8xk2m tier=frontend kubectl label pod web-5d4f8c7b9d-8xk2m tier- kubectl annotate deployment web owner=platform-team ``` The trailing `-` in the second command removes the label. ## Deleting resources Delete by file, by name or by label: ```bash kubectl delete -f deployment.yaml kubectl delete pod web-5d4f8c7b9d-8xk2m kubectl delete pods -l app=web ``` > Warning: `kubectl delete namespace ` deletes everything inside that namespace, including PersistentVolumeClaims and, depending on the reclaim policy, their data. Check the current context first. ## Logs, exec and port forwarding Read container logs. Add `-f` to follow, `--since` to limit the time range and `-c` to choose a container in multi-container Pods: ```bash kubectl logs web-5d4f8c7b9d-8xk2m kubectl logs -f web-5d4f8c7b9d-8xk2m --since=10m kubectl logs web-5d4f8c7b9d-8xk2m -c sidecar ``` If a container crashed and restarted, the current log is often empty. Read the previous instance's log instead: ```bash kubectl logs web-5d4f8c7b9d-8xk2m --previous ``` Read logs from all Pods of a Deployment at once: ```bash kubectl logs deployment/web --all-containers --prefix kubectl logs -l app=web --tail=50 ``` Open a shell inside a running container. Everything after `--` is the command to run: ```bash kubectl exec -it web-5d4f8c7b9d-8xk2m -- sh kubectl exec web-5d4f8c7b9d-8xk2m -- cat /etc/nginx/nginx.conf ``` Forward a local port to a Pod or Service. This is the safest way to reach an internal service, like an admin UI or database, without exposing it: ```bash kubectl port-forward service/web 8080:80 ``` While it runs, `http://localhost:8080` on your machine reaches the Service. Copy files to or from a container. The container image must include `tar` for this to work: ```bash kubectl cp web-5d4f8c7b9d-8xk2m:/etc/nginx/nginx.conf ./nginx.conf kubectl cp ./index.html web-5d4f8c7b9d-8xk2m:/usr/share/nginx/html/index.html ``` ## Debugging Many production images do not contain a shell. `kubectl debug` attaches an ephemeral container with the tools you need, sharing the process namespace of the target container: ```bash kubectl debug -it web-5d4f8c7b9d-8xk2m --image=busybox:1.36 --target=nginx ``` Run a throwaway Pod to test DNS or connectivity from inside the cluster. `--rm` deletes it when you exit: ```bash kubectl run nettest --rm -it --image=busybox:1.36 --restart=Never -- sh ``` Inside it, `nslookup web.shop.svc.cluster.local` or `wget -qO- http://web.shop` check that a Service resolves and answers. Show events for a single object, or for the whole namespace in time order: ```bash kubectl events --for pod/web-5d4f8c7b9d-8xk2m kubectl get events -n shop --sort-by=.lastTimestamp ``` Check resource usage. `kubectl top` requires the metrics-server add-on to be installed in the cluster: ```bash kubectl top nodes kubectl top pods -A --sort-by=memory ``` Check what your current user is allowed to do. This is useful when a command returns `Forbidden`: ```bash kubectl auth can-i create deployments -n shop kubectl auth can-i --list -n shop ``` ## Deployments, scaling and rollouts Scale a Deployment: ```bash kubectl scale deployment/web --replicas=5 ``` Change the image of a container and follow the rollout: ```bash kubectl set image deployment/web nginx=nginx:1.29 kubectl rollout status deployment/web ``` Inspect the history, and roll back to the previous or to a specific revision: ```bash kubectl rollout history deployment/web kubectl rollout undo deployment/web kubectl rollout undo deployment/web --to-revision=2 ``` Restart all Pods of a Deployment, for example to pick up a changed Secret mounted as environment variables. Pods are replaced gradually, following the Deployment's update strategy: ```bash kubectl rollout restart deployment/web ``` Wait for a condition in scripts or CI pipelines instead of using `sleep`: ```bash kubectl wait --for=condition=Available deployment/web --timeout=120s ``` ## ConfigMaps and Secrets Create a ConfigMap from literal values or from a file: ```bash kubectl create configmap web-config --from-literal=LOG_LEVEL=info --from-file=nginx.conf ``` Create a Secret. Replace `your_strong_password` with a real value, and prefer `--from-file` so the password does not end up in your shell history: ```bash kubectl create secret generic db-credentials --from-literal=username=app --from-literal=password=your_strong_password ``` Decode a Secret value to check it: ```bash kubectl get secret db-credentials -o jsonpath='{.data.password}' | base64 -d ``` > Important: Secrets are only base64 encoded, not encrypted. Anyone who can read Secrets in a namespace can read their values, so restrict that permission with RBAC. ## Productivity: completion and aliases Enable Bash completion for `kubectl` in your shell. On Ubuntu the `bash-completion` package must be installed: ```bash echo 'source <(kubectl completion bash)' >> ~/.bashrc ``` Add a short alias and make completion work for it too: ```bash echo 'alias k=kubectl' >> ~/.bashrc echo 'complete -o default -F __start_kubectl k' >> ~/.bashrc source ~/.bashrc ``` Now `k get po -n kube-` completes namespace names. For Zsh, use `kubectl completion zsh` instead. ## Quick reference | Task | Command | |------|---------| | Current context | `kubectl config current-context` | | Change default namespace | `kubectl config set-context --current --namespace=NAME` | | Everything not Running | `kubectl get pods -A --field-selector status.phase!=Running` | | Why a Pod fails | `kubectl describe pod NAME` | | Logs of a crashed container | `kubectl logs NAME --previous` | | Shell in a container | `kubectl exec -it NAME -- sh` | | Preview changes | `kubectl diff -f FILE` | | Apply changes | `kubectl apply -f FILE` | | Roll back | `kubectl rollout undo deployment/NAME` | | Reach an internal service | `kubectl port-forward svc/NAME 8080:80` | ## Conclusion With these commands you can switch safely between clusters, inspect and change resources, find out why a Pod is failing and roll back a bad release. The two habits that prevent most accidents are checking the current context before any change and running `kubectl diff` before `kubectl apply`. To practise them on a real workload, follow [Kubernetes Pods, Services and Deployments](/docs/docker-kubernetes/kubernetes-pods-services-deployments), then publish the application with an [Ingress](/docs/docker-kubernetes/ingress-configuration-in-kubernetes).