DS DevShelfHub Projects · AI tools
Cheatsheets / Kubernetes
Cheatsheet · Dev tooling

Kubernetes Cheatsheet: kubectl, Pods, Services and Helm

By DevShelfHub

Kubernetes (k8s) is the industry-standard container orchestration platform: you describe desired state in YAML, the control plane reconciles reality. This cheatsheet covers the daily kubectl surface, workload controllers, Services, Ingress, ConfigMaps, Secrets, volumes, health probes, RBAC, and Helm 3 — from first cluster to production ops.

98 items 8 min kubectl Deploy Helm

Kubernetes (k8s) is an open-source container orchestration platform originally designed at Google and donated to the CNCF in 2014. It solves the problem of running containerised workloads at scale: instead of manually placing containers on servers, you describe the desired state of your application in YAML manifests and Kubernetes continuously reconciles the cluster toward that state. This declarative model — say what you want, not how to achieve it — is the conceptual foundation for everything else in k8s.

The cluster has two logical layers: the control plane (API server, etcd, scheduler, controller manager) and worker nodes where containers actually run. Every interaction goes through the API server — kubectl is simply a CLI wrapper around REST calls to that API. The smallest deployable unit is a Pod (one or more containers sharing a network namespace), but in practice you manage Pods through higher-level controllers: Deployments for stateless apps, StatefulSets for databases, DaemonSets for node-level agents, and Jobs for batch work.

Traffic routing uses Services (stable virtual IPs that load-balance across Pod replicas) and Ingress resources for HTTP hostname/path routing. Configuration is injected via ConfigMaps and Secrets — never baked into images. Helm 3 is the de facto package manager: a chart bundles all manifests for an application and values.yaml controls environment-specific overrides. This cheatsheet covers the daily kubectl surface, workload specs, networking primitives, storage, RBAC, and Helm — everything you need from first cluster to production.

Start hereQuick start · 6 you’ll reach for daily

List podskubectl get pods -A
Applykubectl apply -f …
Tail logskubectl logs -f deploy/api
Shell inkubectl exec -it … -- sh
Port-forwardkubectl port-forward svc/api 8080:80
Roll backkubectl rollout undo deploy/api

Target versions · paceVersions

Targets: kubernetes ≥ 1.30 kubectl matches ±1 minor helm ≥ 3.14

Snippets target k8s 1.30+. The big shifts vs early-k8s: PodSecurityAdmission replaces PSP; apps/v1 is the only stable workload API; networking.k8s.io/v1 for Ingress; storage.k8s.io/v1 for StorageClasses. Docker shim is gone — containerd / CRI-O underneath.

install · contextsSetup

bash
# Install
brew install kubectl helm kind kustomize
brew install --cask docker          # docker desktop has built-in single-node cluster

# Spin up a local cluster
kind create cluster --name dev
# or
minikube start --driver=docker

# Connect to a remote cluster
kubectl config view
kubectl config get-contexts
kubectl config use-context my-prod-cluster
kubectl config set-context --current --namespace=team-a

# Sanity check
kubectl cluster-info
kubectl get nodes -o wide
kubectl version --short

# Useful aliases
alias k=kubectl
alias kgp='kubectl get pods'
alias kdp='kubectl describe pod'
alias klog='kubectl logs -f --tail=200'

the daily CLIkubectl

kubectl get pods,svc,deployMulti-kind list.
kubectl get pods -AAll namespaces.
kubectl get pods -o wideIncludes node + IP.
kubectl get pods -o yaml / -o jsonFull object body.
kubectl get pods --selector app=apiLabel selector. -l short form.
kubectl describe pod NAMEEvents, status, container details.
kubectl logs POD / -c container / --previousLatest / pick a container / previous crashed instance.
kubectl exec -it POD -- bashShell inside the pod.
kubectl port-forward svc/api 8080:80Tunnel to a service locally.
kubectl apply -f file.yaml / -k dir/Declarative apply. Kustomize with -k.
kubectl delete -f file.yamlDelete what the file declares.
kubectl rollout status / restart / undo deploy/apiDeployment lifecycle.
kubectl scale deploy/api --replicas=5Manual scale.
kubectl top pod / nodeResource usage (needs metrics-server).
kubectl explain pod.spec.containers.resourcesField-level reference from the cluster.
kubectl get pods -wWatch for changes.
kubectl debug node/N -it --image=alpinePrivileged debug pod on a node.

smallest deployable unitPods

apiVersion: v1, kind: PodDirect pod — mostly for debugging. Use Deployments in prod.
spec.containers[]One or more containers, sharing network + volumes.
spec.initContainers[]Run-to-completion before main containers. Migrations, file fetches.
spec.restartPolicyAlways (default) / OnFailure / Never.
spec.nodeSelector / affinity / tolerationsWhere the pod is allowed to run.
spec.serviceAccountNameRBAC identity inside the cluster.
spec.securityContext / runAsNonRootDrop privileges. Required under restricted PSA.
spec.terminationGracePeriodSecondsWait between SIGTERM and SIGKILL on shutdown.
Sidecar containers (1.29+)restartPolicy: Always on an init container. Native sidecar.

managed podsDeployments

apps/v1 DeploymentPreferred for long-running stateless services.
spec.replicasDesired pod count. Pair with HPA for auto-scaling.
spec.strategy.type: RollingUpdateDefault. maxUnavailable / maxSurge tune the window.
spec.strategy.type: RecreateKill all old before new. For singleton / DB-style.
readinessProbe / livenessProbe / startupProbeTraffic gate / restart trigger / slow-boot allowance.
resources.requests / limitsSchedulability + caps. Set both.
HorizontalPodAutoscaler (HPA)Scale replicas by CPU / memory / custom metric.
StatefulSetStable pod identity + ordered rollout. For DBs, queues.
DaemonSetOne pod per node. Logs, metrics, CNI.
Job / CronJobRun-to-completion / scheduled tasks.
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api
  labels: { app: api }
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate: { maxUnavailable: 1, maxSurge: 1 }
  selector:
    matchLabels: { app: api }
  template:
    metadata:
      labels: { app: api }
    spec:
      containers:
        - name: api
          image: ghcr.io/me/api:0.4.1
          ports:
            - containerPort: 8000
          envFrom:
            - configMapRef: { name: api-config }
            - secretRef:    { name: api-secrets }
          resources:
            requests: { cpu: 100m, memory: 256Mi }
            limits:   { cpu: 500m, memory: 512Mi }
          readinessProbe:
            httpGet: { path: /healthz, port: 8000 }
            periodSeconds: 5
          livenessProbe:
            httpGet: { path: /healthz, port: 8000 }
            initialDelaySeconds: 15
            periodSeconds: 20

stable network endpointServices

type: ClusterIP (default)Internal-only virtual IP.
type: NodePortExposes a port on every node. Dev only.
type: LoadBalancerCloud LB provisioned (ELB/ALB/GLB).
type: ExternalNameCNAME to an external host.
selector + matchLabelsHow pods are picked. Label drift is the #1 cause of 0 endpoints.
port vs targetPortService port vs container port.
Headless service (clusterIP: None)DNS returns pod IPs directly. Required for StatefulSets.
Endpoints / EndpointSliceBacking object listing pod IPs. Inspect when traffic isn’t flowing.
DNS: svc.ns.svc.cluster.localStable in-cluster name.

HTTP routing into the clusterIngress

networking.k8s.io/v1 IngressDefines hostname + path → service routing.
ingressClassName: nginx / traefik / awsPick a controller. IngressClass registers them.
spec.rules[].host + http.paths[]Virtual-host routing.
pathType: Prefix / Exact / ImplementationSpecificMatch semantics. Most paths want Prefix.
spec.tls[] + secretNameBind a TLS cert (usually managed by cert-manager).
Controller annotationsBackend-specific (rate limits, auth, body size). Read the controller docs.
Gateway API (gateway.networking.k8s.io)Successor to Ingress. HTTPRoute / TLSRoute. Prefer for new clusters.
yaml
---
apiVersion: v1
kind: Service
metadata: { name: api }
spec:
  type: ClusterIP                       # internal-only; default
  selector: { app: api }
  ports:
    - name: http
      port: 80                          # service port
      targetPort: 8000                  # container port
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: api-ingress
  annotations:
    nginx.ingress.kubernetes.io/proxy-body-size: "8m"
spec:
  ingressClassName: nginx
  tls:
    - hosts: ["api.example.com"]
      secretName: api-tls
  rules:
    - host: api.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: api
                port: { number: 80 }

runtime configurationConfigMaps & Secrets

kind: ConfigMap, data: { KEY: value }Non-sensitive key/value. Up to ~1 MiB total.
kind: Secret, type: Opaque, stringData: { … }Base64-encoded; treat as “don’t log” rather than “encrypted”.
envFrom: configMapRef / secretRefMount all keys as env vars.
env: { valueFrom: { secretKeyRef: … } }Mount a single key as one env var.
volume: configMap / secretMount values as files in the container.
immutable: trueLock a ConfigMap / Secret. Faster + safer.
External Secrets / Sealed Secrets / SOPSSync from a real secret store; keep manifests git-safe.
enable encryption at restCluster-level: encrypt Secret data in etcd.
yaml
---
apiVersion: v1
kind: ConfigMap
metadata: { name: api-config }
data:
  LOG_LEVEL: "info"
  FEATURE_X:  "true"
---
apiVersion: v1
kind: Secret
metadata: { name: api-secrets }
type: Opaque
stringData:                             # plain values; encoded automatically
  DATABASE_URL: "postgres://user:pw@db:5432/app"
  JWT_KEY:      "supersecret"
---
# Mount a ConfigMap as files
apiVersion: v1
kind: Pod
metadata: { name: cfg-demo }
spec:
  containers:
    - name: app
      image: alpine
      command: ["sleep", "3600"]
      volumeMounts:
        - { name: cfg, mountPath: /etc/app, readOnly: true }
  volumes:
    - name: cfg
      configMap:
        name: api-config
        items:
          - { key: LOG_LEVEL, path: log_level }

cluster partitioningNamespaces

kubectl create ns team-aLogical isolation: names + RBAC + quota.
kubectl get pods -n team-aPer-namespace queries.
ResourceQuotaCap CPU / memory / pod counts per namespace.
LimitRangePer-container default + max resource limits.
NetworkPolicyRestrict ingress / egress at pod level (needs CNI support).
Role / RoleBinding (namespaced)RBAC inside a namespace.
ClusterRole / ClusterRoleBindingCluster-wide RBAC.
PodSecurityAdmission labelspod-security.kubernetes.io/enforce: restricted on the namespace.

storageVolumes

emptyDirEphemeral, pod-lifetime scratch.
hostPathNode directory. Use sparingly — ties pods to nodes.
PersistentVolumeClaim (PVC)Preferred Bind to a dynamically-provisioned PV.
StorageClassDefines the provisioner + parameters.
accessModes: ReadWriteOnce / ReadWriteManyNode-exclusive vs shared.
CSI driversCloud volumes, NFS, Ceph, Longhorn — via CSI.
subPathMount a path inside a volume rather than the root.
volumeMode: Filesystem / BlockFilesystem (default) or raw block device.

health signalsProbes

readinessProbePod removed from Service endpoints when failing. Use for traffic gating.
livenessProbeFailing → container restart. Use sparingly.
startupProbeLong-boot grace. Disables liveness until it passes.
httpGet / tcpSocket / grpc / execFour ways to probe.
initialDelaySeconds, periodSeconds, timeoutSecondsAlways tune for your app’s real boot + check times.
failureThreshold + periodSecondsEffective time before action.
Don’t share endpoint for liveness + readinessLiveness should check “process alive”; readiness checks “ready to serve”.

packaged manifestsHelm

helm repo add NAME URLAdd a chart repo.
helm search repo NAMEFind charts.
helm install RELEASE CHART -n NS --create-namespaceInstall. Release name is local; chart is upstream.
helm upgrade --install REL CHART -f values.yamlPreferred Idempotent install or upgrade.
helm list -A / helm history RELWhat’s installed / past revisions.
helm rollback REL NRevert to revision N.
helm template CHART -f values.yamlRender manifests without installing.
helm uninstall RELRemove. --keep-history retains revisions.
kustomize alternativeNo templates — pure overlays. Use for in-cluster ops, helm for upstream apps.

ns · config · deploy · service · ingressEnd-to-end · Ship a service

From an empty namespace to a working HTTP service behind an ingress, with rollout watching and a rollback path. The shape every team converges on.

bash
# Full app: namespace -> config -> secret -> deployment -> service -> ingress.

kubectl create namespace team-a --dry-run=client -o yaml | kubectl apply -f -

kubectl create configmap api-config -n team-a \
  --from-literal=LOG_LEVEL=info \
  --from-literal=FEATURE_X=true \
  --dry-run=client -o yaml | kubectl apply -f -

kubectl create secret generic api-secrets -n team-a \
  --from-literal=DATABASE_URL='postgres://...' \
  --dry-run=client -o yaml | kubectl apply -f -

kubectl apply -n team-a -f deployment.yaml
kubectl apply -n team-a -f service.yaml
kubectl apply -n team-a -f ingress.yaml

kubectl -n team-a rollout status deploy/api --timeout=120s
kubectl -n team-a get pods,svc,ingress -o wide
kubectl -n team-a logs -f deploy/api --tail=100

# Roll back if things go bad
kubectl -n team-a rollout undo deploy/api
kubectl -n team-a rollout history deploy/api

Best practiceGood to know

Always set requests + limits. Without requests the scheduler can’t place pods correctly; without limits one pod can starve the node. Set both, then iterate from observed P95 usage.
Readiness gates traffic, liveness restarts. A common misuse: pointing liveness at /healthz that also depends on the DB. A DB blip = kill-loop on every pod. Liveness should be cheap and process-local.
Use kubectl apply --server-side. Tracks field ownership cleanly across teams + controllers. Avoids the “last apply wins, fields silently vanish” class of bug.

Common trapsWatch out for

Selector / label drift on Services. Service shows zero endpoints, traffic 503s. Either the deployment labels changed or the service selector did. Compare kubectl get pods --show-labels with kubectl describe svc.
ConfigMap / Secret changes don’t restart pods. Pods read the value at mount time. Bounce pods (kubectl rollout restart) or use a controller that watches the configmap (Reloader).
OOMKilled isn’t logged loudly. kubectl describe pod shows it as a status code. Set memory requests generously; observe P95 RSS for a week before tightening.

Go deeperSee also

Kubernetes FAQ

What is Kubernetes?

Kubernetes (k8s) is an open-source container orchestration platform that automates deployment, scaling, and management of containerised applications. It groups containers into Pods and manages them across a cluster of nodes. Kubernetes handles load balancing, self-healing, rolling updates, and secret management out of the box.

What is the difference between a Pod and a Deployment in Kubernetes?

A Pod is the smallest deployable unit in Kubernetes — one or more containers that share a network namespace and storage. A Deployment wraps Pods in a replication controller that maintains a desired replica count, performs rolling updates, and handles rollbacks. You almost never create Pods directly; use a Deployment, StatefulSet, or DaemonSet instead.

How do I expose a Kubernetes service externally?

Create a Service of type LoadBalancer to provision a cloud load balancer, or use NodePort to expose a port on every cluster node. For HTTP/HTTPS traffic, an Ingress resource with an ingress controller (NGINX, Traefik) routes domain names and paths to backend Services, avoiding the need for a load balancer per service.

What are ConfigMaps and Secrets in Kubernetes?

ConfigMaps store non-sensitive configuration as key-value pairs and can be mounted as environment variables or files inside a Pod. Secrets store sensitive data (passwords, API keys, TLS certs) in base64-encoded form and follow the same mounting patterns. For production, back Secrets with an external vault (AWS Secrets Manager, HashiCorp Vault) rather than etcd storage.

What is Helm in Kubernetes?

Helm is the package manager for Kubernetes. A Helm chart bundles all the Kubernetes manifests (Deployments, Services, ConfigMaps, etc.) for an application along with a values.yaml file that controls configuration. Install a chart with helm install, upgrade with helm upgrade, and manage releases with helm list and helm rollback.