Day 4 of #40daysofkubernetes challenge
Baby steps towards Kubernetes - When and When not to use it

Kubernetes
Kubernetes is a container orchestration platform which is capable of creating, managing, restarting, monitoring and deleting containers based on the desired state we declare, without us managing each container by hand.
Challenges of using standalone containers
Before getting into Kubernetes it is worth looking at what plain containers cannot do, because that is what Kubernetes is built to fix. Most of these I ran into myself over the last few days.
Nothing watches the container. My Go container exited and I only found out when I ran docker ps and saw nothing there. Docker started it and then forgot about it. Kubernetes keeps checking whether the pod is alive and serving, and restarts it when it is not.
The container is tied to one machine. docker run starts a container on the machine we typed it on. If we have ten servers, someone has to decide which one each container goes to, and redo it by hand when a server dies. Kubernetes has a scheduler that makes that decision for us.
Scaling is manual. To go from one container to twenty, we run the command twenty times, and we have to remember to bring them back down later. Kubernetes lets us declare how many we want and adjusts on its own based on the load.
Deployments have a gap. Updating means stopping the old container and starting the new one, and in between nothing is serving. If the new one is broken, getting back to the old version is another manual step. Kubernetes brings up the new pods first and only removes the old ones once the new ones are healthy, and a rollback is one command.
Why we need Kubernetes in the first place
Let's say we are working in an organization which has massive unpredictable traffic and we have to scale the number of containers up and down based on the traffic. Or a very critical system like a banking application which needs to have almost 99.99% uptime. In these cases it would be very difficult for humans to do all the maintenance work in production. This is where Kubernetes comes in, by automatically doing all of this.
When to use Kubernetes
Scale: Let's say there is an Amazon sale and suddenly the server is facing 50,000 users a second, which was 500 before, and after an hour the traffic drops back to 500. In this case we want the number of containers to go up at the high point and come back down at the low point, keeping cost in mind. Kubernetes does this automatically with the Horizontal Pod Autoscaler, which adds and removes pods based on the load it observes.
Reliability: Here we can consider ourselves a bank. We have high traffic, and more than that, the moment our servers are down the whole nation is looking at us, so reliability is our top concern. In this case the ability of Kubernetes to monitor, restart and replace unhealthy pods is very useful for us.
More than one machine: We can use the same bank example. As we are a bank we will be running our servers and databases on premises due to data residency concerns, so of course we will have more than one machine in our fleet. These machines have to be managed efficiently. The control plane model of Kubernetes centralizes this and decides which machine each container should run on, so we do not have to place anything by hand.
Frequent deployments with no downtime: Here we can take whatever application we want. Every application needs to be deployed, and a manual deployment can take minutes if not hours, and if something goes wrong the rollback will also take a lot of time, which cannot be afforded in time critical projects. So the Kubernetes deployment model with rolling updates and rollbacks comes in and saves us.
Self-healing and health checks: Restarting a crashed container is the easy case. The harder one is a process that is still running but has stopped responding, a deadlock or a hung connection pool, where the container looks perfectly healthy from outside. Kubernetes keeps probing the application itself with liveness and readiness checks, so a pod that is alive but not serving gets restarted, and a pod that is not ready yet stops receiving traffic until it is. It also handles the case where an entire machine dies, by rescheduling those pods onto the remaining nodes.
When we should not use Kubernetes
Simple application on a single machine: If we have an application which is simple and has no big traffic, and the whole thing runs on a single VM, Kubernetes is not a good option for us. We can use plain containers instead. The Go todo app I containerized earlier in this challenge is exactly this, one binary on one machine, and docker run gets it going in two seconds.
Small team: Kubernetes orchestration needs a dedicated team to run it, which is not possible in small teams. Someone has to own upgrades, networking, monitoring and debugging the cluster itself, and in a small team that time is taken away from building the actual product.
Stateful systems that are hard to replace: Kubernetes is at its best with stateless pods, where any pod can be killed and replaced by an identical one. A database is the opposite. It has data on disk, it has a primary and replicas, and replacing a pod is not a neutral act. It can be done with StatefulSets and persistent volumes, but we take on a lot of complexity and often gain very little over running the database on a dedicated machine or using a managed service.
Legacy applications that cannot be containerized: Some older applications expect things a container cannot easily give them, like a fixed IP address, a specific hostname, a hardware licence dongle, or writing straight to local disk as their only storage. Forcing such an application into a pod takes more effort than it is worth, and we usually end up fighting the platform. Running it as it is on a VM is the saner choice.
Short-lived or batch work: Some workloads run once and exit, like a nightly report or a one-off data migration. If the actual work takes four minutes a day, a cluster sitting there for the other 23 hours and 56 minutes is pure cost. A scheduled job on a plain VM, or a serverless function, does the same thing for far less.
Conclusion
The thing I took away from Day 4 is that Kubernetes is not an upgrade that every containerized application should get. It solves a specific set of problems - many machines, unpredictable traffic, frequent deployments, staying up when things fail - and if we do not have those problems, all it gives us is complexity we have to maintain.
Containers solved packaging and made an application run the same way everywhere. Kubernetes solves what happens after that, once one container on one machine is no longer enough. Knowing when we are actually at that point is as useful as knowing how to use the tool.




