kubectl in Practice
kubectl is the command-line tool you use to interact with a Kubernetes cluster. Everything you do - creating a Deployment, inspecting a crashed Pod, streaming logs, deleting a Service - goes through this single binary. It translates your commands into HTTP calls to the API server, and formats the responses back into readable output. Knowing how to use it well is probably the most transferable skill in the entire Kubernetes ecosystem.
Every kubectl command is ultimately an HTTP request to the API server. The tool handles authentication, formatting, and the mechanics of the call - but the operation always goes through the same central entry point.
Getting Information
kubectl get is the command you’ll run more than any other. It lists resources of a given type, with a concise tabular output that gives you the current state at a glance. You can ask for a single resource type, several at once, or everything in a namespace.
kubectl get podskubectl get deploymentskubectl get serviceskubectl get nodeskubectl get allThe output columns vary by resource type. For Pods, you see READY, STATUS, RESTARTS, and AGE. READY shows how many containers inside the Pod are passing their readiness check, in the form running/total. A Pod showing 1/1 Running with 0 restarts is healthy. A Pod showing 0/1 CrashLoopBackOff with a rising restart count is failing repeatedly and Kubernetes is backing off before retrying. These two columns tell you the health of a Pod at a glance before you need to dig deeper.
When you need more than the summary, kubectl describe gives you the full picture of a single resource. It includes all the fields, the current status, and most importantly the Events section at the bottom, which is a chronological log of what Kubernetes has done to this resource. When a Pod fails to start, the events are where you find out whether the image couldn’t be pulled, the container crashed immediately on startup, or the scheduler couldn’t find a suitable node.
kubectl describe pod <pod-name>kubectl describe deployment <deployment-name>kubectl describe node <node-name>Applying and Deleting Resources
kubectl apply is how you create or update resources from a manifest file. If the resource doesn’t exist yet, Kubernetes creates it. If it already exists, Kubernetes computes the difference between what’s in the file and what’s currently stored, and applies only the changes. This idempotency is what makes apply safe to run repeatedly - you can run it in a CI pipeline without worrying about whether the resource already exists.
kubectl apply -f deployment.yamlkubectl apply -f ./manifests/ # applies every YAML file in a directorykubectl delete removes resources. You can target a resource by its name, or pass a file to delete exactly what that file describes.
kubectl delete pod <pod-name>kubectl delete deployment my-appkubectl delete -f deployment.yamlBe careful with delete: it’s immediate and there’s no confirmation prompt. Deleting a Deployment removes the Deployment, its ReplicaSets, and all the Pods it owns in a single operation.
Controlling the Output Format
The default tabular output is useful for a quick overview. The -o flag changes the format to something more detailed or machine-readable.
-o wide adds extra columns that don’t fit in the default view, like which node a Pod is running on, or what its IP address is. -o yaml outputs the full resource object as YAML - this is invaluable when you want to see what Kubernetes has set on an object, including all the fields that were defaulted or populated by controllers. -o json gives you the same thing in JSON, useful for piping into tools like jq. -o name gives you just the resource names, which is useful in scripts.
kubectl get pods -o widekubectl get pod my-pod -o yamlkubectl get pods -o nameThe --watch flag (shortened to -w) keeps the command running and prints new lines whenever something changes. It’s useful when you’re waiting for a Pod to start or a rolling update to finish.
kubectl get pods --watchFiltering with Namespaces and Labels
Without a -n flag, kubectl operates in the default namespace. Almost every command accepts -n <namespace> to target a different one, and --all-namespaces (or -A) to query across all of them at once.
kubectl get pods -n kube-systemkubectl get pods -ALabels are key-value pairs attached to resources, and the -l flag lets you filter by them. If your Pods all have a label app=backend, you can limit every command to just those Pods without knowing their exact names.
kubectl get pods -l app=backendkubectl describe pods -l app=backendkubectl delete pods -l app=backendGenerating Manifests Without Applying Them
The combination --dry-run=client -o yaml is one of the most useful patterns in kubectl. It generates a valid YAML manifest without creating anything in the cluster. When you’re starting a new manifest from scratch, this is far faster than writing it by hand and looking up every field name.
kubectl run my-pod --image=nginx:1.28 --dry-run=client -o yamlkubectl create deployment web --image=nginx:1.28 --replicas=3 --dry-run=client -o yamlHands-On Practice
1. Get all resources in the default namespace:
kubectl get allNotice that there’s already a Service named kubernetes. This is the Service that Pods use to reach the API server from inside the cluster.
2. Describe that Service:
kubectl describe service kubernetesRead through the output carefully. Notice the Endpoints field - it points to the API server’s address. The Events section at the bottom is empty because this Service is managed by the cluster itself and never changes.
3. Create a Pod without writing a manifest:
kubectl run explore-me --image=nginx:1.284. Inspect it using each output format:
kubectl get pod explore-mekubectl get pod explore-me -o widekubectl get pod explore-me -o yamlThe YAML output contains far more than what you wrote. Kubernetes has filled in dozens of default values and added status fields. This is the live state of the object as stored in etcd.
5. Read the startup events:
kubectl describe pod explore-meScroll to the bottom and find the Events section. You should see the sequence Scheduled, Pulling, Pulled, Created, Started. If the image pull failed, the reason would appear here.
6. Check the logs:
kubectl logs explore-me7. Clean up:
kubectl delete pod explore-me