← Back to list

Kubernetes 1.36 “Haru”: What’s New In This Release

Key updates in DRA, gang scheduling, user namespaces, and Kubernetes stability enhancements

Kirshi Yin in Curious Devs Corner · 2026-05-19 13:51 · 16 claps · 7.8 min read paywalled
#kubernetes #devops #technology-news #software-engineering #cloud-computing
Open on Medium ↗
Wiki topics: ☁️ · DevOps & Cloud 🔭 · Astronomy & Space

Kubernetes 1.36 “Haru”: What’s New In This Release

Key updates in DRA, gang scheduling, user namespaces, and Kubernetes stability enhancements

Kubernetes Haru 1.36 release logo.

Kubernetes Haru 1.36 release logo.

Kubernetes released “Haru” at the end of April 2026 with 70 enhancements. Among them, 18 features graduated to Stable, 25 moved to Beta, and 25 entered Alpha.

“Haru” comes from the Japanese words for spring (春), clear skies (晴), and distant horizons (遥か). Led by release lead Ryota Sawada, the release focuses less on flashy changes and more on stability, operational simplicity, and completing long-running efforts across the platform.

The release reflects three major themes:

  • Maturity and cleanup, with long-awaited features like User Namespaces for Pods reaching General Availability
  • Better operational visibility, including Node Log Query becoming Stable and reducing the need for SSH access during debugging
  • Foundations for future workloads, especially around smarter scheduling and Dynamic Resource Allocation (DRA) for AI/ML and GPU-heavy environments

In this article, we’ll explore some of the most important new enhancements.

1. DRA Becomes More Production-Ready

Kubernetes continues improving Dynamic Resource Allocation (DRA), one of the biggest API changes introduced to Kubernetes in recent years.

DRA moves beyond the traditional resources.requests and resources.limits model and introduces a more flexible way to allocate specialized hardware such as GPUs, FPGAs, high-performance network cards, and custom AI accelerators.

The new release promotes several important DRA features:

  • DRA Extended Resources → Beta (enabled by default): DRA drivers can expose hardware as standard Kubernetes extended resources. This improves compatibility with existing quota management and scheduler behavior.
  • DRA Prioritized List → GA: Workloads can define preferred hardware options in order. For example, a workload can request an H100 GPU first and fall back to a T4 if needed. The scheduler selects the best available option.
  • DRA Admin Access → GA: Cluster administrators can grant privileged access to specific devices for trusted workloads without exposing the entire node.
  • Device Taints & Tolerations → Beta: Similar to node taints, but applied at the device level. For example, if a GPU becomes unhealthy, Kubernetes can mark only that device as NoSchedule instead of affecting the whole node.
  • Device Binding Conditions → Beta: DRA drivers can report whether device allocation succeeded, failed, or is still pending. This helps the scheduler make smarter retry decisions.

Here’s a simple example of a DRA ResourceClaim requesting a GPU with at least 16 GiB of memory:

apiVersion: resource.k8s.io/v1beta2
kind: ResourceClaim
metadata:
  name: gpu-claim
spec:
  devices:
    requests:
    - name: gpu
      deviceClassName: nvidia.com/gpu
      selectors:
      - cel:
          expression: device.attributes["memory"].isGreaterThan(quantity("16Gi"))

And inside the Pod spec:

spec:
  resourceClaims:
  - name: gpu-claim
    resourceClaimName: gpu-claim

  containers:
  - name: trainer
    resources:
      claims:
      - name: gpu-claim

Before DRA, GPU scheduling mostly relied on device plugins or vendor-specific tooling. DRA introduces a native Kubernetes API for managing specialized hardware in a more standardized and flexible way.

2. Gang Scheduling Arrives in Alpha

One long-standing limitation in Kubernetes has been the lack of native gang scheduling.

This becomes a problem for distributed ML training, large batch jobs, and HPC workloads where a group of pods must start together. If only part of the workload gets scheduled, the entire job can stall or fail.

Until now, many teams have relied on external schedulers like Volcano or Apache YuniKorn to solve this problem.

Kubernetes 1.36 introduces an alpha implementation through the new scheduling.k8s.io/v1alpha2 API with two new resources:

  • PodGroup
  • Workload

A PodGroup defines a set of pods that must be scheduled together. The scheduler evaluates the entire group in a single scheduling cycle. If Kubernetes cannot place all required pods, none of them start.

Here’s a simplified example:

apiVersion: scheduling.k8s.io/v1alpha2
kind: PodGroup
metadata:
  name: distributed-training-job
spec:
  podGroupTemplateRef:
    workload:
      workloadName: training-workload
      podGroupTemplateName: worker
  schedulingPolicy:
    gang:
      minCount: 8
---
apiVersion: scheduling.k8s.io/v1alpha2
kind: Workload
metadata:
  name: training-workload
spec:
  podGroupTemplates:
  - name: worker
    schedulingPolicy:
      gang:
        minCount: 4

To test this feature, you must enable the GenericWorkload feature gate.

You can inspect PodGroups with:

kubectl get podgroups

Kubernetes 1.36 also introduces topology-aware workload scheduling improvements through the TopologyAwareWorkloadScheduling feature gate.

This adds new scheduler extension points that help Kubernetes make smarter placement decisions for grouped workloads. For example, you can:

  • place all training pods inside the same availability zone for lower latency
  • spread workloads across multiple racks for better resilience
  • optimize placement for GPU-heavy clusters

Another useful addition is the new PodGroupScheduled status condition. It shows whether the full group was scheduled successfully or remains unschedulable, which makes troubleshooting and operator automation much easier.

3. User Namespaces Reach General Availability

Kubernetes finally graduates User Namespaces for Pods to General Availability.

This feature improves container isolation by changing how user IDs inside a container map to the host system.

Without user namespaces, a container running as UID 0 (root) also maps to UID 0 on the host. If an attacker manages to escape the container, they could potentially gain root access on the node.

User namespaces change this behavior. A process that appears as root inside the container maps to an unprivileged user ID on the host instead.

For example:

  • container UID: 0
  • host UID: 100000

So even if a container escape happens, the process does not gain root privileges on the node.

You can enable this behavior per pod:

spec:
  hostUsers: false

  containers:
  - name: app
    image: myapp:latest
    securityContext:
      runAsUser: 0

Setting hostUsers: false tells the kubelet to create a separate user namespace for the pod.

Inside the container, the application still behaves as if it runs as root, which helps compatibility with existing software. On the host, the kernel maps that user to an unprivileged ID.

This is a meaningful security improvement for multi-tenant clusters, CI/CD runners, and anywhere you run third-party or untrusted workloads. The feature requires a Linux kernel ≥ 5.19 and a CRI runtime that supports it (containerd 1.7+ or CRI-O 1.25+).

4. ImageVolume Is Stable

Instead of running an image as a container, Kubernetes now lets you mount an OCI image directly as a volume. The kubelet pulls the image, unpacks it, and exposes it as a read-only filesystem inside the pod.

This works well when you want to separate application code from large static assets. A common case shows up in ML workloads. You can package model weights as an OCI image and mount them into an inference container without copying files around at runtime.

spec:
  volumes:
  - name: model-weights
    image:
      reference: registry.example.com/models/llama-3:latest
      pullPolicy: IfNotPresent
  containers:
  - name: inference-server
    image: myserver:latest
    volumeMounts:
    - name: model-weights
      mountPath: /models
      readOnly: true

Here, the model image gets pulled like any other container image, but Kubernetes does not run it. It just extracts the filesystem content and mounts it into /models.

This removes a few common patterns. You no longer need init containers that copy data into shared volumes. You also avoid sidecars that only exist to sync files or fetch artifacts.

It also improves how you manage versioned assets. Since everything lives in an OCI image, you get registry-based versioning, caching, and content-addressable storage without extra tooling.

The feature works especially well for AI/ML workloads where model files can be large and frequently updated.

5. In-Place Pod Vertical Scaling

Kubernetes improves in-place vertical scaling for pods by tightening how it handles invalid resize requests.

Before this change, you could request a resize that exceeded what the node could actually provide. Kubernetes would accept the update, but the pod would later end up in an Infeasible state. You only discovered the problem after checking pod status, which made debugging slow and confusing.

Now, Kubernetes rejects those requests earlier during admission if the node cannot satisfy them. That means you get immediate feedback instead of waiting for a failed scheduling outcome.

Runtime integrations also get more control in this release. The CRI and NRI layers can block a resize if the runtime detects a safety issue. This is important for environments where resource management does not fully sit inside Kubernetes, such as hypervisors or specialized sandbox runtimes.

A pod with CPU and memory requests still looks like this:

spec:
  containers:
  - name: app
    resources:
      requests:
        memory: "512Mi"
        cpu: "500m"
      limits:
        memory: "1Gi"
        cpu: "1"

To change resources while the pod runs, you patch it using the resize subresource:

kubectl patch pod myapp --subresource resize --type merge \
  -p '{"spec":{"containers":[{"name":"app","resources":{"requests":{"cpu":"750m"}}}]}}'

This feature is still in beta.

6. MutatingAdmissionPolicy Becomes GA

Before this feature, most mutation logic lived in admission webhooks, which meant running and maintaining extra services. Now Kubernetes can apply those changes directly inside the API server using CEL expressions.

You can use it to set defaults, inject labels, or adjust resource specs during object creation.

Here’s a simple example that sets a default CPU limit if a container does not define one:

apiVersion: admissionregistration.k8s.io/v1
kind: MutatingAdmissionPolicy
metadata:
  name: set-default-resource-limits
spec:
  matchConstraints:
    resourceRules:
    - apiGroups: [""]
      apiVersions: ["v1"]
      resources: ["pods"]
      operations: ["CREATE"]
  mutations:
  - patchType: ApplyConfiguration
    applyConfiguration:
      expression: |
        Object{
          spec: Object.spec{
            containers: object.spec.containers.map(c, Object.spec.containers{
              resources: Object.spec.containers.resources{
                limits: c.resources.limits.orValue({}) + (has(c.resources.limits.cpu) ? {} : {"cpu": "500m"})
              }
            })
          }
        }

This runs inside the API server, so you avoid external webhook latency, scaling issues, and extra infrastructure.

When you combine it with ValidatingAdmissionPolicy, you get a full admission control setup that stays completely inside Kubernetes and removes the need for custom webhook services.

7. Manifest-Based Admission Control + Constrained Impersonation

Kubernetes adds two important improvements for cluster security and reliability.

Manifest-Based Admission Control (alpha) helps when etcd is down or unreachable. In older setups, webhook-based admission could fail or behave unpredictably during outages. Now Kubernetes can load admission webhooks and CEL policies from files on disk at API server startup.

That means admission rules still run even if etcd is unavailable, and they stay active during downtime.

# AdmissionConfiguration with staticManifestsDir
apiVersion: apiserver.config.k8s.io/v1
kind: AdmissionConfiguration
staticManifestsDir: /etc/kubernetes/admission-manifests

This makes the API server more self-sufficient at startup and reduces dependency on external components for basic policy enforcement.

The second change is Constrained Impersonation, now in beta and enabled by default.

Impersonation lets one user or service account act as another identity. That’s powerful, but it can hide who actually performed an action. This release adds better tracking and audit visibility so you can see when impersonation happens and under what conditions.

The action can now be tracked via the apiserver.latency.k8s.io/impersonation audit annotation. Four new metrics land alongside this:

apiserver_impersonation_attempts_total{mode, decision}
apiserver_impersonation_attempts_duration_seconds{mode, decision}
apiserver_impersonation_authorization_attempts_total{mode, decision}
apiserver_impersonation_authorization_attempts_duration_seconds{mode, decision}

Together, these changes improve reliability during outages and make identity behavior easier to audit.

8. Small Improvements for Daily Work

A few smaller improvements change how the system feels in daily use.

  • HPA Scale-to-Zero improvements — the HPAScaleToZero feature gate gets better handling for scaling to and from zero replicas, making serverless-style patterns on Kubernetes more reliable.
  • **kubectl wait now supports multiple conditions** — you can wait for a pod to be both Ready and have a custom condition True in a single command:
kubectl wait pod/mypod --for=condition=Ready --for=condition=initialized=True --timeout=60s
  • **kubectl diff --show-secret** — secrets are no longer redacted in diff output when you explicitly pass this flag. Debugging is now easier without having to separately decode secrets.
  • StrictIPCIDRValidation is now on by default — API fields no longer accept malformed CIDR values like 010.000.000.005 or ambiguous masks like 192.168.0.5/24.
  • DaemonSet and Job stale cache protection — both controllers now skip syncing when their cache is stale, preventing the spurious duplicate pod creation that occasionally occurred in clusters under high load.

Conclusion

Kubernetes 1.36 is a maturity release. In this article, you saw the most important improvements and how to use them.

You can always dive into the full CHANGELOG for the rest of the changes.

If you’re newer to Kubernetes and some of this felt too unfamiliar, it’s worth understanding the fundamentals first. I cover all the basics in my ebook **Master Kubernetes from Scratch**, which walks through the core architecture and operational concepts.

Thanks for reading, see you in the next one!

You might also like:


메타데이터
post_id
042ec27036ca
slug
kubernetes-1-36-haru-release-042ec27036ca
url
https://medium.com/curious-devs-corner/kubernetes-1-36-haru-release-042ec27036ca
canonical_url
https://medium.com/curious-devs-corner/kubernetes-1-36-haru-release-042ec27036ca
author_url
https://medium.com/@kirshiyin
status
ok
fetched_at
2026-06-14 11:28:49