Toolmingo
Guides9 min read

Kubernetes Cheat Sheet: kubectl Commands & YAML Reference

A complete Kubernetes cheat sheet — kubectl commands, Pod/Deployment/Service YAML, ConfigMaps, namespaces, scaling, debugging, and Helm. Copy-ready for daily k8s work.

The Kubernetes commands and YAML patterns you reach for every day — Pods, Deployments, Services, ConfigMaps, namespaces, scaling, and debugging — all in one place.

Quick reference

The 25 kubectl commands that cover 90% of daily k8s work.

Command What it does
kubectl get pods List Pods in current namespace
kubectl get pods -A List Pods in ALL namespaces
kubectl get pods -o wide Show Pod IPs and node names
kubectl describe pod <name> Full Pod details + events
kubectl logs <pod> Print Pod logs
kubectl logs -f <pod> Follow live logs
kubectl logs <pod> -c <container> Logs from specific container
kubectl exec -it <pod> -- bash Open shell inside Pod
kubectl apply -f manifest.yaml Create or update resources
kubectl delete -f manifest.yaml Delete resources from file
kubectl delete pod <name> Delete a Pod
kubectl get deployments List Deployments
kubectl scale deploy <name> --replicas=3 Scale a Deployment
kubectl rollout status deploy/<name> Watch rollout progress
kubectl rollout undo deploy/<name> Roll back to previous version
kubectl get services List Services
kubectl port-forward pod/<name> 8080:80 Forward local port to Pod
kubectl get configmaps List ConfigMaps
kubectl get secrets List Secrets
kubectl get namespaces List all namespaces
kubectl config get-contexts List cluster contexts
kubectl config use-context <ctx> Switch cluster/context
kubectl top pods CPU + memory usage (needs metrics-server)
kubectl get events --sort-by=.lastTimestamp Recent cluster events
kubectl explain pod.spec In-terminal YAML field docs

Core resource types

Resource Short What it is
Pod po Smallest deployable unit — one or more containers
Deployment deploy Manages ReplicaSets; rolling updates + rollback
ReplicaSet rs Keeps N Pod replicas running
StatefulSet sts Like Deployment but for stateful apps (ordered, stable names)
DaemonSet ds One Pod per node (logging agents, node exporters)
Job Runs to completion; restarts on failure
CronJob cj Runs Job on a schedule
Service svc Stable network endpoint for Pods
Ingress HTTP routing rules into the cluster
ConfigMap cm Key-value config injected into Pods
Secret Like ConfigMap but base64-encoded (use a vault in prod)
PersistentVolumeClaim pvc Request for storage
Namespace ns Virtual cluster / isolation boundary
ServiceAccount sa Pod identity for RBAC
HorizontalPodAutoscaler hpa Auto-scale based on CPU/memory

Pod YAML

Minimal Pod — useful for debugging:

apiVersion: v1
kind: Pod
metadata:
  name: debug-pod
  namespace: default
  labels:
    app: debug
spec:
  containers:
    - name: app
      image: busybox:1.36
      command: ["sleep", "3600"]
      resources:
        requests:
          cpu: "100m"
          memory: "128Mi"
        limits:
          cpu: "500m"
          memory: "256Mi"
  restartPolicy: Never

Run a one-off debug pod then delete it:

kubectl run debug --image=busybox:1.36 --rm -it --restart=Never -- sh

Deployment YAML

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  namespace: default
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
        - name: app
          image: my-registry/my-app:1.2.3
          ports:
            - containerPort: 8080
          env:
            - name: PORT
              value: "8080"
            - name: DB_HOST
              valueFrom:
                secretKeyRef:
                  name: db-secret
                  key: host
          readinessProbe:
            httpGet:
              path: /healthz
              port: 8080
            initialDelaySeconds: 5
            periodSeconds: 10
          livenessProbe:
            httpGet:
              path: /healthz
              port: 8080
            initialDelaySeconds: 15
            periodSeconds: 20
          resources:
            requests:
              cpu: "100m"
              memory: "128Mi"
            limits:
              cpu: "500m"
              memory: "512Mi"
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0

Service YAML

# ClusterIP — internal only (default)
apiVersion: v1
kind: Service
metadata:
  name: my-app-svc
spec:
  selector:
    app: my-app
  ports:
    - protocol: TCP
      port: 80        # port on the Service
      targetPort: 8080 # port on the Pod
  type: ClusterIP
Service type When to use
ClusterIP Internal communication only (default)
NodePort Expose on each node's IP:port (dev/testing)
LoadBalancer Cloud load balancer (AWS ELB, GCP LB)
ExternalName DNS alias to an external hostname

Ingress YAML

Requires an ingress controller (nginx, traefik, etc.):

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-app-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
    - host: myapp.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: my-app-svc
                port:
                  number: 80
  tls:
    - hosts:
        - myapp.example.com
      secretName: myapp-tls

ConfigMap and Secret

# ConfigMap — non-sensitive config
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  LOG_LEVEL: "info"
  MAX_CONNECTIONS: "100"
  config.json: |
    { "debug": false, "timeout": 30 }
# Secret — base64-encoded values
apiVersion: v1
kind: Secret
metadata:
  name: db-secret
type: Opaque
data:
  # echo -n 'mypassword' | base64
  password: bXlwYXNzd29yZA==
  host: ZGIuZXhhbXBsZS5jb20=

Inject into a Pod as env vars:

envFrom:
  - configMapRef:
      name: app-config
  - secretRef:
      name: db-secret

Mount as files:

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

Namespaces

# Create namespace
kubectl create namespace staging

# Run commands in a namespace
kubectl get pods -n staging
kubectl apply -f deploy.yaml -n staging

# Set default namespace for current context
kubectl config set-context --current --namespace=staging

# Delete everything in a namespace (careful!)
kubectl delete all --all -n staging

Scaling and rollouts

# Scale manually
kubectl scale deployment my-app --replicas=5

# Auto-scale on CPU (HPA)
kubectl autoscale deployment my-app --cpu-percent=70 --min=2 --max=10

# Check HPA status
kubectl get hpa

# Update image (triggers rolling update)
kubectl set image deployment/my-app app=my-registry/my-app:1.3.0

# Watch rollout
kubectl rollout status deployment/my-app

# Pause and resume rollout
kubectl rollout pause deployment/my-app
kubectl rollout resume deployment/my-app

# Roll back
kubectl rollout undo deployment/my-app

# Roll back to specific revision
kubectl rollout history deployment/my-app
kubectl rollout undo deployment/my-app --to-revision=2

Debugging

# Describe shows events — check here first
kubectl describe pod my-pod

# Logs (last 100 lines)
kubectl logs my-pod --tail=100

# Previous container logs (after crash)
kubectl logs my-pod --previous

# All containers in pod
kubectl logs my-pod --all-containers

# Shell into running pod
kubectl exec -it my-pod -- bash
kubectl exec -it my-pod -- sh          # if no bash

# Specific container in multi-container pod
kubectl exec -it my-pod -c sidecar -- bash

# Copy files to/from pod
kubectl cp my-pod:/etc/config/file.txt ./file.txt
kubectl cp ./local-file.txt my-pod:/tmp/

# Port forward to test locally
kubectl port-forward pod/my-pod 8080:80
kubectl port-forward service/my-app-svc 8080:80

# Get raw YAML of any resource
kubectl get pod my-pod -o yaml

# Watch pods update in real time
kubectl get pods -w

# Check resource usage
kubectl top pods
kubectl top nodes

# Cluster info
kubectl cluster-info
kubectl get nodes -o wide

Common Pod status meanings:

Status Meaning
Pending Waiting for node scheduling or image pull
ContainerCreating Pulling image or mounting volumes
Running At least one container is running
CrashLoopBackOff Container crashing repeatedly — check logs
OOMKilled Container exceeded memory limit
ImagePullBackOff Can't pull image (wrong tag, no auth)
Terminating Being deleted — stuck? check finalizers
Evicted Node ran out of resources

PersistentVolumeClaim

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: data-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: standard   # cloud-specific: gp2, premium-rwo, etc.

Mount in Pod:

volumes:
  - name: data-vol
    persistentVolumeClaim:
      claimName: data-pvc
volumeMounts:
  - name: data-vol
    mountPath: /data

RBAC

# ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
  name: my-app-sa
  namespace: default
---
# Role (namespace-scoped)
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: pod-reader
  namespace: default
rules:
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["get", "list", "watch"]
---
# Bind role to service account
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: pod-reader-binding
  namespace: default
subjects:
  - kind: ServiceAccount
    name: my-app-sa
    namespace: default
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

Use ClusterRole + ClusterRoleBinding for cluster-wide permissions.


Helm basics

# Add a chart repo
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update

# Search for charts
helm search repo nginx

# Install a chart
helm install my-nginx bitnami/nginx

# Install with custom values
helm install my-app ./my-chart -f values.yaml

# Override values inline
helm install my-app ./my-chart --set image.tag=1.3.0,replicas=3

# List releases
helm list

# Upgrade a release
helm upgrade my-app ./my-chart -f values.yaml

# Roll back Helm release
helm rollback my-app 1

# Uninstall
helm uninstall my-app

# Render YAML without installing (dry run)
helm template my-app ./my-chart -f values.yaml

Common mistakes

Mistake Fix
Pod stuck in Pending Check kubectl describe pod — usually resource limits or no node with space
ImagePullBackOff Wrong image name/tag or missing imagePullSecret
Service not reaching Pods Check selector labels match Pod labels exactly
CrashLoopBackOff kubectl logs --previous to see crash reason
Deployment not updating Check rollout status; verify image tag actually changed
Env var not appearing envFrom vs env, check secret/configmap name and key spelling
HPA stuck at 0/0 metrics-server not installed or no resources.requests on container
Evicted pods Pods evicted under memory/disk pressure — add resource requests

Useful one-liners

# Get all resources in a namespace
kubectl get all -n my-namespace

# Delete all completed/failed pods
kubectl delete pods --field-selector=status.phase=Succeeded
kubectl delete pods --field-selector=status.phase=Failed

# Force delete stuck pod
kubectl delete pod my-pod --grace-period=0 --force

# Watch events in real time
kubectl get events -w --sort-by=.lastTimestamp

# Get all pod IPs
kubectl get pods -o custom-columns="NAME:.metadata.name,IP:.status.podIP"

# Find which pods are consuming most CPU
kubectl top pods --sort-by=cpu -A

# Get all images running in the cluster
kubectl get pods -A -o jsonpath='{range .items[*]}{.spec.containers[*].image}{"\n"}{end}' | sort | uniq

# Check which nodes are under pressure
kubectl describe nodes | grep -A5 "Conditions:"

# Dry run apply (validate without applying)
kubectl apply -f manifest.yaml --dry-run=client

# Generate YAML without applying
kubectl create deployment test --image=nginx --dry-run=client -o yaml

6 FAQ

Q: What is the difference between a Deployment and a StatefulSet?
Deployments treat Pods as interchangeable — they get random names and no stable storage. StatefulSets give each Pod a stable hostname (app-0, app-1) and a dedicated PVC that survives restarts. Use StatefulSets for databases, message queues, and anything that needs stable identity.

Q: When should I use a Job instead of a Deployment?
Use a Job for one-off or batch tasks that need to run to completion — database migrations, data import scripts, report generation. Deployments are for long-running services. For recurring batch tasks, use a CronJob.

Q: How do I pass secrets safely into Pods?
Kubernetes Secrets are only base64-encoded (not encrypted at rest by default). For production, enable etcd encryption at rest, or better: use an external secret manager (HashiCorp Vault, AWS Secrets Manager, GCP Secret Manager) via an operator like External Secrets Operator.

Q: What's the difference between requests and limits in resources?
requests is the minimum reserved — the scheduler uses this to decide which node to place the Pod on. limits is the hard cap — exceed it and CPU is throttled (not killed), but exceed memory limits and the container is OOMKilled. Always set both; omitting requests leads to poor scheduling decisions.

Q: How do I update a Deployment without downtime?
Use RollingUpdate strategy (the default). Set maxUnavailable: 0 and maxSurge: 1 so a new Pod starts before an old one stops. Add a readinessProbe so traffic only routes to a Pod after it's actually ready — this is the key to zero-downtime deploys.

Q: What is a namespace and when should I use one?
A namespace is a virtual cluster inside a Kubernetes cluster. Use namespaces to isolate environments (dev, staging, production), separate teams, or apply different resource quotas and RBAC policies. The default namespace is fine for small projects; anything larger benefits from explicit namespaces.

Related tools

Keep reading

All Toolmingotools are free & run in your browser

No sign-up, no upload, no watermark. Your files never leave your device.

Browse all tools