The first time you put an agent on Kubernetes, the temptation is obvious and wrong. You have a pod, the pod has a Python process, the process holds the OpenAI key, the MCP client, the retry logic, the per-tenant budget check. It works. Then you deploy a second agent, and a third, and you are copy-pasting the same connection plumbing into every Deployment — different keys, drifting timeouts, no shared view of what any of them is actually calling.
Kubernetes has seen this movie before. A decade ago every service embedded its own mTLS, retries, and traffic-splitting until the service mesh pulled that logic out of the application and into a sidecar data plane. The application went back to declaring intent — "route me to payments" — and the mesh owned the network. The agent ecosystem is now re-deriving exactly that split, one project on each side of the line.
The control plane: agents as objects#
kagent's one real idea is that an agent should be a Kubernetes object, not a container that happens to hold an agent. You write an Agent resource — instructions, a model reference, a set of ToolServer resources — and a controller reconciles it the way it reconciles a Deployment. That sounds like paperwork until you notice what you get for free: rollbacks, kubectl get agents, RBAC on who can change a prompt, and tools defined once as shared resources instead of re-wired per pod. It was accepted into the CNCF Sandbox in May 2025 after Solo.io contributed it, and its engine runs agents on Google's ADK rather than reinventing the loop.
That layering matters: kagent isn't a competing agent framework so much as the scheduler for one. The loop belongs to ADK; the lifecycle belongs to Kubernetes.
The data plane: a mesh for tool traffic#
agentgateway is the other half. Instead of every agent holding its own MCP clients and provider keys, tool and model calls exit through a proxy that federates MCP servers, speaks A2A between agents, and presents one OpenAI-compatible endpoint in front of Anthropic, Gemini, Bedrock, and the rest — with the auth, rate limits, budgets, and failover living there. It is written in Rust for the same reason Envoy is written in C++: a data plane sits in the hot path of every request, so its overhead is your overhead.
Put the two together and the shape is familiar. kagent is your control plane — declarative agents reconciled into existence. agentgateway is your data plane — the network those agents ride on. Neither one is "the framework"; the framework (ADK, or whatever you like) is just the workload in the middle.
The alternative bet#
Not everyone accepts the mesh framing. Dapr Agents makes a different wager: model each agent as a virtual actor, lean on Dapr's existing distributed runtime for state and messaging, and let scale-to-zero pack thousands of cheap agents onto a cluster. Here connectivity and durability come from Dapr's building blocks rather than a dedicated gateway. It is the right call if you are already a Dapr shop and think in actors; it is a lot of new substrate if you are not.
The decision that actually matters#
The framework wars — LangGraph vs CrewAI vs ADK — are loud, but on Kubernetes they are not the load-bearing choice. The load-bearing choice is which layer owns connectivity. If the answer is "the agent," you will rebuild service-mesh problems, badly, inside your prompt loop. If the answer is "a data plane," your agents get smaller and your cluster gets a single place to see and govern every tool and model call.
Kubernetes made that call years ago for microservices. Agents are just the newest workload to learn that the network is not the application's job.



