Common Anti-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-pattern | Fix |
|---|---|
:latest tag | Pin by tag + digest |
| No requests/limits | Set from measured usage |
| Single replica in prod | Controller + multiple replicas + PDB |
| Liveness == readiness | Distinct probes; liveness tests only the process |
| One giant namespace | Namespaces per team/env + quotas |
| Snowflake clusters | Declarative, 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 — 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.
- Using
:latestor 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.
- 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.
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