Kubernetes 1.34 landed in August 2025 with important changes in native sidecars, init containers, and the first stabilization wave for WaitForFirstConsumer in generic-volume mode. The 1.35 cycle has entered feature freeze, preliminary release notes are in the repository, and the stable three-releases-per-year pattern keeps working like clockwork. Time to look at what’s coming, what deserves real attention, and what can safely be left for another day.

Key takeaways

  • CEL-based admission policies land stable in 1.35: they replace admission webhooks with expressions evaluated inside the control plane, eliminating an external failure point.

  • DRA (Dynamic Resource Allocation) lands stable for three accelerator types: GPU, NPU, and specific accelerators with a richer API model than device plugins.

  • The new KubeletConfigSource API allows pushing kubelet configuration without node restart.

  • Two expected features stay in beta: zone-based PodAffinity/PodAntiAffinity and in-place pod resize.

  • The healthy operational pattern is staying one version behind the latest stable and reading the full release notes before planning the upgrade.

Context: where we come from in the 1.3x cycle

Since 1.30, the project has prioritized stabilization over novelty, and that shows in the quality of what ships. Kubernetes is a graduated CNCF project[1] since 2018, and that quarterly cadence has not missed a single cycle in years. Versions 1.32 and 1.33 finally completed the in-tree-to-out-of-tree CSI migration for the major providers. Version 1.34 stabilized native sidecar support, improved the pod-priority model, and added more control over how the scheduler reacts when a node loses capacity.

The cultural key is that the project has accepted that for the people who run it Kubernetes is infrastructure, not product. Big philosophy changes are rare; what dominates are incremental improvements in robustness, operator experience, and edge-case coverage. 1.35 continues that line.

The news that actually matters

CEL admission policies (stable). CEL as a validation language progressively replaces admission webhooks written in code. The original proposal, KEP-3488[2], laid the groundwork for this model.

The operational difference is significant: an admission webhook that goes down blocks the cluster; a CEL expression evaluated inside the control plane has no such risk. For small clusters where every external dependency is one more piece that can fail at 3 AM, replacing webhooks with CEL reduces incidents.

# Example ValidatingAdmissionPolicy with CEL (stable in 1.35)
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
  name: require-memory-limit
spec:
  failurePolicy: Fail
  matchConstraints:
    resourceRules:
      - apiGroups: ["apps"]
        apiVersions: ["v1"]
        operations: ["CREATE", "UPDATE"]
        resources: ["deployments"]
  validations:
    - expression: >
        object.spec.template.spec.containers.all(c,
          has(c.resources.limits) && has(c.resources.limits.memory))
      message: "Every container must define a memory limit"

This lets you express validation policies without deploying an external webhook with its own TLS certificate, its own high availability, and its own extra monitoring.

General DRA for accelerators (stable). DRA replaces the old device-plugin model with something richer and more expressive:

  • Accelerators can declare detailed capabilities, not just a count.
  • Pods can request accelerators with more granular criteria.
  • Accelerator sharing between Pods is facilitated when the hardware allows it.

The official DRA documentation[3] details the ResourceClaim and ResourceClaimTemplate model that replaces device plugins. For teams running GPU or NPU workloads, DRA is the way forward. If you don’t have accelerators, DRA is transparent.

KubeletConfigSource API. Previously, changing kubelet configuration meant rotating the node or manipulating system files and restarting the service. With the new API, the control plane can push fresh configuration to the kubelet without restart. The more nodes a team runs, the more this changes how it rolls out configuration updates.

What stays in beta

Zone-based PodAffinity/PodAntiAffinity. Promises to simplify multi-region high-availability design but has been in beta since 1.32, with edge cases under scheduler load. Not a blocker for production use if already configured, but worth waiting for 1.36 stabilization before refactoring placement policies.

In-place pod resize. The ability to change a pod’s requested CPU and memory without a restart. On paper, useful; in practice it has subtle implications with the kernel and with certain runtimes.

Still beta with an explicit feature gate. Not a priority for stable workloads; for highly dynamic workloads, validate in test environments before enabling in production.

Deprecations to watch

1.35 continues the gradual retirement of old APIs. If there are still objects with an old apiVersion (beta, v1beta1) for resources that are already stable, now is the time to migrate them. The kubectl convert command does the bulk of the work.

The kubelet and kube-apiserver flags that had been kept for compatibility also disappear in 1.35 or 1.36. If your Ansible playbooks or configuration management still pass them, now is a good time to clean up. The 1.35 release notes list them explicitly; reading them before planning the upgrade window avoids incidents.

How to plan the upgrade

The project’s predictable cadence lets you plan upgrades with confidence. The recommendation for a small or medium production cluster is to always stay one version behind the latest stable. Right now that means 1.33 in production, 1.34 in test environments, with 1.35 under observation once the release candidate ships.

This one-version lag gives time for first-hour bugs to be found and fixed in minor patches. It is not so far back as to lose official support: only the last three versions are supported.

For teams running more than one cluster, the sensible pattern is to keep one on the latest version acting as a canary. This upgrade discipline is analogous to what’s applied in PostgreSQL 18 and any critical infrastructure: test first, controlled propagation, don’t update everything at once.

The upgrade itself, when using kubeadm or a managed distribution, is reasonably straightforward. Serious upgrade problems rarely come from the control-plane binary; they come from custom resources, admission webhooks, volumes with exotic CSI, or networking with CNIs that didn’t keep up. That’s where to invest test time: not in running the upgrade itself, but in verifying the full environment works correctly afterward. For teams running Kubernetes with AI systems on top, upgrade tests must include that Wasm workloads and observability components keep working correctly with the new version.

My reading

Kubernetes 1.35 is one more incremental release in a series of incremental releases, and that’s fine. The project has reached the point where it no longer needs revolutions; it needs to polish what it has and file down the edges. CEL for admission, general DRA for accelerators, and the kubelet-configuration API are useful and cover real cases without breaking anything.

Those staying in beta deserve attention but not rushed adoption. The healthy operational pattern: upgrade with discipline, one version behind the latest, read the release notes seriously, and let others discover the first-day bugs.

Read this article in Spanish: Kubernetes 1.35: lo que ya se ve venir.

Frequently asked questions

Which Kubernetes version should I run in production when 1.35 ships?

One version behind the latest stable: right now that means 1.33 in production, 1.34 in test environments, and 1.35 under observation once the release candidate ships. That lag gives time for first-hour bugs to be fixed in minor patches without losing official support, which only covers the last three versions. With more than one cluster, keep one on the latest version as a canary.

Can I replace my admission webhooks with CEL policies in 1.35?

Yes: CEL-based admission policies land stable in 1.35 through ValidatingAdmissionPolicy in admissionregistration.k8s.io/v1. The expression is evaluated inside the control plane, so you do not need to deploy an external webhook with its own TLS certificate, high availability and extra monitoring. You also avoid the risk of a downed webhook blocking the cluster.

Where do Kubernetes upgrades usually break, and where should I spend test time?

Rarely in the control-plane binary: with kubeadm or a managed distribution the upgrade itself is reasonably straightforward. Serious problems come from custom resources, admission webhooks, volumes with exotic CSI, and CNIs that did not keep up, so invest the time in verifying the full environment works afterward. Migrate objects with an old apiVersion beforehand using kubectl convert and clean up deprecated kubelet and kube-apiserver flags.

Sources

  1. graduated CNCF project
  2. KEP-3488
  3. official DRA documentation