Updated: 2026-07-12

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 several 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.

  • Several 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. 1.32 and 1.33 finally completed the in-tree-to-out-of-tree CSI migration for the major providers. 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 most users 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 several cycles ago. 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. For teams with many nodes, this significantly changes how configuration updates are operated.

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, very 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 have been stable for several cycles, now is the time to migrate them. The kubectl convert command covers most cases.

Several 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, but not so far back as to lose official support (only the last three versions are supported).

For teams running several clusters, 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.

Sources

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