Kubernetes is the default recommendation for container orchestration, to the point where choosing something else requires justifying yourself. That is an unusual position for infrastructure, and worth examining on its merits rather than accepting.

What you are actually adopting

Kubernetes is not one thing. Adopting it means taking on a permanent operational responsibility for several substantial systems at once:

  • The control plane — API server, scheduler, controller manager, and etcd, which is a distributed system with its own operational requirements
  • etcd and state — the single most critical datastore in the stack, with backup and compaction behaviour that catches people out
  • networking — CNI plugins, ingress controllers, service meshes if you go there
  • Storage — PersistentVolumeClaims, storage classes, and the expansion limits of most volume drivers
  • Upgrade lifecycle — roughly a minor version every few months, each one a genuine project

None of this is unreasonable for a large organisation. The point is that it is a large commitment, and it does not shrink because the YAML looks clean.

The workload shapes where Kubernetes is the right answer

  1. You have many teams deploying independently. Scheduling, resource quotas, network policies and self-service isolation are genuinely hard to reproduce well without it.
  2. You need a specific runtime behaviour. Sidecars, init containers, custom scheduling, per-workload networking policy. If you can describe why, you probably need it.
  3. Your hardware or compliance model demands it. On-premises clusters for air-gapped or residency-restricted workloads.
  4. Your organisation is built to run it. If you have a platform team whose actual job is operating Kubernetes, the cost calculation changes completely.
  5. You need portability across environments. If you must run the same artefact in a managed cloud, on-premises and at the edge, a standard runtime has real value.

The cases where it usually is not

A small team with a handful of services. If four people deploy twelve services, the platform team is three of you, and the operational surface is a single managed cluster, you have added a large system to solve a problem you do not have.

You do not have anyone whose job is reliability. Kubernetes does not make your service reliable. Someone has to patch, upgrade, tune, watch the etcd disk, and read the logs when admission webhooks fail. Without that person, you have added an outage surface rather than removed one.

Your workload is not container-shaped. Long-running batch work, spiky event processing, or anything where you are paying for idle reserved capacity to get a good utilisation number.

The honest test

Ask who will be on call for the cluster at 3am in eighteen months, and whether they have the time to learn it properly. If the honest answer is “whoever is nearest”, the platform is a net negative.

The alternatives, honestly compared

OptionGood forCosts you
Managed containers
ECS, Cloud Run, App Service, Cloud Run
Most services under a few thousand requests per second. No control plane to run. Less control. Some portability limits. Per-request pricing surprises at scale.
Serverless
Lambda, Cloud Functions
Event-driven, spiky, unpredictable load. Genuinely near-zero idle cost. Cold starts, execution limits, awkward long-running work, vendor coupling.
Platform as a service
Heroku, Render, Fly.io, Railway
Getting a service deployed this afternoon, without an infrastructure person. Cost at scale, less control, and you are inside their constraints.
Plain IaC
Terraform, ECS, systemd, Nomad
Predictable workloads, steady traffic, teams that value control. Underrated. You build the deployment story yourself. Rollout, health checks, draining.
Kubernetes
EKS, GKE, AKS, self-managed
Many teams, complex scheduling, portability, hard compliance constraints. Real operational load, permanent, and it does not go away.

The migration is the expensive part

The most common Kubernetes project we get brought into is not an adoption. It is an escape from a partial adoption that was never finished.

A cluster that was stood up, ran two services, and now has workloads nobody understands running an out-of-support version, with stateful data in hostPath volumes and a YAML file in someone's Documents folder as the only record of the deployment process. Replacing that is considerably more work than starting on a managed platform.

If that describes you, the first useful step is not Kubernetes. It is finding out what is actually running before deciding what it should be running on.

What we will usually recommend

Start on the simplest thing that could work, and move when a specific requirement forces you to. Concretely: a managed container service for most services, serverless for genuinely spiky or event-driven work, and infrastructure as code describing all of it. Add Kubernetes when you hit a concrete wall — a compliance requirement, a scheduling need, a portability commitment — and not before.

This is not the advice that generates the most Kubernetes work. It is the advice that tends to produce the fewest outages, which is the metric we actually care about.