:::note[TL;DR]
kubectl get,describe,logs, andexeccover 90% of day-to-day Kubernetes operations- Use
kubectl apply -f(notcreate) for everything in CI/CD — it’s idempotent and handles both create and update kubectl rollout undois your fast rollback;rollout statusblocks until the deployment completes- For debugging:
describe podshows events,logs --previousshows the last crash,top podsshows resource pressure - Always set resource
requestsandlimitsin production — without them pods can starve each other :::
Cluster info
kubectl version # client and server version
kubectl cluster-info # cluster endpoint
kubectl get nodes # list nodes
kubectl get nodes -o wide # with IP and OS info
kubectl describe node <name> # node details
kubectl top nodes # CPU/memory usage
Namespaces
kubectl get namespaces
kubectl get ns # short form
kubectl create namespace staging
kubectl delete namespace staging
# Work in a specific namespace
kubectl get pods -n staging
kubectl config set-context --current --namespace=staging
Pods
kubectl get pods # list pods in current namespace
kubectl get pods -A # all namespaces
kubectl get pods -o wide # with node and IP
kubectl get pods --watch # watch for changes
kubectl describe pod <name> # detailed info + events
kubectl delete pod <name>
kubectl delete pod <name> --grace-period=0 # force delete
:::warning
Force-deleting pods (--grace-period=0) skips the graceful shutdown sequence. The pod won’t finish in-flight requests or run preStop hooks. Only use this for stuck pods that won’t terminate normally — not as a routine restart method.
:::
# Create from image
kubectl run nginx --image=nginx
# Logs
kubectl logs <pod>
kubectl logs <pod> -c <container> # multi-container pod
kubectl logs <pod> --previous # crashed container logs
kubectl logs <pod> -f # follow / tail
# Exec into a pod
kubectl exec -it <pod> -- /bin/bash
kubectl exec -it <pod> -c <container> -- /bin/sh
# Copy files
kubectl cp <pod>:/path/to/file ./local-file
kubectl cp ./local-file <pod>:/path/to/file
Deployments
kubectl get deployments
kubectl get deploy # short form
kubectl describe deploy <name>
# Create
kubectl create deployment nginx --image=nginx --replicas=3
# Apply from file
kubectl apply -f deployment.yaml
# Scale
kubectl scale deploy <name> --replicas=5
# Update image
kubectl set image deploy/<name> <container>=nginx:1.25
# Rollout
kubectl rollout status deploy/<name>
kubectl rollout history deploy/<name>
kubectl rollout undo deploy/<name>
kubectl rollout undo deploy/<name> --to-revision=2
# Restart all pods
kubectl rollout restart deploy/<name>
# Delete
kubectl delete deploy <name>
Services
kubectl get services
kubectl get svc # short form
kubectl describe svc <name>
# Expose a deployment
kubectl expose deploy nginx --port=80 --type=ClusterIP
kubectl expose deploy nginx --port=80 --type=NodePort
kubectl expose deploy nginx --port=80 --type=LoadBalancer
# Port forwarding (local testing)
kubectl port-forward svc/<name> 8080:80
kubectl port-forward pod/<name> 8080:80
ConfigMaps & Secrets
# ConfigMap
kubectl create configmap app-config --from-literal=ENV=prod
kubectl create configmap app-config --from-file=config.env
kubectl get configmaps
kubectl describe configmap app-config
# Secret
kubectl create secret generic db-secret \
--from-literal=password=mysecret
kubectl create secret generic db-secret \
--from-file=./secret.key
kubectl get secrets
kubectl describe secret db-secret
# Decode a secret value
kubectl get secret db-secret -o jsonpath='{.data.password}' | base64 -d
Resource management
# Get everything
kubectl get all
kubectl get all -n staging
# Apply / delete from files
kubectl apply -f manifest.yaml
kubectl apply -f ./k8s/ # apply entire directory
kubectl delete -f manifest.yaml
:::note
kubectl apply is idempotent — it creates the resource if it doesn’t exist and updates it if it does. kubectl create fails if the resource already exists. Use apply for all CI/CD and production workflows; reserve create for one-off interactive operations.
:::
# Dry run (validate without creating)
kubectl apply -f manifest.yaml --dry-run=client
# View YAML for an existing resource
kubectl get deploy nginx -o yaml
kubectl get pod nginx-abc -o json
# Edit live resource
kubectl edit deploy nginx
# Patch
kubectl patch deploy nginx -p '{"spec":{"replicas":2}}'
# Labels & selectors
kubectl get pods --selector=app=nginx
kubectl label pod <name> env=prod
kubectl annotate pod <name> description="web server"
Ingress
kubectl get ingress
kubectl get ing
kubectl describe ingress <name>
kubectl apply -f ingress.yaml
Persistent volumes
kubectl get pv # persistent volumes
kubectl get pvc # persistent volume claims
kubectl describe pvc <name>
Contexts & kubeconfig
kubectl config get-contexts # list contexts
kubectl config current-context # show current
kubectl config use-context prod # switch context
kubectl config view # show full kubeconfig
# Set default namespace for context
kubectl config set-context --current --namespace=default
Troubleshooting
:::tip
When a pod is stuck, always run kubectl describe pod <name> first — the Events section at the bottom shows exactly what Kubernetes tried to do and why it failed. Node pressure, image pull errors, and scheduling failures all appear there before they show up in logs.
:::
# Pod stuck in Pending
kubectl describe pod <name> # look at Events section
# Pod CrashLoopBackOff
kubectl logs <pod> --previous # check last crash logs
# Check resource usage
kubectl top pods
kubectl top pods -A
# Events
kubectl get events
kubectl get events -n staging
kubectl get events --sort-by='.lastTimestamp'
# Node not ready
kubectl describe node <name>
kubectl get nodes --show-labels
# Check endpoint behind a service
kubectl get endpoints <svc-name>
Useful manifest snippets
Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: my-app:latest
ports:
- containerPort: 3000
env:
- name: NODE_ENV
value: production
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
ClusterIP Service
apiVersion: v1
kind: Service
metadata:
name: my-app
spec:
selector:
app: my-app
ports:
- port: 80
targetPort: 3000
type: ClusterIP
ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
ENV: production
LOG_LEVEL: info
Want to run a database in Kubernetes? Check out Run PostgreSQL with Docker first — the concepts carry over.
Summary
kubectl get,describe,logs, andexecare the four commands you’ll use 90% of the time for day-to-day operations- Deployments manage replica sets and rolling updates; Services expose them; ConfigMaps and Secrets inject config
kubectl apply -fis the standard way to manage resources — use--dry-run=clientto validate before applying- Health checks (
livenessProbe,readinessProbe) and resource limits are essential for production stability - Context switching (
kubectl config use-context) lets you manage multiple clusters from one machine
Frequently Asked Questions
What’s the difference between kubectl apply and kubectl create?
kubectl create creates a resource and fails if it already exists. kubectl apply creates or updates — it’s idempotent. Use apply for everything in CI/CD and production workflows. Use create only for one-off interactive operations.
How do I debug a pod that’s stuck in CrashLoopBackOff?
Run kubectl logs <pod> --previous to see the logs from the last crash. The --previous flag is key — without it, you get logs from the current (probably empty) container. Also check kubectl describe pod <name> for the Events section, which often shows the root cause.
What’s the difference between a Deployment and a StatefulSet?
Deployments are for stateless workloads — pods are interchangeable, can be replaced in any order. StatefulSets are for stateful workloads (databases, queues) — pods have stable network identities and ordered startup/shutdown. Use StatefulSets for anything that writes to persistent storage and needs stable hostnames.
What to Read Next
- Docker Compose in Production — if Kubernetes feels heavy, Compose is a simpler production option for smaller workloads
- Docker Cheat Sheet — Kubernetes runs Docker containers; know these commands too