Table of Contents
- Permanent Removal of gitRepo Volumes — The Biggest Kubernetes 1.36 Breaking Change
- Metric Renames and Portworx/Flex-volumes Removal
- Official Deprecation of externalIPs — Security-Related Kubernetes 1.36 Change
- 4 Key GA Promotions
- Beta and Alpha Introductions — Kubernetes 1.36 AI/ML Features
- kubectl ARCH Column Addition and Practical Use
- Kubernetes 1.36 Changes — Upgrade Checklist
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.
| Method | Pros | Cons | Best For |
|---|---|---|---|
| init container | No extra sidecar needed, one-time clone at startup | Clone occurs on every Pod restart | Batch jobs with low deployment frequency |
| git-sync sidecar | Continuous sync, changes reflected immediately | Additional container resource consumption | Real-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.
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_errors→volume_operation_errors_totaletcd_bookmark_counts→etcd_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.
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.
Official Deprecation of externalIPs — Security-Related Kubernetes 1.36 Change
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:
| Alternative | Characteristics | Limitations |
|---|---|---|
| LoadBalancer Service | Automatic cloud LB provisioning | Requires cloud environment, incurs cost |
| NodePort | Direct exposure via node IP + port | Port range limited to 30000–32767 |
| Gateway API | Unified L7 routing management | Only 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.
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.
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.
| Feature | Stage | Enabled by Default | Key Change |
|---|---|---|---|
| InPlacePodLevelResourcesVerticalScaling | Beta | Yes | Resource adjustment without Pod restart |
| DeviceTaintRules & Tolerations | Beta | Yes | Taint/toleration support for DRA devices |
| ConstrainedImpersonation | Beta | Yes | Enhanced impersonation security controls |
| TopologyAwareWorkloadScheduling | Alpha | No | Topology-aware PodGroup scheduling |
| WorkloadAwarePreemption | Alpha | No | AI/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.
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.
Related Posts
- GPT-5 Release: 7 Key Changes — Complete Model Lineup and SDK Breaking Change Guide – Covers the model lineup from GPT-5 to GPT-5.5, context windows, and SDK breaking changes with version comparison tables…
- Gmail Gemini Data Security — Complete Guide to Personal vs. Workspace Policy Differences – Gemini integrated into Gmail has completely different data handling policies depending on account type. Personal accounts vs. Workspace, Gemini API…