Kubernetes 1.36 Changes: 18 GA Promotions and Breaking Change Guide

Table of Contents

kubectl get node -o wide
# NAME   STATUS   ROLES   AGE   VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE   KERNEL-VERSION   CONTAINER-RUNTIME   ARCH
# node1  Ready    ...     ...   v1.36.0   ...           ...           ...        ...              ...                 amd64

The kubectl get node -o wide output now includes an ARCH column. This release packs far bigger changes than that — 70 enhancements in total. Codenamed ‘ハル(Haru)’, released on 2026-04-22, the release contains 18 GA promotions, 25 Beta entries, and 25 new Alpha introductions — a substantial scale.

For those running servers solo at a startup, checking Breaking Changes first is the logical order. This post covers upgrade-breaking changes first, then walks through GA, Beta, and Alpha features in sequence.

Permanent Removal of gitRepo Volumes — The Biggest Kubernetes 1.36 Breaking Change

The highest-impact Breaking Change in v1.36 is the permanent disabling of the gitRepo volume plugin (KEP-5040). It was already deprecated back in v1.11, but this time the re-enable option itself is gone. The root cause is a security vulnerability that allows arbitrary code execution with root privileges — this isn’t just a deprecation, it’s a complete removal.

Workloads that previously used gitRepo volumes must migrate through one of two paths.

MethodProsConsBest For
init containerNo extra sidecar needed, one-time clone at startupClone occurs on every Pod restartBatch jobs with low deployment frequency
git-sync sidecarContinuous sync, changes reflected immediatelyAdditional container resource consumptionReal-time config repo reflection

The init container migration pattern looks like this:

apiVersion: v1
kind: Pod
metadata:
  name: git-init-example
spec:
  initContainers:
  - name: git-clone
    image: alpine/git:latest
    command: ['git', 'clone', 'https://github.com/example/repo.git', '/workspace']
    volumeMounts:
    - name: workspace
      mountPath: /workspace
  containers:
  - name: app
    image: my-app:latest
    volumeMounts:
    - name: workspace
      mountPath: /workspace
  volumes:
  - name: workspace
    emptyDir: {}

The git-sync sidecar approach adds a k8s.gcr.io/git-sync/git-sync:v4.2.1 image as a separate container, sharing files with the app container through a shared emptyDir volume. The --period flag controls the sync interval, and specifying --depth 1 for a shallow clone can significantly reduce initialization time for large repositories.

gitRepo Volume Cannot Be Re-enabled
Starting with v1.36, gitRepo cannot be turned back on even via feature gates. This is exactly why checking for gitRepo usage with kubectl get pods -A -o json | grep gitRepo before upgrading is essential.

The background and timeline for KEP-5040 can be found in the Kubernetes v1.36 Sneak Peek — Removal Details.

Metric Renames and Portworx/Flex-volumes Removal

Less visible than the gitRepo removal, but potentially more damaging for those running monitoring pipelines — metric name changes.

Metric Renaming

  • volume_operation_total_errorsvolume_operation_errors_total
  • etcd_bookmark_countsetcd_bookmark_total

If Prometheus alert rules or Grafana dashboards reference the old metric names, alerts will silently stop firing immediately after the upgrade. The same applies to recording rules — when the metric name changes, the PromQL query itself returns empty results. Running a grep sweep before deployment is the safe approach.

# Prometheus rule 
grep -rn "volume_operation_total_errors\|etcd_bookmark_counts" \
  /etc/prometheus/rules/

Storage Plugin Cleanup

The Portworx in-tree plugin has been completely removed. Migration to the CSI driver is mandatory — in-tree provisioning of Portworx volumes is no longer possible. Flex-volumes have also been removed from kubeadm.

When transitioning to Portworx CSI, a new pxd.portworx.com StorageClass needs to be created, and existing PV/PVCs must be recreated on a CSI basis. For cases with existing data, the official Portworx migration tool (pxctl volume migrate) or snapshot-based data restoration is the way to go. If Flex-volumes are in use, the first step is scoping the impact with kubectl get pv -o json | jq '.items[] | select(.spec.flexVolume != null)'.

DRA RBAC Granularity Requirements

With DRAResourceClaimGranularStatusAuthorization now enabled by default as Beta, DRA drivers require fine-grained RBAC permissions for resourceclaims/binding and resourceclaims/driver subresources. Clusters managing GPU or other device allocation through DRA may experience device allocation failures if these subresource permissions aren’t added to the existing ClusterRole.

Pre-upgrade Breaking Change Check Order
Step 1: Search for gitRepo volume workloads → Step 2: Bulk-replace Prometheus/Grafana metric names → Step 3: Verify Portworx in-tree → CSI migration → Step 4: Add DRA ClusterRole subresource permissions. Following this order minimizes the risk of upgrade-day incidents.

The Service .spec.externalIPs field has been officially deprecated in v1.36 (KEP-5707). Full removal is scheduled for v1.43, so it won’t stop working immediately — but deprecation warning logs will start appearing.

The deprecation stems from CVE-2020-8554, a man-in-the-middle attack vulnerability. Using externalIPs, a MITM attack that hijacks external IPs from within the cluster is possible. This vulnerability is fundamentally a design-level issue, which is why the decision was made to remove the feature entirely rather than patch it.

Three alternatives are available:

AlternativeCharacteristicsLimitations
LoadBalancer ServiceAutomatic cloud LB provisioningRequires cloud environment, incurs cost
NodePortDirect exposure via node IP + portPort range limited to 30000–32767
Gateway APIUnified L7 routing managementOnly some implementations are GA

When migrating to NodePort, the Service previously exposed via externalIPs is modified as follows:

spec:
  type: ClusterIP
  externalIPs:
  - 203.0.113.10
  ports:
  - port: 80
---
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 8080
    nodePort: 30080

For on-premises environments that want to use the LoadBalancer type, MetalLB is a practical option. Registering a static IP range in MetalLB’s IPAddressPool enables automatic external IP assignment to LoadBalancer Services, maintaining similar accessibility to the externalIPs approach.

externalIPs Migration Deadline
There’s a grace period of roughly 7 minor versions until removal in v1.43, but given that a security vulnerability is the cause, early migration is recommended. The first step is identifying affected Services with kubectl get svc -A -o json | jq '.items[] | select(.spec.externalIPs != null) | .metadata.name'.

Community-authored step-by-step guides for Gateway API migration are still scarce. This area is worth monitoring as official documentation updates roll out.

4 Key GA Promotions

Out of the 18 features promoted to GA (stable) in v1.36, here are the four with the greatest practical impact.

UserNamespacesSupport

This feature maps the root user inside a container to an unprivileged user on the host. Even in a container escape attack, the attacker only has regular user privileges on the host, adding an extra layer to the security boundary. It’s particularly useful in multi-tenant clusters.

To enable User Namespaces, set hostUsers: false in the Pod spec. With this field set, UID 0 (root) inside the container maps to an unprivileged UID of 65536 or higher on the host.

spec:
  hostUsers: false
  containers:
  - name: app
    image: my-app:latest
    securityContext:
      runAsUser: 0

User Namespaces only work with OCI runtimes (runc 1.2+, crun 1.9+) and Linux kernel 5.19+. Nodes running older kernels like CentOS 7 cannot use this feature, so verifying the node OS version is a prerequisite.

MutatingAdmissionPolicy v1

CEL (Common Expression Language)-based mutation logic can now run directly within the API server. What previously required a separate Webhook server can now be replaced with inline CEL expressions.

apiVersion: admissionregistration.k8s.io/v1
kind: MutatingAdmissionPolicy
metadata:
  name: add-default-label
spec:
  matchConstraints:
    resourceRules:
    - apiGroups: [""]
      apiVersions: ["v1"]
      operations: ["CREATE"]
      resources: ["pods"]
  mutations:
  - patchType: "ApplyConfiguration"
    applyConfiguration:
      expression: >
        Object{metadata: Object.metadata{
          labels: object.metadata.labels +
            {"environment": "production"}
        }}

This example automatically adds the environment: production label when a Pod is created. Since it’s processed within the API server without a Webhook server, no separate deployment configuration is needed, and the structural issue where Webhook server failures could affect API server availability is eliminated.

NodeLogQuery

The ability to query node logs directly via kubectl has reached GA. Being able to check node-level logs without SSH access is especially helpful for reducing debugging time in solo-managed environments.

kubectl get --raw "/api/v1/nodes/node1/proxy/logs/kubelet"

kubectl get --raw "/api/v1/nodes/node1/proxy/logs/syslog"

Calling the node log API requires the kubelet’s --enable-debugging-handlers setting to be active, and the calling user needs get permissions on the nodes/proxy resource.

Fine-grained Kubelet API Authorization

The KubeletFineGrainedAuthz feature gate has been promoted to GA. Access control for the Kubelet API can now be configured at a granular level, enabling per-node permission separation.

Previously, all Kubelet API access was bundled under a single permission, making it impossible to separate node log access from Pod exec permissions. With KubeletFineGrainedAuthz GA, RBAC designs that individually permit nodes/log, nodes/metrics, nodes/exec, and similar resources are now possible — extending the principle of least privilege down to the node level.

Practical Implications of UserNamespaces and MutatingAdmissionPolicy
UserNamespaces paired with Pod Security Standards’ restricted profile creates a dual-layer container security setup. The key value of MutatingAdmissionPolicy is eliminating the structural issue where Webhook server failures could impact API server availability.

Beta and Alpha Introductions — Kubernetes 1.36 AI/ML Features

InPlacePodLevelResourcesVerticalScaling (Beta, Enabled by Default)

Pod-level in-place resizing of CPU and memory has been promoted to Beta and is now enabled by default. Previously, changing resources required restarting the Pod — now resource requests on a running Pod can be modified directly.

kubectl patch pod my-pod --subresource=resize \
  --patch '{"spec":{"containers":[{"name":"app","resources":{"requests":{"cpu":"500m"}}}]}}'

That said, practical application examples (YAML manifests) for InPlacePodLevelResourcesVerticalScaling Beta are not yet sufficiently documented. Feature gate details can be found in the Kubernetes v1.36 CHANGELOG.

FeatureStageEnabled by DefaultKey Change
InPlacePodLevelResourcesVerticalScalingBetaYesResource adjustment without Pod restart
DeviceTaintRules & TolerationsBetaYesTaint/toleration support for DRA devices
ConstrainedImpersonationBetaYesEnhanced impersonation security controls
TopologyAwareWorkloadSchedulingAlphaNoTopology-aware PodGroup scheduling
WorkloadAwarePreemptionAlphaNoAI/ML workload-aware preemption

DeviceTaintRules & Tolerations (KEP-5055)

Taints and tolerations can now be applied to DRA (Dynamic Resource Allocation) devices. In scenarios where some GPUs are faulty or need to be reserved for specific workloads, device-level scheduling control is now possible using the same mechanism as node taints.

The taint/toleration configuration uses the same effect values as node taints (NoSchedule, PreferNoSchedule, NoExecute). A typical usage pattern is reserving specific GPU models (e.g., NVIDIA A100) for high-performance training and applying PreferNoSchedule for general inference workloads. This enables workload isolation to be granularized from the node level down to the device level.

AI/ML Workload Alpha Features

TopologyAwareWorkloadScheduling supports topology-aware scheduling at the PodGroup level. Minimizing GPU-to-GPU communication latency in distributed training requires placing Pods on the same NUMA node or the same rack — this feature addresses that at the scheduler level.

WorkloadAwarePreemption is designed for long-running workloads like AI/ML training jobs. When such workloads become preemption candidates, this feature makes preemption decisions based on workload characteristics. The goal is to reduce the inefficiency of preempting Pods that are close to completing their training runs. As an Alpha feature, production adoption is premature at this stage.

kubectl ARCH Column Addition and Practical Use

The ARCH column in kubectl get node -o wide output shown at the beginning of this post is a small but practical change. It provides at-a-glance visibility into node architecture when operating multi-architecture (amd64/arm64) clusters.

kubectl get node -o wide
# NAME   STATUS   ROLES   AGE   VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE   KERNEL-VERSION   CONTAINER-RUNTIME   ARCH
# node1  Ready    ...     ...   v1.36.0   ...           ...           ...        ...              ...                 amd64

Previously, checking node architecture required kubectl describe node or kubectl get node -o jsonpath='{.status.nodeInfo.architecture}'. With it now included in the wide output by default, a separate command is no longer necessary.

This is also useful when diagnosing image compatibility issues in environments where ARM and x86 nodes coexist. Particularly when mixing Graviton instances for cost savings, it helps quickly determine whether a deployment failure is caused by an architecture mismatch.

Multi-architecture Cluster Operations Note
Combining the ARCH column with nodeSelector or nodeAffinity using the kubernetes.io/arch label enables explicit control over architecture-specific Pod placement. A common pattern is separating arm64-only and amd64-only workloads.

Kubernetes 1.36 Changes — Upgrade Checklist

For those preparing to upgrade to v1.36, working through the following checklist in order is the most efficient approach.

The key is to address the four Breaking Changes first (gitRepo removal, metric renames, Portworx in-tree removal, DRA RBAC requirements), then plan for the one Deprecation (externalIPs) within the grace period.

Among the v1.36 GA features, UserNamespacesSupport and MutatingAdmissionPolicy bring significant changes to both security and operational efficiency. InPlacePodLevelResourcesVerticalScaling, now Beta, has the potential to fundamentally change how VPA is operated. The AI/ML workload Alpha features point toward the direction of future releases.

Related topics include kubernetes mutating admission policy CEL authoring patterns, kubernetes in-place pod resize practical YAML examples, and upgrade strategies by cluster scale. With InPlacePodLevelResourcesVerticalScaling now Beta-enabled by default, in-place resize adoption is an area with direct impact on current clusters. The full enhancement list and additional Kubernetes 1.36 changes can be found in the Kubernetes v1.36 Release Official Blog Post.

Scroll to Top