Skip to main content

· Thomas Hatch, CEO

Different Logo, Same Cage

Everyone is fleeing VMware, and most teams are landing in the next walled garden. A forced migration is the only moment anyone re-architects — and the industry is about to spend the biggest one in a decade on changing vendors instead of changing the layer.

Everyone’s fleeing VMware right now. Good. Should’ve happened years ago.

But watch what’s actually happening: teams are ripping out VMware and dropping straight into another walled garden. Different logo, same trap.

I created Salt to make infrastructure declarative, not vendor-shaped. That was the whole point. Then we watched Kubernetes and Terraform turn “infrastructure as code” into “infrastructure as vendor config.” I say this with love, I was a sysadmin: we built the cage, we just made it prettier.

This reset is the best opportunity the industry has had in a decade to fix that, and we’re on track to waste it.

A forced migration is the only time anyone re-architects

Nobody re-examines a working platform. The budget doesn’t exist, the risk isn’t worth it, and the person who’d have to champion it has eleven other things to do this quarter. Architecture changes when something forces it.

A forced migration is that something. It’s the one point in a platform’s life when “we’ve always done it this way” stops being an acceptable answer - when a team has executive attention, a line item, and standing permission to ask uncomfortable questions about decisions nobody has questioned in eight years.

Which is why it matters so much that the question most teams are asking right now is “what do we move to” rather than “what did this platform cost us that we stopped noticing.”

The same story, in miniature

You don’t need a hyperscale migration to watch this dynamic play out. It already happened this year, quietly, to a component most teams don’t think about.

In March, ingress-nginx reached end-of-life. The repository was archived; the final release shipped days before. Kubernetes SIG Network and the Security Response Committee were unusually direct about what that meant: no further releases, no bugfixes, and no updates to resolve any security vulnerabilities that may be discovered. They recommended everyone begin migrating immediately.

Note carefully what retired. It was the controller, not the Ingress API. The API is still part of Kubernetes and isn’t going anywhere. Plenty of write-ups got that backwards, and the distinction is the whole difficulty - because what teams actually depend on was never in the API to begin with.

Now every team has a decision dressed up as a technicality.

Lift and shift to another ingress controller. Feels safe. Isn’t. Your nginx annotations don’t come with you - and the way they fail is the problem. Kubernetes annotations are free-form strings with no schema validation, so a controller that doesn’t recognize nginx.ingress.kubernetes.io/* keys doesn’t reject them. It never reads them. No error, no warning, no status condition. Your routing quietly stops doing something it used to do, and you find out in production.

Or modernize to Gateway API, which is what SIG Network actually recommends. That means admitting how much custom logic got duct-taped into annotations over the years, because the Ingress API was never enough on its own.

Either path, the real story surfaces: Kubernetes networking accumulated debt nobody counted.

Retirements don’t create complexity, they just force you to face it.

Annotation archaeology

It’s worth being concrete about why this hurts, because “annotations don’t transfer” sounds like a config chore and isn’t.

An annotation was never a setting. It was an escape hatch. The Ingress API gave you a hostname, a path, and a backend, and everything else you needed arrived as vendor-specific keys stapled to the side. Sort those keys by where they land today and the migration stops looking like a translation exercise.

Some port cleanly. Timeouts have a standard home in Gateway API now. So does path rewriting - with a catch that matters: the standard rewrite handles prefix and full-path replacement, not regular-expression capture groups, which is what a great many real rewrite rules were actually built on. CORS became standard only this April, which means your target controller may or may not implement it yet.

Some don’t port at all. Delegating authentication to an external service - the auth-url pattern half the industry uses for SSO in front of internal tools - exists only as an experimental proposal, with patchy per-implementation support. Request body size limits have no standard field. And rate limiting, which is load-bearing in more production ingresses than anyone likes to admit, has no accepted proposal whatsoever; the tracking issue is still open. Every implementation solves it its own way, through its own policy objects.

Ricardo Katz of Red Hat put the honest version of this well earlier in the year: if you’re speaking just about ingress-nginx without any annotations, Gateway API can do everything - but because of the annotations, there are a lot of things ingress-nginx can do that Gateway API cannot do yet.

Even the official migration tooling is upfront about the limit. The conversion utility reached 1.0 in March and its own documentation states it is not intended to copy annotations across, and that widely used provider-specific annotations may still not be supported.

So somebody has to go through every annotation, work out what behavior it was actually producing, decide whether that behavior was load-bearing or vestigial, and then find out whether the target supports it at all. That’s not a networking project. That’s a project to recover decisions nobody wrote down.

That’s the entire VMware situation compressed into one controller deprecation. The forcing function doesn’t add difficulty. It sends you the invoice for the difficulty you already experienced.

One size never fit

We need different ways to deploy different services, rather than assuming a Kubernetes approach is one size fits all. Stateless web services and stateful data services have genuinely different requirements - different failure modes, different consistency guarantees, different recovery paths - and pretending otherwise is how you end up with an operator maintaining an operator maintaining a database that a purpose-built service would have run correctly on day one.

I built Salt to handle the diverse and complex systems we actually deploy. The industry’s answer since then has been to flatten that diversity into a single orchestration model and absorb the mismatch as operational overhead.

The cost of coordination

I want to say something careful here, because the easy version of this point is unfair.

The CNCF has been genuinely good for this ecosystem. But the way it coordinates has costs that don’t show up in the landscape diagram. Trademark assignment is the mechanism by which project rules get enforced - which became very visible when Synadia moved to reclaim the NATS trademark, having funded by its own account roughly 97% of the server’s contributions, and CNCF responded that donated projects become community property protected from unilateral vendor control. Both positions are defensible. That’s what makes it instructive.

Buoyant’s William Morgan described the dynamic that produces these fights more bluntly than I would: an ecosystem where participants treat projects as free products to be consumed and project spaces as free helpdesks.

And then there’s the landscape itself - hundreds of tools, catalogued rather than curated. A catalog is not an architecture. Handing a platform team two hundred components and a diagram is not the same as handing them a foundation, and the work of choosing, combining, and keeping that combination healthy is harder than the diagram makes it look. That work is the tax. It has just never appeared on an invoice.

The question this reset should be asking

So here’s the test I’d apply to whatever you’re evaluating right now. Not “can it run our workloads”. Everything can run your workloads - that’s table stakes. Ask instead: when we want to leave this platform, what exactly do we have to rewrite?

If the answer is application code, you’ve encoded a vendor into your architecture and you’ll be back here in five years having this same conversation about a different logo. If the answer is a configuration file, the abstraction is real.

That test is uncomfortable to run during a migration, because the platform that scores best on it is rarely the one with the smoothest migration path from where you are today. Vendor-shaped platforms make it easy to arrive and hard to leave. That’s not an accident, and it isn’t going to change because we asked nicely.

The real question in this reset isn’t VMware versus whoever’s next. It’s whether automation can finally abstract the hypervisor layer, or whether we’re just renaming lock-in and calling it modernization.

That’s a technical question with a technical answer, and it’s the one we’re building toward at ContextOS: a platform where your application describes what it needs and the layer underneath decides how to deliver it - across bare metal, virtualized, or multi-region - without your architecture encoding any vendor’s vocabulary into itself. When the abstraction is real, a migration stops being a project. It becomes a configuration change.

If you’re mid-migration right now, you have leverage you won’t have again for years. Spend it on the layer, not the logo.

Reset the tool. Not just the vendor.

Mid-migration right now? Sign up for the ContextOS beta.

Sources

  • kubernetes.dev, Ingress NGINX Retirement: What You Need to Know, November 12, 2025; kubernetes.io, Ingress NGINX: Statement from the Kubernetes Steering and Security Response Committees, January 29, 2026 — repository archived March 24, 2026, final release v1.15.1, March 19, 2026
  • Google Open Source Blog, The End of an Era: Transitioning Away from Ingress NGINX, February 12, 2026 — recommended migration targets
  • Project Contour — annotations documentation, the specific Ingress annotations Contour reads
  • Kubernetes Gateway API — v1.5 release, April 21, 2026 (HTTPRoute CORS filter moves to Standard); v1.6 release, August 3, 2026; GEP-726 (path redirects and rewrites), GEP-1742 (timeouts), GEP-1494 (HTTP auth, experimental); rate limiting tracking issue kubernetes-sigs/gateway-api#326, still open
  • kubernetes-sigs/ingress2gateway — 1.0 release, March 20, 2026, and repository documentation (“not intended to copy annotations from Ingress to Gateway API”)
  • devclass, Kubernetes Leadership Warns of Ingress NGINX Risks but Has Also Hastened Its Deprecation, January 29, 2026 — Ricardo Katz on annotations, James Strong on the timeline
  • The New Stack, Oliver Wolf, Kubernetes Made Deploying Easy. Nobody Warned You About the Databases., July 21, 2026
  • The New Stack, Steven J. Vaughan-Nichols, Synadia Attempts To Reclaim NATS Trademark Back From CNCF, April 29, 2025 — Derek Collison on contribution share, William Morgan on ecosystem dynamics, CNCF’s response
  • Giant Swarm, The CNCF Landscape Has 230+ Tools. Choosing From It Is Where Platform Teams Get Stuck, August 3, 2026

Your AI stack,
running in minutes.

Join the closed beta. Ship your first AI app this week.