Learning Kubernetes From Zero, By Actually Shipping to Production
The problem with learning infrastructure from tutorials
Most Kubernetes tutorials teach you to deploy a single stateless container and call it a day. That's a reasonable starting point, but it's nothing like what a real production platform actually needs, and I found that out the hard way when FlipLytics needed a proper home.
I'd never touched Kubernetes before this project. My infrastructure background up to that point was VMware, provisioning VMs by hand, and Nginx doing straightforward reverse proxying. Kubernetes was a genuinely different way of thinking about infrastructure, and I didn't have the luxury of learning it slowly. I needed a real, working, production platform, and I needed to be the one who built and understood every part of it.
Starting with the cluster itself
I used Terraform to provision a DigitalOcean Kubernetes cluster, with a highly available control plane and auto-scaling node pools. That part, at least, felt familiar. Provisioning infrastructure as code was something I already knew how to do.
What wasn't familiar was everything that came after the cluster existed. A cluster with nothing running on it is just an empty room.
Learning to actually write Helm charts
FlipLytics wasn't one application, it was a genuine multi-service platform: a Django backend, five separate frontends, a dedicated FastAPI event producer, Celery workers, and more. Each of those needed its own Helm chart, and I had to learn to write every one of them from scratch.
This is where the real learning happened. It's one thing to read that Helm charts template Kubernetes manifests. It's a different thing entirely to sit there working out why a Deployment isn't picking up a ConfigMap change, or why a Service isn't routing to the right pods, and realising the label selectors don't match. I made almost every beginner mistake there is to make, on infrastructure that real customers were about to depend on.
Networking was the genuinely hard part
Coming from a world of simple Nginx reverse proxy configs, Kubernetes networking took real effort to properly understand. Services, ClusterIPs, Ingress rules, how pod-to-pod communication actually resolves inside a cluster, none of it maps cleanly onto what I already knew. I had to build a mental model from scratch: what does a Service actually do versus a Deployment, why does DNS resolution work the way it does inside the cluster, what's actually happening when an Ingress controller routes external traffic in.
I didn't get this right the first time. I broke things. I fixed them. I broke them again in a slightly different way. That loop, uncomfortable as it was, is genuinely how I learned it properly, rather than just learning to recite the concepts.
Isolating workloads with tainted node pools
Once the basics were working, I started thinking about problems tutorials never cover: what happens if one workload's resource usage affects another's? For FlipLytics, I set up a dedicated, tainted node pool specifically for backup workloads, so that a heavy backup job could never compete for resources with the actual customer-facing application, and so a misbehaving backup process couldn't take anything else down with it.
That's a deliberate design decision, not something Kubernetes does for you by default. Nobody tells you about taints and tolerations in a beginner tutorial, because you don't need them until you're running something real enough to actually worry about failure isolation.
Bringing CI/CD inside the cluster
The last piece was self-hosted GitHub Actions runners, deployed inside the cluster itself using Actions Runner Controller, provisioned via Ansible. I did this specifically so that sensitive workloads, database backups in particular, never had to touch GitHub's public runners at all. That's a security decision as much as an infrastructure one: keeping a database credential's blast radius as small as possible.
What actually stuck
If I'd tried to learn Kubernetes in the abstract, I don't think any of this would have stuck the way it has. Learning it by being personally, immediately responsible for a real production system meant every concept had a consequence attached to it. A misconfigured Service didn't just fail a tutorial step, it meant a broken deployment I had to actually fix, on a system with real users behind it.
I'd genuinely recommend this approach to anyone trying to learn infrastructure properly: find a real project that actually needs it, and let the stakes teach you the parts a tutorial never will.
