Kubernetes & kubectl Cheatsheet

kubectl is the command-line tool for interacting with Kubernetes clusters. Most day-to-day Kubernetes work happens through these commands.

Core kubectl Commands#

CommandWhat it does
kubectl get <resource>List resources (pods, deployments, services, etc.)
kubectl describe <resource> <name>Show detailed info including events
kubectl apply -f <file.yaml>Create or update resources from a YAML file
kubectl delete <resource> <name>Delete a resource
kubectl create <resource>Create a resource imperatively
kubectl edit <resource> <name>Open resource config in your editor
kubectl logs <pod>Print logs from a pod
kubectl exec -it <pod> -- <cmd>Run a command inside a running container
kubectl port-forward <pod> 8080:80Forward a local port to a pod port
kubectl cp <pod>:/path /local/pathCopy files to/from a pod
kubectl scale deployment <name> --replicas=3Scale a deployment
kubectl rollout status deployment/<name>Watch a rolling deployment
kubectl rollout undo deployment/<name>Roll back to the previous deployment version
kubectl top podsShow CPU and memory usage for pods (requires metrics-server)
kubectl top nodesShow CPU and memory usage per node
kubectl explain <resource>Show the API schema and field docs for a resource

Add -n <namespace> to any command to target a specific namespace. Add --all-namespaces (or -A) to query across all namespaces.

Kubernetes Resource Types#

ResourceShort nameWhat it is
PodpoThe smallest deployable unit; one or more containers
DeploymentdeployManages a set of identical pods with rolling updates
ServicesvcStable network endpoint that routes traffic to pods
ConfigMapcmStores non-sensitive configuration as key-value pairs
SecretsecretStores sensitive data (base64-encoded, not encrypted by default)
NamespacensVirtual cluster for resource isolation
PersistentVolumepvA piece of storage in the cluster
PersistentVolumeClaimpvcA request for storage by a pod
IngressingRoutes external HTTP/HTTPS traffic to services
HorizontalPodAutoscalerhpaAutomatically scales pod replicas based on CPU/memory

Common YAML Patterns#

Minimal Pod spec#

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
  labels:
    app: my-app
spec:
  containers:
    - name: app
      image: nginx:1.25
      ports:
        - containerPort: 80

Deployment spec#

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
        - name: app
          image: my-app:1.0.0
          ports:
            - containerPort: 8080
          resources:
            requests:
              cpu: "100m"
              memory: "128Mi"
            limits:
              cpu: "500m"
              memory: "256Mi"

Always set resources.requests and resources.limits. Without them the scheduler cannot make good placement decisions and a pod can consume all node memory.

ClusterIP Service#

apiVersion: v1
kind: Service
metadata:
  name: my-app-svc
spec:
  selector:
    app: my-app
  ports:
    - port: 80
      targetPort: 8080
  type: ClusterIP

ConfigMap and using it in a Pod#

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  LOG_LEVEL: "info"
  MAX_CONNECTIONS: "100"

Reference in a pod as environment variables:

envFrom:
  - configMapRef:
      name: app-config

Or mount it as a file:

volumes:
  - name: config-vol
    configMap:
      name: app-config
volumeMounts:
  - name: config-vol
    mountPath: /etc/config

Namespace Commands#

# List all namespaces
kubectl get namespaces

# Create a namespace
kubectl create namespace staging

# Run all commands in a namespace without -n flag
kubectl config set-context --current --namespace=staging

# List pods in a specific namespace
kubectl get pods -n staging

Context and Config#

# List all contexts (clusters you can connect to)
kubectl config get-contexts

# Switch to a different context
kubectl config use-context my-cluster-prod

# Create or update a context
kubectl config set-context my-context --cluster=my-cluster --user=my-user --namespace=default

# Show your current config
kubectl config view

Debugging Commands#

These are the commands you reach for when something is broken.

# See all events in a namespace (sorted by time)
kubectl get events --sort-by='.lastTimestamp' -n my-namespace

# Describe a pod — look at the Events section at the bottom
kubectl describe pod my-pod -n my-namespace

# Get logs from a crashed container's previous run
kubectl logs my-pod --previous

# Get logs from a specific container in a multi-container pod
kubectl logs my-pod -c sidecar-container

# Open a shell inside a running pod
kubectl exec -it my-pod -- /bin/sh

# Run a temporary debug pod
kubectl run debug --image=busybox --rm -it --restart=Never -- /bin/sh

Common error patterns:

Labels and Selectors#

Labels are key-value pairs attached to resources. Selectors filter resources by label.

# Show labels on pods
kubectl get pods --show-labels

# Filter pods by label
kubectl get pods -l app=my-app

# Filter by multiple labels
kubectl get pods -l app=my-app,env=prod

# Add a label to a running pod (not recommended for managed resources)
kubectl label pod my-pod version=v2

Deployments use selector.matchLabels to find which pods they manage. The pod template labels must match.

Key Concepts Summary#

ConceptOne-line explanation
PodRuns your container(s); ephemeral, replaced not restarted
DeploymentKeeps N replicas of a pod running and handles rollouts
ServiceDNS name + load balancer for a group of pods
ConfigMapConfig data that pods can read as env vars or files
SecretLike ConfigMap but for passwords, tokens, and keys
NamespaceScope for resources; use for team or environment isolation
PVCPod’s request for a persistent disk
IngressHTTP router that sits in front of Services
HPAAuto-scales your Deployment based on load
NodeA VM or physical machine that runs pods

Common Beginner Mistakes#

Wrong namespace. Many teams forget -n <namespace> and wonder why their pod isn’t visible. Set your default namespace with kubectl config set-context.

Image pull errors. If the image is private, create a docker-registry Secret and add imagePullSecrets to the pod spec.

Missing resource limits. Pods without limits can starve other pods on the same node and trigger OOM kills.

Editing live resources with kubectl edit. Changes are not tracked in Git. Always manage resources via YAML files and kubectl apply.

Using latest as the image tag. Kubernetes caches images. Deploying :latest does not guarantee the newest image. Use specific version tags.