20,000 Workloads to Kubernetes: Post-Mortem
The migration deck said "20,000 microservices to Kubernetes." Nobody runs 20,000 microservices — only a handful of companies on earth operate even a fraction of that. The real inventory was roughly 900 distinct services running as some 20,000 VM instances. The inflated number mattered, because a plan built on it treated every instance as identical, containerization-ready, and safe to move on autopilot.
The plan
- "Just containerize and deploy"
- Automated conversion tooling, minimal per-service review
- Aggressive cutover waves measured in weeks
What went wrong
In the first major wave, roughly two-thirds of the migrated services failed readiness or health checks. The causes were rarely exotic:
- Hardcoded IP addresses in config files nobody had opened in years
- Services writing temp files to /opt/app/tmp — read-only in the new images
- One service parsed its own hostname to decide which environment it was in; it expected to live on a box named "prod-db-01"
- Hundreds of hardcoded localhost references to daemons that no longer ran next to the app
- Time-zone assumptions that broke batch jobs the moment containers defaulted to UTC
None of this shows up in an automated scan of the deployment artifact. It is infrastructure archaeology, and it costs real time per service.
What works instead
- Inventory first. Deduplicate instances into actual services and classify each one — this is the assessment step of any sane cloud migration roadmap, and in 6R/7R terms it decides which workloads to replatform, which to rehost as-is, and which to retire.
- A container-readiness checklist per service: filesystem writes, network and hostname assumptions, config sources, clock and locale.
- Small waves, stateless first, with phased traffic shifting and instant rollback. Canary releases belong at the traffic layer; data migrations — where patterns like dual-write apply — are a separate workstream, not a containerization fix.
- A timeline in months per tranche, not a cutover weekend.
Estates like this are exactly why we scope cloud migration engagements around discovery before anyone writes a Dockerfile.
Lesson: Containerization is not "docker build". Undocumented dependencies — not Kubernetes — are what kill replatforming projects, and the only way to find them is to look at one service at a time.