Kubernetes cheat sheet

A scannable Kubernetes reference: 34 short snippets across 14 topics, each linking back to the lesson it came from.

At a glance

TopicWhat it covers
Pods, Deployments and ServicesThe Pod is the smallest schedulable unit. Its containers share one network namespace, so they reach each other onlesson
ConfigMaps, Secrets and probesConfiguration belongs in a ConfigMap rather than in the image, so the same image can run in every environmentlesson
Rollouts and debuggingUpdating a Deployment's pod template starts a rolling update. Kubernetes brings new pods up and old ones down accordinglesson
Cluster architecture and a local setupA Kubernetes cluster is a set of machines split into a control plane that holds the desired state and makes decisionslesson
kubectl fundamentals and writing manifestsAn imperative command tells the cluster what to do once. A declarative file describes what should exist, for ever. Onlylesson
Labels, selectors, namespaces and annotationsA label is a key-value pair attached to an object. A selector is a query over labels. Almost every relationship inlesson
Storage: volumes, PersistentVolumes and StorageClassesContainers are disposable and their filesystem disappears with them. A volume is declared on the pod and mounted intolesson
StatefulSets, DaemonSets and JobsA Deployment generates pods with random suffixes, starts them in any order and treats them as interchangeable. Alesson
Ingress, Gateway API and exposing applicationsIngress is a routing rule expressed as a Kubernetes object. On its own it does nothing. You also need an Ingresslesson
Resource requests, limits and autoscalingA request is what the scheduler reserves on a node and what the autoscaler measures against. A limit is the ceiling thelesson
Networking, DNS and NetworkPolicyKubernetes assumes a flat network with three simple rules: every pod gets its own IP, every pod can reach every otherlesson
RBAC, service accounts and pod securityAuthorization is a decision the API server makes on every request: does this identity have this verb on this resourcelesson
Helm and packaging applicationsA Helm chart is a parameterised bundle of manifests. A release is one installed instance of that chart in a namespacelesson
Scheduling: affinity, taints and tolerationsThe scheduler runs two phases: filtering, which removes nodes that cannot run the pod, and scoring, which ranks thelesson

Quick snippets

Pods, Deployments and Services

Pods

kubectl apply -f pod.yaml
kubectl get pods -o wide
kubectl describe pod web
kubectl delete pod web

Services

apiVersion: v1
kind: Service
metadata:
  name: web
spec:
  type: ClusterIP          # ClusterIP | NodePort | LoadBalancer
  selector:
    app: web
  ports:
    - port: 80             # the port clients of the Service use
      targetPort: 80       # the container port behind it

Services

kubectl get svc
kubectl get endpoints web        # an empty list means the selector matches nothing
kubectl port-forward svc/web 8080:80
# other pods address it by DNS name:
#   http://web.<namespace>.svc.cluster.local

Full lesson: Pods, Deployments and Services →

ConfigMaps, Secrets and probes

ConfigMaps

apiVersion: v1
kind: ConfigMap
metadata:
  name: web-config
data:
  LOG_LEVEL: info
  nginx.conf: |
    server {
      listen 80;
      location / { return 200 "ok"; }
    }

Secrets

kubectl create secret generic db-creds \
  --from-literal=username=app \
  --from-literal=password='s3cr3t'

kubectl get secret db-creds -o jsonpath='{.data.password}' | base64 -d

Full lesson: ConfigMaps, Secrets and probes →

Rollouts and debugging

Rollouts

kubectl set image deployment/web web=nginx:1.28-alpine
kubectl rollout status deployment/web        # blocks until finished
kubectl rollout history deployment/web
kubectl rollout undo deployment/web          # back to the previous revision
kubectl rollout undo deployment/web --to-revision=3
kubectl rollout restart deployment/web       # restart pods without changing the spec

Debugging a failing pod

kubectl get pods -w
kubectl describe pod web-7d9c8b6f4-abcde     # events are at the bottom
kubectl logs web-7d9c8b6f4-abcde
kubectl logs web-7d9c8b6f4-abcde --previous  # the container that crashed
kubectl exec -it web-7d9c8b6f4-abcde -- sh
kubectl get events --sort-by=.lastTimestamp

Full lesson: Rollouts and debugging →

Cluster architecture and a local setup

Everything talks to the API server

kubectl cluster-info                 # which cluster am I even talking to
kubectl version                      # client and server versions
kubectl config current-context
kubectl get nodes -o wide            # kubelet version, IPs, runtime
kubectl get --raw='/readyz?verbose'  # control plane component health
kubectl api-resources                # every kind the server knows, and its scope

A real cluster on your laptop

# kubeconfig lives at $KUBECONFIG or ~/.kube/config
export KUBECONFIG=~/.kube/config:~/.kube/kind-dev
kubectl config set-context --current --namespace=dev
kubectl config view --minify          # just the context you are using

Full lesson: Cluster architecture and a local setup →

kubectl fundamentals and writing manifests

Declarative versus imperative

# generate a skeleton, then own it as a file
kubectl create deployment web --image=nginx:1.27-alpine --replicas=3 \
  --dry-run=client -o yaml > deploy.yaml

kubectl apply -f deploy.yaml
kubectl get deploy,pods -o wide
kubectl describe deploy web

The anatomy of a manifest

kubectl explain deployment.spec.strategy.rollingUpdate
kubectl explain pod.spec.containers.resources --recursive | head -40

The apply, diff and dry-run loop

kubectl apply -f deploy.yaml --dry-run=client       # syntax only, no server
kubectl apply -f deploy.yaml --dry-run=server       # schema + admission, no write
kubectl diff -f deploy.yaml                         # exactly what would change
kubectl apply -f deploy.yaml
kubectl apply -f manifests/ -R --prune -l env=dev   # directory, recursive, prune removed objects

Full lesson: kubectl fundamentals and writing manifests →

Labels, selectors, namespaces and annotations

Labels and selectors are how objects find each other

metadata:
  labels:
    app.kubernetes.io/name: web
    app.kubernetes.io/instance: web-prod
    app.kubernetes.io/version: "1.27"
    app.kubernetes.io/component: frontend
    app.kubernetes.io/part-of: storefront
    app.kubernetes.io/managed-by: helm
    environment: prod
    track: stable

Labels and selectors are how objects find each other

kubectl get pods --show-labels
kubectl get pods -l 'app.kubernetes.io/name=web,environment in (prod,staging)'
kubectl get pods -l '!canary'
kubectl label pod web-abc123 track=stable
kubectl label pod web-abc123 track-        # remove a label
kubectl get pods -l app=web --field-selector status.phase=Running

Namespaces divide names, not networks

kubectl create namespace team-a
kubectl get namespaces
kubectl get pods -n team-a
kubectl get pods --all-namespaces
kubectl config set-context --current --namespace=team-a
kubectl get pods -A -o custom-columns=NS:.metadata.namespace,NAME:.metadata.name

# a common pattern: one namespace per team or per environment
kubectl create namespace storefront-staging
kubectl create namespace storefront-prod

Full lesson: Labels, selectors, namespaces and annotations →

Storage: volumes, PersistentVolumes and StorageClasses

StorageClasses and StatefulSets

kubectl get storageclass
kubectl get pv,pvc -n storefront-prod
kubectl describe pvc pgdata -n storefront-prod    # events explain Pending
kubectl get pvc pgdata -o jsonpath='{.spec.resources.requests.storage}'

Full lesson: Storage: volumes, PersistentVolumes and StorageClasses →

StatefulSets, DaemonSets and Jobs

Jobs and CronJobs

kubectl get jobs -w
kubectl logs job/migrate
kubectl describe job migrate          # events show why a pod was retried
kubectl get cronjobs
kubectl create job --from=cronjob/nightly-report manual-run-1

Full lesson: StatefulSets, DaemonSets and Jobs →

Ingress, Gateway API and exposing applications

An Ingress object is only half the story

# the controller is a normal workload; install it once per cluster
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm install ingress-nginx ingress-nginx/ingress-nginx -n ingress-nginx --create-namespace

kubectl get pods -n ingress-nginx
kubectl get ingressclass
kubectl get svc -n ingress-nginx        # the LoadBalancer the whole world hits

Hosts, paths and TLS

kubectl get ingress
kubectl describe ingress storefront     # shows each rule and the resolved backend
kubectl get endpoints api               # an ingress with no endpoints returns 503

Full lesson: Ingress, Gateway API and exposing applications →

Resource requests, limits and autoscaling

Requests, limits and QoS

spec:
  containers:
    - name: api
      image: ghcr.io/example/api:2.1.0
      resources:
        requests:
          cpu: 250m          # 0.25 of a core, reserved on the node
          memory: 256Mi      # used for scheduling and eviction ordering
        limits:
          cpu: "1"           # throttled above this, never killed
          memory: 512Mi      # exceeded means OOMKilled

Requests, limits and QoS

kubectl top pods -n storefront
kubectl top nodes
kubectl get pod api-abc -o jsonpath='{.status.qosClass}'
kubectl describe pod api-abc | grep -A3 Limits

Vertical scaling, cluster scaling and disruption

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: api
spec:
  minAvailable: 2                  # or maxUnavailable: 1
  selector:
    matchLabels:
      app: api

Full lesson: Resource requests, limits and autoscaling →

Networking, DNS and NetworkPolicy

The cluster network model

kubectl get pods -o wide                 # pod IPs and the node each runs on
kubectl get svc -A                       # ClusterIP, and ExternalIP if any
kubectl get svc kubernetes -o jsonpath='{.spec.clusterIP}'
kubectl get nodes -o custom-columns=NAME:.metadata.name,PODCIDR:.spec.podCIDR
kubectl get endpointslices -l kubernetes.io/service-name=web

CoreDNS and how names resolve

# what a pod's resolver actually contains
kubectl exec -it web-abc -- cat /etc/resolv.conf
# nameserver 10.96.0.10
# search storefront.svc.cluster.local svc.cluster.local cluster.local
# options ndots:5

CoreDNS and how names resolve

spec:
  dnsPolicy: ClusterFirst
  dnsConfig:
    options:
      - name: ndots
        value: "2"
      - name: timeout
        value: "2"

Full lesson: Networking, DNS and NetworkPolicy →

RBAC, service accounts and pod security

RBAC: roles, bindings and verbs

kubectl auth can-i get pods -n storefront --as=system:serviceaccount:storefront:ci
kubectl auth can-i --list -n storefront --as=system:serviceaccount:storefront:ci
kubectl create role deployer --verb=get,list,watch,update --resource=deployments -n storefront
kubectl describe clusterrole cluster-admin     # note the wildcards

Service accounts and token projection

kubectl create serviceaccount api -n storefront
kubectl get serviceaccounts -A
kubectl get rolebindings,clusterrolebindings -A -o wide | grep storefront
kubectl auth whoami --as=system:serviceaccount:storefront:api

Keeping containers unprivileged

# enforce a baseline on a namespace, with a visible warning first
kubectl label namespace storefront \
  pod-security.kubernetes.io/enforce=restricted \
  pod-security.kubernetes.io/enforce-version=latest \
  pod-security.kubernetes.io/warn=restricted \
  pod-security.kubernetes.io/audit=restricted

kubectl get pod api-abc -o jsonpath='{.spec.securityContext}'

Full lesson: RBAC, service accounts and pod security →

Helm and packaging applications

Charts and releases

storefront/
  Chart.yaml            # name, version, appVersion, dependencies
  values.yaml           # defaults for every template variable
  charts/               # vendored subcharts
  templates/
    _helpers.tpl        # named templates you can include
    NOTES.txt           # printed after a successful install
    deployment.yaml
    service.yaml
    ingress.yaml
    tests/test-connection.yaml
  .helmignore

Charts and releases

helm create storefront
helm lint ./storefront
helm template storefront ./storefront --debug | less   # render locally, no cluster
helm install storefront ./storefront -n storefront --create-namespace
helm list -A
helm status storefront -n storefront
helm get values storefront -n storefront
helm get manifest storefront -n storefront      # what is actually deployed

Templates and values

# values.yaml
replicaCount: 2
image:
  repository: ghcr.io/example/storefront
  tag: ""                     # empty means use .Chart.AppVersion
resources:
  requests:
    cpu: 100m
    memory: 128Mi
ingress:
  enabled: false

Full lesson: Helm and packaging applications →

Scheduling: affinity, taints and tolerations

Taints and tolerations

kubectl taint nodes node-1 dedicated=gpu:NoSchedule
kubectl taint nodes node-1 dedicated=gpu:NoSchedule-     # remove
kubectl describe node node-1 | grep -A4 Taints
kubectl label nodes node-1 node-pool=gpu

Taints and tolerations

spec:
  nodeSelector:
    node-pool: gpu
  tolerations:
    - key: dedicated
      operator: Equal
      value: gpu
      effect: NoSchedule
  containers:
    - name: trainer
      image: ghcr.io/example/trainer:0.9.1

Topology spread, priority and node maintenance

kubectl cordon node-1                       # stop new pods being scheduled
kubectl drain node-1 --ignore-daemonsets --delete-emptydir-data
kubectl uncordon node-1
kubectl get pods -A -o wide --field-selector spec.nodeName=node-1
kubectl get pdb -A                           # what drain must respect

Full lesson: Scheduling: affinity, taints and tolerations →

FAQ

Is this Kubernetes cheat sheet free to use?
Yes. No sign-up and no tracking: the page is static, every example is on the page itself, and you can print it or save it as a one-page reference.
Where do the examples come from?
Every snippet is taken from the 14 lessons of the Kubernetes course on this site, and each section links back to the lesson it was pulled from.
How do I go deeper than a cheat sheet?
Open the full Kubernetes course — it carries the worked explanations, the edge cases and the exercises behind every line here.

Git Linux Docker Nginx CI / CD Bash Scripting

Last refreshed 2026-09-27.