Kubernetes
11 min readJuly 7, 2026Updated August 19, 2026

Upgrading to Kubernetes 1.36: What Breaks and What to Check First

Part ofKubernetes
AJ
Ajeet Yadav
Platform & Cloud Engineer
Upgrading to Kubernetes 1.36: What Breaks and What to Check First

Quick answer

Kubernetes 1.36 'Haru' permanently disables gitRepo volumes and deprecates Service externalIPs, while kube-proxy's IPVS mode goes on a deprecation clock that ends in v1.43 — and it lands just as ingress-nginx goes unmaintained. Here's the pre-upgrade audit, ordered by blast radius, with the exact commands to find out if you're affected.

11 min read · Kubernetes

Kubernetes 1.36 "Haru" shipped upstream on April 22, 2026, and the managed providers are rolling it out now — which means this is the window where upgrade planning actually happens. Most 1.36 coverage leads with the shiny GA features (user namespaces, mutating admission policies, OCI volumes). This post is about the other list: the things that stop working.

The headline that too many recaps bury: kube-proxy's IPVS mode is on the way out. It is deprecated, not removed — but the schedule is now fixed: a KubeProxyIPVS gate arrives in v1.37, flips to default-off in v1.40, and the implementation is deleted in v1.43. Nothing breaks on the 1.36 upgrade itself, which is exactly why fleets defer the migration until it becomes an emergency. That alone justifies a pre-upgrade audit, so here's the full one, ordered by blast radius.

Run these four commands before you schedule anything:

bash
1# 1. Are you running IPVS? (deprecated — plan a migration to nftables/iptables)
2kubectl -n kube-system get configmap kube-proxy -o yaml | grep -A1 "mode:"
3
4# 2. Any pods still using gitRepo volumes?
5kubectl get pods -A -o json | jq -r '.items[] | select(.spec.volumes[]?.gitRepo) | "\(.metadata.namespace)/\(.metadata.name)"'
6
7# 3. Any Services using externalIPs?
8kubectl get services -A -o json | jq -r '.items[] | select(.spec.externalIPs) | "\(.metadata.namespace)/\(.metadata.name)"'
9
10# 4. Are you running ingress-nginx? (retired March 2026 — separate from 1.36, same window)
11kubectl get pods -A -l app.kubernetes.io/name=ingress-nginx -o wide

If all four come back empty, your 1.36 upgrade is boring — the best kind. If not, here's what each hit means.

1. kube-proxy IPVS mode is deprecated (removal in v1.43)

IPVS was deprecated in 1.35 under KEP-5495 and still works in 1.36 — kube-proxy simply logs a warning on startup. The published schedule: the KubeProxyIPVS feature gate arrives in v1.37 defaulting on, flips to default-off in v1.40, and pkg/proxy/ipvs is deleted in v1.43. If the audit shows mode: ipvs, nothing breaks at 1.36, but this is the release to put the migration on the roadmap.

You have two migration targets:

  • nftables — the intended successor, GA since 1.33. It's what the IPVS deprecation notes point you at, and it outperforms iptables mode at scale (no full-table rewrites on every Service change). This is the right choice if you moved to IPVS for performance in the first place.
  • iptables — the long-standing default, still fully supported. Fine for small and medium clusters where IPVS was cargo-culted rather than needed.

The migration is a kube-proxy ConfigMap change (mode: nftables) plus a rolling restart of the kube-proxy DaemonSet — but do it as its own change window before the version upgrade, not bundled with it. Two things to verify in staging first: your nodes' kernels ship a recent nftables (any current distro kernel is fine; very old node images may not be), and anything that inspects iptables rules directly — old network policy tooling, homegrown debug scripts — since nftables mode doesn't populate the chains they expect.

Managed-cluster note: EKS, GKE, and AKS default to iptables (or their own dataplanes — Cilium, Calico eBPF replace kube-proxy entirely and don't care). IPVS in the wild is mostly self-managed kubeadm-era clusters that chose it around 2019-2021 for scale. That's exactly the fleet least likely to have read the 1.35 deprecation notice.

2. gitRepo volumes are permanently disabled

The gitRepo volume type has been deprecated since v1.11, and the kubelet has refused it by default since 1.33 — with a GitRepoVolumeDriver feature gate as a temporary opt-out. In 1.36 that opt-out window closes: the gate is locked off, so the plugin is permanently disabled and cannot be re-enabled (the dead code itself is scheduled for removal in 1.39). The API server still accepts pods that declare a gitRepo volume — they schedule, then the kubelet errors and the pod never starts. That failure mode is nastier than a validation error, because nothing breaks until the pod restarts on a 1.36 node, possibly weeks after the upgrade.

The reason it's unrecoverable: the plugin ran git as root on the node, and crafted repos could achieve code execution there. Migration is straightforward — an init container running git clone into an emptyDir, or a git-sync sidecar if you need the checkout to track a branch continuously. Same result, no root git on the host.

3. Service externalIPs is deprecated (removal planned for 1.43)

Nothing breaks in 1.36 — you get API deprecation warnings, and the field keeps working. But the direction is final: .spec.externalIPs is the API behind CVE-2020-8554, which lets any user who can create Services intercept traffic to arbitrary IPs, because the field has no validation and no ownership model — two Services can claim the same IP and nothing stops them.

With removal slated for 1.43, you have roughly two years — which is exactly why this goes on the checklist now, while you're already auditing. Migration paths, in order of preference: a LoadBalancer Service (cloud or MetalLB on-prem) where IP assignment is controller-owned rather than user-claimed, Gateway API for HTTP(S) traffic, or NodePort for quick-and-dirty exposure. And if the audit shows nobody uses the field, turn on the DenyServiceExternalIPs admission controller (available since 1.21) and close the CVE today instead of waiting for 1.43 to do it for you.

Kubernetes Production Readiness Checklist

The pre-launch checks we run before calling a cluster production-ready — probes, resources, RBAC, upgrades, and backups. Plain Markdown you can commit to your repo.

Free. Instant download. You'll also get the occasional deep-dive from the newsletter — unsubscribe anytime.

4. Not in the release notes: ingress-nginx is unmaintained

This isn't a 1.36 change, but it hits the same upgrade window so it belongs on the same checklist: the ingress-nginx project retired in March 2026. No more releases, no more security patches — for the most widely deployed ingress controller in the ecosystem. Your existing deployment keeps running; it just accumulates unpatched CVEs from here on, and an internet-facing proxy is the worst possible place for that.

If you're on it, the 1.36 upgrade is the natural moment to plan the exit: Gateway API with a maintained implementation (Cilium, Envoy Gateway, or your cloud's controller) is the strategic destination, and most ingress-nginx annotations have documented equivalents. Treat it as its own project — don't bundle a traffic-plane migration into a version upgrade — but scope it now, because "we'll deal with it later" is how unmaintained proxies stay in production for years.

5. New defaults worth knowing (not breaking, but check)

  • HPA scale-to-zero improved, but still gated. HPAScaleToZero has been alpha since v1.16; 1.36 fixes long-standing bugs in scaling to and from zero, but the gate is still off by default. It graduates to beta and on by default in v1.37, so minReplicas: 0 becomes valid for most clusters one release from now, not this one. Opt-in, so nothing changes until someone sets it; make sure that someone isn't surprised the API no longer rejects it.
  • Node log query is GA and locked on. kubectl get --raw "/api/v1/nodes/<node>/proxy/logs/?query=kubelet" now works everywhere — genuinely useful for debugging without node SSH, but worth knowing your kubelet API serves logs. Which is also why...
  • Fine-grained kubelet API authorization is GA. You can now RBAC the kubelet's sub-resources (nodes/proxy, logs, stats) individually instead of the old all-or-nothing nodes/proxy grant. If your monitoring stack has a broad kubelet grant, 1.36 is the release where you can narrow it.
  • User namespaces are GA. The biggest security win of the release for multi-tenant clusters — pods run as root in the container while mapped to an unprivileged UID on the host. It has kernel version requirements on your nodes; I've covered how user namespaces actually work in a separate deep dive.
  • Mutating admission policies are GA. CEL-based, in-process mutation that replaces a whole class of mutating webhooks. If you run webhooks or Gatekeeper today, see the admission webhooks and OPA Gatekeeper post for the landscape this reshapes.

The upgrade itself: nothing new, same discipline

None of the above changes the mechanics of a safe upgrade — control plane first, one minor version at a time, node pools after, with the kubelet allowed to trail the API server by up to three minor versions. I've written up the full zero-downtime process — PodDisruptionBudgets, surge node pools, drain ordering, rollback strategy — in the Kubernetes upgrade strategy guide; everything there applies to 1.36 unchanged. What 1.36 adds is simply more homework before that process starts: run the audit, clear the four findings, then upgrade like any other release.

Quick reference

ChangeStatus in 1.36Action
kube-proxy IPVS modeDeprecated (default-off v1.40, removed v1.43)Plan a migration to nftables (or iptables); nothing breaks in 1.36
gitRepo volumesPermanently disabledReplace with init container or git-sync sidecar
Service externalIPsDeprecated (removal ~1.43)Migrate to LoadBalancer/Gateway API; enable DenyServiceExternalIPs if unused
ingress-nginxRetired (Mar 2026, not a 1.36 change)Plan Gateway API migration as its own project
HPA scale-to-zeroStill alpha, off by default (beta + on by default in v1.37)Awareness only; minReplicas: 0 needs the feature gate until 1.37
Kubelet log query / fine-grained authzGAOptionally narrow kubelet RBAC grants

Frequently Asked Questions

Do I need to migrate off IPVS before upgrading to 1.36?

No — IPVS still works in 1.36 and beyond; you will just see a deprecation warning on kube-proxy startup. The hard dates are v1.40 (disabled unless you set the KubeProxyIPVS gate) and v1.43 (implementation removed). When you do migrate, make it its own change window. Switch the mode to nftables (or iptables) on your current version, roll the DaemonSet, soak it, and only then start the version upgrade. Bundling a dataplane change into an upgrade window means that when something breaks, you can't tell which change did it.

Will my Services using externalIPs stop working when I upgrade to 1.36?

No. In 1.36 the field is deprecated, not removed — you'll see API warnings, and traffic keeps flowing. Removal is planned for around v1.43, so you have multiple release cycles. The reason to act sooner is security, not breakage: the field is the vector for CVE-2020-8554, and if nothing in your cluster legitimately uses it, the DenyServiceExternalIPs admission controller closes that hole today.

Is iptables mode being removed too?

No. iptables mode remains supported and is still the default. nftables is the designated successor and where the performance work is happening, so new large clusters should prefer it — but there is no announced timeline for removing iptables mode, and removing a default that most of the ecosystem runs on would be a multi-year process. IPVS was removed because nftables covers its reason to exist (performance at scale) without its maintenance burden.

Can I keep running ingress-nginx after its retirement?

Technically yes — retirement means no new releases, not a kill switch. Practically, you're running an internet-facing proxy that will never receive another security patch, and ingress controllers parse untrusted traffic by definition. Treat it like any other unmaintained dependency on your attack surface: contain it short-term, and put a migration to a maintained Gateway API implementation on this quarter's roadmap rather than next year's.

Does 1.36 change the supported version skew or upgrade path?

No — the rules are unchanged: upgrade one minor version at a time, control plane before nodes, and kubelets may lag the API server by up to three minor versions. So a fleet on 1.34 goes 1.34 → 1.35 → 1.36, and node pools on 1.34 can temporarily run under a 1.36 control plane while you roll them. The zero-downtime upgrade guide covers the sequencing in detail.

See also


Planning a fleet-wide Kubernetes upgrade and want a second pair of eyes on the sequencing? Get in touch.

Official References

Was this article helpful?

Be the first to rate this article

Related Topics

Kubernetes
Upgrades
kube-proxy
Networking
Security
Release Notes

Found this useful? Share it.

Practice this

Related tools

Read Next