Aggregated Discovery during API server upgrades

Aggregated Discovery during API server upgrades

Kubernetes Mixed Version Proxy is moving to Beta in 1.36 and is enabled by default through the UnknownVersionInteroperabilityProxy feature gate. The point is narrow and practical: during API server upgrades, a request that lands on an older API server should not get a false 404 if a newer peer can serve the resource.

That false 404 is not a cosmetic issue. A cluster-wide client can interpret it as absence, then act on that assumption. Garbage collection can make the wrong choice. Namespace deletion can stall because a resource appears to have vanished rather than simply moved out of reach of the local server.

Why mixed-version control planes return the wrong answer

An older API server cannot serve every resource in a mixed-version control plane. During an upgrade, that server may still receive requests for APIs that only a newer peer understands. Without extra handling, the local server answers from its own limited view and reports 404 Not Found.

That answer is wrong, but it is wrong in a way that looks valid. Nothing crashes. The request completes. The client just receives a lie with a status code attached.

The old API server cannot serve every resource itself

The failure shows up when the local API server is behind the cluster version that introduced a resource or changed its discovery shape. The server can still handle many requests, but not all of them. In an HA control plane, that is normal during rolling upgrades.

Mixed Version Proxy lets the older server forward the request to a capable peer instead of inventing a local truth. The proxied request carries the x-kubernetes-peer-proxied header, which marks the hop and keeps the behaviour explicit.

Discovery is what stops a 404 from becoming a lie

Proxying requests only works if the server can identify a peer that actually knows about the resource. Kubernetes 1.36 replaces the older StorageVersion API based capability lookup with Aggregated Discovery. That shift matters because discovery now has to cover more than a narrow set of storage-backed resources.

Aggregated Discovery gives API servers a shared view of what peers serve. That lets the local server map an incoming request to a capable peer instead of guessing or falling back to a hard 404.

Peer discovery, proxying, and the trust chain between API servers

The trust model is blunt. One API server is allowed to ask another API server for help, but only inside a bounded and verified peer relationship. If that trust chain is broken, proxying falls apart and the cluster drops back to the local view.

That is not graceful in the sentimental sense, but it is predictable. A failed peer lookup is better than a fake absence.

Aggregated Discovery replaces the old capability lookup

The older approach used the StorageVersion API to work out peer capability. Kubernetes 1.36 moves that job to Aggregated Discovery and adds peer-aggregated discovery. API servers merge local and peer discovery data into a single discovery document.

The merge is sorted deterministically, so the order does not depend on which server answered first. Clients get a stable view unless they ask not to see peer data.

peer-ca-file, peer-advertise-ip, and peer-advertise-port set the boundary

Peer communication needs TLS verification. The --peer-ca-file flag provides the CA used to verify peer certificates. Without it, proxying fails because the server cannot trust the peer connection.

Peer reachability is set with --peer-advertise-ip and --peer-advertise-port. If those are not set, the peer address falls back to --advertise-address or --bind-address. That works until the control plane is behind addresses that are useful locally and useless to other API servers, which is a fairly ordinary way for configuration to disappoint people.

--peer-ca-file is a required flag for secure peer traffic. The kubeadm path is direct enough:

yaml
apiVersion: kubeadm.k8s.io/v1beta4
kind: ClusterConfiguration
apiServer:
extraArgs:
peer-ca-file: /etc/kubernetes/pki/ca.crt

Without that CA, discovery falls back to only the local APIs. Proxying then fails the way TLS usually fails, with everybody looking at the wrong layer for a while.

profile=nopeer keeps the local view on purpose

Aggregated Discovery does not force the peer view on every client. A client can request the local-only document with:

http
Accept: application/json;g=apidiscovery.k8s.io;v=v2;as=APIGroupDiscoveryList;profile=nopeer

That profile keeps peer data out of the response. It is useful when a client wants only the API server it connected to, not the merged cluster view. The default behaviour is the opposite: local and peer discovery data are combined into the unified document.

That distinction matters during API server upgrades. Some clients want the full picture. Others want a narrow one and do not care that the cluster is mid-change. Kubernetes now gives both views, which is the sensible answer for once.

Related posts

Agentic AI still needs domain judgement

Agentic AI can write the thing, but it still cannot tell you whether the thing is right. That is where domain expertise matters, because a clean config or neat bit of glue logic can still be wrong in...

Weekly Tech Digest | 06 Jul 2026

Stay updated with the latest in tech! This digest covers AI ethics, auto industry shifts, and the impact of politics on technology, exploring today's pressing issues.

wolfCOSE zero-allocation parsing in embedded C

wolfCOSE looks sensible only if you care about what your firmware actually has to carry. I like that, because on small targets the wrong crypto feature can cost more than the message itself, and there...