Common Anti-Patterns
Topic 70

Common Anti-Patterns

PitfallsAnti-patterns

The same mistakes recur across every kind of Kubernetes workload, and recognizing them is half of avoiding them. This final topic is a catalog of the common anti-patterns — each paired with the consequence it causes and the fix — drawing the pitfalls from across the course into one reference.

If the rest of the course is what to do, this is the short list of what not to do, framed as anti-pattern → why it bites → the fix.

Image and Configuration

The :latest tag. Consequence: no reproducibility and no rollback — both old and new resolve to whatever it points at now. Fix: pin by tag-plus-digest (Topics 06, 37). Config baked into images. Consequence: the same image can't move across environments and secrets leak into the image. Fix: ConfigMaps and Secrets, externalized (Topic 10). Secrets in Git or env vars. Fix: encryption at rest, an external store, and file mounts (Topic 35).

Resources and Workloads

No requests or limits. Consequence: BestEffort Pods scheduled blindly and evicted first; noisy neighbors. Fix: set requests from measured usage (Topic 25). Bare Pods or single replicas in production. Consequence: no self-healing, no availability. Fix: controllers with multiple replicas (Topics 05-06). Stateful workloads as Deployments (or self-running databases by default). Fix: StatefulSets/operators where truly needed, managed services otherwise (Topics 14, 39).

Anti-patternFix
:latest tagPin by tag + digest
No requests/limitsSet from measured usage
Single replica in prodController + multiple replicas + PDB
Liveness == readinessDistinct probes; liveness tests only the process
One giant namespaceNamespaces per team/env + quotas
Snowflake clustersDeclarative, reproducible clusters + GitOps

Health, Network, and Organization

Liveness probe that checks dependencies (or equals readiness). Consequence: restart storms when a dependency blips. Fix: minimal liveness, dependency-aware readiness (Topic 29). Flat open network / no NetworkPolicy. Consequence: any compromised Pod reaches everything. Fix: default-deny baseline (Topic 23). Everything in default, one giant namespace. Consequence: no isolation, no quotas, noisy neighbors. Fix: purposeful namespaces with quotas (Topics 11, 52).

Operations and Mindset

Click-ops and kubectl drift. Consequence: the cluster diverges from anything written down and changes are unauditable. Fix: declarative manifests and GitOps (Topics 04, 43). Snowflake clusters built and patched by hand. Consequence: unreproducible and impossible to recover. Fix: declarative, reproducible cluster provisioning. SSHing to nodes to fix Pods and treating Kubernetes as a magic autoscaler round out the list — both fixed by trusting the reconcile loop and changing desired state through the API. The through-line of the whole course: declare desired state, keep it in Git, let the loop converge, and build the production gates in deliberately. That is what separates a demo cluster from one you can trust.

Anti-pattern vs the practice that replaces it

Anti-pattern — the convenient shortcut — :latest, no limits, one namespace, click-ops — that bites later.

Best practice — the deliberate choice — digest pins, requests, namespaces+quotas, GitOps — covered across this chapter.

Common Mistakes
  • Using :latest or unpinned images, destroying reproducibility and rollback.
  • Shipping Pods with no requests/limits and single replicas in production.
  • A liveness probe that checks dependencies, causing restart storms.
  • A flat, open network with no NetworkPolicy and everything in one namespace.
  • Click-ops, kubectl drift, snowflake clusters, and SSHing to nodes to fix Pods.
Best Practices
  • Pin images by digest; externalize config; keep secrets out of Git and env vars.
  • Set requests/limits; run controllers with multiple replicas and PDBs.
  • Use distinct, correct probes; adopt a default-deny NetworkPolicy and purposeful namespaces.
  • Manage everything declaratively through GitOps; build reproducible clusters.
  • Trust the reconcile loop — change desired state through the API, never patch nodes by hand.
RelatedThe reconcile loop — the model these fixes all rest on (Topic 01)Production-readiness — the positive form of this catalog (Topic 66)GitOps — the antidote to click-ops and drift (Topic 43)

Knowledge Check

Why is the :latest image tag an anti-pattern?

  • It destroys reproducibility and rollback — old and new resolve to whatever it points at now
  • The image can never be pulled by Kubernetes, so the Pod stays stuck in ErrImagePull while the kubelet keeps retrying the registry under exponential backoff
  • It caps the Deployment at a single replica regardless of the replica count requested in the spec
  • It disables NetworkPolicy enforcement for every Pod that runs in the same namespace

What is the fix for the 'everything in one giant namespace' anti-pattern?

  • Purposeful namespaces per team/environment with quotas and RBAC
  • Scheduling everything onto a single larger node with more CPU and memory
  • Pinning every workload to the :latest tag for consistent rollouts
  • Running every service as containers inside one shared Pod

What is the through-line that ties the course's best practices together?

  • Declare desired state, keep it in Git, let the reconcile loop converge, and build production gates in deliberately
  • Always upgrade to the newest Kubernetes version the moment each release ships, draining and replacing every node so the control plane and kubelets stay on the latest minor
  • Run as few replicas as possible across the fleet to keep node and compute spend down
  • Manage the cluster imperatively with kubectl edit for direct hands-on control

You got correct