<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Kubernetes Blog</title>
    <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/</link>
    <description>The Kubernetes blog is used by the project to communicate new features, community reports, and any news that might be relevant to the Kubernetes community.</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <image>
      <url>https://raw.githubusercontent.com/kubernetes/kubernetes/master/logo/logo.png</url>
      <title>The Kubernetes project logo</title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/</link>
    </image>
    
    <atom:link href="https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/feed.xml" rel="self" type="application/rss+xml" />
    
    
    <item>
      <title>Kubernetes v1.37: KubeletInUserNamespace (aka Rootless mode) Graduates to Beta</title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/09/04/kubernetes-v1-37-rootless-beta/</link>
      <pubDate>Fri, 04 Sep 2026 10:30:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/09/04/kubernetes-v1-37-rootless-beta/</guid>
      <description>
        
        
        &lt;p&gt;Kubernetes v1.37 promotes the &lt;code&gt;KubeletInUserNamespace&lt;/code&gt; feature gate to beta.
With this feature enabled, all of the node components (kubelet, CRI and OCI runtimes,
CNI plugins, and kube-proxy) can run as a non-root user on the host, using a
&lt;a href=&#34;https://man7.org/linux/man-pages/man7/user_namespaces.7.html&#34;&gt;Linux user namespace&lt;/a&gt;.
This technique is also known as &lt;em&gt;rootless mode&lt;/em&gt;.
The work started as an experiment in 2018, and was merged into Kubernetes v1.22 (2021)
as an alpha feature (Kubernetes Enhancement Proposal &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/2033/&#34;&gt;KEP-2033&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;This feature should not be confused with &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/workloads/pods/user-namespaces/&#34;&gt;user namespaces for pods&lt;/a&gt;
(&lt;code&gt;hostUsers: false&lt;/code&gt; with the &lt;code&gt;UserNamespacesSupport&lt;/code&gt; feature gate, GA since v1.36),
which puts pods in user namespaces but still runs the node components as root.
These two features do not conflict.
Moreover, they can be combined to nest Kubernetes inside Kubernetes without resorting to
the full &lt;code&gt;privileged: true&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;why-run-the-node-components-in-a-user-namespace&#34;&gt;Why run the node components in a user namespace?&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#why-run-the-node-components-in-a-user-namespace&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Because the node components have historically had container-breakout vulnerabilities
that could compromise full root privileges on the host.&lt;/p&gt;
&lt;p&gt;Examples of such vulnerabilities include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://nvd.nist.gov/vuln/detail/CVE-2022-0811&#34;&gt;CVE-2022-0811&lt;/a&gt;
(&amp;quot;cr8escape&amp;quot;): CRI-O could be tricked into setting arbitrary sysctls, such as
&lt;code&gt;kernel.core_pattern&lt;/code&gt;, resulting in arbitrary code execution as root on the host&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://nvd.nist.gov/vuln/detail/CVE-2023-27561&#34;&gt;CVE-2023-27561&lt;/a&gt;:
runc could be tricked into bypassing the masked paths of a container via a volume
mount race, exposing the host&#39;s procfs files (a regression of CVE-2019-19921)&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://nvd.nist.gov/vuln/detail/CVE-2024-10220&#34;&gt;CVE-2024-10220&lt;/a&gt;:
the kubelet could be made to execute arbitrary commands as root via &lt;code&gt;gitRepo&lt;/code&gt; volumes
(&lt;code&gt;gitRepo&lt;/code&gt; volumes had a similar vulnerability,
&lt;a href=&#34;https://nvd.nist.gov/vuln/detail/CVE-2018-11235&#34;&gt;CVE-2018-11235&lt;/a&gt;, back in 2018 too)&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://nvd.nist.gov/vuln/detail/CVE-2025-31133&#34;&gt;CVE-2025-31133&lt;/a&gt;:
runc could be tricked into bind-mounting attacker-controlled paths and writing to the
host&#39;s procfs files, such as &lt;code&gt;/proc/sysrq-trigger&lt;/code&gt; and
&lt;code&gt;/proc/sys/kernel/core_pattern&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://nvd.nist.gov/vuln/detail/CVE-2026-53488&#34;&gt;CVE-2026-53488&lt;/a&gt;:
containerd could be tricked into executing arbitrary commands on the host, via
crafted labels in a container image&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;By running the node components in a user namespace, the potential damage is confined to
the non-root user&#39;s account.
Notably, an attacker cannot conceal their intrusion by modifying the kernel, the boot
loader, or the firmware.&lt;/p&gt;
&lt;p&gt;It should still be noted that user namespaces are not effective for mitigating
vulnerabilities in the kernel itself.
User namespaces should be used in conjunction with traditional hardening measures such as
&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/tutorials/security/seccomp/&#34;&gt;seccomp&lt;/a&gt; to prevent containers from invoking
unnecessary system calls.&lt;/p&gt;
&lt;h3 id=&#34;use-cases&#34;&gt;Use cases&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#use-cases&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Production clusters&lt;/strong&gt;: mitigate potential container-breakout vulnerabilities.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Shared machines (e.g., HPC)&lt;/strong&gt;: users can deploy Kubernetes without asking the machine
administrator for root privileges, and without the risk of accidentally breaking
other users&#39; environments.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Laptops&lt;/strong&gt;: prevent a local cluster from accidentally breaking the host system configuration,
e.g., the host iptables rules used for VPNs.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AI sandbox&lt;/strong&gt;: a Kubernetes application developer may create a dedicated local user account for
running an AI coding agent and a test Kubernetes cluster.
This setup is useful for preventing the AI agent from breaking the host when it is deceived by
malicious information on the Internet.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Kubernetes-in-Kubernetes&lt;/strong&gt;: a nested cluster can run inside a parent cluster as a user-namespaced
pod (&lt;code&gt;hostUsers: false&lt;/code&gt;), isolating workloads more strictly than Kubernetes API namespaces do.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bootstrapping&lt;/strong&gt;: a temporary unprivileged cluster can be used to bootstrap an actual
cluster, e.g., with Cluster API.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;how-does-it-work&#34;&gt;How does it work?&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#how-does-it-work&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;A Linux kernel &lt;em&gt;user namespace&lt;/em&gt; maps a host level non-root user (e.g., UID 1000) to a &lt;em&gt;fake root&lt;/em&gt; user inside the namespace. The UID 0
privileges are limited to the inside of the namespace.
The fake root is enough for most of the node components&#39; tasks: mounting volumes,
creating cgroups, and configuring the network namespaces of pods.
It still comes with some &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/2033/#notesconstraintscaveats-optional&#34;&gt;caveats&lt;/a&gt; that may break compatibility with specific CNI and CSI drivers, though.&lt;/p&gt;
&lt;p&gt;The user namespace has to be created outside of Kubernetes.
For example, &lt;a href=&#34;https://docs.docker.com/engine/security/rootless/&#34;&gt;Rootless&lt;/a&gt; Docker can be used to prepare the user namespace in which Kubernetes runs.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;KubeletInUserNamespace&lt;/code&gt; feature gate itself is quite &amp;quot;boring&amp;quot;: basically it just lets the kubelet
ignore permission errors that occur when &lt;a href=&#34;https://github.com/kubernetes/kubernetes/blob/v1.37.0-beta.0/pkg/kubelet/cm/container_manager_linux.go#L499-L517&#34;&gt;setting some sysctl values&lt;/a&gt;
(e.g., &lt;code&gt;vm.overcommit_memory&lt;/code&gt; and &lt;code&gt;kernel.panic&lt;/code&gt;)
and when &lt;a href=&#34;https://github.com/kubernetes/kubernetes/blob/v1.37.0-beta.0/pkg/kubelet/kubelet.go#L586-L601&#34;&gt;watching kernel messages via &lt;code&gt;/dev/kmsg&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;See &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/tasks/administer-cluster/kubelet-in-userns/&#34;&gt;Running Kubernetes Node Components as a Non-root User&lt;/a&gt;
for further information.&lt;/p&gt;
&lt;h2 id=&#34;what-changed-from-alpha-to-beta&#34;&gt;What changed from Alpha to Beta?&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#what-changed-from-alpha-to-beta&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;KubeletInUserNamespace&lt;/code&gt; feature gate is now enabled by default.
Enabling the gate does not put the kubelet into a user namespace automatically, so nothing
changes for existing &amp;quot;rootful&amp;quot; clusters.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;kubectl get nodes -o yaml&lt;/code&gt; now reports whether nodes are running in a user namespace via
the &lt;a href=&#34;https://pkg.go.dev/k8s.io/api/core/v1#NodeSystemInfo&#34;&gt;&lt;code&gt;runningInUserNamespace&lt;/code&gt;&lt;/a&gt; property.
A cluster administrator can use this property to set node labels or taints, to avoid scheduling workloads
that need real root privileges (e.g., some CNI plugin installers) onto rootless nodes.&lt;/li&gt;
&lt;li&gt;For Kubernetes&#39; own CI/CD testing, the node conformance end to end tests now run on a rootless cluster
(&lt;a href=&#34;https://prow.k8s.io/job-history/gs/kubernetes-ci-logs/logs/ci-kubernetes-e2e-kind-rootless&#34;&gt;ci-kubernetes-e2e-kind-rootless&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Several related improvements have also happened outside the promotion of the feature gate itself:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Linux kernel v6.3 (2023)&lt;/strong&gt;: added support for &lt;a href=&#34;https://kernelnewbies.org/Linux_6.3&#34;&gt;idmapped tmpfs&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Kubernetes v1.33 (2025)&lt;/strong&gt;: enabled the &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/workloads/pods/user-namespaces/&#34;&gt;&lt;code&gt;UserNamespacesSupport&lt;/code&gt;&lt;/a&gt; feature gate
by default, allowing user-namespaced pods (&lt;code&gt;hostUsers: false&lt;/code&gt;) to be created without extra configuration.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;containerd v2.1 (2025)&lt;/strong&gt;: added support for &lt;a href=&#34;https://github.com/containerd/containerd/releases/tag/v2.1.0&#34;&gt;writable cgroups&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With these improvements, a Kubernetes cluster with &lt;code&gt;KubeletInUserNamespace&lt;/code&gt; can now also be nested
inside Kubernetes pods with &lt;code&gt;hostUsers: false&lt;/code&gt; (&lt;code&gt;UserNamespacesSupport&lt;/code&gt;).&lt;/p&gt;
&lt;h2 id=&#34;how-to-use-it&#34;&gt;How to use it&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#how-to-use-it&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;h3 id=&#34;kind&#34;&gt;kind&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#kind&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The easiest way is to use &lt;a href=&#34;https://kind.sigs.k8s.io/&#34;&gt;kind&lt;/a&gt; (a Kubernetes SIG Testing project)
to run a Kubernetes cluster in rootless Docker, rootless nerdctl, or rootless Podman:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Example using Docker&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;dockerd-rootless-setuptool.sh install
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kind create cluster
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Depending on the host configuration, you may need additional configuration for
systemd, kernel modules, sysctl, etc.&lt;/p&gt;
&lt;p&gt;See the &lt;a href=&#34;https://docs.docker.com/engine/security/rootless/&#34;&gt;Docker documentation&lt;/a&gt; and
the &lt;a href=&#34;https://kind.sigs.k8s.io/docs/user/rootless/&#34;&gt;kind documentation&lt;/a&gt; for further information.&lt;/p&gt;
&lt;h3 id=&#34;minikube&#34;&gt;minikube&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#minikube&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;a href=&#34;https://minikube.sigs.k8s.io/docs/&#34;&gt;minikube&lt;/a&gt; (a Kubernetes SIG Cluster Lifecycle project)
also supports running a Kubernetes cluster in rootless Docker or rootless Podman:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;dockerd-rootless-setuptool.sh install
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;minikube start --driver&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;docker
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;See the &lt;a href=&#34;https://minikube.sigs.k8s.io/docs/drivers/docker/&#34;&gt;minikube documentation&lt;/a&gt;
for further information.&lt;/p&gt;
&lt;h3 id=&#34;usernetes&#34;&gt;Usernetes&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#usernetes&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;a href=&#34;https://github.com/rootless-containers/usernetes&#34;&gt;Usernetes&lt;/a&gt; (a third-party project)
is a distribution of rootless Kubernetes, maintained by the author of this article.
The project began in 2018, and it is where the &lt;code&gt;KubeletInUserNamespace&lt;/code&gt; feature gate
originally came from.&lt;/p&gt;
&lt;p&gt;Unlike kind and minikube, Usernetes supports creating a cluster with multiple rootless
Docker / Podman / nerdctl nodes, connected using VXLAN via the Flannel CNI plugin.&lt;/p&gt;
&lt;p&gt;Usernetes also experimentally supports a &lt;a href=&#34;https://github.com/rootless-containers/usernetes/tree/master/kubernetes&#34;&gt;Kubernetes-in-Kubernetes&lt;/a&gt; mode.&lt;/p&gt;
&lt;h3 id=&#34;k3s&#34;&gt;k3s&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#k3s&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;a href=&#34;https://k3s.io&#34;&gt;k3s&lt;/a&gt; (a CNCF Sandbox project) also supports &lt;a href=&#34;https://docs.k3s.io/advanced#running-rootless-servers-experimental&#34;&gt;rootless mode&lt;/a&gt;.
Unlike kind, minikube, and the current generation of Usernetes, rootless k3s does not rely on an external runtime such as rootless Docker.&lt;/p&gt;
&lt;h2 id=&#34;what-s-next&#34;&gt;What&#39;s next?&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#what-s-next&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Depending on feedback and adoption, the Kubernetes project plans to graduate this feature to
General Availability (GA) in a future release. If you have feedback on this feature, please
open an issue in the &lt;a href=&#34;https://github.com/kubernetes/kubernetes&#34;&gt;kubernetes/kubernetes&lt;/a&gt; repository.&lt;/p&gt;
&lt;p&gt;The project is also discussing several Kubernetes Enhancement Proposals that may contribute to
simplifying Kubernetes-in-Kubernetes with this feature:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5474/&#34;&gt;KEP-5474: Enable Writable cgroups for unprivileged containers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5714&#34;&gt;KEP-5714: Allow specifying whether to unshare cgroup namespaces&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;getting-involved&#34;&gt;Getting involved&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#getting-involved&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;We always welcome new contributors. If you would like to get involved, you can join the
&lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/node/&#34;&gt;Node Special Interest Group&lt;/a&gt;
(SIG Node).&lt;/p&gt;
&lt;p&gt;If you would like to share feedback, you can do so on our
&lt;a href=&#34;https://kubernetes.slack.com/messages/sig-node&#34;&gt;public Slack channel&lt;/a&gt;
(visit &lt;a href=&#34;https://slack.k8s.io/&#34;&gt;https://slack.k8s.io/&lt;/a&gt; for an invitation if you need one).&lt;/p&gt;
&lt;p&gt;Special thanks to everyone who helped design and implement this feature,
including but not limited to (in alphabetical order):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Bing Hongtao (&lt;a href=&#34;https://github.com/HirazawaUi&#34;&gt;HirazawaUi&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Jordan Liggitt (&lt;a href=&#34;https://github.com/liggitt&#34;&gt;liggitt&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Sergey Kanzhelev (&lt;a href=&#34;https://github.com/SergeyKanzhelev&#34;&gt;SergeyKanzhelev&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Tim Hockin (&lt;a href=&#34;https://github.com/thockin&#34;&gt;thockin&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes v1.37: DRA Updates</title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/09/03/kubernetes-v1-37-dra-updates/</link>
      <pubDate>Thu, 03 Sep 2026 10:30:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/09/03/kubernetes-v1-37-dra-updates/</guid>
      <description>
        
        
        &lt;p&gt;Kubernetes 1.37 is here and &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/scheduling-eviction/dynamic-resource-allocation/&#34;&gt;Dynamic Resource Allocation (DRA)&lt;/a&gt; keeps pushing past where it started! This release brings DRA Extended Resource support to GA, a milestone the team has been building toward for three straight releases. Several more features graduate to Beta or GA. A fresh batch of alpha features rounds out the release.&lt;/p&gt;
&lt;p&gt;I&#39;ll dive into what&#39;s new for DRA in Kubernetes 1.37!&lt;/p&gt;
&lt;h2 id=&#34;what-s-stable-in-1-37&#34;&gt;What&#39;s stable in 1.37&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#what-s-stable-in-1-37&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;&lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5004&#34;&gt;DRA Extended Resource support&lt;/a&gt; has graduated to GA. This is the mechanism that lets DRA drivers satisfy requests made through the traditional extended resource API, think &lt;code&gt;example.com/gpu&lt;/code&gt; in a Pod spec, without requiring a separate device plugin alongside the DRA driver. An extended resource name can be set directly on a DeviceClass, and Pods requesting it get matched to a device through DRA with no ResourceClaim needed on the workload&#39;s part.&lt;/p&gt;
&lt;p&gt;It&#39;s been on a steady path since KEP acceptance in 1.34. Alpha landed in 1.35, Beta in 1.36, and now it&#39;s Stable. For cluster operators, this is what makes DRA adoption gradual. Existing workloads written against extended resources keep working unmodified while the backend allocation logic moves over to DRA.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.kubernetes.dev/resources/keps/4817/&#34;&gt;ResourceClaims status with possible standardized network interface data&lt;/a&gt; adds a &lt;code&gt;devices&lt;/code&gt; field to ResourceClaim &lt;code&gt;.status&lt;/code&gt;, letting DRA drivers report per-device status, including, for network devices, the interface name, MAC address, and IP addresses. This gives users and controllers visibility into device state that was previously invisible once a device was configured in a Pod, and makes it possible to build things like network services that rely on a device&#39;s reported IPs.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5055/&#34;&gt;DRA: device taints and tolerations&lt;/a&gt; is now Stable; DRA drivers can mark devices as tainted so they&#39;re skipped for new Pod scheduling, and cluster admins can apply the same taints cluster-wide via a DeviceTaintRule, without reconfiguring drivers. Pods already using a tainted device can be evicted automatically, unless their ResourceClaim explicitly tolerates the taint. This mirrors node taints and tolerations, letting operators take a single device offline for maintenance or mark it degraded, without disrupting the rest of the cluster.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/6072&#34;&gt;Standard numaNode device attribute&lt;/a&gt; standardizes &lt;code&gt;resource.kubernetes.io/numaNode&lt;/code&gt; as a shared attribute name, so devices from different drivers can be compared on the same NUMA node instead of each driver inventing its own name for it. It landed directly as stable in 1.37, since it&#39;s a naming/registration KEP with no feature gate or in-tree behavior change.&lt;/p&gt;
&lt;h2 id=&#34;feature-promoted-to-beta&#34;&gt;Feature promoted to Beta&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#feature-promoted-to-beta&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;&lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5729&#34;&gt;ResourceClaim support for workloads&lt;/a&gt;
graduates to Beta behind the &lt;code&gt;DRAWorkloadResourceClaims&lt;/code&gt; feature gate, which stays disabled by default.
In a cluster that has the feature enabled, Workloads and PodGroups can reference ResourceClaims directly, so
a single claim can be shared across an entire group of Pods. This is instead of claims being capped at 256
Pods through the old per-Pod reservation limit.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5304/&#34;&gt;DRA Device Attributes Downward API&lt;/a&gt; is aimed at
supporting device injection into KubeVirt VMs. Drivers populate a &lt;code&gt;Metadata&lt;/code&gt; field when preparing a claim,
and the framework writes it to a JSON file mounted into the container via CDI, letting workloads read a
device&#39;s PCI bus address, MAC address, and other attributes directly instead of requiring custom controllers
to watch and translate ResourceClaims and ResourceSlices.&lt;/p&gt;
&lt;h2 id=&#34;alpha-features&#34;&gt;Alpha features&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#alpha-features&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;&lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5491&#34;&gt;List types for attributes&lt;/a&gt; moved into a second Alpha in 1.37,
letting a device attribute hold more than one value instead of a single scalar, such as a CPU that&#39;s
adjacent to more than one PCIe root. This makes it possible to match or distinguish devices based on
overlapping or non-overlapping sets of values, while single-value attributes keep working as they do today.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5517&#34;&gt;Node allocatable resource requests&lt;/a&gt; moved into Alpha 2. It
lets the scheduler and kubelet treat DRA-managed CPU, memory, and similar node resources the same way they
treat ordinary resource requests, so a node doesn&#39;t get oversubscribed and users no longer have to duplicate
the same request in both a ResourceClaim and the pod spec.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5677&#34;&gt;Resource availability visibility&lt;/a&gt; moved to a second Alpha in Kubernetes 1.37. Users create a ResourcePoolStatusRequest to get a point-in-time availability snapshot. To refresh it, delete and recreate the request; it is not a continuous monitoring API.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5945&#34;&gt;DRA: Optional Node Operations&lt;/a&gt; lets a driver skip kubelet&#39;s
prepare and unprepare calls for allocations that don&#39;t need any setup on the node. This makes it possible to
avoid an unnecessary dependency on the driver for allocations where there&#39;s genuinely nothing for it to do
locally.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.kubernetes.dev/resources/keps/6080&#34;&gt;Derived Attributes&lt;/a&gt; is a new feature that lets you use &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/reference/using-api/cel/&#34;&gt;CEL&lt;/a&gt; expressions to match up devices based on your own
custom rules. Before this, pairing devices from different vendors (like a GPU/TPU and a NIC on the same NUMA
node) only worked if both drivers used the exact same attribute name. If one used &lt;code&gt;numa&lt;/code&gt; and the other used
&lt;code&gt;numaNode&lt;/code&gt;, the scheduler couldn&#39;t pair them together. Now, you can easily bridge these differences yourself
inside your manifest, meaning you don&#39;t have to wait for hardware vendors to agree on standardized attribute
names. Beyond just fixing naming differences, you can also use CEL to handle more complex scenarios like
slicing a specific ID out of a long, monolithic topology string, or grouping devices into custom performance
tiers based on their available capacity.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5963&#34;&gt;DRA Device Compatibility Groups&lt;/a&gt; lets drivers tag partitions
of a device, like MIG vs vGPU profiles on the same GPU, with compatibility groups, so the scheduler rejects
incompatible combinations up front instead of the driver failing at node preparation time. It&#39;s controlled by
the &lt;code&gt;DRADeviceCompatibilityGroups&lt;/code&gt; feature gate, disabled by default.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.kubernetes.dev/resources/keps/6132&#34;&gt;PreQueueingHint extension point&lt;/a&gt; is new as Alpha in 1.37.
DRA ResourceClaim events used to trigger a full scan of every unschedulable pod, an O(N²) cost during large
scale-ups. The DRA plugin now uses a pod informer index to narrow that to just the pods actually affected,
cutting the requeue path to O(1) and roughly doubling scheduling throughput in early benchmarks. Controlled
by the &lt;code&gt;SchedulerPreQueueingHints&lt;/code&gt; feature gate.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5075&#34;&gt;DRA Consumable Capacity&lt;/a&gt; now supports fractional values in
CapacityRequestPolicyRange, enabling more precise capacity requests and allocation for devices with fractional resources.
This improves flexibility for workloads that require fine-grained resource allocation. The enhancement is gated by the
&lt;code&gt;DRAFractionalCapacityRange&lt;/code&gt; feature gate, which is in Beta in 1.37.&lt;/p&gt;
&lt;h2 id=&#34;what-s-next&#34;&gt;What’s next&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#what-s-next&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;DRA continues to mature with every release. Several features currently in Alpha and Beta are on track to progress in the
coming releases, and the community keeps working on DRA&#39;s performance, scalability, and reliability. Expect another
ambitious set of DRA features in Kubernetes 1.38.&lt;/p&gt;
&lt;h2 id=&#34;getting-involved&#34;&gt;Getting involved&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#getting-involved&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;A good starting point is joining the WG Device Management &lt;a href=&#34;https://kubernetes.slack.com/archives/C0409NGC1TK&#34;&gt;Slack channel&lt;/a&gt; and &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/wg/device-management/#meetings&#34;&gt;meetings&lt;/a&gt; which happens at US/EU and EU/APAC friendly time slots.&lt;/p&gt;
&lt;p&gt;Not all enhancement ideas are tracked as issues yet, so come talk to us if you want to help or have some ideas yourself! We have work to do at all levels, from difficult core changes to usability enhancements in &lt;code&gt;kubectl&lt;/code&gt; which could be picked up by newcomers.&lt;/p&gt;
&lt;h2 id=&#34;acknowledgments&#34;&gt;Acknowledgments&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#acknowledgments&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The following KEP owners added or promoted a feature in the 1.37 release (in alphabetic order):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Alay Patel (&lt;a href=&#34;https://github.com/alaypatel07&#34;&gt;alaypatel07&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Byonggon Chun(&lt;a href=&#34;https://github.com/bg-chun&#34;&gt;bg-chun&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Gaurav Ghildiyal (&lt;a href=&#34;https://github.com/gauravkghildiyal&#34;&gt;gauravkghildiyal&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Jiefeng Xu (&lt;a href=&#34;https://github.com/jiefeng-xu&#34;&gt;jiefeng-xu&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;John A. Hull (&lt;a href=&#34;https://github.com/johnahull&#34;&gt;johnahull&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Jon Huhn (&lt;a href=&#34;https://github.com/nojnhuh&#34;&gt;nojnhuh&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Lionel Jouin (&lt;a href=&#34;https://github.com/LionelJouin&#34;&gt;LionelJouin&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Patrick Ohly (&lt;a href=&#34;https://github.com/pohly&#34;&gt;pohly&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Praveen Krishna (&lt;a href=&#34;https://github.com/pravk03&#34;&gt;pravk03&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Shingo Omura (&lt;a href=&#34;https://github.com/everpeace&#34;&gt;everpeace&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Troy Chiu (&lt;a href=&#34;https://github.com/troychiu&#34;&gt;troychiu&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This would not have been possible without the help of the reviewers and approvers.
So a huge thanks to everyone else who helped shape this release, in ways big and small. Given enough eyeballs, all bugs are shallow and this release had plenty of them, watching closely and caring enough to make things better. DRA got better this cycle because of all of you.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes v1.37: Scale Workloads to Zero with HorizontalPodAutoscaler</title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/09/02/kubernetes-v1-37-hpa-scale-to-zero-beta/</link>
      <pubDate>Wed, 02 Sep 2026 10:30:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/09/02/kubernetes-v1-37-hpa-scale-to-zero-beta/</guid>
      <description>
        
        
        &lt;p&gt;Kubernetes v1.37 includes API support for horizontal autoscaling of workloads down
to zero replicas. This feature is now Beta and enabled by default. A
&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/workloads/autoscaling/horizontal-pod-autoscale/&#34;&gt;HorizontalPodAutoscaler&lt;/a&gt;
(HPA) that uses a suitable &lt;em&gt;object metric&lt;/em&gt; or &lt;em&gt;external metric&lt;/em&gt; can now scale a
workload to zero replicas, then bring it back when the metric changes.&lt;/p&gt;
&lt;p&gt;Before v1.37, you needed an add-on or external component, or you had to enable the
Alpha feature gate, to scale from zero. It is now part of core Kubernetes.&lt;/p&gt;
&lt;p&gt;Scaling to zero removes the last idle Pod from workloads such as queue consumers and
batch processors. The savings are largest when each Pod reserves expensive resources,
including dedicated CPUs or GPUs.&lt;/p&gt;
&lt;p&gt;The trade-off is cold-start time: the HPA must observe the metric, schedule a Pod, and
start the application. This works well when work can wait in a durable queue.&lt;/p&gt;
&lt;p&gt;Kubernetes Services do not buffer requests while no Pods are ready, so HTTP and other
request-driven workloads need a separate buffering layer.&lt;/p&gt;
&lt;h2 id=&#34;why-scaling-from-zero-needs-a-different-metric&#34;&gt;Why scaling from zero needs a different metric&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#why-scaling-from-zero-needs-a-different-metric&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The HPA commonly scales on CPU or memory usage. Both metrics come from running Pods.
Once the replica count reaches zero, there are no Pods left to measure and no signal
that can tell the HPA to scale back up.&lt;/p&gt;
&lt;p&gt;Object and external metrics do not have that limitation. A queue length, for example,
exists independently of the workers that consume it. The HPA can continue reading the
queue length while no workers are running.&lt;/p&gt;
&lt;p&gt;The following example scales a queue consumer to and from zero using an external
metric.&lt;/p&gt;
&lt;h2 id=&#34;configure-an-external-metric&#34;&gt;Configure an external metric&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#configure-an-external-metric&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The following example uses a Prometheus metric named &lt;code&gt;queue_consumer_lag&lt;/code&gt;. It assumes
that Prometheus already collects a series similar to this one:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-promql&#34; data-lang=&#34;promql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;queue_consumer_lag&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nl&#34;&gt;namespace&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;default&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;#34;,&lt;/span&gt;&lt;span class=&#34;nl&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;worker_tasks&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;#34;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Kubernetes needs a metrics adapter to make that value available through the External
Metrics API. One implementation is the
&lt;a href=&#34;https://github.com/kubernetes-sigs/prometheus-adapter&#34;&gt;Prometheus Adapter&lt;/a&gt;, which can
expose the series using an &lt;code&gt;externalRules&lt;/code&gt; entry:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;externalRules&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;seriesQuery&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;{__name__=&amp;#34;queue_consumer_lag&amp;#34;,name!=&amp;#34;&amp;#34;}&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metricsQuery&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;sum(&amp;lt;&amp;lt;.Series&amp;gt;&amp;gt;{&amp;lt;&amp;lt;.LabelMatchers&amp;gt;&amp;gt;}) by (name)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;resources&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;overrides&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;namespace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;resource&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;namespace&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The exact adapter installation and discovery rules depend on your monitoring setup.
See the Prometheus Adapter guide to
&lt;a href=&#34;https://github.com/kubernetes-sigs/prometheus-adapter/blob/v0.12.0/docs/externalmetrics.md&#34;&gt;external metrics&lt;/a&gt;
for the full configuration options.&lt;/p&gt;
&lt;p&gt;Before creating the HPA, you can verify that Kubernetes can read the metric:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl get --raw &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;s1&#34;&gt;&amp;#39;/apis/external.metrics.k8s.io/v1beta1/namespaces/default/queue_consumer_lag?labelSelector=name%3Dworker_tasks&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The request should return the current value for &lt;code&gt;worker_tasks&lt;/code&gt;. If it does not, fix the
metrics pipeline before configuring the HPA. An HPA cannot scale from zero when its
metric is unavailable.&lt;/p&gt;
&lt;h2 id=&#34;configure-the-hpa&#34;&gt;Configure the HPA&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#configure-the-hpa&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The following HPA targets a Deployment named &lt;code&gt;queue-worker&lt;/code&gt;. It allows between zero
and ten replicas, with one replica requested for each 30 queued tasks:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;autoscaling/v2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;HorizontalPodAutoscaler&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;queue-worker&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kubernetes.io/description&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Scales queue-worker based on the number of queued tasks&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;scaleTargetRef&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;apps/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Deployment&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;queue-worker&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;minReplicas&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;maxReplicas&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metrics&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;External&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;external&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metric&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;queue_consumer_lag&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;selector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;matchLabels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;worker_tasks&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;target&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Value&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;30&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;When the queue is empty, the HPA can reduce the Deployment to zero replicas. When
tasks arrive, the external metric remains available and the HPA calculates a new
replica count, capped at ten by &lt;code&gt;maxReplicas&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Start the Deployment with at least one replica. Manually setting a Deployment to zero
has always paused autoscaling. The HPA preserves that behavior and will not wake a
workload that it did not scale down itself.&lt;/p&gt;
&lt;p&gt;Normal HPA behavior still applies. In particular, the default downscale stabilization
window is five minutes. The window prevents a short drop in queue length from
immediately removing all workers. You can configure the window through
&lt;code&gt;spec.behavior.scaleDown&lt;/code&gt; if your workload needs different behavior.&lt;/p&gt;
&lt;h2 id=&#34;how-the-hpa-distinguishes-zero-from-paused&#34;&gt;How the HPA distinguishes zero from paused&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#how-the-hpa-distinguishes-zero-from-paused&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Scaling from zero creates an ambiguity. A replica count of zero can mean that the HPA
scaled the workload down, or that an operator manually paused it.&lt;/p&gt;
&lt;p&gt;The controller resolves this with a &lt;code&gt;ScaledToZero&lt;/code&gt; status condition. When the HPA
scales a workload from one or more replicas to zero, it records
&lt;code&gt;ScaledToZero=True&lt;/code&gt;. The condition tells later reconciliation loops that the
controller owns the zero state and should continue evaluating object or external
metrics.&lt;/p&gt;
&lt;p&gt;After scaling the workload back up, the controller changes the condition to
&lt;code&gt;ScaledToZero=False&lt;/code&gt; with the reason &lt;code&gt;NotScaledToZero&lt;/code&gt;. A workload at zero without
the &lt;code&gt;ScaledToZero=True&lt;/code&gt; condition remains paused.&lt;/p&gt;
&lt;p&gt;You can inspect the conditions with:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl describe hpa queue-worker
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If the adapter cannot return the configured metric, the HPA reports
&lt;code&gt;ScalingActive=False&lt;/code&gt; with a reason such as &lt;code&gt;FailedGetExternalMetric&lt;/code&gt;. Restore the
metric or manually scale the workload to recover capacity.&lt;/p&gt;
&lt;h2 id=&#34;before-upgrading-or-rolling-back&#34;&gt;Before upgrading or rolling back&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#before-upgrading-or-rolling-back&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;In Kubernetes v1.37, the &lt;code&gt;HPAScaleToZero&lt;/code&gt; feature gate is enabled by default on both the
&lt;code&gt;kube-apiserver&lt;/code&gt; and &lt;code&gt;kube-controller-manager&lt;/code&gt;. The API server accepts
&lt;code&gt;minReplicas: 0&lt;/code&gt;; the controller manager performs the condition-based scaling.&lt;/p&gt;
&lt;p&gt;During a version-skewed control plane upgrade, wait until both components support the
feature and have it enabled before creating HPAs with &lt;code&gt;minReplicas: 0&lt;/code&gt;. A controller
manager with the feature disabled treats &lt;code&gt;replicas: 0&lt;/code&gt; as a manual pause and may leave
a workload at zero.&lt;/p&gt;
&lt;p&gt;Before disabling the feature gate or downgrading to a version without the
condition-based implementation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Change affected HPAs to &lt;code&gt;minReplicas: 1&lt;/code&gt; or higher.&lt;/li&gt;
&lt;li&gt;Scale any workload currently at zero to at least one replica.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;minReplicas: 0&lt;/code&gt; also requires at least one object or external metric. The API server
rejects an HPA that only contains resource metrics such as CPU or memory.&lt;/p&gt;
&lt;h2 id=&#34;from-alpha-to-beta&#34;&gt;From Alpha to Beta&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#from-alpha-to-beta&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The first Alpha implementation shipped in Kubernetes v1.16. Kubernetes v1.36 added
the &lt;code&gt;ScaledToZero&lt;/code&gt; condition and the controller behavior needed to distinguish an
automatic scale-down from a manual pause.&lt;/p&gt;
&lt;p&gt;Kubernetes v1.37 enables the feature by default after adding integration and end-to-end
coverage for scaling down to zero and back up from an external metric. The next step is
to gather operational feedback before considering graduation to GA.&lt;/p&gt;
&lt;h2 id=&#34;how-can-i-learn-more&#34;&gt;How can I learn more?&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#how-can-i-learn-more&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Read the documentation for
&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/workloads/autoscaling/horizontal-pod-autoscale/#scaling-to-and-from-zero&#34;&gt;scaling to and from zero&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Read
&lt;a href=&#34;https://kep.k8s.io/2021&#34;&gt;KEP-2021: HPA supports scaling to and from zero pods for object and external metrics&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Learn how to configure the
&lt;a href=&#34;https://github.com/kubernetes-sigs/prometheus-adapter/blob/v0.12.0/docs/externalmetrics.md&#34;&gt;Prometheus Adapter for external metrics&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;how-to-get-involved&#34;&gt;How to get involved&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#how-to-get-involved&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;This feature is owned by
&lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/autoscaling/&#34;&gt;SIG Autoscaling&lt;/a&gt;.
Join &lt;a href=&#34;https://slack.k8s.io/&#34;&gt;Kubernetes Slack&lt;/a&gt; and the
&lt;a href=&#34;https://kubernetes.slack.com/archives/C09R1LV8S&#34;&gt;&lt;code&gt;#sig-autoscaling&lt;/code&gt; channel&lt;/a&gt; to share
feedback from Beta usage.&lt;/p&gt;
&lt;h2 id=&#34;acknowledgements&#34;&gt;Acknowledgements&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#acknowledgements&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Thanks to the SIG Autoscaling contributors who took this feature from the original
v1.16 implementation to the condition-based redesign and Beta graduation. Thanks
also to &lt;a href=&#34;https://github.com/gjtempleton&#34;&gt;Guy Templeton&lt;/a&gt; and
&lt;a href=&#34;https://github.com/adrianmoisey&#34;&gt;Adrian Moisey&lt;/a&gt; for reviewing the KEP, and to the
release, documentation, and production-readiness reviewers who helped prepare it for
Kubernetes v1.37.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes v1.37: etcd RangeStream Cuts Memory Use on Large List Reads</title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/09/01/kubernetes-v1-37-etcd-range-stream/</link>
      <pubDate>Tue, 01 Sep 2026 10:30:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/09/01/kubernetes-v1-37-etcd-range-stream/</guid>
      <description>
        
        
        &lt;p&gt;I am excited to announce that etcd RangeStream is graduating to beta in
Kubernetes v1.37. Paired with etcd v3.7, it reduces the memory the API server and
etcd need to read a large collection, and makes peak usage more predictable.&lt;/p&gt;
&lt;h2 id=&#34;the-cost-of-large-reads&#34;&gt;The cost of large reads&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#the-cost-of-large-reads&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The API server serves most list and watch requests from its in-memory watch cache.
Populating that cache requires reading a resource&#39;s full state from etcd, at
startup and on every re-initialization. For a resource with many objects, or large
ones, such as Pods, that read is expensive.&lt;/p&gt;
&lt;p&gt;The API server already paginated these reads, asking etcd for a fixed number of
keys at a time rather than the whole collection at once. But a page bounded by key
count has no awareness of object size, so a page of large objects can still be
very large. That makes memory usage hard to predict, and a bad combination of
object size and concurrent reads can be enough to trigger an OOM. etcd&#39;s unary
&lt;code&gt;Range&lt;/code&gt; assembles each page in full before sending it, and the API server holds it
while decoding, so the same payload sits in memory on both sides at once. Most of
that cost lands on etcd, which is also where streaming helps most.&lt;/p&gt;
&lt;h2 id=&#34;streaming-reads-with-rangestream&#34;&gt;Streaming reads with RangeStream&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#streaming-reads-with-rangestream&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;etcd v3.7 adds a streaming version of that read, the &lt;code&gt;RangeStream&lt;/code&gt; RPC. It takes
the same &lt;code&gt;RangeRequest&lt;/code&gt; as &lt;code&gt;Range&lt;/code&gt; and returns the same result set, but instead of
building the whole response up front, etcd splits it into chunks and streams them.
Chunk size is tuned adaptively to the values being returned, so a collection of
large objects is bounded by bytes rather than by a key count, and memory is freed
as the stream progresses instead of being held until a whole page is assembled.&lt;/p&gt;
&lt;p&gt;When the feature is enabled, the API server uses &lt;code&gt;RangeStream&lt;/code&gt; wherever it reads a
whole collection out of etcd. This includes watch cache initialization, and the
fallback paths where a list request cannot be served from the cache and reads etcd
directly. In either case the API server decodes each chunk as it arrives and
releases it before pulling the next one, so neither side ever holds the whole
collection.&lt;/p&gt;
&lt;h2 id=&#34;requirements&#34;&gt;Requirements&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#requirements&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Kubernetes v1.37 or later&lt;/li&gt;
&lt;li&gt;etcd v3.7 or later&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;RangeStream is used when the &lt;code&gt;EtcdRangeStream&lt;/code&gt; feature gate is enabled on the
kube-apiserver, which is beta and on by default in v1.37, and etcd is v3.7 or
later. The API server resolves etcd&#39;s support at startup
and also falls back at runtime if a call returns &lt;code&gt;Unimplemented&lt;/code&gt;, so an API server
paired with an older etcd keeps using the paginated &lt;code&gt;Range&lt;/code&gt; path on its own. To
turn it off, disable the gate:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;--feature-gates=EtcdRangeStream=false
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;confirming-rangestream-is-in-use&#34;&gt;Confirming RangeStream is in use&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#confirming-rangestream-is-in-use&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The API server records streamed reads under their own operation label on its etcd
metrics. A non-zero count here means &lt;code&gt;RangeStream&lt;/code&gt; is in use:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;etcd_request_duration_seconds_count{operation=&amp;#34;listStream&amp;#34;}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If it stays at zero, the API server is still using the paginated &lt;code&gt;Range&lt;/code&gt; path, most
likely because etcd is older than v3.7.&lt;/p&gt;
&lt;h2 id=&#34;learn-more&#34;&gt;Learn more&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#learn-more&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/5966&#34;&gt;KEP-5966: etcd RangeStream&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://etcd.io/docs/v3.7/learning/api/&#34;&gt;RangeStream in the etcd API guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://etcd.io/blog/2026/announcing-etcd-3.7/&#34;&gt;Announcing etcd v3.7&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-etcd&#34;&gt;SIG etcd&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you have questions or feedback, join the &lt;code&gt;#sig-etcd&lt;/code&gt; channel on
&lt;a href=&#34;https://slack.k8s.io/&#34;&gt;Kubernetes Slack&lt;/a&gt;.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes v1.37: Storage Version Migration Enabled by Default</title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/08/31/kubernetes-v1-37-storage-version-migration-ga/</link>
      <pubDate>Mon, 31 Aug 2026 10:30:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/08/31/kubernetes-v1-37-storage-version-migration-ga/</guid>
      <description>
        
        
        &lt;p&gt;I am excited that &lt;em&gt;storage version migration&lt;/em&gt; (SVM) has graduated to General Availability (GA) in Kubernetes v1.37!&lt;/p&gt;
&lt;p&gt;After a number of releases of work and testing, the built-in StorageVersionMigration API (&lt;code&gt;storagemigration.k8s.io/v1&lt;/code&gt;)
and control plane controller are now fully stable and enabled by default across all v1.37 Kubernetes clusters.&lt;/p&gt;
&lt;h2 id=&#34;the-problem-with-stale-storage-versions&#34;&gt;The problem with stale storage versions&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#the-problem-with-stale-storage-versions&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;In Kubernetes, stored API resources are written using a specific &lt;em&gt;storage version&lt;/em&gt; (schema representation). The way Kubernetes interacts with object storage fundamentally requires mutation of a resource in order to ensure that the latest storage version is used for all resources. This creates problems when you want to change the storage version of a resource.&lt;/p&gt;
&lt;p&gt;One example of a scenario where you may want to change the storage version of a resource is when you are promoting a CRD to drop an older API version (such as &lt;code&gt;v1alpha1&lt;/code&gt;) to a newer version (leaving just &lt;code&gt;v1beta1&lt;/code&gt; and &lt;code&gt;v1&lt;/code&gt;). It&#39;s a problem to drop the older API version whilst there are still resources stored with the old alpha version.&lt;/p&gt;
&lt;p&gt;To avoid problems, you designate &lt;code&gt;v1&lt;/code&gt; as the new storage version; but, on it&#39;s own, that&#39;s not enough.  While new writes are stored as &lt;code&gt;v1&lt;/code&gt;, any existing resource could remain stored as &lt;code&gt;v1alpha1&lt;/code&gt; or &lt;code&gt;v1beta1&lt;/code&gt; in storage. You cannot safely remove &lt;code&gt;v1alpha1&lt;/code&gt; from the CRD&#39;s &lt;code&gt;.status.storedVersions&lt;/code&gt; or drop serving support until every single resource in storage has been re-written to not be serialized and stored with the alpha version.&lt;/p&gt;
&lt;p&gt;Another relevant example is &lt;em&gt;encryption at rest&lt;/em&gt; and, related, &lt;em&gt;key rotation&lt;/em&gt;.
When you configure encryption at rest or rotate encryption keys, existing resources in storage remain &lt;strong&gt;unencrypted&lt;/strong&gt; (or encrypted under old keys) until they are actively
re-written through the Kubernetes API server.&lt;/p&gt;
&lt;p&gt;Historically, cluster administrators and CRD authors had to rely on manual
&lt;code&gt;kubectl get&lt;/code&gt; / &lt;code&gt;kubectl replace&lt;/code&gt; scripts, or to deploy the out-of-tree &lt;code&gt;kube-storage-version-migrator&lt;/code&gt; component to force re-writes.
These approaches were often tedious, error-prone, and difficult to monitor.&lt;/p&gt;
&lt;h2 id=&#34;how-storage-version-migration-works&#34;&gt;How storage version migration works&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#how-storage-version-migration-works&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Initiating a storage version migration is as simple as creating a declarative StorageVersionMigration object.
The built-in StorageVersionMigrator controller in the Kubernetes control plane watches for these objects, and automatically migrates existing resources to the default storage version for that API.&lt;/p&gt;
&lt;h3 id=&#34;example-custom-resources&#34;&gt;Example: Migrating a custom resource API&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#example-custom-resources&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Suppose you have updated a CustomResourceDefinition (&lt;code&gt;crontabs.example.com&lt;/code&gt;) to use &lt;code&gt;v1&lt;/code&gt; as its storage version.
To migrate all existing stored resources off older versions, create a StorageVersionMigration:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;storagemigration.k8s.io/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;StorageVersionMigration&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;crontabs-migration&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;resource&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;group&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;example.com&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;resource&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;crontabs&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Apply the manifest using &lt;code&gt;kubectl&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl apply -f crontabs-migration.yaml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;monitoring-and-verifying-migrations&#34;&gt;Monitoring and verifying migrations&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#monitoring-and-verifying-migrations&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The StorageVersionMigrator controller updates the &lt;code&gt;status&lt;/code&gt; of the StorageVersionMigration object as migration progresses.
You can inspect the migration status using &lt;code&gt;kubectl&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl get storageversionmigration.storagemigration.k8s.io/crontabs-migration -o yaml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A successful migration will report a &lt;code&gt;Succeeded&lt;/code&gt; condition set to True:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;status&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;conditions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Running&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;status&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;False&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;lastUpdateTime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;2026-08-02T10:05:00Z&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;reason&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;StorageVersionMigrationInProgress&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Succeeded&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;status&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;True&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;lastUpdateTime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;2026-08-02T10:05:00Z&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;reason&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;StorageVersionMigrationSucceeded&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Once the migration has succeeded, you can be confident that all instances of the resource in storage are stored in the current storage version. For
CRDs, the stored version should be updated in the CRD&#39;s &lt;code&gt;.status.storedVersions&lt;/code&gt; to only contain the preferred version. If the
&lt;code&gt;.status.storedVersions&lt;/code&gt; is not updated following a successful migration then that means that the CRD was updated during the migration. In
that case, the migration should be retried in order to safely deprecate an older storage version.&lt;/p&gt;
&lt;h2 id=&#34;including-migrations-in-your-crd-manifests&#34;&gt;Including migrations in your CRD manifests&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#including-migrations-in-your-crd-manifests&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Because StorageVersionMigration is a standard declarative Kubernetes API, CRD authors can bundle or trigger migrations directly
alongside CRD upgrades. For example, you can include the migration in the same manifest as your updated CustomResourceDefinition:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;apiextensions.k8s.io/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;CustomResourceDefinition&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;crontabs.example.com&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;group&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;example.com&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# Updated versions list where v1 has storage: true&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;...&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;storagemigration.k8s.io/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;StorageVersionMigration&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;crontabs-migration&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;resource&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;group&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;example.com&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;resource&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;crontabs&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;what-s-next&#34;&gt;What&#39;s next?&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#what-s-next&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Learn more about the concepts behind &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/overview/working-with-objects/storage-version/&#34;&gt;Storage Versions&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Read the step-by-step task guide: &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/tasks/manage-kubernetes-objects/storage-version-migration/&#34;&gt;Migrate Kubernetes Objects Using Storage Version Migration&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;SIG API Machinery would love to hear your feedback as you adopt built-in Storage Version Migration in your clusters. Reach out to us on the &lt;a href=&#34;https://kubernetes.slack.com/messages/sig-api-machinery&#34;&gt;#sig-api-machinery&lt;/a&gt; Slack channel or participate in our community discussions!&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes v1.37: Pod Certificates and Cluster Trust Bundles</title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/08/28/kubernetes-v1-37-pod-certificates-and-cluster-trust-bundles/</link>
      <pubDate>Fri, 28 Aug 2026 10:30:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/08/28/kubernetes-v1-37-pod-certificates-and-cluster-trust-bundles/</guid>
      <description>
        
        
        &lt;h2 id=&#34;pod-certificate-cluster-trust-bundles-blog-post&#34;&gt;Pod Certificate / Cluster Trust Bundles Blog Post&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#pod-certificate-cluster-trust-bundles-blog-post&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Kubernetes brings a wealth of features that make it easy to run your production
workloads securely and reliably.  While aspects like scheduling, health checks
and resource limits are probably at the front of your mind, one other important
feature of Kubernetes is production identity — how your workload can
authenticate to other systems in order to do its job.&lt;/p&gt;
&lt;p&gt;Up until now, the primary production identity mechanism built into Kubernetes
has been service account JWTs (JSON Web Tokens).  These are
cryptographically-signed tokens, issued by the control plane of your cluster,
that let anyone in the world understand who is calling when your workload uses
them.&lt;/p&gt;
&lt;p&gt;In Kubernetes 1.37, the foundations of a new built-in production identity
technology have gone GA.  Pod Certificates (and the closely-associated Cluster
Trust Bundles) build X.509 certificate issuance for TLS and mTLS directly into
core Kubernetes.&lt;/p&gt;
&lt;p&gt;Why?&lt;/p&gt;
&lt;p&gt;Service account JWTs have a lot going for them:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;They are built directly into Kubelet, and work pretty magically. They are
written to your workload container’s filesystem before your workload starts
up, and automatically kept up to date.&lt;/li&gt;
&lt;li&gt;The issuance system follows least-privilege principles; the node restriction
admission plugin ensures that tokens can only be requested by the Kubelet that
is actually currently running your pod.&lt;/li&gt;
&lt;li&gt;They can be federated, allowing you to use them to authenticate to other
systems outside of Kubernetes.  Service account JWTs underpin the pod-to-cloud
authentication store for all of the largest cloud providers, and have
widespread support across many additional services and software packages.  If
it can understand JWTs, you can authenticate to it with a service account
token.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;However, service account JWTs have one big downside — they are bearer tokens.
With bearer tokens, if you &lt;em&gt;have&lt;/em&gt; the token, then you &lt;em&gt;are&lt;/em&gt; the identity
asserted by the token.  And since you necessarily have to hand copies of the JWT
to all your peers in order to authenticate to them, &lt;em&gt;they&lt;/em&gt; can be you, too.&lt;/p&gt;
&lt;p&gt;There are partial mitigations for this, and service account tokens make use of
them (time-, object-, and audience-binding), but none are complete defences.&lt;/p&gt;
&lt;p&gt;A solution to this problem lies in proof-of-possession credentials, where you
don’t send your &lt;em&gt;entire&lt;/em&gt; credential to your peer, but only a proof that you
possess the credential.  In practice, these schemes are always built on
asymmetric cryptographic signatures (RSA, ECDSA, and friends).&lt;/p&gt;
&lt;p&gt;There are few different standard approaches, such as request signing (AWS SigV4,
JWT DPoP, RFC 9421), but the most widely-deployed and understood solution is
X.509 certificates, as used in TLS.  In TLS, your credential is split into two
pieces&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A private key, which for maximum security should be generated within your
workload (or within a hardware security module), and never leave.&lt;/li&gt;
&lt;li&gt;A certificate, which is a description of your identity and public key, signed
by a Certificate Authority.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The goal of Pod Certificates is to make using X.509 certificates from your
Kubernetes workload just as easy as using service account JWTs, while
maintaining Kubernetes’ high security bar.  I think we’ve hit this target.&lt;/p&gt;
&lt;p&gt;As I’ll cover in the architecture and example sections below, there are many
similarities between the design of service account JWT issuance and Pod
Certificates.  One significant place they diverge, however, is that Pod
Certificates is a much more flexible mechanism.  Kubernetes only offers one
flavor of service account JWTs, with standardized claims.&lt;/p&gt;
&lt;p&gt;The X.509 ecosystem is significantly more varied than the JWT ecosystem, and
X.509 certificates used for different purposes  contain different extensions and
information.  For this reason, Pod Certificates has common machinery built into
Kubelet, but offers a pluggable interface so that many different types of
certificates can be issued within a single cluster, at the same time.&lt;/p&gt;
&lt;p&gt;In the fullness of time, I expect Kubernetes to offer at least two built-in
certificate providers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;One that issues server TLS certificates for the DNS names used by Kubernetes
services.&lt;/li&gt;
&lt;li&gt;One that offers SPIFFE client certificates, filling the same role that service
account JWTs fill today.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the remainder of this article, I’ll take you through the overall architecture
of a Kubernetes workload using Pod Certificates, as well as give you an example
of installing and using a real (toy) Pod Certificates signer controller.&lt;/p&gt;
&lt;h2 id=&#34;architecture&#34;&gt;Architecture&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#architecture&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;When you use Pod Certificates and Cluster Trust Bundles, there are the following
major components:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Your application, which requests certificates in its pod spec, and reads the
keys, certificates and trust bundles from the container filesystem to use for
(m)TLS.&lt;/li&gt;
&lt;li&gt;Kubelet, which issues PodCertificateRequest objects and reads
ClusterTrustBundle objects on behalf of your workload.&lt;/li&gt;
&lt;li&gt;The signer controller, which answers PodCertificateRequests and publishes
ClusterTrustBundles.&lt;/li&gt;
&lt;/ul&gt;


&lt;figure class=&#34;diagram-large &#34;&gt;
    &lt;img src=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/08/28/kubernetes-v1-37-pod-certificates-and-cluster-trust-bundles/pod-certificates-architecture.svg&#34;
         alt=&#34;Block diagram of an application using Pod Certificates&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;Architecture of an application using Pod Certificates&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The best way to get a sense of what these components each do is to follow the
issuance process chronologically:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Once your application pod is scheduled to a node, Kubelet identifies all of
the podCertificate and clusterTrustBundle projected volumes sources in its
spec.&lt;/li&gt;
&lt;li&gt;For each podCertificate source:
&lt;ol&gt;
&lt;li&gt;Kubelet generates a new private key according to the keyType field.&lt;/li&gt;
&lt;li&gt;Kubelet creates a PodCertificateRequest addressed to the signer named in
the source.&lt;/li&gt;
&lt;li&gt;The signer controller sees the PodCertificateRequest and decides whether
or not to issue the certificate.&lt;/li&gt;
&lt;li&gt;The signer controller issues the certificate by filling out the
status.certificateChain field.&lt;/li&gt;
&lt;li&gt;The signer controller also fills out the status.beginRefreshAt field to
instruct Kubelet when it should begin trying to refresh the certificate.&lt;br&gt;
certificate to the container filesystem.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;For each clusterTrustBundle source:&lt;br&gt;
6) Kubelet retrieves the issued certificate, and writes the private key and
&lt;ol&gt;
&lt;li&gt;Kubelet collects all the ClusterTrustBundles that match the signer name&lt;/li&gt;
&lt;li&gt;Kubelet unifies all of the certificates from all matching
ClusterTrustBundles, and (stably) reorders them (to prevent applications
from accidentally depending on a particular ordering).&lt;br&gt;
and label selectors in the source.&lt;/li&gt;
&lt;li&gt;Kubelet writes the certificates to the file path named in the source.&lt;br&gt;
and trust anchors from the filesystem.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Your application pod starts up, and the application reads keys, certificates,&lt;/li&gt;
&lt;li&gt;Kubelet periodically updates the files from clusterTrustBundle sources as the
contents of the selected ClusterTrustBundles changes. The application must
pick up the changes using inotify or polling.&lt;/li&gt;
&lt;li&gt;As each certificate’s beginRefreshAt time passes, Kubelet repeats the process
in step 2 to refresh the certificates, and write the update private keys and
certificate chains to the filesystem.  As in step 5, the application must
pick up changes using inotify or polling.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Some key takeaways:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Automatic rotation is built in.  Applications &lt;em&gt;must&lt;/em&gt; properly handle it.  Any
signers eventually shipped in core Kubernetes will issue certificates with a
max lifetime of 24 hours.  The maximum lifetime allowed for other signers is
91 days.&lt;/li&gt;
&lt;li&gt;To make automatic rotation support as simple as possible, Kubelet supports
writing the private key and certificate chain to a single file (a &lt;em&gt;credential
bundle&lt;/em&gt;) This allows the application to simply subscribe to inotify events for
(or poll) the single file, read the contents, and use them.  Kubelet does
support writing the private key and certificate chain to separate files, but
then the application needs to carefully manage the potential race conditions
of reading the files mid-rotation.&lt;/li&gt;
&lt;li&gt;Wherever possible, security checks are built into kube-apiserver, rather than
burdening signer or application developers.  As an example, the built-in node
restriction admission plugin enforces node isolation, ensuring that one
compromised node cannot spread access by requesting certificates for pods that
aren’t scheduled to it.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;try-it-out&#34;&gt;Try it out&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#try-it-out&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Because the Kubernetes project does not yet ship any Pod Certificate signers in
core, in order to try these features out, you will need to install a third-party
signer into your cluster.  To make this easier, I have written
&lt;a href=&#34;https://github.com/ahmedtd/tinycert&#34;&gt;Tinycert&lt;/a&gt;, which you can install into your
cluster (or a Kind cluster).&lt;/p&gt;
&lt;p&gt;Tinycert is not a full production solution, but it’s a good starting point for
experimenting with Pod Certificates, as well as a base for creating your own
signers.&lt;/p&gt;
&lt;p&gt;Tinycert provides:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The
&lt;a href=&#34;https://ahmedtd.github.io/tinycert-service&#34;&gt;ahmedtd.github.io/tinycert-service&lt;/a&gt;
signer, which issues certificates with DNS SANs for all of the Kubernetes
Services your Pod is part of.&lt;/li&gt;
&lt;li&gt;The
&lt;a href=&#34;https://ahmedtd.github.io/tinycert-spiffe&#34;&gt;ahmedtd.github.io/tinycert-spiffe&lt;/a&gt;
signer, which issues SPIFFE-compatible certificates that identify the
namespace and service account of your Pod.  These can be used as both client
and (with effort) server certificates.&lt;/li&gt;
&lt;li&gt;A Go library,
&lt;a href=&#34;https://github.com/ahmedtd/tinycert/lib/spiffefsd&#34;&gt;github.com/ahmedtd/tinycert/lib/spiffefsd&lt;/a&gt;
to help your applications load SPIFFE certificates and trust bundles from a
&lt;a href=&#34;https://github.com/spiffe/spiffe/pull/376&#34;&gt;SPIFFE Filesystem Delivery (Draft
Standard)&lt;/a&gt; folder, as well as
configure the Go TLS library for proper client and server authentication.&lt;/li&gt;
&lt;li&gt;An example of a SPIFFE client and server application communicating using
mutual TLS and SPIFFE certificates.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;what-next&#34;&gt;What next?&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#what-next&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Take a look at the documentation for &lt;a href=&#34;https://kubernetes.io/docs/reference/access-authn-authz/certificate-signing-requests/#pod-certificate-requests&#34;&gt;Pod
Certificates&lt;/a&gt;
and &lt;a href=&#34;https://kubernetes.io/docs/reference/access-authn-authz/certificate-signing-requests/#cluster-trust-bundles&#34;&gt;Cluster Trust
Bundles&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Review and offer feedback on the &lt;a href=&#34;https://github.com/spiffe/spiffe/pull/376&#34;&gt;SPIFFE Filesystem Delivery draft
standard&lt;/a&gt;, which aims to make it as
easy as possible to use SPIFFE certificates directly on native Kubernetes.&lt;/li&gt;
&lt;li&gt;Participate in Kubernetes SIG Auth to help shape the future of signers that
are built directly in to core Kubernetes.&lt;/li&gt;
&lt;li&gt;Try building your own signer based on Tinycert.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Happy hacking!&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes v1.37: Metrics API graduates to stable</title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/08/27/kubernetes-v1-37-metrics-api-ga/</link>
      <pubDate>Thu, 27 Aug 2026 10:30:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/08/27/kubernetes-v1-37-metrics-api-ga/</guid>
      <description>
        
        
        &lt;p&gt;Kubernetes v1.37 promotes the &lt;code&gt;metrics.k8s.io&lt;/code&gt; API to stable (&lt;code&gt;v1&lt;/code&gt;). This
API provides CPU and memory usage for nodes and Pods, and is the API behind
commands such as &lt;code&gt;kubectl top&lt;/code&gt; and resource-metrics-based autoscaling.&lt;/p&gt;
&lt;p&gt;For cluster operators and application developers, this graduation means that
the API now has the stability guarantees associated with a Kubernetes stable
API. The &lt;code&gt;v1&lt;/code&gt; API has the same resource types and fields as &lt;code&gt;v1beta1&lt;/code&gt;; this is
an API-version graduation, not a change to the metrics that are collected or
returned.&lt;/p&gt;
&lt;h2 id=&#34;a-long-lived-api-reaches-stable&#34;&gt;A long-lived API reaches stable&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#a-long-lived-api-reaches-stable&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The resource Metrics API was introduced as alpha in Kubernetes v1.6 and became
beta in v1.8. It has remained unchanged and has been used in production for
years by clients including the HorizontalPodAutoscaler (HPA) and &lt;code&gt;kubectl top&lt;/code&gt;.
Kubernetes v1.37 formally graduates that proven API to &lt;code&gt;metrics.k8s.io/v1&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The API exposes two resource types:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;NodeMetrics&lt;/code&gt;, for CPU and memory usage for a node.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PodMetrics&lt;/code&gt;, for CPU and memory usage for a Pod, with a per-container
breakdown in its &lt;code&gt;containers&lt;/code&gt; field.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The API remains intentionally small. It provides the resource metrics needed
for autoscaling and basic inspection; it is not a replacement for a full
monitoring pipeline or the custom metrics (&lt;code&gt;custom.metrics.k8s.io&lt;/code&gt;) API.&lt;/p&gt;
&lt;h2 id=&#34;changes&#34;&gt;What changed with the v1.37 release?&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#changes&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The &lt;code&gt;v1&lt;/code&gt; API surface is identical to &lt;code&gt;v1beta1&lt;/code&gt;, except for the API version.
There are no renamed fields, new fields, or changes to the meaning of the
returned CPU and memory values.&lt;/p&gt;
&lt;p&gt;For example, a client can retrieve node metrics from the stable endpoint:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl get --raw /apis/metrics.k8s.io/v1/nodes
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Likewise, it can retrieve metrics for the pods in a namespace:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl get --raw /apis/metrics.k8s.io/v1/namespaces/default/pods
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;kubectl top&lt;/code&gt; supports both API versions. It prefers &lt;code&gt;v1&lt;/code&gt; when available and
automatically falls back to &lt;code&gt;v1beta1&lt;/code&gt; on clusters that do not yet serve &lt;code&gt;v1&lt;/code&gt;.
The HPA controller currently supports only &lt;code&gt;v1beta1&lt;/code&gt;. Support for
discovery-based selection between &lt;code&gt;v1&lt;/code&gt; and &lt;code&gt;v1beta1&lt;/code&gt; is planned, but is not
available in Kubernetes v1.37.&lt;/p&gt;
&lt;h2 id=&#34;what-you-need-to-do&#34;&gt;What you need to do&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#what-you-need-to-do&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;You don&#39;t need to enable any feature gate. The Metrics API is served through the
&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/tasks/extend-kubernetes/configure-aggregation-layer/&#34;&gt;API aggregation layer&lt;/a&gt;,
by an implementation such as &lt;a href=&#34;https://github.com/kubernetes-sigs/metrics-server&#34;&gt;metrics-server&lt;/a&gt;.
You can choose any implementation of &lt;code&gt;metrics.k8s.io&lt;/code&gt;; for the v1 metrics API to be
available in your cluster, your chosen implementation must serve the &lt;code&gt;v1.metrics.k8s.io&lt;/code&gt; API, and you need to &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/tasks/extend-kubernetes/configure-aggregation-layer/&#34;&gt;register&lt;/a&gt; an associated &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/reference/kubernetes-api/apiregistration/api-service-v1/&#34;&gt;APIService&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;During the transition, implementations should serve both &lt;code&gt;v1&lt;/code&gt; and &lt;code&gt;v1beta1&lt;/code&gt;.
Keeping both versions available maintains compatibility with older clients.
The &lt;code&gt;v1beta1&lt;/code&gt; API remains available in Kubernetes v1.37.&lt;/p&gt;
&lt;p&gt;You can see which versions your cluster serves with:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl get --raw /apis/metrics.k8s.io/ &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; jq .
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Once your metrics implementation supports &lt;code&gt;v1&lt;/code&gt;, you can also check that its
APIService is available:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl get apiservice v1.metrics.k8s.io
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;learn-more&#34;&gt;Learn more&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#learn-more&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Read the &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/tasks/debug/debug-cluster/resource-metrics-pipeline/&#34;&gt;Resource metrics pipeline&lt;/a&gt;
documentation.&lt;/li&gt;
&lt;li&gt;Read &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5207/&#34;&gt;KEP-5207&lt;/a&gt;, the proposal for (graduating) this API.&lt;/li&gt;
&lt;li&gt;Learn about the &lt;a href=&#34;https://github.com/kubernetes/metrics#resource-metrics-api&#34;&gt;Metrics API&lt;/a&gt;
and its reference implementation, &lt;a href=&#34;https://github.com/kubernetes-sigs/metrics-server&#34;&gt;metrics-server&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;get-involved&#34;&gt;Get involved&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#get-involved&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The Metrics API is maintained by &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/instrumentation/&#34;&gt;SIG Instrumentation&lt;/a&gt;.
To ask questions, share feedback, or contribute, join the
&lt;a href=&#34;https://kubernetes.slack.com/messages/sig-instrumentation&#34;&gt;#sig-instrumentation&lt;/a&gt;
channel on Kubernetes Slack or attend a SIG Instrumentation meeting.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes v1.37: Garhwal</title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/08/26/kubernetes-v1-37-release/</link>
      <pubDate>Wed, 26 Aug 2026 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/08/26/kubernetes-v1-37-release/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Editors:&lt;/strong&gt; Arsh Sharma, Christopher Tineo, Kirti Goyal, Sophia Ugochukwu, Swathi Rao, Troy Connor&lt;/p&gt;
&lt;p&gt;Similar to previous releases, the release of &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/releases/1.37/&#34;&gt;Kubernetes v1.37&lt;/a&gt; introduces new Stable, Beta, and Alpha features. The consistent delivery of high-quality releases underscores the strength of our development cycle and the vibrant support from our community.&lt;/p&gt;
&lt;p&gt;This release consists of 67 enhancements.
Of those enhancements, 16 have graduated to Stable, 23 have graduated to Beta,
27 are entering Alpha, and 1 is a deprecation/removal.&lt;/p&gt;
&lt;h2 id=&#34;release-theme-and-logo&#34;&gt;Release theme and logo&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#release-theme-and-logo&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;

&lt;figure class=&#34;release-logo &#34;&gt;
    &lt;img src=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/08/26/kubernetes-v1-37-release/k8s-v1.37.svg&#34;
         alt=&#34;Kubernetes v1.37 Garhwal release logo: a ringaal-inspired woven frame surrounds snow-capped Himalayan peaks, terraced fields, deodar trees, a winding river, a mountain house marked 1.37, colourful flags, a Himalayan monal, and red buransh flowers with Kubernetes helm symbols at their centres&#34;/&gt; 
&lt;/figure&gt;
&lt;p&gt;The theme for Kubernetes v1.37 is &lt;strong&gt;Garhwal&lt;/strong&gt; (गढ़वाल, pronounced &lt;em&gt;gaṛhvāl&lt;/em&gt;), a Himalayan region of Uttarakhand, India. The snow-capped peaks of the Garhwal Himalaya, deodar forests, terraced fields, rivers and streams, and mountain paths shape both the region and the logo. Together, these elements reflect a community in which every layer, route, and contribution is connected.&lt;/p&gt;
&lt;p&gt;The logo is imagined as a window into Garhwal&#39;s landscape.&lt;sup&gt;1&lt;/sup&gt; Inside, terraced fields climb towards the snowy peaks, each level supported by the one below, much as every Kubernetes release depends on work carried forward. A river winds through the valley and gathers mountain streams, reflecting contributions from many SIGs and communities flowing into one project.&lt;/p&gt;
&lt;p&gt;The deodar forest represents the wider Kubernetes ecosystem, where distinct projects share common ground and grow side by side. Stonework and woodcraft shape the path and mountain house, placing people at the centre and evoking shared foundations maintained for those who follow. Above the river, colourful flags catch the wind and bring the scene to life.&lt;/p&gt;
&lt;p&gt;Encircling the scene is a patterned frame inspired by basketry woven from &lt;em&gt;ringaal&lt;/em&gt;, a flexible dwarf Himalayan bamboo. Individual strips gain strength when interlaced, just as code, reviews, tests, documentation, and coordination come together to make a release.&lt;/p&gt;
&lt;p&gt;Within the frame, the &lt;a href=&#34;https://en.wikipedia.org/wiki/Himalayan_monal&#34;&gt;Himalayan monal&lt;/a&gt;, Uttarakhand&#39;s state bird, lives at high altitudes in the Himalaya. Its iridescent plumage holds many colours at once, much as the Kubernetes community brings many skills and perspectives into one project. Flowers of red &lt;em&gt;buransh&lt;/em&gt; (&lt;em&gt;Rhododendron arboreum&lt;/em&gt;), Uttarakhand&#39;s state tree, carry Kubernetes helms at their centres, linking a familiar bloom of Garhwal with the symbol shared by the community. The house bears १.३७ (1.37 in Devanagari numerals), grounding the release in the landscape.&lt;/p&gt;
&lt;p&gt;&lt;sub&gt;1. Keep looking through the window (the logo). Watch the river flow and the flags catch the wind. In 37 seconds, the landscape reveals its magic. 😉&lt;/sub&gt;&lt;/p&gt;
&lt;h2 id=&#34;spotlight-on-key-updates&#34;&gt;Spotlight on key updates&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#spotlight-on-key-updates&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Kubernetes v1.37 is packed with new features and improvements. Here are a few select updates the &lt;a href=&#34;https://github.com/kubernetes/sig-release/blob/master/releases/release-1.37/release-team.md&#34;&gt;Release Team&lt;/a&gt; would like to highlight!&lt;/p&gt;
&lt;h3 id=&#34;stable-resilient-watchcache-initialization&#34;&gt;Stable: Resilient watchcache initialization&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#stable-resilient-watchcache-initialization&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Kubernetes v1.37 completes the work on &lt;em&gt;resilient watch cache initialization&lt;/em&gt;: the
&lt;code&gt;ResilientWatchCacheInitialization&lt;/code&gt; feature gate reached Stable back in v1.34, and in v1.37 the remaining
&lt;code&gt;WatchCacheInitializationPostStartHook&lt;/code&gt; gate graduates to Stable and is locked on. It has defaulted to
enabled since v1.36, hardening the API server at startup and during
recovery.  Watchcache initialization and reinitialization no longer create a traffic spike of requests against &lt;code&gt;etcd&lt;/code&gt;, and
requests are handled gracefully instead of piling up while the cache warms.&lt;/p&gt;
&lt;p&gt;Instead of allowing expensive list and watch requests to overload &lt;code&gt;etcd&lt;/code&gt; or exhaust API Priority and Fairness capacity, &lt;code&gt;kube-apiserver&lt;/code&gt; now safely delegates bounded requests and rejects others with HTTP 429 responses. This reduces the risk of control
plane outages in large clusters.  Clients (including custom controllers and operators) should be designed to handle HTTP &lt;code&gt;429 Too Many Requests&lt;/code&gt; responses gracefully by respecting &lt;code&gt;Retry-After&lt;/code&gt; headers and implementing exponential backoff.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/4568/&#34;&gt;KEP #4568&lt;/a&gt; led by &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/api-machinery/&#34;&gt;SIG API Machinery&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;beta-horizontalpodautoscaler-scale-to-zero&#34;&gt;Beta: HorizontalPodAutoscaler scale to zero&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#beta-horizontalpodautoscaler-scale-to-zero&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;In Kubernetes v1.37, HorizontalPodAutoscaler &lt;em&gt;scale to zero&lt;/em&gt; support is graduating to Beta. First introduced in
Kubernetes v1.16, it is now &lt;strong&gt;enabled by default&lt;/strong&gt;.
For workloads that are using object or external metrics, this feature allows HorizontalPodAutoscalers to scale down to
zero Pods when idle, then restore them when demand returns. Doing that can reduce costs for queue consumers, batch jobs,
and GPU workloads. Setting &lt;code&gt;spec.minReplicas: 0&lt;/code&gt; applies this functionality for workloads.&lt;/p&gt;
&lt;p&gt;Scaling to zero based on CPU and memory metrics is &lt;strong&gt;not&lt;/strong&gt; supported because those metrics depend on active Pods.
Instead, this feature is for situations such as leaving the replica count at zero until there is queued work to process.&lt;/p&gt;
&lt;p&gt;While the HorizontalPodAutoscaler is holding a
workload at zero replicas, it records a &lt;code&gt;ScaledToZero&lt;/code&gt; condition with &lt;code&gt;True&lt;/code&gt; in the HorizontalPodAutoscaler&#39;s status. The
&lt;code&gt;HorizontalPodAutoscaler&lt;/code&gt; controller then uses this condition to distinguish a workload that it scaled to zero (and will
scale back up when the metric returns) from one that was manually deactivated by setting its replica count to 0. Once the
workload is scaled back up, the condition is set to &lt;code&gt;False&lt;/code&gt; with the reason &lt;code&gt;NotScaledToZero&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/2021/&#34;&gt;KEP #2021&lt;/a&gt; led by &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/autoscaling/&#34;&gt;SIG Autoscaling&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;beta-manifest-based-admission-control-configuration&#34;&gt;Beta: Manifest-based admission control configuration&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#beta-manifest-based-admission-control-configuration&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Kubernetes v1.37 graduates &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/reference/access-authn-authz/manifest-admission-control/&#34;&gt;manifest-based admission control&lt;/a&gt;
configuration to Beta. Admission webhooks and CEL-based policies can now be loaded from manifest files on disk, via the
&lt;code&gt;staticManifestsDir&lt;/code&gt; field in &lt;code&gt;AdmissionConfiguration&lt;/code&gt;, instead of living only in the Kubernetes API. Policies loaded this
way are enforced from API server startup, keep working while &lt;code&gt;etcd&lt;/code&gt; is unavailable, and can protect the API-based admission
resources themselves from modification.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5793/&#34;&gt;KEP #5793&lt;/a&gt; led by &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/api-machinery/&#34;&gt;SIG API Machinery&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;alpha-pod-level-checkpoint-and-restore&#34;&gt;Alpha: Pod-level checkpoint and restore&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#alpha-pod-level-checkpoint-and-restore&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Kubernetes v1.37 introduces Alpha support for &lt;strong&gt;Pod-level&lt;/strong&gt; checkpoint and restore,
extending the CRI with &lt;code&gt;CheckpointPod&lt;/code&gt; and &lt;code&gt;RestorePod&lt;/code&gt; RPCs, which allow the kubelet and compatible container runtimes to create a Pod checkpoint and restore a Pod from it.
To use this feature, your container runtime(s) must also implement these new RPCs.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5823/&#34;&gt;KEP #5823&lt;/a&gt; led by
&lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/node/&#34;&gt;SIG Node&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;features-graduating-to-stable&#34;&gt;Features graduating to Stable&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#features-graduating-to-stable&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;This lists all the features that graduated to Stable (also known as &lt;em&gt;General Availability&lt;/em&gt;). For a full list of updates
including new features and graduations from Alpha to Beta, see the release notes.&lt;/p&gt;
&lt;p&gt;This release includes a total of 16 enhancements promoted to Stable:&lt;/p&gt;
&lt;h3 id=&#34;kyaml&#34;&gt;KYAML&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#kyaml&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;em&gt;KYAML&lt;/em&gt; is a safer and less ambiguous subset of YAML designed specifically for Kubernetes, &lt;strong&gt;not a replacement for it&lt;/strong&gt;. Every
KYAML file is valid YAML, so KYAML is a valid input for any version of &lt;code&gt;kubectl&lt;/code&gt;, and spec files do not need to be written in
KYAML for the input to be parsed. Your existing manifests, tooling, and pipelines don&#39;t need to change.
Introduced as an Alpha feature in v1.34 and graduating to Beta in v1.35, KYAML graduates to Stable in v1.37 with conformance
testing complete, and &lt;code&gt;kubectl get -o kyaml&lt;/code&gt; is now Stable.&lt;/p&gt;
&lt;p&gt;To learn more about KYAML, check out &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/08/11/how-to-pretty-print-kubernetes-yaml-as-kyaml/&#34;&gt;How to Pretty-Print Your Kubernetes YAML as KYAML and Why You&#39;d Want To&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5295/&#34;&gt;KEP #5295&lt;/a&gt; led by &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/cli/&#34;&gt;SIG CLI&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;the-metrics-k8s-io-api&#34;&gt;The metrics.k8s.io API&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#the-metrics-k8s-io-api&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The &lt;em&gt;metrics.k8s.io&lt;/em&gt; API graduates to Stable in Kubernetes v1.37 after spending nearly nine years in Beta. The API provides a
standard way to retrieve CPU and memory usage for pods and nodes, powering widely used Kubernetes features such as the
HorizontalPodAutoscaler (HPA) and commands like &lt;code&gt;kubectl top&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The graduation follows the Kubernetes project’s goal of avoiding permanent Beta APIs. Now that &lt;code&gt;v1&lt;/code&gt; exists, future
Kubernetes releases will move over to it; &lt;code&gt;v1beta1&lt;/code&gt; remains usable throughout the transition, in line with the API
deprecation policy, so you can adopt the Stable API without breaking existing workflows.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5207/&#34;&gt;KEP #5207&lt;/a&gt; led
by &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/instrumentation/&#34;&gt;SIG Instrumentation&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;selinuxmount-and-selinuxchangepolicy&#34;&gt;&lt;code&gt;SELinuxMount&lt;/code&gt; and &lt;code&gt;SELinuxChangePolicy&lt;/code&gt;&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#selinuxmount-and-selinuxchangepolicy&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;In Kubernetes v1.37, &lt;code&gt;SELinuxMount&lt;/code&gt; and &lt;code&gt;SELinuxChangePolicy&lt;/code&gt; flags reach Stable and are enabled by default: this means that
volumes get mounted with &lt;code&gt;-o context=&amp;lt;label&amp;gt;&lt;/code&gt; (the MountOption default) instead of being recursively relabeled, but only when
the volume&#39;s CSI driver opts in via &lt;code&gt;.spec.seLinuxMount: true&lt;/code&gt; for the CSIDriver object.&lt;/p&gt;
&lt;p&gt;A mount can only carry one SELinux context, so &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/1710/#story-3-cluster-upgrade&#34;&gt;Pods with different SELinux labels sharing a volume on the same node, which
used to coexist under recursive relabeling, can now fail to start&lt;/a&gt;.
To retain the old behavior for a workload, it is advised to set the &lt;code&gt;.spec.seLinuxChangePolicy&lt;/code&gt; to &lt;code&gt;Recursive&lt;/code&gt; on a Pod.&lt;/p&gt;
&lt;p&gt;This behavior itself also isn&#39;t locked until v1.38, so disabling it cluster-wide remains an option for one more release.&lt;/p&gt;
&lt;p&gt;Clusters without SELinux enabled see no effect at all. To learn more, check &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/04/22/breaking-changes-in-selinux-volume-labeling/&#34;&gt;SELinux Volume Label Changes goes GA (and likely
implications in v1.37)&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/1710/&#34;&gt;KEP #1710&lt;/a&gt; led by &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/storage/&#34;&gt;SIG Storage&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;dra-features-graduating-to-stable&#34;&gt;DRA features graduating to Stable&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#dra-features-graduating-to-stable&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;h4 id=&#34;dra-resourceclaim-status-with-possible-standardized-network-interface-data&#34;&gt;DRA: ResourceClaim status with possible standardized network interface data&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#dra-resourceclaim-status-with-possible-standardized-network-interface-data&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;The ResourceClaim &lt;code&gt;.status.devices&lt;/code&gt; reaches Stable in Kubernetes v1.37, which allows drivers to report device-specific device
status data for each allocated device in a resource claim. This makes it easier to see how a device is configured,
troubleshoot problems, and use the device with other services.&lt;/p&gt;
&lt;p&gt;This is particularly useful for network devices; before this field was added, if a Pod requested a network device via DRA,
there was no way for any other component in the system to learn the IP address that was assigned to that network device.
The new status field provides a standardized way for the DRA driver to export that information to components that need it,
making DRA fully usable for attaching secondary network interfaces to Pods.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/4817/&#34;&gt;KEP #4817&lt;/a&gt; led by &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/node/&#34;&gt;SIG Node&lt;/a&gt; and &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/network/&#34;&gt;SIG Network&lt;/a&gt;.&lt;/p&gt;
&lt;h4 id=&#34;dra-handle-extended-resource-requests-via-dra-driver&#34;&gt;DRA: handle extended resource requests via DRA Driver&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#dra-handle-extended-resource-requests-via-dra-driver&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;DRA Extended Resource support reaches Stable in Kubernetes v1.37. This feature allows DRA drivers to fulfill requests made
through the traditional &lt;em&gt;extended resource&lt;/em&gt; mechanism, such as &lt;code&gt;abc.example/gpu: 3&lt;/code&gt; in a Pod spec, without requiring a
separate &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins/&#34;&gt;device plugin&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;With this mechanism, an extended resource name can be assigned directly to a DeviceClass. Pods requesting that resource can then have a device allocated through DRA without needing to define a ResourceClaim in the workload.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5004/&#34;&gt;KEP #5004&lt;/a&gt; led by &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/scheduling/&#34;&gt;SIG Scheduling&lt;/a&gt;.&lt;/p&gt;
&lt;h4 id=&#34;dra-device-taints-and-tolerations&#34;&gt;DRA: device taints and tolerations&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#dra-device-taints-and-tolerations&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;Support for &lt;em&gt;taints and tolerations&lt;/em&gt; for physical devices managed through DRA is now Stable in Kubernetes v1.37. By default, any available device can be considered for scheduling. This enhancement provides greater control over device scheduling by allowing DRA drivers to mark specific devices as tainted, preventing them from being selected for workloads. Alternatively, cluster administrators can create a DeviceTaintRule to taint devices based on specific selection criteria, such as all devices managed by a particular driver.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5055/&#34;&gt;KEP #5055&lt;/a&gt;
led by &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/scheduling/&#34;&gt;SIG Scheduling&lt;/a&gt;.&lt;/p&gt;
&lt;h4 id=&#34;dra-standard-numanode-device-attribute&#34;&gt;DRA: standard numaNode device attribute&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#dra-standard-numanode-device-attribute&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;Kubernetes v1.37 defines a new standard &lt;em&gt;NUMA node device attribute&lt;/em&gt;. It standardizes
&lt;code&gt;resource.kubernetes.io/numaNode&lt;/code&gt; as a shared attribute name for device NUMA node information, allowing devices managed by
different DRA drivers to be compared based on the same NUMA node. This avoids each driver defining its own attribute name and
provides a consistent way to identify NUMA placement across devices. The enhancement lands directly as Stable because it is a
naming and registration KEP with no feature gate or in-tree behavior changes.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/6072/&#34;&gt;KEP #6072&lt;/a&gt; led by &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/node&#34;&gt;SIG Node&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;node-declared-features&#34;&gt;Node declared features&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#node-declared-features&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;em&gt;Node declared features&lt;/em&gt; graduate to Stable in Kubernetes v1.37, providing a framework to declare the availability of specific, feature-gated Kubernetes features for Nodes.
This would then be used by control plane components (such as the &lt;code&gt;kube-scheduler&lt;/code&gt;, admission controllers, or the API server itself) to manage version skew.&lt;/p&gt;
&lt;p&gt;The feature introduces a new &lt;code&gt;.status.declaredFeatures&lt;/code&gt; field for Nodes, which is used to declare a feature graduating
through the Alpha → Beta → Stable stages. The control plane can use this to adopt
the correct behavior even in a cluster running a mixture of different node versions.&lt;/p&gt;
&lt;p&gt;Once features graduate to Stable and the control plane can assume all nodes support them across the supported version skew
window, nodes stop reporting them.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;kubelet&lt;/code&gt; determines its declared features when it starts, based only on feature gates and the node’s static
configuration (so any changes require a &lt;code&gt;kubelet&lt;/code&gt; restart).&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5328/&#34;&gt;KEP #5328&lt;/a&gt; led by &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/node/&#34;&gt;SIG Node&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;storage-version-migrator&#34;&gt;Storage version migrator&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#storage-version-migrator&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Kubernetes v1.37 sees the &lt;em&gt;StorageVersionMigration API&lt;/em&gt; (&lt;code&gt;storagemigration.k8s.io/v1&lt;/code&gt;) graduate to Stable and become enabled by
default. It helps migrate existing resources, both built-in and custom, from an older storage version to the new storage
version after an API upgrade, such as when the preferred storage version changes from &lt;code&gt;v1beta1&lt;/code&gt; to &lt;code&gt;v1&lt;/code&gt;. It can also be used to rewrite existing
data after a change to encryption at rest, so that stale data is stored using the new encryption settings.&lt;/p&gt;
&lt;p&gt;Historically, cluster administrators and CustomResourceDefinition authors had to use manual &lt;code&gt;kubectl get&lt;/code&gt; or
&lt;code&gt;kubectl replace&lt;/code&gt; scripts, or deploy the out-of-tree &lt;code&gt;kube-storage-version-migrator&lt;/code&gt; component to rewrite existing resources. These
approaches were often tedious, error-prone, and difficult to monitor.&lt;/p&gt;
&lt;p&gt;To start a storage version migration, users would need to create a declarative StorageVersionMigration object. The built-in
&lt;code&gt;StorageVersionMigrator&lt;/code&gt; controller in the Kubernetes control plane watches for these objects and automatically migrates
existing resources to the default storage version for that API. Since StorageVersionMigration is a standard Kubernetes API,
CRD authors can trigger migrations as part of a CRD upgrade instead of managing the migration separately.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/4192/&#34;&gt;KEP #4192&lt;/a&gt; led by &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/api-machinery/&#34;&gt;SIG API Machinery&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;pod-certificates-and-clustertrustbundles&#34;&gt;Stable: Pod certificates and Cluster Trust Bundles&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#pod-certificates-and-clustertrustbundles&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/reference/access-authn-authz/certificate-signing-requests/#pod-certificate-requests&#34;&gt;Pod certificates&lt;/a&gt; and the closely related &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/reference/access-authn-authz/certificate-signing-requests/#cluster-trust-bundles&#34;&gt;ClusterTrustBundles&lt;/a&gt;
both graduate to Stable in Kubernetes v1.37, providing first-class support for distributing private keys, X.509
certificates, and trust bundles to Pods.&lt;/p&gt;
&lt;p&gt;To use this, the developer or administrator chooses a signer name and deploys a &lt;em&gt;signer controller&lt;/em&gt; that
watches PodCertificateRequest objects, issues and refreshes certificates for eligible Pods, and maintains the corresponding ClusterTrustBundle objects containing the trust anchors needed to verify those certificates.
A workload then opts into this identity by defining a &lt;code&gt;podCertificate&lt;/code&gt; projected volume with the chosen signer name. Workloads can also mount a ClusterTrustBundle projected volume to load the trust anchor information.&lt;/p&gt;
&lt;p&gt;This work was done as part of two KEPs - &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/4317/&#34;&gt;KEP #4317&lt;/a&gt; and &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/3257/&#34;&gt;KEP #3257&lt;/a&gt; led by &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/auth/&#34;&gt;SIG Auth&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;features-graduating-to-beta&#34;&gt;Features graduating to Beta&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#features-graduating-to-beta&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;h3 id=&#34;gang-scheduling-support-in-kubernetes&#34;&gt;Gang scheduling support in Kubernetes&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#gang-scheduling-support-in-kubernetes&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;As Kubernetes becomes the de facto standard for managing AI/ML workloads at scale, scheduling workloads such as AI/ML training jobs and HPC simulations becomes more important than ever. However, scheduling becomes challenging because the default Kubernetes scheduler schedules Pods individually, which can result in some Pods being scheduled while others remain pending due to insufficient resources. This partial scheduling can lead to deadlocks and inefficient use of cluster resources.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Gang scheduling&lt;/em&gt; graduates to Beta in Kubernetes v1.37, improving upon native support for gang scheduling through the  Workload API and PodGroup concept.
This feature implements an &lt;em&gt;all-or-nothing&lt;/em&gt; scheduling strategy, ensuring that a defined group of Pods is scheduled only when the cluster has sufficient resources to accommodate the entire group. The Beta graduation of this enhancement also introduces workload-aware preemption to avoid premature preemptions that do not help a workload make progress, along with PodGroup queueing to better coordinate competing workloads.&lt;/p&gt;
&lt;p&gt;Importantly, it addresses livelock scenarios that can occur when multiple workloads are being scheduled simultaneously by the &lt;code&gt;kube-scheduler&lt;/code&gt;, preventing them from repeatedly interfering with one another without making progress.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/4671/&#34;&gt;KEP #4671&lt;/a&gt; led by &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/scheduling/&#34;&gt;SIG Scheduling&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;native-histogram-support-for-kubernetes-metrics&#34;&gt;Native histogram support for Kubernetes metrics&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#native-histogram-support-for-kubernetes-metrics&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Kubernetes exposes hundreds of histogram metrics in &lt;a href=&#34;https://prometheus.io/docs/instrumenting/exposition_formats/&#34;&gt;Prometheus format&lt;/a&gt; across its control plane components, which are essential to
monitor cluster health and debug performance issues. However, classical Prometheus histograms relied on static, pre-defined
buckets that forced a compromise between data accuracy and memory usage. To mitigate this, Prometheus introduced &lt;em&gt;native
histograms&lt;/em&gt; that use dynamic exponential bucket boundaries instead of fixed boundaries, providing significant storage efficiency,
improved query performance, and finer-grained visibility into distributions while maintaining full backward compatibility
with existing monitoring infrastructure.&lt;/p&gt;
&lt;p&gt;Kubernetes v1.37 graduates native histogram support for Kubernetes metrics to Beta. Building on the Alpha implementation,
which introduced the &lt;code&gt;NativeHistograms&lt;/code&gt; feature gate, the Beta phase improves the implementation and rollout experience. When
enabled, Kubernetes components expose histograms in both classic and native formats when the requested scrape protocol supports Native
Histograms, (specifically &lt;code&gt;PrometheusProto&lt;/code&gt;), allowing existing dashboards and alerts to continue working while users migrate at
their own pace. The implementation also refactored histograms created in &lt;code&gt;init()&lt;/code&gt; functions to use lazy initialization,
ensuring native histogram options are correctly applied after feature gates are parsed. These changes provide a more reliable
implementation while retaining safe rollout and rollback through the feature gate or Prometheus-side configuration for
Prometheus 3.x users.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5808/&#34;&gt;KEP #5808&lt;/a&gt; led by &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/instrumentation/&#34;&gt;SIG Instrumentation&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;was-features-graduating-to-beta&#34;&gt;WAS: Features graduating to Beta&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#was-features-graduating-to-beta&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;h4 id=&#34;workload-aware-preemption&#34;&gt;Workload-aware preemption&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#workload-aware-preemption&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;Kubernetes traditionally performs preemption at the Pod level, which can be inefficient for workloads made up of multiple
tightly coupled Pods. In Kubernetes v1.37, workload-aware preemption graduates to Beta, allowing the scheduler to consider a
PodGroup when making preemption decisions. This helps the scheduler consider the workload as a whole when preempting lower
priority workloads, reducing cases where individual Pods are disrupted without providing enough capacity for the workload to
make progress.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5710/&#34;&gt;KEP #5710&lt;/a&gt; led by &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/scheduling/&#34;&gt;SIG Scheduling&lt;/a&gt;.&lt;/p&gt;
&lt;h4 id=&#34;dra-resourceclaim-support-for-workloads&#34;&gt;DRA: ResourceClaim support for workloads&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#dra-resourceclaim-support-for-workloads&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;Dynamic Resource Allocation (DRA) allows Pods to request specialized resources through ResourceClaims. In Kubernetes v1.37,
DRA ResourceClaims support for workloads graduates to Beta, allowing Workload and PodGroup APIs to associate
ResourceClaims and ResourceClaimTemplates with the groups of Pods. This allows ResourceClaims to be shared across a
workload rather than reserved individually for each Pod, while ResourceClaimTemplates can create claims for PodGroups
automatically.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5729/&#34;&gt;KEP #5729&lt;/a&gt; led by &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/scheduling/&#34;&gt;SIG Scheduling&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;cadvisor-less-cri-full-stats&#34;&gt;cAdvisor-less, CRI-full container and Pod stats&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#cadvisor-less-cri-full-stats&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The &lt;code&gt;kubelet&lt;/code&gt; has historically obtained container and Pod statistics from &lt;code&gt;cAdvisor&lt;/code&gt;, while the Container Runtime
Interface (CRI) exposes statistics of its own. Having two sources for the same metrics makes it harder to tell where a
particular value came from.&lt;/p&gt;
&lt;p&gt;In Kubernetes v1.37, the cAdvisor-less, CRI-full Container and Pod Stats enhancement graduates to Beta. The enhancement
expands the CRI to provide the container and pod statistics needed by Kubernetes, allowing the &lt;code&gt;kubelet&lt;/code&gt; to get these metrics
directly from the container runtime instead of relying on &lt;code&gt;cAdvisor&lt;/code&gt; for them.&lt;/p&gt;
&lt;p&gt;This moves container and pod metrics toward a single source of truth, while reducing duplicated metric collection and
simplifying how the &lt;code&gt;kubelet&lt;/code&gt; gathers and exposes these statistics.&lt;/p&gt;
&lt;p&gt;This feature is Beta in v1.37 but &lt;strong&gt;off&lt;/strong&gt; by default; enable the &lt;code&gt;PodAndContainerStatsFromCRI&lt;/code&gt; feature gate to try it.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/2371/&#34;&gt;KEP #2371&lt;/a&gt; led by &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/node/&#34;&gt;SIG Node&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;support-memory-qos-with-cgroups-v2&#34;&gt;Support memory QoS with cgroups v2&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#support-memory-qos-with-cgroups-v2&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Kubernetes is improving its quality of service mechanisms to cover memory protection and isolation for Kubernetes workloads. For nodes running Linux, the &lt;em&gt;memory
QoS&lt;/em&gt; feature uses memory requests and limits to configure cgroup controls that can protect requested memory from reclamation and throttle memory usage before
workloads reach their hard limits. This can help reduce the impact of memory pressure on memory-sensitive workloads and improve node stability.&lt;/p&gt;
&lt;p&gt;In Kubernetes v1.37, memory QoS support is graduating to Beta. The feature uses cgroups v2 memory controls such as &lt;code&gt;memory.min&lt;/code&gt;,
&lt;code&gt;memory.low&lt;/code&gt; and &lt;code&gt;memory.high&lt;/code&gt; to provide different levels of memory protection and throttling. For example, memory requests
can be used to protect memory from reclamation, while &lt;code&gt;memory.high&lt;/code&gt; can be used to throttle workloads that exceed their
configured threshold.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;MemoryQoS&lt;/code&gt; feature gate is enabled by default in v1.37. Cluster operators can control memory protection through the &lt;code&gt;kubelet&lt;/code&gt;’s
&lt;code&gt;memoryReservationPolicy&lt;/code&gt; setting and configure memory throttling with &lt;code&gt;memoryThrottlingFactor&lt;/code&gt;. The defaults are designed to
avoid introducing unexpected memory throttling for existing workloads when upgrading to v1.37, while allowing operators to
opt into the additional memory protection capabilities.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/2570/&#34;&gt;KEP #2570&lt;/a&gt; led by &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/node/&#34;&gt;SIG Node&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;pod-level-resource-managers&#34;&gt;Pod-level resource managers&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#pod-level-resource-managers&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;In Kubernetes v1.37, &lt;em&gt;Pod-level resource managers&lt;/em&gt; graduate to Beta behind the &lt;code&gt;PodLevelResourceManagers&lt;/code&gt; feature gate,&lt;/p&gt;
&lt;p&gt;which stays &lt;strong&gt;disabled by default&lt;/strong&gt;. Enabling it allows the topology, CPU, and memory resource&lt;/p&gt;
&lt;p&gt;managers to use the resources defined for an entire Pod when making&lt;/p&gt;
&lt;p&gt;allocation and NUMA alignment decisions. This makes it possible to manage a Pod as a single resource unit while still
supporting different resource requirements between the containers within it.&lt;/p&gt;
&lt;p&gt;With pod-level resource management, a Pod can reserve a NUMA-aligned pool of CPU and memory based on its overall resource budget. Containers that require dedicated resources can receive exclusive portions of that pool, while other containers, such as sidecars or supporting workloads, can share the remaining resources. This is particularly useful for performance-sensitive workloads such as AI/ML and high-performance computing, where keeping resources close to each other on the same NUMA node can improve performance without requiring every container in the Pod to have dedicated resources.&lt;/p&gt;
&lt;p&gt;The feature also supports a container scope, where containers can continue to receive independent NUMA-aligned allocations. This provides more flexibility for workloads that combine a performance-sensitive container with other containers that have different resource requirements.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5526/&#34;&gt;KEP #5526&lt;/a&gt; led by &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/node/&#34;&gt;SIG Node&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;watch-based-route-controller-reconciliation&#34;&gt;Watch-based route controller reconciliation&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#watch-based-route-controller-reconciliation&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The route controller in the cloud-controller-manager library previously reconciled routes on a fixed interval, by default every 10 seconds. This could result in unnecessary requests to infrastructure providers, even when nothing had changed and could also delay route updates when a new Node is added.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Watch-based route controller reconciliation&lt;/em&gt; graduated to beta in Kubernetes v1.37. This release also adds observability for this work: the route controller&#39;s Alpha &lt;code&gt;route_sync_total&lt;/code&gt; metric gains two labels, &lt;code&gt;trigger&lt;/code&gt; (&lt;code&gt;periodic&lt;/code&gt; or &lt;code&gt;node_change&lt;/code&gt;) and &lt;code&gt;outcome&lt;/code&gt; (&lt;code&gt;changed&lt;/code&gt;, &lt;code&gt;noop&lt;/code&gt;, or &lt;code&gt;error&lt;/code&gt;), so operators can see whether periodic reconciliation is actually correcting route drift or just running as a no-op, and can track failed reconciles.&lt;/p&gt;
&lt;p&gt;With watch-based route controller reconciliation, the route controller can reconcile routes from watch events instead of waiting for the next fixed interval: a reconciliation can start as soon as relevant Node changes occur, such as a Node being added or removed or when its addresses or assigned Pod CIDRs change. A less frequent periodic reconciliation still runs to catch outdated routes and keep the state consistent. This behavior sits behind the &lt;code&gt;CloudControllerManagerWatchBasedRoutesReconciliation&lt;/code&gt; feature gate and is disabled by default, so the transition has not changed default behavior.&lt;/p&gt;
&lt;p&gt;This reduces unnecessary requests to infrastructure providers while allowing routes for newly added Nodes to be reconciled sooner. The change does not alter the route reconciliation logic itself; it changes when reconciliation is triggered.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5237/&#34;&gt;KEP #5237&lt;/a&gt; led by &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/cloud-provider/&#34;&gt;SIG Cloud Provider&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;storage-capacity-scoring-of-nodes&#34;&gt;Storage capacity scoring of Nodes&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#storage-capacity-scoring-of-nodes&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The &lt;code&gt;VolumeBinding&lt;/code&gt; scheduler plugin has always been able to score nodes for statically bound PVs based on free capacity, but that scoring never extended to dynamic provisioning.&lt;/p&gt;
&lt;p&gt;When a CSI driver provisions a new volume on demand, the scheduler had no way to prefer a node with more or less free space.&lt;/p&gt;
&lt;p&gt;This was a gap for local storage, as an admin might want pods landing on the node with the most free capacity to leave room for a later volume expansion or on the node with the least (but still sufficient) free capacity to bin-pack workloads and cut down on the number of nodes a cloud cluster needs to run.&lt;/p&gt;
&lt;p&gt;Kubernetes v1.37 graduates storage capacity scoring for dynamic provisioning to Beta behind the &lt;code&gt;StorageCapacityScoring&lt;/code&gt;
feature gate. First introduced in Alpha in v1.33, this feature consolidates (and deprecates) the older
&lt;code&gt;VolumeCapacityPriority&lt;/code&gt; gate from &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/1845/&#34;&gt;KEP #1845&lt;/a&gt;. When enabled, the
VolumeBinding plugin&#39;s &lt;code&gt;Score&lt;/code&gt; extension point reads &lt;code&gt;CSIStorageCapacity&lt;/code&gt; objects published by a driver&#39;s external
provisioner sidecar and scores nodes for dynamic provisioning the same way it already does for static bindings. Admins choose
the strategy via the &lt;code&gt;Shape&lt;/code&gt; setting in &lt;code&gt;VolumeBindingArgs&lt;/code&gt;, defaulting to &amp;quot;prefer the node with the maximum allocatable&amp;quot; so
there is room for expansion later.&lt;/p&gt;
&lt;p&gt;The feature depends solely on the &lt;code&gt;StorageCapacityScoring&lt;/code&gt; gate: scoring for statically
bound PVs runs as soon as it&#39;s enabled, independent of any CSI driver. A driver only needs &lt;code&gt;StorageCapacity: true&lt;/code&gt; on its
&lt;code&gt;CSIDriver&lt;/code&gt; object so that its dynamically-provisioned volumes also get capacity-aware scoring. The feature is fully
reversible, and disabling the gate stops all VolumeBinding capacity scoring — static and dynamic alike — without affecting
already scheduled pods.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/4049/&#34;&gt;KEP #4049&lt;/a&gt; led by &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/storage/&#34;&gt;SIG Storage&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;integrate-csi-volume-attach-limits-with-cluster-autoscaler&#34;&gt;Integrate CSI volume attach limits with Cluster Autoscaler&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#integrate-csi-volume-attach-limits-with-cluster-autoscaler&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Kubernetes v1.37 improves Cluster Autoscaler&#39;s integration with CSI volume attach limits, so that when it creates new
nodes for pending Pods, Cluster Autoscaler can more accurately determine how many new nodes are required to attach all
pending Pods that use CSI volumes. Cluster Autoscaler already had visibility into CSI volume attach limits for existing
nodes, but not for the nodes it was about to create, which means it could undershoot scale-ups and leave volume-backed
Pods pending even after adding capacity. The problem compounds on the scheduling side: the &lt;code&gt;NodeVolumeLimits&lt;/code&gt; plugin treats a node with no published CSI driver info as having no limits at all, so a freshly created node that hasn&#39;t yet reported its &lt;code&gt;CSINode&lt;/code&gt; object can get crowded with more volume-backed pods than it can actually mount, which is a race condition that, until now, cluster admins had no way to close.&lt;/p&gt;
&lt;p&gt;Kubernetes v1.37 graduates CSI-aware autoscaling to Beta behind the &lt;code&gt;VolumeLimitScaling&lt;/code&gt; feature gate, first introduced in Alpha in v1.35. Cluster autoscaler now runs its scale-up simulations against templated &lt;code&gt;CSINode&lt;/code&gt; objects, so it correctly accounts for attach limits whether it&#39;s scaling an existing node group or scaling one from zero. On the scheduler side, admins can opt in per &lt;code&gt;CSIDriver&lt;/code&gt;, via a new &lt;code&gt;PreventPodSchedulingIfMissing&lt;/code&gt; field, to block pod placement on nodes that haven&#39;t reported their driver yet, with dedicated &lt;code&gt;CSIDriverMissingOnNode&lt;/code&gt; and &lt;code&gt;CSINodeMissing&lt;/code&gt; errors making those scheduling failures easier to debug. The Beta phase adds e2e coverage for scale-down behavior and CSI opt-in scenarios, and updates the &lt;code&gt;failed_scale_ups_total&lt;/code&gt; and &lt;code&gt;scaled_up_nodes_total&lt;/code&gt; metrics to include CSI driver information. Both the autoscaler and scheduler changes stay strictly opt-in: disabling the feature gate restores today&#39;s default of unlimited pod placement on nodes without &lt;code&gt;CSINode&lt;/code&gt; data, so distros and admins running autoscalers that aren&#39;t CSI-aware yet (e.g. Karpenter) aren&#39;t forced into the new behavior.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5030/&#34;&gt;KEP #5030&lt;/a&gt; led by &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/autoscaling/&#34;&gt;SIG Autoscaling&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;report-last-used-time-on-a-pvc&#34;&gt;Report last used time on a PVC&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#report-last-used-time-on-a-pvc&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;code&gt;PersistentVolumeClaims&lt;/code&gt; tend to outlive the workloads that created them. When an app gets deleted or migrated, its PVC remains behind, consuming storage and increasing costs.&lt;/p&gt;
&lt;p&gt;Kubernetes v1.37 graduates PVC &amp;quot;last used&amp;quot; tracking to Beta behind the &lt;code&gt;PersistentVolumeClaimUnusedSinceTime&lt;/code&gt; feature gate, which shipped disabled by default in Alpha (v1.36) and is now enabled by default. The feature adds a new &lt;code&gt;Unused&lt;/code&gt; condition to &lt;code&gt;PersistentVolumeClaimStatus&lt;/code&gt;, managed by the existing PVC protection controller: &lt;code&gt;Status=True (Reason=NoPodsUsingPVC)&lt;/code&gt; once the last non-terminal Pod referencing the PVC goes away, and back to &lt;code&gt;Status=False (Reason=PodUsingPVC)&lt;/code&gt; as soon as a Pod starts referencing it again. The condition&#39;s &lt;code&gt;lastTransitionTime&lt;/code&gt; doubles as an &amp;quot;unused since&amp;quot; timestamp, so admins can query how long a PVC has actually been idle without Kubernetes tracking which Pod used it last or making any deletion decision itself; that&#39;s left entirely to the admin. One thing worth noting is that the timestamp reflects when the controller observed no Pods using the PVC, not the exact moment the volume unmounted at the infrastructure level, so the reported idle time may run a little short of the true figure but should never overstate it.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5541/&#34;&gt;KEP #5541&lt;/a&gt; led by &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/storage/&#34;&gt;SIG Storage&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;etcd-rangestream-support&#34;&gt;etcd RangeStream support&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#etcd-rangestream-support&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;code&gt;etcd&lt;/code&gt;&#39;s unary &lt;code&gt;Range&lt;/code&gt; RPC builds an entire response in memory before sending it back, which becomes a problem at scale. On a large list, say kube-apiserver&#39;s watch cache warming up on a big cluster, the raw key-value slice, its serialized protobuf form, and the gRPC send buffer all have to coexist in memory at once, and the resulting spikes ripple through kube-apiserver too. Pagination doesn&#39;t really fix the underlying cost either because each paginated page still walks the entire B-tree index to recompute the total result count, turning what should be an &lt;code&gt;O(limit)&lt;/code&gt; operation into an &lt;code&gt;O(total_keys)&lt;/code&gt; one on every single page.&lt;/p&gt;
&lt;p&gt;Kubernetes v1.37 ships &lt;code&gt;etcd&lt;/code&gt; &lt;code&gt;RangeStream&lt;/code&gt; support directly at Beta, behind the &lt;code&gt;EtcdRangeStream&lt;/code&gt; feature gate (&lt;code&gt;kube-apiserver&lt;/code&gt; only, &lt;strong&gt;on&lt;/strong&gt; by default).
This release adds a new server-streaming &lt;code&gt;RangeStream&lt;/code&gt; RPC that reuses the existing &lt;code&gt;RangeRequest&lt;/code&gt; but returns chunks instead of one buffered blob: the server paginates internally with adaptive chunk sizing (each chunk&#39;s target size adjusts based on &lt;code&gt;MaxRequestBytes&lt;/code&gt; and the value sizes observed so far), pins a single MVCC revision so the merged stream stays snapshot-consistent, and derives the total key count from the running tally it builds while streaming, rather than a separate index walk.
&lt;code&gt;kube-apiserver&lt;/code&gt;&#39;s watch cache initialization is the primary consumer, and it now decodes each chunk into synthetic &lt;em&gt;created&lt;/em&gt; events inline as they arrive instead of assembling the full list in memory first, with the same treatment applied to direct &lt;code&gt;GetList&lt;/code&gt; calls when &lt;code&gt;WatchList&lt;/code&gt; is disabled.&lt;/p&gt;
&lt;p&gt;The feature requires &lt;code&gt;etcd&lt;/code&gt; 3.7+; against older &lt;code&gt;etcd&lt;/code&gt;, &lt;code&gt;kube-apiserver&lt;/code&gt; detects the Unimplemented response and falls back to unary &lt;code&gt;Range&lt;/code&gt; automatically, with zero behavior change. If the pinned revision gets compacted mid-stream, &lt;code&gt;kube-apiserver&lt;/code&gt; treats it the same as any other watch cache init failure and retries, which is no worse than the compaction races a paginated List call can already hit today. Beta graduation criteria include a scalability test measuring large-list latency on a 5000-node cluster, and &lt;code&gt;etcdctl get --stream&lt;/code&gt; ships alongside it for anyone who wants to poke at the new RPC directly.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5966/&#34;&gt;KEP #5966&lt;/a&gt; led by &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/etcd/&#34;&gt;SIG etcd&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;concurrent-watch-object-decode&#34;&gt;Concurrent watch object decode&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#concurrent-watch-object-decode&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;code&gt;kube-apiserver&lt;/code&gt; decodes and transforms every watch event from &lt;code&gt;etcd&lt;/code&gt; one at a time on a single goroutine, so one slow per-event transform, most notably a CRD conversion webhook call, blocks every event queued behind it. That&#39;s mostly a nuisance for built-in resources, but for a CRD whose served version differs from its stored version, converting a cold cache serially can take minutes. If that exceeds &lt;code&gt;etcd&lt;/code&gt;&#39;s default 5-minute compaction interval, the revision the cache started reading from gets compacted before initialization finishes, the watch can&#39;t resume, and init just restarts and never converges for a large enough resource, with every client trying to list or watch it getting errors in the meantime.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;ConcurrentWatchObjectDecode&lt;/code&gt; gate has actually been in Beta, off by default, since v1.31, and Kubernetes v1.37 flips it on by default. Enabling it moves the decode/transform step onto a bounded pool of worker goroutines (10 by default, tuned from a sweep that showed gains flattening out around 8–12) instead of a single one, with a collector reassembling events back into their original order before delivery, so event ordering is preserved exactly. In benchmarks over 150k pods, concurrent decode alone cuts cache initialization about 40%, and about 55% combined with the new &lt;code&gt;EtcdRangeStream&lt;/code&gt; feature also landing this release (see KEP 5966). The main tradeoff to watch is conversion webhook load. With the feature on, up to 10 conversions can now run concurrently against a webhook during cache init instead of one at a time. The total call volume is unchanged, only how many run at once, so this mainly matters for webhooks that cap their own concurrency below 10.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/6178/&#34;&gt;KEP #6178&lt;/a&gt; led by &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/api-machinery/&#34;&gt;SIG API Machinery&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;stale-controller-mitigation&#34;&gt;Stale controller mitigation&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#stale-controller-mitigation&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Every controller in &lt;code&gt;kube-controller-manager&lt;/code&gt; works off a local cache built from watching the &lt;code&gt;kube-apiserver&lt;/code&gt;, and that watch
stream is only eventually consistent. A change can show up in milliseconds, or it can take seconds or even minutes under
load. Today operators have no visibility into that lag and no way to tell a normal delay from a controller that&#39;s fallen
dangerously out of sync, so a controller can keep reconciling against a view of the world that&#39;s already stale.&lt;/p&gt;
&lt;p&gt;Stale controller mitigation has been Beta since v1.36, enabled by default per controller behind a &lt;code&gt;StaleControllerConsistency&amp;lt;Controller&amp;gt;&lt;/code&gt;
feature gate; Kubernetes v1.37 extends it to the HorizontalPodAutoscaler controller and adds the circuit-breaking variant and
extra metrics described below. The core mechanism
is a &lt;em&gt;read your writes&lt;/em&gt; guarantee: client-go&#39;s &lt;code&gt;ResourceEventHandlerFuncs&lt;/code&gt; gets a new &lt;code&gt;BookmarkFunc&lt;/code&gt; callback so a controller
can reliably track the resource version of objects it cares about, even through edge cases the existing add/update/delete
callbacks miss. A controller records the resource version of its own writes and, on its next reconcile, skips and requeues
until its informer cache has actually caught up to that write. The DaemonSet controller is a good example of this. It tracks
DaemonSet → Pod resource versions so it won&#39;t re-reconcile against its own stale pod cache. A second, circuit-breaking
variant targets latency-sensitive controllers like node-lifecycle, which can otherwise read a stale node lease from cache and
wrongly decide it&#39;s expired; instead, it does a live GET on the disruptive decision and marks its cache &amp;quot;not ready&amp;quot; until
it&#39;s caught up, rather than acting on a stale read. &lt;code&gt;StaleControllerConsistency&lt;/code&gt; gates the mitigation itself (scoped
initially to controllers KCM has flagged as high-scale), &lt;code&gt;MonitorInformerStaleness&lt;/code&gt; is a separate, observation-only gate that
polls the apiserver directly every 5 seconds purely to surface how far behind an informer&#39;s cache actually is, and
&lt;code&gt;AtomicFIFO&lt;/code&gt; / &lt;code&gt;UnlockWhileProcessingFIFO&lt;/code&gt; are the underlying client-go workqueue plumbing the mitigation depends on. None of
this changes default reconciler behavior; a paused-and-requeued controller can look stuck when it&#39;s really just waiting on
its cache, and it rolls back cleanly since nothing it does is irreversible.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5647&#34;&gt;KEP #5647&lt;/a&gt; led by &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/api-machinery/&#34;&gt;SIG API Machinery&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;manifest-based-admission-control-config&#34;&gt;Manifest-based admission control config&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#manifest-based-admission-control-config&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;In Kubernetes, admission control is responsible for enforcing policies on resources before they are accepted by the API
server. However, admission webhooks and policies configured through the Kubernetes API are dependent on the API server and
etcd during cluster startup and cannot protect the admission configuration resources themselves. This creates a gap during
cluster bootstrap and allows critical admission policies to be modified or removed by users with sufficient privileged access.&lt;/p&gt;
&lt;p&gt;In Kubernetes v1.37, &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/reference/access-authn-authz/manifest-admission-control/&#34;&gt;manifest-based admission control&lt;/a&gt; configuration graduates to Beta, allowing admission webhooks and CEL-based&lt;/p&gt;
&lt;p&gt;policies to be loaded from manifest files on disk and enforced from API server startup. Because the configuration is managed
independently of the Kubernetes API, it can also protect API-based admission resources from modification. Manifest files are
watched for changes and valid updates are reloaded automatically, while invalid updates leave the previously loaded
configuration in place.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5793/&#34;&gt;KEP #5793&lt;/a&gt; led by &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/api-machinery/&#34;&gt;SIG API Machinery&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;improved-handling-for-undecryptable-resources&#34;&gt;Improved handling for undecryptable resources&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#improved-handling-for-undecryptable-resources&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Kubernetes stores resources in etcd, where encryption at rest can be used to protect sensitive data. However, when encrypted
resources can no longer be decrypted, for example because the encryption key is unavailable, the API server cannot read or
manage those resources normally. This can leave resources in the cluster that cannot be accessed through the Kubernetes API,
requiring administrators to manually modify the underlying etcd data to recover them.&lt;/p&gt;
&lt;p&gt;Kubernetes v1.37 includes Beta support for cluster administrators to identify and remove resources that cannot be decrypted by the API server.&lt;/p&gt;
&lt;p&gt;Previously Alpha, and introduced in Kubernetes v1.32, this support allows problem API resources to be removed via&lt;/p&gt;
&lt;p&gt;the Kubernetes API rather than directly manipulating the etcd file. This feature also provides safeguards for administrators
to verify affected resources before deletion.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/3926/&#34;&gt;KEP #3926&lt;/a&gt; led by &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/auth/&#34;&gt;SIG Auth&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;new-features-in-alpha&#34;&gt;New features in Alpha&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#new-features-in-alpha&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;h3 id=&#34;new-recreate-strategy-for-statefulset-rollouts&#34;&gt;New &lt;code&gt;Recreate&lt;/code&gt; strategy for StatefulSet rollouts&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#new-recreate-strategy-for-statefulset-rollouts&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Kubernetes v1.37 introduces the &lt;code&gt;Recreate&lt;/code&gt; strategy for StatefulSet rollouts. The StatefulSet API previously only offered two update
strategies: OnDelete (manual) and RollingUpdate (automatic, default). Similar to Deployments, the &lt;code&gt;Recreate&lt;/code&gt; update strategy
deletes all of the StatefulSet&#39;s Pods before creating new Pods that reflect modifications made to a StatefulSet&#39;s
&lt;code&gt;.spec.template&lt;/code&gt;. Using this strategy requires the &lt;code&gt;StatefulSetRecreateStrategy&lt;/code&gt; &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/reference/command-line-tools-reference/feature-gates/#StatefulSetRecreateStrategy&#34;&gt;feature gate&lt;/a&gt; to be enabled.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/3541/&#34;&gt;KEP #3541&lt;/a&gt; led by &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/apps/&#34;&gt;SIG Apps&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;dra-alpha-features-to-look-out-for&#34;&gt;DRA: Alpha features to look out for&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#dra-alpha-features-to-look-out-for&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;h4 id=&#34;dra-node-allocatable-resource-request&#34;&gt;DRA: Node allocatable resource request&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#dra-node-allocatable-resource-request&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;Kubernetes v1.37 improves Alpha support for managing node resources such as CPU, memory, and huge pages through DRA. It
unifies standard and DRA resource accounting, helping prevent the same node capacity from being counted twice.&lt;/p&gt;
&lt;p&gt;This update introduces distinct API fields for &lt;code&gt;mapping&lt;/code&gt; (for devices directly modeling core resources, like CPU/memory DRA drivers) and &lt;code&gt;overhead&lt;/code&gt; (like auxiliary host memory for accelerator devices). The kubelet now enforces these allocations across pod and container cgroups, integrates them with Memory QoS, OOM score calculations, and in-place pod resizing.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5517/&#34;&gt;KEP #5517&lt;/a&gt;,
led by &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/scheduling/&#34;&gt;SIG Scheduling&lt;/a&gt; with participation from &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/node/&#34;&gt;SIG Node&lt;/a&gt;.&lt;/p&gt;
&lt;h4 id=&#34;dra-derived-attributes&#34;&gt;DRA: derived attributes&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#dra-derived-attributes&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;Kubernetes v1.37 introduces Alpha support for &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/resource-management/dynamic-resource-allocation/dra-api/#derived-attributes&#34;&gt;derived attributes in DRA&lt;/a&gt;. Workloads can use CEL expressions to create virtual
attributes from device information and use them when selecting related devices.&lt;/p&gt;
&lt;p&gt;This makes it easier to co-locate devices such as GPUs and network interfaces, even when their drivers use different
attribute names or formats. For example, a workload can derive a shared NUMA identifier and use it to select devices with
matching topology.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/6080/&#34;&gt;KEP #6080&lt;/a&gt;, led by &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/scheduling/&#34;&gt;SIG Scheduling&lt;/a&gt; with participation from &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/network/&#34;&gt;SIG Network&lt;/a&gt;.&lt;/p&gt;
&lt;h4 id=&#34;dra-device-compatibility-groups&#34;&gt;DRA: device compatibility groups&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#dra-device-compatibility-groups&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;DRA can be used to manage devices that support different partitioning or virtualization schemes. However, some of these
configurations cannot be used together on the same physical device, such as MIG and vGPU on a GPU. Previously, these
incompatibilities could only be detected during device preparation, after the scheduler had already made its decision.&lt;/p&gt;
&lt;p&gt;In Kubernetes v1.37, DRA  adds device compatibility groups, allowing resource drivers to describe which devices can be
allocated together. The scheduler can use this information when making allocation decisions, preventing incomplete devices
from being assigned together and avoiding Pod startup failures caused by incomplete device configurations.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5963/&#34;&gt;KEP #5963&lt;/a&gt;, led by &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/scheduling/&#34;&gt;SIG Scheduling&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;scheduler-preemption-in-place-pod-resize&#34;&gt;Scheduler preemption for in-place Pod resize&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#scheduler-preemption-in-place-pod-resize&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Kubernetes v1.37 introduces &lt;em&gt;scheduler preemption for in-place pod resize&lt;/em&gt;, behind  the (opt-in, Alpha) &lt;code&gt;InPlacePodVerticalScalingSchedulerPreemption&lt;/code&gt; feature gate. This change addresses an important feature gap that remained after the core &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/workloads/pods/pod-lifecycle/#pod-resize-inplace&#34;&gt;pn-place Pod vertical scaling&lt;/a&gt; feature graduated to Stable: if a running pod requested additional resources that exceeded the node&#39;s available capacity, &lt;code&gt;kubelet&lt;/code&gt; marked the
request as &lt;code&gt;Deferred&lt;/code&gt;, leaving the pod waiting until sufficient resources became available on the node. With this
enhancement, the Kubernetes control plane can actively free up capacity on a fully-utilized node and preempt lower-priority
workloads, enabling the pending in-place resizes of critical, higher-priority applications to succeed.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5836/&#34;&gt;KEP #5836&lt;/a&gt; led by &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/scheduling/&#34;&gt;SIG Scheduling&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;dynamic-resize-of-memory-backed-volumes&#34;&gt;Dynamic resize of memory-backed volumes&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#dynamic-resize-of-memory-backed-volumes&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Also building upon in-place Pod vertical scaling, the Alpha &lt;em&gt;in-place scaling for memory backed volumes&lt;/em&gt; feature extends the pod&lt;/p&gt;
&lt;p&gt;&lt;code&gt;/resize&lt;/code&gt; subresource, which previously only enabled dynamic CPU and memory adjustments without restarting containers, to
support updating the &lt;code&gt;sizeLimit&lt;/code&gt; of memory-backed (medium: Memory) &lt;code&gt;emptyDir&lt;/code&gt; volumes on running pods. When a volume&#39;s &lt;code&gt;sizeLimit&lt;/code&gt;
is explicitly adjusted via the /resize subresource, Kubelet dynamically updates the underlying tmpfs mount without container
disruption while safely preventing out-of-memory errors or false-positive eviction triggers. This is particularly useful for
stateful and memory-intensive workloads that rely on in-memory ephemeral storage, allowing them to dynamically scale storage
limits alongside container memory capacity without incurring Pod restarts or application downtime.&lt;/p&gt;
&lt;p&gt;This is an opt-in, off-by-default Alpha feature. To try it out, enable the&lt;/p&gt;
&lt;p&gt;&lt;code&gt;InPlacePodVerticalScalingMemoryBackedVolumes&lt;/code&gt; feature gate.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/6030/&#34;&gt;KEP #6030&lt;/a&gt; led by &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/node/&#34;&gt;SIG Node&lt;/a&gt; and &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/storage/&#34;&gt;SIG Storage&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;specialized-lifecycle-management-for-nodes&#34;&gt;Specialized lifecycle management for Nodes&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#specialized-lifecycle-management-for-nodes&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Several Kubernetes components need to understand a Node&#39;s lifecycle state, and today each one infers it from a different mix
of Node readiness, taints, Pod state, labels, annotations, and provider APIs. This enhancement introduces well-known
lifecycle conditions on Nodes, giving administrators a single Kubernetes-owned place to publish lifecycle state that core
controllers and ecosystem tooling can consume. These new Node Conditions are: &lt;code&gt;DrainInProgress&lt;/code&gt;, &lt;code&gt;Drained&lt;/code&gt;, &lt;code&gt;MaintenancePlanned&lt;/code&gt;, &lt;code&gt;MaintenanceInProgress&lt;/code&gt;, and &lt;code&gt;GracefulNodeShutdownInProgress&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5683/&#34;&gt;KEP #5683&lt;/a&gt; led by &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/node/&#34;&gt;SIG Node&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;was-alpha-features-to-look-out-for&#34;&gt;WAS: Alpha features to look out for&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#was-alpha-features-to-look-out-for&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;h4 id=&#34;compositepodgroup-api&#34;&gt;CompositePodGroup API&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#compositepodgroup-api&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;While previous releases introduced support for gang scheduling of workloads with
a flat structure, modern AI/ML workloads are complex and have more sophisticated
scheduling requirements. In Kubernetes v1.37, the new Alpha &lt;code&gt;CompositePodGroup&lt;/code&gt;
API allows Kubernetes to describe complex workloads as a hierarchy of groups
instead of a flat set of Pods. This enables multi-level gang scheduling,
workload-aware preemption and topology-aware scheduling.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/6012/&#34;&gt;KEP #6012&lt;/a&gt; led by &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/scheduling/&#34;&gt;SIG Scheduling&lt;/a&gt;&lt;/p&gt;
&lt;h4 id=&#34;workload-aware-scheduling-controller-apis&#34;&gt;Workload Aware Scheduling Controller APIs&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#workload-aware-scheduling-controller-apis&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;As an Alpha feature Kubernetes v1.37 provides common framework for integrating workload controllers (such as JobSet, TrainJob, LWS, and RayJob, along with core workloads such as &lt;code&gt;Job&lt;/code&gt;) with &lt;em&gt;Workload-aware Scheduling&lt;/em&gt; (WAS).
As an Alpha feature Kubernetes v1.37 provides common framework for integrating workload controllers (such as JobSet, TrainJob, LWS, and RayJob, along with core workloads such as &lt;code&gt;Job&lt;/code&gt;) with &lt;em&gt;Workload-aware Scheduling&lt;/em&gt; (WAS).&lt;/p&gt;
&lt;p&gt;The framework provides reusable &lt;code&gt;scheduling.k8s.io&lt;/code&gt; API primitives, such as &lt;em&gt;topology constraints&lt;/em&gt; and &lt;em&gt;disruption policies&lt;/em&gt;,
along with shared libraries that handle the creation of scheduling resources. This allows controllers to expose WAS features
natively within their APIs in a consistent way without implementing the same scheduling logic separately.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/6089/&#34;&gt;KEP #6089&lt;/a&gt; led by &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/scheduling/&#34;&gt;SIG Scheduling&lt;/a&gt;.&lt;/p&gt;
&lt;h4 id=&#34;workload-apis-job-controller&#34;&gt;Integrate workload APIs with the Job controller&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#workload-apis-job-controller&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;Initially introduced in Kubernetes v1.36 with limited functionality, this feature builds on top of the &lt;a href=&#34;#workload-aware-scheduling-controller-apis&#34;&gt;Workload Aware Scheduling Controller APIs&lt;/a&gt; adding a new user-facing &lt;code&gt;spec.scheduling&lt;/code&gt; field to the &lt;code&gt;batch/v1&lt;/code&gt; Job in Kubernetes v1.37, allowing users
to explicitly configure scheduling policies, topology constraints, disruption modes, and resource claims. If
&lt;code&gt;spec.scheduling&lt;/code&gt; is omitted, the Job defaults to Basic scheduling, preserving existing behavior while still creating a Basic
Workload/PodGroup for workload-aware scheduling, without enforcing a minCount gate. Users can explicitly opt into Gang
scheduling, where &lt;code&gt;minCount&lt;/code&gt; defaults to the Job’s parallelism, and the controller uses the shared &lt;code&gt;workloadbuilder&lt;/code&gt; library
to translate the scheduling configuration into the corresponding Workload and PodGroup objects instead of implementing custom
translation logic.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5547/&#34;&gt;KEP #5547&lt;/a&gt; led by &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/scheduling/&#34;&gt;SIG Scheduling&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;localhost-nodeport-userspace-proxy-for-nftables&#34;&gt;localhost NodePort userspace proxy for &lt;code&gt;nftables&lt;/code&gt;&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#localhost-nodeport-userspace-proxy-for-nftables&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Kubernetes v1.37 adds an opt-in userspace proxy to the &lt;code&gt;nftables&lt;/code&gt; &lt;code&gt;kube-proxy&lt;/code&gt; backend, allowing NodePort services to be accessed
through &lt;code&gt;localhost&lt;/code&gt; over IPv4 and IPv6. This closes a gap between the &lt;code&gt;nftables&lt;/code&gt; and &lt;code&gt;iptables&lt;/code&gt; backends, as &lt;code&gt;nftables&lt;/code&gt; could not
previously serve localhost NodePorts.&lt;/p&gt;
&lt;p&gt;The proxy is enabled when &lt;code&gt;localhost&lt;/code&gt; or a loopback address is included in the &lt;code&gt;kube-proxy&lt;/code&gt; &lt;code&gt;--nodeport-addresses&lt;/code&gt;
configuration. This can be useful for workloads such as local container registries that rely on &lt;code&gt;localhost:&amp;lt;NodePort&amp;gt;&lt;/code&gt;
connections. The existing behavior of the &lt;code&gt;iptables&lt;/code&gt; and &lt;code&gt;ipvs&lt;/code&gt; backends is unchanged.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/6032/&#34;&gt;KEP #6032&lt;/a&gt; led by &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/network/&#34;&gt;SIG Network&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;other-notable-changes&#34;&gt;Other notable changes&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#other-notable-changes&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;h3 id=&#34;maxunavailable-for-statefulsets-back-on-by-default&#34;&gt;&lt;code&gt;maxUnavailable&lt;/code&gt; for StatefulSets back on by default&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#maxunavailable-for-statefulsets-back-on-by-default&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The &lt;code&gt;maxUnavailable&lt;/code&gt; field for StatefulSets has been re-enabled by default in Kubernetes v1.37 (after a bug was observed
in v1.36).&lt;/p&gt;
&lt;p&gt;The bug occurred where a faulty initial StatefulSet revision created a Pod that never became ready, and with
&lt;code&gt;MaxUnavailableStatefulSet&lt;/code&gt; enabled, the StatefulSet controller failed to update that Pod to the newer, corrected
revision. When the bug triggered, the affected Pod could end up stuck in a CrashLoopBackOff state indefinitely (see &lt;a href=&#34;https://github.com/kubernetes/kubernetes/issues/137409&#34;&gt;kubernetes#137409&lt;/a&gt;).&lt;/p&gt;
&lt;h3 id=&#34;improved-nftables-performance&#34;&gt;Improved &lt;code&gt;nftables&lt;/code&gt; performance&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#improved-nftables-performance&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;kube-proxy now uses the kernel’s netlink interface for nftables rule operations, bypassing the &lt;code&gt;nft&lt;/code&gt; command-line tool. This makes kube-proxy more efficient when inspecting and managing its nftables rules, improving rule-management performance.&lt;/p&gt;
&lt;h3 id=&#34;context-handling-and-contextual-logging-in-client-go&#34;&gt;Context handling and contextual logging in client-go&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#context-handling-and-contextual-logging-in-client-go&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Support for context propagation and contextual logging in client-go is complete, with the exception of a small number of
authentication plugin log calls that still rely on the global klog logger because the underlying APIs do not support context
passing.&lt;/p&gt;
&lt;h2 id=&#34;graduations-deprecations-and-removals-in-v1-37&#34;&gt;Graduations, deprecations, and removals in v1.37&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#graduations-deprecations-and-removals-in-v1-37&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;h3 id=&#34;graduations-to-stable&#34;&gt;Graduations to Stable&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#graduations-to-stable&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;This lists all the features that graduated to Stable (also known as general availability). For a full list of updates
including new features and graduations from Alpha to Beta, see the release notes.&lt;/p&gt;
&lt;p&gt;This release includes a total of 16 enhancements promoted to Stable:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.kubernetes.dev/resources/keps/1710/&#34;&gt;Speed up recursive SELinux label change&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.kubernetes.dev/resources/keps/3257/&#34;&gt;ClusterTrustBundles&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.kubernetes.dev/resources/keps/4317/&#34;&gt;Pod Certificates&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.kubernetes.dev/resources/keps/4762/&#34;&gt;Allow setting arbitrary FQDN as the pod&#39;s hostname&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.kubernetes.dev/resources/keps/4817/&#34;&gt;DRA: Resource Claim Status with possible standardized network interface data&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.kubernetes.dev/resources/keps/4951/&#34;&gt;Configurable tolerance for HorizontalPodAutoscalers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5311/&#34;&gt;Relaxed validation for Services names&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.kubernetes.dev/resources/keps/4680/&#34;&gt;Add Resource Health Status to the Pod Status for Device Plugin and DRA&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5055/&#34;&gt;DRA: device taints and tolerations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5004/&#34;&gt;DRA: Handle extended resource requests via DRA Driver&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5328/&#34;&gt;Node Declared Features&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.kubernetes.dev/resources/keps/3085/&#34;&gt;Add condition for sandbox creation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.kubernetes.dev/resources/keps/4192/&#34;&gt;Move Storage Version Migrator in-tree&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.kubernetes.dev/resources/keps/4568/&#34;&gt;Resilient Watchcache Initialization&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.kubernetes.dev/resources/keps/6072/&#34;&gt;DRA: Standard numaNode Device Attribute&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5207/&#34;&gt;metrics.k8s.io API definition&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5295/&#34;&gt;KYAML&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;deprecations-removals-and-community-updates&#34;&gt;Deprecations, removals and community updates&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#deprecations-removals-and-community-updates&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;As Kubernetes develops and matures, features may be deprecated, removed, or replaced with better ones for the project&#39;s
overall health.
See the Kubernetes &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/reference/using-api/deprecation-policy/&#34;&gt;deprecation and removal policy&lt;/a&gt; for more details on this process.
Many of these deprecations and removals were announced in the &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/07/31/kubernetes-v1-37-sneak-peek/&#34;&gt;Deprecations and Removals blog&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;deprecation-of-kube-dns&#34;&gt;Deprecation of &lt;code&gt;kube-dns&lt;/code&gt;&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#deprecation-of-kube-dns&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;CoreDNS has been the default cluster DNS add-on since Kubernetes v1.13, and &lt;code&gt;kube-dns&lt;/code&gt; has not kept pace since then; features like EndpointSlices and dual-stack Services aren&#39;t available in it.&lt;/p&gt;
&lt;p&gt;Kubernetes has already retired the kube-dns subproject and has split node-local-dns out into its own &lt;a href=&#34;https://github.com/kubernetes-sigs/node-local-dns&#34;&gt;repository&lt;/a&gt;, where it continues to be maintained and works with CoreDNS. It is expected that no new packages will be built for kube-dns after v1.40.&lt;/p&gt;
&lt;p&gt;If you still run &lt;code&gt;kube-dns&lt;/code&gt;, &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/tasks/administer-cluster/coredns/&#34;&gt;start planning to migrate your clusters to CoreDNS&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;deprecating-kube-proxy-s-support-for-ipvs-mode&#34;&gt;Deprecating &lt;code&gt;kube-proxy&lt;/code&gt;&#39;s support for &lt;code&gt;ipvs&lt;/code&gt; mode&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#deprecating-kube-proxy-s-support-for-ipvs-mode&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;code&gt;kube-proxy&lt;/code&gt; support for &lt;code&gt;ipvs&lt;/code&gt; mode was introduced in v1.8 to resolve &lt;code&gt;iptables&lt;/code&gt; performance bottlenecks. However, since the
kernel &lt;code&gt;ipvs&lt;/code&gt; API alone cannot fully implement Kubernetes Services, &lt;code&gt;ipvs&lt;/code&gt; mode continues to use &lt;code&gt;iptables&lt;/code&gt; underneath
(&lt;a href=&#34;https://github.com/kubernetes/enhancements/blob/master/keps/sig-network/3866-nftables-proxy/README.md#the-ipvs-mode-of-kube-proxy-will-not-save-us&#34;&gt;KEP-3866, &amp;quot;The ipvs mode of kube-proxy will not save us&amp;quot;&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Clusters running &lt;code&gt;kube-proxy&lt;/code&gt; in &lt;code&gt;ipvs&lt;/code&gt; mode (or mode: &lt;code&gt;ipvs&lt;/code&gt; in KubeProxyConfiguration) now log a deprecation warning on startup. The deprecation timeline looks like this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;By v1.40, &lt;code&gt;ipvs&lt;/code&gt; mode for &lt;code&gt;kube-proxy&lt;/code&gt; is expected to be disabled by default (still selectable via the feature gate)&lt;/li&gt;
&lt;li&gt;By v1.43, support for &lt;code&gt;ipvs&lt;/code&gt; mode would be removed entirely &lt;a href=&#34;https://github.com/kubernetes/enhancements/blob/master/keps/sig-network/5495-deprecate-ipvs-mode-in-kube-proxy/README.md#graduation-criteria&#34;&gt;KEP #5495, Graduation Criteria&lt;/a&gt;.
To confirm which mode you’re currently running, use:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl -n kube-system get configmap kube-proxy -o &lt;span class=&#34;nv&#34;&gt;jsonpath&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;{.data.config\.conf}&amp;#39;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; grep &lt;span class=&#34;s1&#34;&gt;&amp;#39;mode:&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To understand the rationale behind this deprecation, see &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5495/&#34;&gt;KEP #5495&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;kubectl-kubectl-run-filename-f-to-be-deprecated&#34;&gt;&lt;code&gt;kubectl&lt;/code&gt;: &lt;code&gt;kubectl run --filename/-f&lt;/code&gt; to be deprecated&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#kubectl-kubectl-run-filename-f-to-be-deprecated&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The &lt;code&gt;--filename&lt;/code&gt; (or &lt;code&gt;-f&lt;/code&gt;) flag for &lt;code&gt;kubectl run&lt;/code&gt; is being deprecated as the generated pod is always built purely from CLI arguments like &lt;code&gt;NAME&lt;/code&gt; and &lt;code&gt;--image&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;See &lt;a href=&#34;https://github.com/kubernetes/kubernetes/issues/138671&#34;&gt;kubernetes/kubernetes#138671&lt;/a&gt; for the original issue and discussion.&lt;/p&gt;
&lt;h3 id=&#34;kubelet-static-pods-can-no-longer-reference-secrets-or-configmaps&#34;&gt;&lt;code&gt;kubelet&lt;/code&gt;: static Pods can no longer reference Secrets or ConfigMaps&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#kubelet-static-pods-can-no-longer-reference-secrets-or-configmaps&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Static Pods were never meant to read API resources directly, since they aren&#39;t created through the API server — but a bug let them reference Secrets or ConfigMaps via fields like &lt;code&gt;configMapRef&lt;/code&gt; or &lt;code&gt;secretRef&lt;/code&gt;. That bug is now fixed: as of v1.37 these references are strictly prohibited, and the &lt;code&gt;PreventStaticPodAPIReferences&lt;/code&gt; feature gate that previously let you opt out of the restriction has been removed.&lt;/p&gt;
&lt;p&gt;See &lt;a href=&#34;https://github.com/kubernetes/kubernetes/issues/140226&#34;&gt;kubernetes/kubernetes#140226&lt;/a&gt; for the original issue and discussion.&lt;/p&gt;
&lt;h3 id=&#34;ongoing-major-change-future-removal-of-cgroup-v1-support&#34;&gt;Ongoing major change: Future removal of cgroup v1 support&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#ongoing-major-change-future-removal-of-cgroup-v1-support&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;As modern Linux distributions and container runtimes use &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/architecture/cgroups/&#34;&gt;cgroup v2&lt;/a&gt; as the default,
support for the legacy cgroup v1 is officially being phased out. Since the v1.35 release, the &lt;code&gt;failCgroupV1&lt;/code&gt; setting has
defaulted to true. Consequently, the &lt;code&gt;kubelet&lt;/code&gt; will fail to initialize on any nodes that still rely on cgroup v1 unless an
explicit configuration override is applied.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;kubelet.config.k8s.io/v1beta1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;KubeletConfiguration&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;failCgroupV1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# temporary override&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Using this override should be considered a short-term fix. Advanced resource management capabilities, such as memory QoS and in-place scaling for memory-backed volumes, work only on cgroups v2. While the override remains available in Kubernetes
v1.37, users are encouraged to migrate to cgroups v2, as support for cgroups v1 is planned to be removed in a future release.&lt;/p&gt;
&lt;p&gt;To learn more about this deprecation, refer to &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5573/&#34;&gt;KEP #5573&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;release-notes&#34;&gt;Release notes&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#release-notes&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Check out the full details of the Kubernetes v1.37 release in our &lt;a href=&#34;https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.37.md&#34;&gt;release notes&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;availability&#34;&gt;Availability&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#availability&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/releases/1.37/&#34;&gt;Kubernetes v1.37&lt;/a&gt; is available for download from
the &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/releases/download/&#34;&gt;Kubernetes download page&lt;/a&gt; or direct from on &lt;a href=&#34;https://github.com/kubernetes/kubernetes/releases/tag/v1.37.0&#34;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To get started with Kubernetes, check out &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/tutorials/&#34;&gt;these tutorials&lt;/a&gt; or run local Kubernetes clusters using &lt;a href=&#34;https://minikube.sigs.k8s.io/&#34;&gt;minikube&lt;/a&gt;.
You can also easily install v1.37 using &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/setup/independent/create-cluster-kubeadm/&#34;&gt;kubeadm&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;release-team&#34;&gt;Release team&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#release-team&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Kubernetes is only possible with the support, commitment, and hard work of its community.
Each release team is made up of dedicated community volunteers who work together to build the many pieces that make up the
Kubernetes releases you rely on.&lt;/p&gt;
&lt;p&gt;This requires the specialized skills of people from all corners of our community, from the code itself to its documentation
and project management.&lt;/p&gt;
&lt;p&gt;We would like to thank the entire &lt;a href=&#34;https://github.com/kubernetes/sig-release/blob/master/releases/release-1.37/release-team.md&#34;&gt;release team&lt;/a&gt; for the hours spent hard at work to deliver the Kubernetes v1.37 release to our community.&lt;/p&gt;
&lt;p&gt;The Release Team&#39;s membership ranges from first-time shadows to returning team leads with experience forged over several
release cycles.&lt;/p&gt;
&lt;p&gt;A very special thanks goes out to our release lead, &lt;a href=&#34;https://github.com/dipesh-rawat&#34;&gt;Dipesh Rawat&lt;/a&gt;, for supporting us
through a successful release cycle, advocating for us, making sure that we could all contribute in the best way possible, and
challenging us to improve the release process.&lt;/p&gt;
&lt;h3 id=&#34;project-velocity&#34;&gt;Project velocity&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#project-velocity&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The CNCF K8s &lt;a href=&#34;https://k8s.devstats.cncf.io/d/11/companies-contributing-in-repository-groups?orgId=1&amp;var-period=m&amp;var-repogroup_name=All&#34;&gt;DevStats&lt;/a&gt; project aggregates a number of interesting data points related to the velocity of Kubernetes and various sub-projects.&lt;/p&gt;
&lt;p&gt;This includes everything from individual contributions to the number of companies that are contributing and is an
illustration of the depth and breadth of effort that goes into evolving this ecosystem.&lt;/p&gt;
&lt;p&gt;In the v1.37 release cycle, which ran for 15 weeks from May 18th, 2026, to August 26th, 2026, contributions to Kubernetes reached a maximum of 212 different companies and 1,754 individuals.&lt;/p&gt;
&lt;p&gt;Source for this data:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://k8s.devstats.cncf.io/d/11/companies-contributing-in-repository-groups?orgId=1&amp;from=1779058800000&amp;to=1787781600000&amp;var-period=d28&amp;var-repogroup_name=All&amp;var-repo_name=kubernetes%2Fkubernetes&#34;&gt;Companies contributing to Kubernetes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://k8s.devstats.cncf.io/d/11/companies-contributing-in-repository-groups?orgId=1&amp;from=1779055200000&amp;to=1787781600000%20&amp;var-period=d28&amp;var-repogroup_name=All&amp;var-repo_name=kubernetes%2Fkubernetes&#34;&gt;Overall ecosystem contributions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;By contribution we mean when someone makes a commit, code review, comment, creates an issue or PR, reviews a PR (including
blogs and documentation), or comments on issues and PRs.&lt;/p&gt;
&lt;p&gt;If you are interested in contributing, check out our &lt;a href=&#34;https://www.kubernetes.dev/docs/guide/#getting-started&#34;&gt;getting started&lt;/a&gt;
page.&lt;/p&gt;
&lt;h3 id=&#34;event-updates&#34;&gt;Event updates&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#event-updates&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Explore the upcoming KubeCons worldwide:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.lfopensource.cn/kubecon-cloudnativecon-openinfra-summit-pytorch-conference-china/&#34;&gt;KubeCon + CloudNativeCon China&lt;/a&gt;:
September 7–9, 2026, in Shanghai, China&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://events.linuxfoundation.org/kubecon-cloudnativecon-north-america/&#34;&gt;KubeCon + CloudNativeCon North America&lt;/a&gt;:
November 9–12, 2026, in Salt Lake City, United States&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Explore the upcoming Kubernetes Community Days (KCDs) taking place for the rest of 2026:&lt;/p&gt;
&lt;h4 id=&#34;september-2026&#34;&gt;September 2026&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#september-2026&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://community2.cncf.io/events/details/cncf-kcd-south-korea-presents-kcd-x-ceph-x-openinfra-day-korea-2026/&#34;&gt;KCD x Ceph x OpenInfra Day Korea&lt;/a&gt;:
September 1, 2026, in Seoul, South Korea&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://community2.cncf.io/events/details/cncf-kcd-sf-bay-area-presents-kcd-san-francisco-bay-area-2026/&#34;&gt;KCD San Francisco Bay Area&lt;/a&gt;:
September 1, 2026, in Mountain View, United States&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://community2.cncf.io/events/details/cncf-kcd-washington-dc-presents-kcd-washington-dc-2026/&#34;&gt;KCD Washington DC&lt;/a&gt;:
September 15, 2026, in Washington, DC, United States&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://community2.cncf.io/events/details/cncf-kcd-gujarat-presents-kcd-gujarat-2026/&#34;&gt;KCD Gujarat&lt;/a&gt;:
September 19, 2026, in Ahmedabad, India&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://community2.cncf.io/events/details/cncf-kcd-brasil-presents-kcd-sao-paulo-2026/&#34;&gt;KCD São Paulo&lt;/a&gt;:
September 26, 2026, in São Paulo, Brazil&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://community2.cncf.io/events/details/cncf-kcd-sofia-presents-kubernetes-community-days-sofia-2026/&#34;&gt;KCD Sofia&lt;/a&gt;:
September 29, 2026, in Sofia, Bulgaria&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;october-2026&#34;&gt;October 2026&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#october-2026&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://community2.cncf.io/events/details/cncf-kcd-uk-presents-kubernetes-community-days-uk-edinburgh-2026/&#34;&gt;KCD UK – Edinburgh&lt;/a&gt;:
October 19–20, 2026, in Edinburgh, United Kingdom&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://community2.cncf.io/events/details/cncf-kcd-nigeria-presents-kcd-nigeria-2026-telling-the-african-cloud-native-story/&#34;&gt;KCD Nigeria&lt;/a&gt;:
October 24, 2026, in Lagos, Nigeria&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;november-2026&#34;&gt;November 2026&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#november-2026&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://community2.cncf.io/events/details/cncf-kcd-porto-presents-kcd-porto-2026-collab-with-devops-days-portugal/&#34;&gt;KCD Porto&lt;/a&gt;:
November 19–20, 2026, in Porto, Portugal&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://sessionize.com/kcd-hangzhou-2026/&#34;&gt;KCD Hangzhou&lt;/a&gt;:
November 28, 2026, in Hangzhou, China&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;december-2026&#34;&gt;December 2026&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#december-2026&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://community2.cncf.io/events/details/cncf-kcd-suisse-romande-presents-kcd-suisse-romande-2026/&#34;&gt;KCD Suisse Romande&lt;/a&gt;:
December 9–10, 2026, in Meyrin, Switzerland&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://community2.cncf.io/events/details/cncf-kcd-provence-presents-kcd-provence-2026/&#34;&gt;KCD Provence&lt;/a&gt;:
December 10, 2026, in Aix-en-Provence, France&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://community2.cncf.io/events/details/cncf-kcd-florida-presents-kcd-florida-2026-miami/&#34;&gt;KCD Florida – Miami&lt;/a&gt;:
December 11, 2026, in Miami, United States&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can find the latest event details at the &lt;a href=&#34;https://community2.cncf.io/events/#/list&#34;&gt;CNCF Events Page&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;upcoming-release-webinar&#34;&gt;Upcoming release webinar&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#upcoming-release-webinar&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Join members of the Kubernetes v1.37 Release Team on Wednesday, September 23rd, 2026 at 4:00 PM (UTC) to learn about the release highlights of this release. For more information and registration, visit the &lt;a href=&#34;https://community2.cncf.io/events/details/cncf-cncf-online-programs-presents-cloud-native-live-kubernetes-v137-webinar/&#34;&gt;event page on the CNCF Online Programs site&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;get-involved&#34;&gt;Get involved&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#get-involved&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The simplest way to get involved with Kubernetes is by joining one of the many &lt;a href=&#34;https://kubernetes.dev/community/community-groups/sigs/&#34;&gt;Special Interest Groups&lt;/a&gt; (SIGs) that align with your interests.&lt;/p&gt;
&lt;p&gt;If you don&#39;t know where to start, join our monthly &lt;a href=&#34;https://www.kubernetes.dev/docs/orientation/&#34;&gt;New Contributor Orientations&lt;/a&gt;
where we teach the community how the project is structured, and we&#39;ll guide you on how to make your first contribution to the project.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Read more on how to become a &lt;a href=&#34;https://www.kubernetes.dev/docs/guide/&#34;&gt;Kubernetes Contributor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Read more about what’s happening with Kubernetes on our &lt;a href=&#34;https://kubernetes.io/blog/&#34;&gt;blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Join us on &lt;a href=&#34;http://slack.k8s.io/&#34;&gt;Slack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Follow us on &lt;a href=&#34;https://bsky.app/profile/kubernetes.io&#34;&gt;Bluesky&lt;/a&gt; for the latest updates&lt;/li&gt;
&lt;li&gt;Follow us on &lt;a href=&#34;https://www.linkedin.com/company/kubernetes/&#34;&gt;LinkedIn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Follow us on &lt;a href=&#34;https://x.com/kubernetesio&#34;&gt;X&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Join the community discussion on &lt;a href=&#34;https://discuss.kubernetes.io/&#34;&gt;Discuss&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Post questions (or answer questions) on &lt;a href=&#34;http://stackoverflow.com/questions/tagged/kubernetes&#34;&gt;Stack Overflow&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Share your &lt;a href=&#34;https://www.cncf.io/case-studies/&#34;&gt;Kubernetes End User Story&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Learn more about the &lt;a href=&#34;https://github.com/kubernetes/sig-release/tree/master/release-team&#34;&gt;Kubernetes Release Team&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>How to Pretty-Print Your Kubernetes YAML as KYAML and Why You&#39;d Want To</title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/08/11/how-to-pretty-print-kubernetes-yaml-as-kyaml/</link>
      <pubDate>Tue, 11 Aug 2026 10:00:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/08/11/how-to-pretty-print-kubernetes-yaml-as-kyaml/</guid>
      <description>
        
        
        &lt;p&gt;YAML has been the standard way to write Kubernetes manifests for years. Every example, tutorial, and configuration file you come across is written in it. The problem isn&#39;t that YAML is a bad format. It&#39;s that YAML gives you a lot of choices, and not all of them are equally good for writing Kubernetes manifests. Some features make files harder to read, some are easy to misuse and others can lead to surprising behavior.&lt;/p&gt;
&lt;p&gt;The interesting part is that Kubernetes doesn&#39;t actually need most of those features. It only relies on a small subset of YAML. This led to a simple question: if Kubernetes only needs a small part of YAML, why not &lt;em&gt;standardize&lt;/em&gt;  on that part and avoid the rest? Instead of introducing a new configuration language, &lt;a href=&#34;https://github.com/kubernetes/community/tree/main/sig-cli&#34;&gt;SIG CLI&lt;/a&gt; introduced &lt;strong&gt;KYAML&lt;/strong&gt;, a stricter, more consistent way to write YAML.&lt;/p&gt;
&lt;h2 id=&#34;what-is-kyaml&#34;&gt;What is KYAML?&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#what-is-kyaml&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;&lt;em&gt;&lt;strong&gt;KYAML is a strict subset (or &amp;quot;dialect&amp;quot;) of standard YAML, designed to be parseable by the existing ecosystem without any changes, as proposed in &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5295/&#34;&gt;KEP 5295&lt;/a&gt;.&lt;/strong&gt;&lt;/em&gt; It does not introduce a new format or a new parser. It just narrows the scope of choices you make when writing YAML, so everyone ends up making the same ones.&lt;/p&gt;
&lt;p&gt;Think of it less like a new language and more like an agreed-upon style. &lt;em&gt;&lt;strong&gt;Everything valid in KYAML is valid YAML.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&#34;how-kyaml-solves-it&#34;&gt;How KYAML solves it&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#how-kyaml-solves-it&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Standard YAML has a few well-known traps and JSON is not without its own.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Whitespace sensitivity.&lt;/strong&gt; Indentation defines structure in YAML, which means a wrongly indented file can remain syntactically valid while representing a different object than intended. This gets especially painful with templating tools like Helm, where you are manipulating indentation from outside the YAML context.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Silent type coercion.&lt;/strong&gt; String quoting is optional in YAML, which sounds convenient until it is not. Some values that look like strings get coerced into other types without warning. The classic example is the &lt;a href=&#34;https://hitchdev.com/strictyaml/why/implicit-typing-removed/&#34;&gt;&amp;quot;Norway Bug&amp;quot;&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;country&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;NO&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In standard YAML, &lt;code&gt;NO&lt;/code&gt; is parsed as a boolean &lt;code&gt;false&lt;/code&gt;, not the string &lt;code&gt;&amp;quot;NO&amp;quot;&lt;/code&gt; and it has caught more than a few people off guard.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;JSON is not the answer either.&lt;/strong&gt; It lacks comment support, is strict about trailing commas, and requires every key to be quoted, none of which makes for a good config writing experience.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;KYAML addresses all of these by making structure and types explicit:&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Does not depend on whitespace for structure&lt;/li&gt;
&lt;li&gt;Always quotes value strings so no silent type coercion&lt;/li&gt;
&lt;li&gt;Always uses &lt;code&gt;{}&lt;/code&gt; for maps and structs&lt;/li&gt;
&lt;li&gt;Always uses &lt;code&gt;[]&lt;/code&gt; for lists&lt;/li&gt;
&lt;li&gt;Allows comments and trailing commas, unlike JSON&lt;/li&gt;
&lt;li&gt;Includes a &lt;code&gt;---&lt;/code&gt; header to distinguish it from JSON at a glance, since both start with &lt;code&gt;{&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;YAML calls this &lt;strong&gt;flow style&lt;/strong&gt;, as opposed to the conventional &lt;strong&gt;block style&lt;/strong&gt; most people use. KYAML sits halfway between JSON and YAML, more explicit than default YAML, friendlier than JSON.&lt;/p&gt;
&lt;p&gt;Here is the same Pod manifest written in both formats for comparison.&lt;/p&gt;
&lt;h3 id=&#34;standard-yaml&#34;&gt;Standard YAML&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#standard-yaml&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Pod&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;my-pod&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;app&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;demo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;containers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;nginx&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;nginx:1.20&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;kyaml&#34;&gt;KYAML&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#kyaml&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;{&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;v1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Pod&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;{&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;my-pod&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;{&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;app&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;demo&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;}&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;}&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;{&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;containers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;{&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;nginx&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;nginx:1.20&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;}&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;}&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;}&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Notice the double-quoted string values, the braces around every mapping, the brackets around the list and the trailing commas. The additional syntax makes the document structure explicit instead of relying on indentation.&lt;/p&gt;
&lt;h2 id=&#34;how-to-pretty-print-yaml-as-kyaml&#34;&gt;How to pretty print YAML as KYAML&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#how-to-pretty-print-yaml-as-kyaml&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;There are different ways to get KYAML output.&lt;/p&gt;
&lt;h3 id=&#34;option-1-kubectl-o-kyaml&#34;&gt;Option 1: kubectl -o kyaml&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#option-1-kubectl-o-kyaml&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Since Kubernetes 1.34, &lt;code&gt;kubectl&lt;/code&gt; supports KYAML as a native output format.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Kubernetes 1.35+ (beta; feature enabled by default, still requires -o kyaml CLI param)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl get deployment my-app -o kyaml
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Kubernetes 1.34 (alpha, opt-in)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;KUBECTL_KYAML&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl get deployment my-app -o kyaml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To save the output to a file:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl get deployment my-app -o kyaml &amp;gt; my-app.yaml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;There are currently no plans to make KYAML the default output format. If you prefer using KYAML by default, you can configure your preferred default with &lt;code&gt;kuberc&lt;/code&gt;. For more details, see the &lt;a href=&#34;https://kubernetes.io/docs/reference/kubectl/kuberc/&#34;&gt;kuberc documentation&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Kubernetes 1.36+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl kuberc &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt; --section defaults --command get --option &lt;span class=&#34;nv&#34;&gt;output&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;kyaml
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Kubernetes 1.33–1.35 (alpha prefix still required)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl alpha kuberc &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt; --section defaults --command get --option &lt;span class=&#34;nv&#34;&gt;output&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;kyaml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;option-2-kubernetes-yamlfmt&#34;&gt;Option 2: Kubernetes&#39; yamlfmt&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#option-2-kubernetes-yamlfmt&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;a href=&#34;https://github.com/kubernetes-sigs/yaml&#34;&gt;sigs.k8s.io/yaml&lt;/a&gt; ships a &lt;code&gt;yamlfmt&lt;/code&gt; tool that can convert files to KYAML.&lt;/p&gt;
&lt;p&gt;Install via Go:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;go install sigs.k8s.io/yaml/yamlfmt@latest
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Running it against a file prints the KYAML version to &lt;strong&gt;stdout&lt;/strong&gt;. It also accepts a directory, in which case it converts and prints every file in that directory.
&lt;em&gt;So you&#39;ll need to redirect the output to a file (or files) if you want the conversion to stick.&lt;/em&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;yamlfmt -o&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;kyaml my-deployment.yaml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It can also show you a diff instead of a full conversion:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;yamlfmt -o&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;kyaml -d my-deployment.yaml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;option-3-google-s-yamlfmt&#34;&gt;Option 3: Google&#39;s yamlfmt&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#option-3-google-s-yamlfmt&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;For converting existing files, Google&#39;s &lt;code&gt;yamlfmt&lt;/code&gt; added a dedicated &lt;a href=&#34;https://github.com/google/yamlfmt/blob/main/docs/config-file.md#kyaml-formatter&#34;&gt;&lt;code&gt;kyaml&lt;/code&gt; formatter&lt;/a&gt; in v0.21.0.&lt;/p&gt;
&lt;p&gt;Install via Go, or grab a binary from the &lt;a href=&#34;https://github.com/google/yamlfmt/releases&#34;&gt;releases page&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;go install github.com/google/yamlfmt/cmd/yamlfmt@latest
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It is also available as a &lt;a href=&#34;https://github.com/google/yamlfmt/blob/main/docs/pre-commit.md&#34;&gt;pre-commit hook&lt;/a&gt; and as a &lt;a href=&#34;https://github.com/google/yamlfmt#basic-usage&#34;&gt;Docker image&lt;/a&gt; for CI pipelines.&lt;/p&gt;
&lt;p&gt;Add a &lt;code&gt;.yamlfmt&lt;/code&gt; config to your project root:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;formatter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;kyaml&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Preview the output without modifying your file:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;yamlfmt -dry my-deployment.yaml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;then apply:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;yamlfmt my-deployment.yaml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To convert an entire directory:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;yamlfmt ./k8s/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;kyaml&lt;/code&gt; formatter takes no additional configuration and does not share options with the default formatter so mixing them will cause an error.&lt;/p&gt;
&lt;p&gt;For more on the available modes and flags, check the &lt;a href=&#34;https://github.com/google/yamlfmt/blob/main/docs/command-usage.md&#34;&gt;command usage docs&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;is-kyaml-worth-adopting&#34;&gt;Is KYAML worth adopting?&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#is-kyaml-worth-adopting&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Every valid KYAML file is a valid YAML file. So whatever you write in KYAML, your existing tools, your &lt;code&gt;kubectl&lt;/code&gt;, your CI pipelines, none of them need to change. You can even pass KYAML as input to any version of &lt;code&gt;kubectl&lt;/code&gt;, not just 1.34+, because at the end of the day it is just YAML.&lt;/p&gt;
&lt;p&gt;KYAML is not strictly necessary. You can keep writing block-style YAML and things will work. But it is a &lt;em&gt;deliberate choice&lt;/em&gt; to make your configs less error-prone and more consistent especially across a team or a larger repo.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;It is less of a migration and more of a better habit.&lt;/em&gt;&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Gateway API v1.6: TCPRoute and UDPRoute Graduate to Standard</title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/08/03/gateway-api-v1-6-release/</link>
      <pubDate>Mon, 03 Aug 2026 08:00:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/08/03/gateway-api-v1-6-release/</guid>
      <description>
        
        
        &lt;p&gt;&lt;img src=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/08/03/gateway-api-v1-6-release/gateway-api-logo.svg&#34; alt=&#34;Gateway API logo&#34;&gt;&lt;/p&gt;
&lt;p&gt;The Kubernetes SIG Network community is thrilled to share the release of &lt;strong&gt;Gateway API v1.6.0&lt;/strong&gt;, which was released on June 30th of this year!&lt;/p&gt;
&lt;p&gt;Gateway API has become the standard for modern, role-oriented,
and expressive service networking in Kubernetes.
In previous releases, Gateway API established a production-grade foundation
for HTTP and TLS layer 7 traffic.
With version 1.6.0, Gateway API takes a major step forward by expanding
standard layer 4 protocol routing and introducing cleaner API boundaries for experimental innovation.&lt;/p&gt;
&lt;p&gt;Here is a quick summary of what&#39;s new in Gateway API v1.6.0:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;TCPRoute and UDPRoute Graduate to Standard&lt;/strong&gt;: Raw L4 TCP and UDP traffic routing reach GA stability in the &lt;code&gt;v1&lt;/code&gt; API version.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Experimental API Group Separation&lt;/strong&gt;: Experimental resources transition to a distinct API group (&lt;code&gt;gateway.networking.x-k8s.io&lt;/code&gt;) with an &lt;code&gt;X&lt;/code&gt; prefix to make experimental vs. standard boundaries crystal clear.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let&#39;s dive into the details!&lt;/p&gt;
&lt;h2 id=&#34;tcproute-and-udproute-graduate-to-standard&#34;&gt;TCPRoute and UDPRoute graduate to Standard&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#tcproute-and-udproute-graduate-to-standard&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Leads: &lt;a href=&#34;https://github.com/youngnick&#34;&gt;Nick Young&lt;/a&gt;, &lt;a href=&#34;https://github.com/rikatz&#34;&gt;Ricardo Katz&lt;/a&gt; and &lt;a href=&#34;https://github.com/zac-nixon&#34;&gt;Zac Nixon&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://gateway-api.sigs.k8s.io/geps/gep-2644/&#34;&gt;GEP-2644 - TCPRoute&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gateway-api.sigs.k8s.io/geps/gep-2645/&#34;&gt;GEP-2645 - UDPRoute&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Until now, Gateway API only offered a stable routing model for HTTP and TLS traffic.
Workloads that speak a raw protocol over TCP or UDP - databases,
DNS, VoIP, gaming, IoT telemetry - had no portable way to plug
into a Gateway. Users either fell back to a plain Kubernetes Service,
or to an implementation-specific CRD that doesn&#39;t travel between Gateway controllers.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://gateway-api.sigs.k8s.io/guides/user-guides/tcp/&#34;&gt;TCPRoute&lt;/a&gt; and &lt;a href=&#34;https://gateway-api.sigs.k8s.io/guides/user-guides/udp/&#34;&gt;UDPRoute&lt;/a&gt; close that gap: they route traffic to backends based on protocol and port alone, no L7 awareness required.
With this release, both have graduated from the Experimental channel to Standard, and moved to the &lt;code&gt;v1&lt;/code&gt; API version.
The &lt;code&gt;v1alpha2&lt;/code&gt; version of each was deprecated as of the v1.6 release, and will be removed in a future release.&lt;/p&gt;
&lt;h3 id=&#34;how-it-works&#34;&gt;How it works&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#how-it-works&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;A Gateway needs a listener that allows TCPRoute attachment:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;gateway.networking.k8s.io/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Gateway&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;example-gateway&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;gatewayClassName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;example-gateway-class&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;listeners&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;foo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;protocol&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;TCP&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;port&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;12345&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;allowedRoutes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kinds&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;TCPRoute&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A TCPRoute then attaches to that listener and forwards traffic to a backend:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;gateway.networking.k8s.io/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;TCPRoute&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;tcp-app&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;parentRefs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;example-gateway&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;sectionName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;foo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;rules&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;backendRefs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;my-foo-service&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;port&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;6000&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Traffic arriving on the Gateway&#39;s port &lt;code&gt;12345&lt;/code&gt; is proxied to the endpoints of &lt;code&gt;my-foo-service&lt;/code&gt; on port &lt;code&gt;6000&lt;/code&gt;. Omitting &lt;code&gt;sectionName&lt;/code&gt; and &lt;code&gt;port&lt;/code&gt; from &lt;code&gt;parentRefs&lt;/code&gt; attaches the route to every TCP listener on the Gateway instead of a single one.&lt;/p&gt;
&lt;p&gt;UDPRoute follows the same pattern; swap the listener protocol and the route kind:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;gateway.networking.k8s.io/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Gateway&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;example-gateway&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;gatewayClassName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;example-gateway-class&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;listeners&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;foo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;protocol&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;UDP&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;port&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;12345&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;allowedRoutes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kinds&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;UDPRoute&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;gateway.networking.k8s.io/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;UDPRoute&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;udp-app&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;parentRefs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;example-gateway&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;sectionName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;foo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;rules&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;backendRefs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;my-foo-service&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;port&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;6000&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;xbackend-arrives-in-experimental&#34;&gt;XBackend arrives in Experimental&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#xbackend-arrives-in-experimental&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Leads: &lt;a href=&#34;https://github.com/keithmattix&#34;&gt;Keith Mattix II&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes-sigs/gateway-api/issues/4894&#34;&gt;GEP-4894 - Backend Resource&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Gateway API v1.6 introduces the new &lt;code&gt;XBackend&lt;/code&gt; resource, which is a general-purpose decorator for Service (and other backend types) within Gateway API.&lt;/p&gt;
&lt;p&gt;The Service resource is an amazing, stable, and flexible object, but that comes with some costs: The flexibility creates a lot of edge cases that Gateway API needs to handle, and the stability makes it impossible to add new concepts to Service.&lt;/p&gt;
&lt;p&gt;The XBackend resource builds on the ideas in the upstream &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/6116&#34;&gt;&lt;code&gt;EndpointSelector&lt;/code&gt; KEP&lt;/a&gt;, to add a Gateway API-native object that still targets the backend app, while allowing the community to extend it to handle use cases that are difficult or dangerous to handle with Service.&lt;/p&gt;
&lt;p&gt;The first version of XBackend includes support for ExternalHostname destinations, which are ruled out from Service support in Gateway API because of the possibility of confused deputy attacks.&lt;/p&gt;
&lt;p&gt;For XBackend, this support is an Extended/Optional feature, allowing implementations and users to opt in once they understand the security tradeoffs.&lt;/p&gt;
&lt;p&gt;This support is very useful for egress use cases (which are most commonly used for cluster-hosted agentic workloads), which the community is also working towards formalizing in GEPs about Gateways for Egress (work in progress, stay tuned!)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The XBackend API is experimental and its behavior can change, do not assume it is ready for production&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;An example of a Gateway with an ExternalName backend that can be used for egress to a cloud AI API is as follows:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# Gateway-level TLS remains authoritative for incoming connections&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;gateway.networking.k8s.io/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Gateway&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;listeners&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;https&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;protocol&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;HTTPS&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;tls&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;certificateRefs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;gateway-cert&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# Backend resource for external destination&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;gateway.networking.x-k8s.io/v1alpha1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;XBackend&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ai-provider-api&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;namespace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ai-apps&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ExternalHostname&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;externalHostname&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;hostname&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;api.ai-provider.com&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# HTTPRoute referencing XBackend&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;gateway.networking.k8s.io/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;HTTPRoute&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;rules&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;backendRefs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ai-provider-api&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;XBackend&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;group&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;gateway.networking.x-k8s.io&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The community is also working on moving Session Persistence config from &lt;code&gt;XBackendTrafficPolicy&lt;/code&gt; into &lt;code&gt;XBackend&lt;/code&gt;, along with other use cases like retries, TLS origination and similar config that is useful to be able to configure per-application rather than per-Route.&lt;/p&gt;
&lt;h2 id=&#34;experimental-resources-move-off-the-standard-api-group&#34;&gt;Experimental resources move off the standard API group&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#experimental-resources-move-off-the-standard-api-group&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Previously, experimental resources shared the same API group as standard ones - &lt;code&gt;gateway.networking.k8s.io&lt;/code&gt; - distinguished only by a &lt;code&gt;v1alpha2&lt;/code&gt;-style version. TCPRoute and UDPRoute were the last resources to graduate under that scheme.&lt;/p&gt;
&lt;p&gt;Going forward, new experimental resources are defined in a separate group,
&lt;code&gt;gateway.networking.x-k8s.io&lt;/code&gt;,
and the names of their API types get an &lt;code&gt;X&lt;/code&gt; prefix - for example XBackend and XMesh.
When one of these graduates to Standard, it&#39;s renamed into the &lt;code&gt;gateway.networking.k8s.io&lt;/code&gt; group
and drops the &lt;code&gt;X&lt;/code&gt; prefix, the same way XMesh is expected to become Mesh.&lt;/p&gt;
&lt;p&gt;This separation makes the experimental/standard boundary explicit at the API group level, rather than relying on version strings alone.&lt;/p&gt;
&lt;h2 id=&#34;what-s-next-getting-involved&#34;&gt;What&#39;s next &amp;amp; getting involved&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#what-s-next-getting-involved&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The graduation of TCPRoute and UDPRoute to Standard marks an essential milestone
in making Gateway API a complete, universal ingress and mesh networking API
for Kubernetes workloads across layer 4 and layer 7 protocols.&lt;/p&gt;
&lt;h3 id=&#34;try-it-out&#34;&gt;Try it out&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#try-it-out&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;You can start using Gateway API v1.6.0 today with your favorite Gateway controller implementation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Check out the &lt;a href=&#34;https://gateway-api.sigs.k8s.io/&#34;&gt;Gateway API Documentation&lt;/a&gt; for detailed guides and API references.&lt;/li&gt;
&lt;li&gt;View the &lt;a href=&#34;https://github.com/kubernetes-sigs/gateway-api/releases/tag/v1.6.0&#34;&gt;v1.6.0 Release Notes&lt;/a&gt; for complete details on the CRD installation and changes.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Gateway API relies on an extensive conformance test suite to ensure consistent,
portable behavior across all implementations.
Here is a list of the implementations that are conforment with v1.6 on the day we published the article:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes-sigs/gateway-api/tree/main/conformance/reports/v1.6/agentgateway-agentgateway&#34;&gt;Agentgateway&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes-sigs/gateway-api/tree/main/conformance/reports/v1.6/airlock-microgateway&#34;&gt;Airlock Microgateway&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes-sigs/gateway-api/tree/main/conformance/reports/v1.6/gke-gateway&#34;&gt;GKE Gateway&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes-sigs/gateway-api/tree/main/conformance/reports/v1.6/kgateway&#34;&gt;kgateway&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes-sigs/gateway-api/tree/main/conformance/reports/v1.6/nginx-nginx-gateway-fabric&#34;&gt;NGINX Gateway Fabric&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes-sigs/gateway-api/tree/main/conformance/reports/v1.6/traefik-traefik&#34;&gt;Traefik Proxy&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;get-involved&#34;&gt;Get involved&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#get-involved&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Gateway API is an open, community-driven project built under Kubernetes SIG Network. We welcome contributions, feedback, and participation from everyone!&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Join our Slack Channel&lt;/strong&gt;: Join &lt;code&gt;#sig-network-gateway-api&lt;/code&gt; on the &lt;a href=&#34;https://slack.k8s.io/&#34;&gt;Kubernetes Slack&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Attend Community Meetings&lt;/strong&gt;: We hold weekly community meetings. Check out the &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/network/&#34;&gt;SIG Network Calendar&lt;/a&gt; for dates and agendas.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Contribute on GitHub&lt;/strong&gt;: File issues, suggest enhancements (GEPs), or submit PRs at &lt;a href=&#34;https://github.com/kubernetes-sigs/gateway-api&#34;&gt;kubernetes-sigs/gateway-api&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;acknowledgments&#34;&gt;Acknowledgments&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#acknowledgments&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;A huge thank you to all the contributors, reviewers, maintainers, and implementation authors whose hard work made Gateway API v1.6.0 possible!&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes v1.37 Sneak Peek</title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/07/31/kubernetes-v1-37-sneak-peek/</link>
      <pubDate>Fri, 31 Jul 2026 08:00:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/07/31/kubernetes-v1-37-sneak-peek/</guid>
      <description>
        
        
        &lt;p&gt;As we get closer to the release date for Kubernetes v1.37, the project develops and matures,
features may be deprecated, removed, or replaced with better ones for the project&#39;s overall
health. This blog outlines some of the planned changes for the Kubernetes v1.37 release that the
release team feels you should be aware of for the continued maintenance of your Kubernetes
environment and keeping up to date with the latest changes. The information below reflects the
current status of the v1.37 release and may change before the actual release date.&lt;/p&gt;
&lt;h2 id=&#34;deprecations-and-removals-for-kubernetes-v1-37&#34;&gt;Deprecations and removals for Kubernetes v1.37&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#deprecations-and-removals-for-kubernetes-v1-37&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;h3 id=&#34;kubectl-kubectl-run-filename-f-to-be-deprecated&#34;&gt;Kubectl: &lt;code&gt;kubectl run --filename/-f&lt;/code&gt; to be deprecated&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#kubectl-kubectl-run-filename-f-to-be-deprecated&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The &lt;code&gt;--filename&lt;/code&gt; (or &lt;code&gt;-f&lt;/code&gt;) flag for &lt;code&gt;kubectl run&lt;/code&gt; is being deprecated as the generated pod is always built purely from CLI arguments like &lt;code&gt;NAME&lt;/code&gt; and &lt;code&gt;--image&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;See &lt;a href=&#34;https://github.com/kubernetes/kubernetes/issues/138671&#34;&gt;kubernetes/kubernetes#138671&lt;/a&gt; for the original issue and discussion.&lt;/p&gt;
&lt;h3 id=&#34;kubelet-static-pods-can-no-longer-reference-secrets-or-configmaps&#34;&gt;Kubelet: Static Pods can no longer reference Secrets or ConfigMaps&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#kubelet-static-pods-can-no-longer-reference-secrets-or-configmaps&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Static Pods were never meant to read API resources directly, since they aren&#39;t created through the API server — but a bug let them reference Secrets or ConfigMaps via fields like &lt;code&gt;configMapRef&lt;/code&gt; or &lt;code&gt;secretRef&lt;/code&gt;. That bug is now fixed: as of v1.37 these references are strictly prohibited, and the &lt;code&gt;PreventStaticPodAPIReferences&lt;/code&gt; feature gate that previously let you opt out of the restriction has been removed.&lt;/p&gt;
&lt;p&gt;See &lt;a href=&#34;https://github.com/kubernetes/kubernetes/issues/140226&#34;&gt;kubernetes/kubernetes#140226&lt;/a&gt; for the original issue and discussion.&lt;/p&gt;
&lt;h3 id=&#34;deprecating-kube-proxy-s-support-for-ipvs-mode&#34;&gt;Deprecating kube-proxy&#39;s support for &lt;code&gt;ipvs&lt;/code&gt; mode&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#deprecating-kube-proxy-s-support-for-ipvs-mode&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;code&gt;kube-proxy&lt;/code&gt; support for &lt;code&gt;ipvs&lt;/code&gt; mode was introduced in v1.8 to resolve &lt;code&gt;iptables&lt;/code&gt; performance bottlenecks. However, since the kernel &lt;code&gt;ipvs&lt;/code&gt; API alone cannot fully implement Kubernetes Services, &lt;code&gt;ipvs&lt;/code&gt; mode continues to use &lt;code&gt;iptables&lt;/code&gt; underneath (&lt;a href=&#34;https://github.com/kubernetes/enhancements/blob/master/keps/sig-network/3866-nftables-proxy/README.md#the-ipvs-mode-of-kube-proxy-will-not-save-us&#34;&gt;KEP-3866, &amp;quot;The ipvs mode of kube-proxy will not save us&amp;quot;&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Clusters running &lt;code&gt;kube-proxy&lt;/code&gt; in ipvs mode (or mode: ipvs in KubeProxyConfiguration) would now be logging a deprecation warning on startup. The deprecation timeline looks like this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;By v1.40, &lt;code&gt;ipvs&lt;/code&gt; mode for &lt;code&gt;kube-proxy&lt;/code&gt; is expected to be disabled by default (still selectable via the feature gate)&lt;/li&gt;
&lt;li&gt;By v1.43, support for &lt;code&gt;ipvs&lt;/code&gt; mode would be removed entirely &lt;a href=&#34;https://github.com/kubernetes/enhancements/blob/master/keps/sig-network/5495-deprecate-ipvs-mode-in-kube-proxy/README.md#graduation-criteria&#34;&gt;KEP-5495, Graduation Criteria&lt;/a&gt;.
To confirm which mode you’re currently running, use:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl -n kube-system get configmap kube-proxy -o &lt;span class=&#34;nv&#34;&gt;jsonpath&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;{.data.config\.conf}&amp;#39;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; grep &lt;span class=&#34;s1&#34;&gt;&amp;#39;mode:&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To understand the rationale behind this deprecation, see &lt;a href=&#34;https://kubernetes.dev/resources/keps/5495&#34;&gt;KEP-5495: Deprecate ipvs mode in kube-proxy&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;ongoing-major-changes&#34;&gt;Ongoing major changes&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#ongoing-major-changes&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;h3 id=&#34;cgroup-v1-support&#34;&gt;Future removal of cgroup v1 support&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#cgroup-v1-support&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;As modern Linux distributions and container runtimes use &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/architecture/cgroups/&#34;&gt;cgroup v2&lt;/a&gt; as the default, support for the legacy cgroup v1 is officially being phased out. Since the v1.35 release, the &lt;code&gt;failCgroupV1&lt;/code&gt; setting has defaulted to true. Consequently, the &lt;code&gt;kubelet&lt;/code&gt; will fail to initialize on any nodes that still rely on cgroup v1 unless an explicit configuration override is applied.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;kubelet.config.k8s.io/v1beta1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;KubeletConfiguration&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;failCgroupV1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# temporary override&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Using this override should be considered a short-term fix. Advanced resource management capabilities, such as In-Place Pod Resizing and Tiered Memory Protection, depend entirely on cgroup v2. While the override remains available in Kubernetes v1.37, users are encouraged to migrate to cgroup v2, as support for cgroup v1 is planned to be removed in a future release.&lt;/p&gt;
&lt;p&gt;To learn more about this deprecation, refer to &lt;a href=&#34;https://kubernetes.dev/resources/keps/5573&#34;&gt;KEP-5573: Remove cgroup v1 support&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;breaking-changes-in-kubernetes-v1-37&#34;&gt;Breaking changes in Kubernetes v1.37&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#breaking-changes-in-kubernetes-v1-37&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;h3 id=&#34;SELinuxMount-GA&#34;&gt;SELinux volume relabeling (&amp;quot;SELinuxMount&amp;quot;) graduates to GA&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#SELinuxMount-GA&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;SELinuxMount is expected to reach GA and be enabled by default in v1.37. Volumes would then be
mounted with &lt;code&gt;-o context=&amp;lt;label&amp;gt;&lt;/code&gt; (the mount option default) instead of being recursively
relabeled, but &lt;strong&gt;only&lt;/strong&gt; when the volume&#39;s CSI driver opts in via a CSIDriver that sets &lt;code&gt;.spec seLinuxMount: true&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Because a single mount can only hold one SELinux context, pods with different SELinux labels sharing a volume on the same node (which previously coexisted under recursive relabeling) may now fail to start. To retain the previous recursive behavior for a specific workload, set &lt;code&gt;seLinuxChangePolicy: Recursive&lt;/code&gt; in the Pod spec.&lt;/p&gt;
&lt;p&gt;Clusters without SELinux enabled see no effect at all. To learn more, check &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/04/22/breaking-changes-in-selinux-volume-labeling/&#34;&gt;SELinux Volume Label Changes goes GA (and likely implications in v1.37)&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;featured-enhancements-of-kubernetes-v1-37&#34;&gt;Featured enhancements of Kubernetes v1.37&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#featured-enhancements-of-kubernetes-v1-37&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;h3 id=&#34;metrics-api-ga&#34;&gt;Metrics API goes GA&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#metrics-api-ga&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The &lt;code&gt;metrics.k8s.io&lt;/code&gt; API is expected to graduate to Stable (GA) in Kubernetes v1.37 after spending nearly nine years in Beta. The API provides a standard way to retrieve CPU and memory usage for pods and nodes, powering widely used Kubernetes features such as the Horizontal Pod Autoscaler (HPA) and commands like &lt;code&gt;kubectl top&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This graduation recognizes the API&#39;s stability and widespread adoption, with no functional changes expected. Both &lt;code&gt;v1&lt;/code&gt; and &lt;code&gt;v1beta1&lt;/code&gt; will remain usable during the transition, enabling developers to adopt the stable API at their own pace without breaking existing workflows.&lt;/p&gt;
&lt;p&gt;To learn more about this enhancement, refer to &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5207/&#34;&gt;KEP-5207: metrics.k8s.io API definition&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;kubelet-in-userns-a-k-a-rootless-mode&#34;&gt;Kubelet in UserNS a.k.a. Rootless Mode&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#kubelet-in-userns-a-k-a-rootless-mode&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Traditionally, Kubernetes node components such as the &lt;code&gt;kubelet&lt;/code&gt; run with root privileges on the host. While necessary for many deployments, this also means that a vulnerability in one of these components could potentially have a greater impact on the underlying system.&lt;/p&gt;
&lt;p&gt;With Kubernetes v1.37, kubelet in User Namespace (Rootless Mode) is expected to graduate to
Beta. This enhancement allows Kubernetes node components to run inside a Linux user namespace as an unprivileged user on the host while still behaving as root within the namespace. By reducing the need for host-level root privileges, it adds an extra layer of isolation and helps limit the impact of potential vulnerabilities affecting node components.&lt;/p&gt;
&lt;p&gt;To learn more about this enhancement, refer to &lt;a href=&#34;https://kubernetes.dev/resources/keps/4960&#34;&gt;KEP-2033: Kubelet in UserNS(aka Rootless Mode)&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;volume-health-monitor&#34;&gt;Volume health monitor&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#volume-health-monitor&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Historically, Kubernetes has lacked an API for CSI drivers to report storage failures, which become evident only through
failed mounts or hung I/O. Since remediation controllers had nothing machine-readable to act upon, the only way to figure out the root cause behind this failure was to cross-reference Kubernetes objects alongside external vendor dashboards.&lt;/p&gt;
&lt;p&gt;In Kubernetes v1.37, this KEP resets graduation to Alpha after an initial implementation in v1.21 and introduces four new CSI
RPCs. The controller plugin reports the health of storage volumes using &lt;code&gt;ControllerListVolumeHealth&lt;/code&gt; (lists unhealthy volumes) and &lt;code&gt;ControllerGetVolumeHealth&lt;/code&gt; (checks a specific volume). A controller-side health monitor polls these CSI controllers and stores the results in
&lt;code&gt;PersistentVolumeClaim.status.healthStatus&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;On the node side, the kubelet calls &lt;code&gt;NodeGetVolumeHealth&lt;/code&gt; to obtain the health of individual volumes on that node and records
it in &lt;code&gt;Pod.status.volumeHealth&lt;/code&gt;, while &lt;code&gt;NodeGetStorageHealth&lt;/code&gt; reports the health of the drivers registered to a node in
&lt;code&gt;CSINode.status.storageHealth&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The error vocabulary is kept simple, extensible, and machine-parsable (&lt;code&gt;Inaccessible&lt;/code&gt;, &lt;code&gt;Degraded&lt;/code&gt;, etc.), with further driver-specific elaboration available via &lt;code&gt;reason&lt;/code&gt; and &lt;code&gt;message&lt;/code&gt;. Finally, the controller-side and node-side reports are kept independent and are hence displayed separately, providing a more holistic view of storage health to consumers.&lt;/p&gt;
&lt;p&gt;To learn more about this enhancement, refer to &lt;a href=&#34;https://kubernetes.dev/resources/keps/1432&#34;&gt;KEP-1432: Volume Health Monitor&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;want-to-know-more&#34;&gt;Want to know more?&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#want-to-know-more&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;New features and deprecations are also announced in the Kubernetes release notes. We will formally announce what&#39;s new in &lt;a href=&#34;https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.37.md&#34;&gt;Kubernetes v1.37&lt;/a&gt; as part of the CHANGELOG for that release.&lt;/p&gt;
&lt;p&gt;Kubernetes v1.37 release is planned for &lt;strong&gt;Wednesday, August 26th, 2026&lt;/strong&gt;. Stay tuned for updates!&lt;/p&gt;
&lt;p&gt;You can see the announcements of changes in the release notes for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.36.md&#34;&gt;Kubernetes v1.36&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.35.md&#34;&gt;Kubernetes v1.35&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.34.md&#34;&gt;Kubernetes v1.34&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.33.md&#34;&gt;Kubernetes v1.33&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;get-involved&#34;&gt;Get involved&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#get-involved&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The simplest way to get involved with Kubernetes is by joining one of the many &lt;a href=&#34;https://kubernetes.dev/community/community-groups/sigs/&#34;&gt;Special Interest Groups&lt;/a&gt; (SIGs) that align with your interests.&lt;/p&gt;
&lt;p&gt;If you don&#39;t know where to start, join our monthly &lt;a href=&#34;https://www.kubernetes.dev/docs/orientation/&#34;&gt;New Contributor Orientations&lt;/a&gt;
where we teach the community how the project is structured, and we&#39;ll guide you on how to make your first contribution to the project.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Read more on how to become a &lt;a href=&#34;https://www.kubernetes.dev/docs/guide/&#34;&gt;Kubernetes Contributor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Read more about what’s happening with Kubernetes on our &lt;a href=&#34;https://kubernetes.io/blog/&#34;&gt;blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Join us on &lt;a href=&#34;http://slack.k8s.io/&#34;&gt;Slack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Follow us on &lt;a href=&#34;https://x.com/kubernetesio&#34;&gt;X&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Follow us on &lt;a href=&#34;https://www.linkedin.com/company/kubernetes/&#34;&gt;LinkedIn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Follow us on &lt;a href=&#34;https://bsky.app/profile/kubernetes.io&#34;&gt;Bluesky&lt;/a&gt; for the latest updates&lt;/li&gt;
&lt;li&gt;Join the community discussion on &lt;a href=&#34;https://discuss.kubernetes.io/&#34;&gt;Discuss&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Post questions (or answer questions) on &lt;a href=&#34;http://stackoverflow.com/questions/tagged/kubernetes&#34;&gt;Stack Overflow&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Share your &lt;a href=&#34;https://www.cncf.io/case-studies/&#34;&gt;Kubernetes End User Story&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Learn more about the &lt;a href=&#34;https://github.com/kubernetes/sig-release/tree/master/release-team&#34;&gt;Kubernetes Release Team&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>How the controller-runtime Cache Actually Works, and Why Your Controller Does Not Crash the API Server</title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/07/29/controller-runtime-cache-explained/</link>
      <pubDate>Wed, 29 Jul 2026 10:00:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/07/29/controller-runtime-cache-explained/</guid>
      <description>
        
        
        

&lt;div class=&#34;pageinfo pageinfo-primary&#34;&gt;
&lt;p&gt;This article has been revised since it was first published, to correct several significant technical inaccuracies in the original text.&lt;/p&gt;

&lt;/div&gt;

&lt;p&gt;Kubernetes has long been the default platform for distributed workloads, and writing your own
controller for it is now a matter of a few hours. The common path — Golang, using &lt;code&gt;kubebuilder&lt;/code&gt; on top of
&lt;code&gt;controller-runtime&lt;/code&gt; — gives you a project scaffold, types, and a reconciler. For typical
scenarios that is more than enough. But as soon as load grows or the controller starts behaving
in ways you did not expect, a whole class of edge cases shows up. Most of them trace back to
the same root cause: a fuzzy mental model of how &lt;code&gt;controller-runtime&lt;/code&gt; works inside. If you
write Kubernetes controllers in Go, this article should help you build a coherent picture and
avoid expensive surprises in production.&lt;/p&gt;
&lt;p&gt;This article walks through the internals of &lt;code&gt;controller-runtime&lt;/code&gt; and, along the way, shows which
architectural decisions are baked into Kubernetes itself. The starting point is how
controllers actually read objects from the Kubernetes API.&lt;/p&gt;
&lt;p&gt;A common misconception goes like this: &lt;code&gt;r.Get()&lt;/code&gt; inside &lt;code&gt;Reconcile&lt;/code&gt; queries &lt;code&gt;kube-apiserver&lt;/code&gt;
directly; &lt;code&gt;r.List()&lt;/code&gt; returns a fresh, live view of the world; and after &lt;code&gt;r.Update()&lt;/code&gt; you can
re-read the object and immediately see the new state. In practice the model is the opposite:
&lt;code&gt;controller-runtime&lt;/code&gt; operates against a local copy of the data populated through &lt;strong&gt;list&lt;/strong&gt; + &lt;strong&gt;watch&lt;/strong&gt;.
Reads inside a reconciler cost almost nothing and do not load the control plane even at
hundreds of calls per second — but the price of this design is that a controller can quietly
consume gigabytes of memory, perform hidden O(n) scans, and regularly trip over stale reads.&lt;/p&gt;
&lt;p&gt;This post is aimed at engineers who already write controllers in Go with &lt;code&gt;controller-runtime&lt;/code&gt;
but want to consolidate the pieces into a single mental model rather than carry around a bag
of isolated observations. The focus is the practical impact on production clusters: memory,
network traffic, read consistency, and reconciler behavior.&lt;/p&gt;
&lt;h2 id=&#34;tl-dr&#34;&gt;TL;DR&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#tl-dr&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;If you take only one idea from this article, take this:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;r.Get()&lt;/code&gt; and &lt;code&gt;r.List()&lt;/code&gt; inside a reconciler typically do not read from the API server. They
read from a local in-memory cache, which the manager warms up with &lt;strong&gt;list&lt;/strong&gt; and then keeps
current through &lt;strong&gt;watch&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Almost every other property of the system follows from that one fact:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Reads are cheap, but not strongly consistent immediately after a write.&lt;/li&gt;
&lt;li&gt;Writes go straight to the API server, not through the cache.&lt;/li&gt;
&lt;li&gt;The size of the local cache and the set of indexes directly drive memory consumption.&lt;/li&gt;
&lt;li&gt;An incorrectly written &lt;code&gt;List()&lt;/code&gt; can silently turn into a linear scan over tens of thousands
of objects.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;APIReader&lt;/code&gt; is rarely needed — but in some places you really cannot do without it.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The rest of the article unpacks why this is so and how the model is wired underneath.&lt;/p&gt;
&lt;h2 id=&#34;a-bit-of-context-what-a-reconciliation-loop-is&#34;&gt;A bit of context: what a reconciliation loop is&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#a-bit-of-context-what-a-reconciliation-loop-is&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;To avoid arguments about terminology, start with the basic model.&lt;/p&gt;
&lt;p&gt;A controller in Kubernetes lives inside a reconciliation loop: it continuously compares the
desired state of an object with the actual state and tries to bring one in line with the
other. The idea is described in the original
&lt;a href=&#34;https://github.com/kubernetes/design-proposals-archive/blob/main/architecture/principles.md&#34;&gt;architectural notes&lt;/a&gt;
on Kubernetes. In practice it looks like this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A user or another controller mutates an object.&lt;/li&gt;
&lt;li&gt;An event lands in a queue.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Reconcile&lt;/code&gt; reads the current state.&lt;/li&gt;
&lt;li&gt;The controller decides what to create, update, or delete.&lt;/li&gt;
&lt;li&gt;The system produces a new event and the loop repeats.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;What matters here is not that the controller &amp;quot;does something&amp;quot; — it is &lt;strong&gt;where it learns about
changes from&lt;/strong&gt; and &lt;strong&gt;where it reads state from&lt;/strong&gt;. That is exactly where the cache comes in.&lt;/p&gt;
&lt;p&gt;On a live cluster, the easiest way to see this in action is:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl get pods --watch
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In watch mode, &lt;code&gt;kubectl&lt;/code&gt; subscribes to the same event stream that controllers consume.
You create or delete a Pod and you see not a single &amp;quot;final&amp;quot; object but a chain of states: the
scheduler assigns a node, the kubelet updates status, other controllers contribute their
changes. Kubernetes controllers do not poll continuously — they consume an event stream and
maintain a local state that is kept current.&lt;/p&gt;
&lt;p&gt;For a visual walkthrough, see &lt;a href=&#34;https://www.youtube.com/watch?v=P50otWVh7w4&#34;&gt;Reconciliation loop pattern in visual representation&lt;/a&gt;,
a talk that shows how the reconciliation loop plays out on a real Pod and the states it
passes through.&lt;/p&gt;
&lt;h2 id=&#34;why-the-cache-exists-in-controller-runtime-at-all&#34;&gt;Why the cache exists in &lt;code&gt;controller-runtime&lt;/code&gt; at all&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#why-the-cache-exists-in-controller-runtime-at-all&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Imagine the simplest possible controller:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;func&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;r&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Reconciler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;Reconcile&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ctx&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;context&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Context&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;req&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;ctrl&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Request&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ctrl&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Result&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;pod&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;corev1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Pod&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ctx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;req&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;NamespacedName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;pod&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;ctrl&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Result&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{},&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// ... meaningful logic ...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Looks straightforward. But what happens when you call &lt;code&gt;r.Get&lt;/code&gt;? Does it fire an HTTP request at
the API server? If it did, picture the scene: a dozen controllers, each issuing a &lt;strong&gt;get&lt;/strong&gt; and
a &lt;strong&gt;list&lt;/strong&gt; per reconcile, with hundreds of reconciles per second. The API server and &lt;code&gt;etcd&lt;/code&gt;
would be writing each other farewell letters within minutes.&lt;/p&gt;
&lt;p&gt;To prevent that, Kubernetes was built around a &lt;em&gt;watch model&lt;/em&gt; rather than polling from the
very beginning. The standard mechanism works like this: a client takes a snapshot of the slice
of the world it cares about once, then subscribes to a stream of changes and keeps a local copy
current. This is the &lt;strong&gt;list&lt;/strong&gt; + &lt;strong&gt;watch&lt;/strong&gt; pattern, and there is no &amp;quot;what is in the world right
now?&amp;quot; loop anywhere in it.&lt;/p&gt;
&lt;p&gt;This idea has lived in &lt;code&gt;client-go&lt;/code&gt; since the very first controllers in
&lt;code&gt;kube-controller-manager&lt;/code&gt;. &lt;code&gt;controller-runtime&lt;/code&gt; wraps it in a friendly framework so
that you do not have to glue the &lt;code&gt;Reflector&lt;/code&gt;, the delta queue, and the &lt;code&gt;Indexer&lt;/code&gt; together
yourself (more on those below).&lt;/p&gt;
&lt;p&gt;So when people talk about &amp;quot;the controller-runtime cache&amp;quot;, they are not talking about a clever
optimization. They are describing the foundation of the entire model: you read from memory,
you write to the API server, and you receive feedback through a watch.&lt;/p&gt;
&lt;p&gt;The rest of this article walks through how each piece is wired up.&lt;/p&gt;
&lt;h2 id=&#34;glossary&#34;&gt;Glossary&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#glossary&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;A few terms collected up front, so you do not have to jump back and forth later. Skim or skip
if any of them are already familiar.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;GVK (GroupVersionKind)&lt;/strong&gt; — the triple that uniquely identifies an API type in
Kubernetes: group, version, and kind, for example &lt;code&gt;apps/v1/Deployment&lt;/code&gt;. Almost every API in
&lt;code&gt;controller-runtime&lt;/code&gt; works in terms of GVK rather than the name you would type in &lt;code&gt;kubectl&lt;/code&gt;
(such as &lt;code&gt;deployments&lt;/code&gt;).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;resourceVersion&lt;/strong&gt; — a &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/reference/using-api/api-concepts/#resource-versions&#34;&gt;monotonic counter&lt;/a&gt;
that the API server tracks automatically, and that changes every time the object is written.
Although it&#39;s a decimal number, the field is represented as a string.
Resource versions serve two main purposes. The first one, you can use them for
&lt;em&gt;optimistic concurrency control&lt;/em&gt; (for example: on &lt;strong&gt;update&lt;/strong&gt;, the API server checks
that the &lt;code&gt;resourceVersion&lt;/code&gt; you provide matches the one in &lt;code&gt;etcd&lt;/code&gt;, otherwise it
returns &lt;code&gt;409 Conflict&lt;/code&gt;). The second place you are going to see resource versions
in your controller is to resume a &lt;strong&gt;watch&lt;/strong&gt;. Read
&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/reference/using-api/api-concepts/#watch-bookmarks&#34;&gt;watch bookmarks&lt;/a&gt; to learn
more.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Manager&lt;/strong&gt; — the &lt;code&gt;ctrl.Manager&lt;/code&gt; object in &lt;code&gt;controller-runtime&lt;/code&gt;. This is what your controller
constructs in &lt;code&gt;main.go&lt;/code&gt; and runs through &lt;code&gt;mgr.Start(ctx)&lt;/code&gt;. It orchestrates everything: it
owns the shared cache, builds the client, starts controllers, webhooks, the healthz
endpoint, and other runnables. A single process usually has exactly one manager, with many
controllers living inside it.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Informer&lt;/strong&gt; — an entity from &lt;code&gt;client-go&lt;/code&gt; that maintains a watch on a single GVK, keeps an
indexed local store, and dispatches events to subscribers. In &lt;code&gt;controller-runtime&lt;/code&gt; an
informer is created automatically when you register &lt;code&gt;Watches(...)&lt;/code&gt; or perform the first
&lt;code&gt;Get&lt;/code&gt;/&lt;code&gt;List&lt;/code&gt; on a given type.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Store&lt;/strong&gt; — the in-memory backing store of an informer, where the objects themselves live.
Each informer in &lt;code&gt;controller-runtime&lt;/code&gt; has its own store.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ResourceEventHandler&lt;/strong&gt; — an interface with three methods: &lt;code&gt;OnAdd&lt;/code&gt;, &lt;code&gt;OnUpdate&lt;/code&gt;, &lt;code&gt;OnDelete&lt;/code&gt;.
The informer calls them for every event delivered through the delta queue. The store is
always updated before the handler runs, so a handler never sees an indexer that is behind
its own event. Subscribers (your controllers) register handlers like this and learn about
changes through them.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;workqueue&lt;/strong&gt; — a queue of reconcile requests (&lt;code&gt;namespace/name&lt;/code&gt;) with deduplication and rate
limiting. On every event the controller enqueues a request; workers pop them one at a time
and hand them to &lt;code&gt;Reconcile&lt;/code&gt; as a &lt;code&gt;ctrl.Request&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Predicate&lt;/strong&gt; — a controller-side filter. A predicate decides whether an event should be
enqueued at all (for example, &amp;quot;react only to changes in &lt;code&gt;spec&lt;/code&gt;, ignore &lt;code&gt;status&lt;/code&gt;&amp;quot;).&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With those in hand, you can dive in.&lt;/p&gt;
&lt;h2 id=&#34;anatomy-what-lives-under-the-cache-package&#34;&gt;Anatomy: what lives under the cache package&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#anatomy-what-lives-under-the-cache-package&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;If you peek into &lt;code&gt;sigs.k8s.io/controller-runtime/pkg/cache&lt;/code&gt;, you will see that it is a thin
wrapper over &lt;code&gt;k8s.io/client-go/tools/cache&lt;/code&gt;. The same primitives that power the rest of
Kubernetes live underneath:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Reflector&lt;/strong&gt; — keeps a &lt;strong&gt;watch&lt;/strong&gt; open against the API server and writes incoming changes
into a queue as &lt;em&gt;deltas&lt;/em&gt;. A delta is a record of the form &amp;quot;object X received an &lt;code&gt;Added&lt;/code&gt; /
&lt;code&gt;Updated&lt;/code&gt; / &lt;code&gt;Deleted&lt;/code&gt; event, and here is its new version&amp;quot;. Effectively a single line in a
change log.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;strong&gt;delta queue&lt;/strong&gt; (&lt;code&gt;RealFIFO&lt;/code&gt;, or &lt;code&gt;DeltaFIFO&lt;/code&gt; on older client-go) — holds those deltas in
arrival order until the informer processes them.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Indexer (Store)&lt;/strong&gt; — the in-memory object store, plus the indexes built over it.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;SharedIndexInformer&lt;/strong&gt; — the conductor that ties everything together and dispatches events
to subscribers — your controllers and any other observers.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At a glance the pipeline looks like this:&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/07/29/controller-runtime-cache-explained/pipeline.svg&#34;
         alt=&#34;A vertical flow chart with seven labeled boxes connected by arrows, from API server at the top to Reconcile at the bottom.&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;Pipeline diagram: API server to Reflector to the delta queue to Indexer to Event handlers&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Now walk through each link.&lt;/p&gt;
&lt;h3 id=&#34;reflector-and-resourceversion&#34;&gt;Reflector and resourceVersion&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#reflector-and-resourceversion&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Within the cache, the Reflector is the only component that talks to the API server. It has
exactly two jobs: fetch the initial snapshot at startup, then keep a &lt;strong&gt;watch&lt;/strong&gt; open from there
on. (Writes and &lt;code&gt;APIReader&lt;/code&gt; reads bypass the cache entirely and reach the API server on their
own — more on those later.)&lt;/p&gt;
&lt;p&gt;This is where the &lt;code&gt;resourceVersion&lt;/code&gt; earns its keep. Along with the objects, the API server
reports the version at which the snapshot was produced. The Reflector then says to the API
server, &amp;quot;open a &lt;strong&gt;watch&lt;/strong&gt; from version X&amp;quot;, and receives a stream of events for everything that
happened after that version. That is the basis of consistency: there is no gap between the
snapshot and the stream, because the stream resumes exactly where the snapshot ended.&lt;/p&gt;
&lt;p&gt;That snapshot no longer arrives as a separate &lt;strong&gt;list&lt;/strong&gt; call by default. Current versions use a
&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/reference/using-api/api-concepts/#streaming-lists&#34;&gt;streaming list&lt;/a&gt; instead: the Reflector
opens the &lt;strong&gt;watch&lt;/strong&gt; with &lt;code&gt;sendInitialEvents=true&lt;/code&gt;, and the API server begins the stream with
synthetic &lt;code&gt;ADDED&lt;/code&gt; events for the whole current state before switching to live changes. One
request instead of two, and a plain &lt;strong&gt;list&lt;/strong&gt; as the fallback. The pattern is unchanged —
snapshot, then stream — which is why this article keeps saying &lt;strong&gt;list&lt;/strong&gt; + &lt;strong&gt;watch&lt;/strong&gt;, the way the
Kubernetes documentation does.&lt;/p&gt;
&lt;p&gt;If the connection drops, the Reflector reconnects with the last known &lt;code&gt;resourceVersion&lt;/code&gt;. If
the API server replies with &lt;code&gt;410 Gone&lt;/code&gt; (&amp;quot;that version is no longer in the history, you are
too far behind&amp;quot;), the Reflector fetches a fresh snapshot and starts over. This is called a
&lt;em&gt;relist&lt;/em&gt;, and it does not happen on a schedule — only in those failure scenarios.&lt;/p&gt;
&lt;h3 id=&#34;the-delta-queue&#34;&gt;The delta queue&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#the-delta-queue&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;This piece is worth pausing on, and it is also the piece that changed most recently.&lt;/p&gt;
&lt;p&gt;Historically the buffer between the Reflector and the rest of the informer was &lt;code&gt;DeltaFIFO&lt;/code&gt;,
which held deltas in a map keyed by &lt;code&gt;namespace/name&lt;/code&gt;: deltas for one object accumulated in a
slot, &lt;code&gt;Pop()&lt;/code&gt; handed back the whole slice for that key at once, and a &lt;code&gt;dedupDeltas&lt;/code&gt; helper
collapsed consecutive &lt;code&gt;Deleted&lt;/code&gt; entries. If you have read about informer internals before,
that is probably the picture you are carrying.&lt;/p&gt;
&lt;p&gt;That is no longer the default. Shared informers now use &lt;code&gt;RealFIFO&lt;/code&gt;, and since client-go 1.36
&lt;code&gt;DeltaFIFO&lt;/code&gt; cannot be switched back on at all. Which version you compile against is what
decides this, not the version of the cluster you point at. The new queue is deliberately
simpler — a flat, strictly ordered slice of deltas:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;RealFIFO&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;struct&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;items&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Delta&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Its own documentation states the design goal plainly: every notification from the Reflector is
passed, in order, through &lt;code&gt;Pop&lt;/code&gt;. Which means:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Order is preserved globally&lt;/strong&gt;, not just per object. Deltas come out in exactly the
sequence they arrived.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;One &lt;code&gt;Pop&lt;/code&gt;, one delta.&lt;/strong&gt; There is no per-key slot and no slice — &lt;code&gt;Pop&lt;/code&gt; takes
&lt;code&gt;items[0]&lt;/code&gt;. (There is also a &lt;code&gt;PopBatch&lt;/code&gt; for processing several deltas in one pass, on by
default since client-go 1.35, but it is a batching optimization, not a merge: each delta is
still delivered.)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No deduplication whatsoever.&lt;/strong&gt; &lt;code&gt;RealFIFO&lt;/code&gt; has no &lt;code&gt;dedupDeltas&lt;/code&gt; equivalent. Nothing is
collapsed — including consecutive deletes, and including intermediate states.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So the worked example gets simpler than it used to be. Suppose three events for
&lt;code&gt;default/my-deploy&lt;/code&gt; arrive in quick succession:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;Added&lt;/code&gt; — the Deployment is created (say, with &lt;code&gt;spec.replicas=1&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Updated&lt;/code&gt; — somebody bumps &lt;code&gt;spec.replicas&lt;/code&gt; to &lt;code&gt;2&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Updated&lt;/code&gt; — and immediately to &lt;code&gt;3&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;All three are appended to the queue and popped one at a time, and the informer dispatches them
in order: first &lt;code&gt;OnAdd&lt;/code&gt;, then two &lt;code&gt;OnUpdate&lt;/code&gt; calls (the intermediate &lt;code&gt;1→2&lt;/code&gt;, then the final
&lt;code&gt;2→3&lt;/code&gt;). The event handler runs three times, no shortcuts.&lt;/p&gt;
&lt;p&gt;The store is written &lt;em&gt;before&lt;/em&gt; the handlers are notified, and handler delivery is asynchronous — the informer writes the indexer, then hands the
notification to a per-subscriber buffer that the subscriber&#39;s own goroutine drains later. So
your handler never sees an indexer lagging behind its own event, but it can see one that has
moved well past it. Handling the &lt;code&gt;1→2&lt;/code&gt; update, a &lt;code&gt;Get&lt;/code&gt; from the cache can legitimately
return &lt;code&gt;3&lt;/code&gt; — or &lt;code&gt;NotFound&lt;/code&gt;, if the object has since been deleted. Never treat the object in the
store as &amp;quot;the state at the time of my event&amp;quot;.&lt;/p&gt;
&lt;p&gt;Deduplication does exist — but it lives one layer up, in the controller&#39;s workqueue, and with
&lt;code&gt;RealFIFO&lt;/code&gt; that is now the &lt;em&gt;only&lt;/em&gt; place it happens. The mechanic is straightforward: for each
delta, the controller&#39;s event handler extracts the &lt;code&gt;namespace/name&lt;/code&gt; &lt;em&gt;key&lt;/em&gt; from the object and
enqueues it. Re-inserting the same key silently coalesces with the existing entry; the
workqueue does not care about the object itself.&lt;/p&gt;
&lt;p&gt;A concrete picture: you create a Pod. Within a second or two a flurry of &lt;code&gt;Updated&lt;/code&gt; deltas
arrives — the scheduler assigns a node, the kubelet sets &lt;code&gt;Pending&lt;/code&gt;, then &lt;code&gt;ContainerCreating&lt;/code&gt;,
&lt;code&gt;Running&lt;/code&gt;, &lt;code&gt;Ready&lt;/code&gt;. Five deltas in a row, and the event handler fires on every one of them —
but throughout this window the workqueue holds a single entry with the key &lt;code&gt;default/my-pod&lt;/code&gt;.
By the time &lt;code&gt;Reconcile&lt;/code&gt; pops it, the cache already holds the final state, and &lt;code&gt;Reconcile&lt;/code&gt;
runs once.&lt;/p&gt;
&lt;p&gt;So you get two layers with cleanly separated responsibilities:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;delta queue&lt;/strong&gt; — an ordered stream of change facts, delivered one at a time and
without merging. Its job is to tell consumers everything that happened, in the right order.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;workqueue&lt;/strong&gt; — a queue of &lt;strong&gt;keys&lt;/strong&gt; with deduplication. This is the layer
that collapses &amp;quot;ten updates in a row → a reconcile or two&amp;quot;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you keep that two-layer picture in your head, it becomes clear why a flood of events
against a single object barely affects controller throughput — the workqueue absorbs them.&lt;/p&gt;
&lt;h3 id=&#34;indexer-the-local-copy-of-the-cluster&#34;&gt;Indexer: the local copy of the cluster&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#indexer-the-local-copy-of-the-cluster&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The Indexer, backed by a &lt;code&gt;ThreadSafeStore&lt;/code&gt;, is the local copy of the cluster. Underneath
it is a plain &lt;code&gt;map[string]interface{}&lt;/code&gt; keyed by &lt;code&gt;namespace/name&lt;/code&gt;, plus a single
&lt;code&gt;sync.RWMutex&lt;/code&gt;, plus a dictionary of registered indexes (covered in their own section below).&lt;/p&gt;
&lt;p&gt;An uncontended &lt;code&gt;r.Get&lt;/code&gt; is cheap: a map lookup followed by a &lt;code&gt;DeepCopy&lt;/code&gt; of the object. The
part of that structure that matters most at scale, though, is not the map — it is the one
&lt;code&gt;sync.RWMutex&lt;/code&gt;, which guards the store and every index at once. Readers hold it for shared
access, the informer needs it exclusively to write, so the two genuinely compete: a &lt;code&gt;List&lt;/code&gt;
holds the read lock while it walks every object of that kind, and the next store write waits
behind that walk. This was a real bottleneck in &lt;code&gt;kube-controller-manager&lt;/code&gt; at scale
(&lt;a href=&#34;https://github.com/kubernetes/kubernetes/issues/130767&#34;&gt;kubernetes#130767&lt;/a&gt;); recent
client-go releases hold the write lock for much less time.&lt;/p&gt;
&lt;h3 id=&#34;sharedindexinformer-and-subscriptions&#34;&gt;SharedIndexInformer and subscriptions&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#sharedindexinformer-and-subscriptions&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;A SharedIndexInformer fuses the Reflector, the delta queue, and the Indexer together and
exposes two interfaces to the rest of the world:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Read objects directly from the indexer.&lt;/li&gt;
&lt;li&gt;Register a &lt;code&gt;ResourceEventHandler&lt;/code&gt; and receive notifications for every event coming out of
the queue — &lt;code&gt;OnAdd&lt;/code&gt;, &lt;code&gt;OnUpdate&lt;/code&gt;, &lt;code&gt;OnDelete&lt;/code&gt;. The store is written before the handler call,
so by the time your handler runs the indexer already reflects that event, and possibly
later ones too.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;quot;Outside&amp;quot; here means your controllers. When a controller registers &lt;code&gt;Watches(...)&lt;/code&gt;, under the
hood it asks the informer: &amp;quot;add a handler that, on every change, enqueues the key into my
workqueue&amp;quot;. The controller&#39;s workers then pop keys one at a time and call your
&lt;code&gt;Reconcile(ctx, ctrl.Request{NamespacedName: ...})&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The keyword in the name is &lt;strong&gt;Shared&lt;/strong&gt;. The manager creates &lt;strong&gt;one&lt;/strong&gt; informer per GVK, and
every controller, webhook, and event source within that manager subscribes to it:&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/07/29/controller-runtime-cache-explained/shared-informer.svg&#34;
         alt=&#34;A single Pod informer at the top with three arrows fanning out to two controllers and a webhook, all inside a ctrl.Manager box.&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;Shared informer diagram: a single list / watch per GVK, feeding multiple subscribers&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;In other words: an informer is the thing that subscribed to Pods once, holds them locally,
and serves every interested party in the process. From the API server&#39;s perspective, that is
one snapshot and one &lt;strong&gt;watch&lt;/strong&gt; per GVK, regardless of how many reconcilers live inside your
process.&lt;/p&gt;
&lt;h2 id=&#34;what-happens-at-startup-and-on-the-very-first-r-get&#34;&gt;What happens at startup and on the very first &lt;code&gt;r.Get&lt;/code&gt;&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#what-happens-at-startup-and-on-the-very-first-r-get&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Step by step, here is what happens between the moment the manager starts and the first
&lt;code&gt;r.Get&lt;/code&gt; inside your reconciler:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The manager&#39;s &lt;code&gt;mgr.Start(ctx)&lt;/code&gt; brings up every registered informer.&lt;/li&gt;
&lt;li&gt;For each GVK, the Reflector fetches a full snapshot: every object of that type that falls
within your scope.&lt;/li&gt;
&lt;li&gt;The snapshot is loaded into the informer&#39;s store, registered indexes are rebuilt, and the
informer is marked as synced.&lt;/li&gt;
&lt;li&gt;The same stream then continues as an ordinary &lt;strong&gt;watch&lt;/strong&gt; from the &lt;code&gt;resourceVersion&lt;/code&gt; the
snapshot synced to.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Only then&lt;/strong&gt; does the controller start invoking &lt;code&gt;Reconcile&lt;/code&gt; — specifically, once every
source it owns reports synced, which includes its event handlers having processed the
initial snapshot. Until that point, workers do not drain the workqueue, even if events have
already started piling up.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So &amp;quot;the reconciler is running but the cache is still empty&amp;quot; is &lt;strong&gt;not a state you can
observe&lt;/strong&gt; — the warm-up happens before the first &lt;code&gt;Reconcile&lt;/code&gt;. (The one exception: a &lt;code&gt;Get&lt;/code&gt; for a
type nothing registered a watch for starts a new informer on the spot, and blocks until it is
warm.)&lt;/p&gt;
&lt;p&gt;What happens during the first &lt;code&gt;r.Get&lt;/code&gt;? Suppose your reconciler contains:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;obj&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;appsv1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Deployment&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ctx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;req&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;NamespacedName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;obj&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Under the hood it boils down to roughly this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;item&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;exists&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;indexer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;GetByKey&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;default/my-deploy&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;exists&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;apierrors&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;NewNotFound&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// DeepCopy into obj&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;No HTTP, no TLS, no protobuf serialization, no &lt;code&gt;etcd&lt;/code&gt;. A map lookup plus a deep copy of the
object, and no I/O at all.&lt;/p&gt;
&lt;p&gt;To repeat, because it matters: even the very first &lt;code&gt;Get&lt;/code&gt; for a registered type reads from a
fully warmed-up, fully indexed snapshot. There is no &amp;quot;first time slow, then fast&amp;quot;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This applies specifically to &lt;code&gt;mgr.GetClient()&lt;/code&gt;. If for some reason you need to
read objects &lt;strong&gt;before&lt;/strong&gt; &lt;code&gt;mgr.Start()&lt;/code&gt; (for example, during initialization), use
&lt;code&gt;mgr.GetAPIReader()&lt;/code&gt;, which goes straight to the API server. The regular client does not hand
you an empty result at that point — it fails fast with &lt;code&gt;ErrCacheNotStarted&lt;/code&gt;. More on this
later.&lt;/p&gt;
&lt;h2 id=&#34;client-cache-read-from-memory-write-to-the-api-server&#34;&gt;Client ≠ Cache: read from memory, write to the API server&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#client-cache-read-from-memory-write-to-the-api-server&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Another point that often gets lost. &lt;code&gt;client.Client&lt;/code&gt; in &lt;code&gt;controller-runtime&lt;/code&gt; is a composite
object:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Reads&lt;/strong&gt; (&lt;code&gt;Get&lt;/code&gt;, &lt;code&gt;List&lt;/code&gt;) go through the cache.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Writes&lt;/strong&gt; (&lt;code&gt;Create&lt;/code&gt;, &lt;code&gt;Update&lt;/code&gt;, &lt;code&gt;Patch&lt;/code&gt;, &lt;code&gt;Apply&lt;/code&gt;, &lt;code&gt;Delete&lt;/code&gt;, &lt;code&gt;DeleteAllOf&lt;/code&gt;) go straight to the API
server.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is not a hack — it is a deliberate design choice:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Reads are frequent; they should be cheap.&lt;/li&gt;
&lt;li&gt;Writes are rare; they should be exact.&lt;/li&gt;
&lt;li&gt;Writing through the cache would invite split-brain — the local copy thinks the change went
through, while the API server has already rejected it.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It is worth dwelling on &amp;quot;should be exact&amp;quot;. This is where &lt;code&gt;resourceVersion&lt;/code&gt; shows up again.&lt;/p&gt;
&lt;p&gt;When you read an object from the cache, you do not get its current state in &lt;code&gt;etcd&lt;/code&gt; — you get
the state as the Reflector last observed it. That state carries a &lt;code&gt;resourceVersion&lt;/code&gt;. You then
mutate the object and call &lt;code&gt;r.Update(ctx, &amp;amp;obj)&lt;/code&gt;. The request goes to the API server right
now, and the API server checks:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Does the &lt;code&gt;resourceVersion&lt;/code&gt; in your PUT match the &lt;code&gt;resourceVersion&lt;/code&gt; in &lt;code&gt;etcd&lt;/code&gt;? Yes — write
it.&lt;/li&gt;
&lt;li&gt;No, &lt;code&gt;etcd&lt;/code&gt; already has a newer one? Reply with &lt;code&gt;409 Conflict&lt;/code&gt; — somebody beat you to it.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is &lt;em&gt;optimistic concurrency control&lt;/em&gt;. No real locks are taken; everybody writes in
parallel; but only one of the racing &lt;code&gt;Update&lt;/code&gt; calls wins — the one that arrives with the
current version. Everyone else gets a &lt;code&gt;409&lt;/code&gt; and is expected to re-read and try again.&lt;/p&gt;
&lt;p&gt;Why does this matter for the cache? If you naively send a PUT with &amp;quot;your&amp;quot; &lt;code&gt;resourceVersion&lt;/code&gt;
from the cache and somebody has updated the object since you read it, you will get &lt;code&gt;409&lt;/code&gt;.
That is &lt;strong&gt;not a bug&lt;/strong&gt;. It is exactly the protection the system is supposed to give you.
Writing without the &lt;code&gt;resourceVersion&lt;/code&gt; check (via &lt;code&gt;Patch&lt;/code&gt; without an optimistic lock, or via
&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/reference/using-api/server-side-apply/&#34;&gt;Server-Side Apply&lt;/a&gt;) is also possible, but that
is a separate conversation.&lt;/p&gt;
&lt;p&gt;The &amp;quot;write → visibility&amp;quot; cycle now looks like this:&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/07/29/controller-runtime-cache-explained/update-visibility.svg&#34;
         alt=&#34;A vertical diagram showing how a write travels from user code through the API server and back into the controller&amp;#39;s cache via a watch event.&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;Write visibility diagram: client.Update to API server to watch event to cache&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Between &amp;quot;you executed &lt;code&gt;Update&lt;/code&gt;&amp;quot; and &amp;quot;the cache reflects the new state&amp;quot; there is a window —
usually milliseconds, but with no guaranteed upper bound. Inside that window, an &lt;code&gt;r.Get&lt;/code&gt; for the
same object returns the previous version. The next section is essentially a list of mistakes
that grow out of that window.&lt;/p&gt;
&lt;h2 id=&#34;common-mistakes-that-everyone-makes&#34;&gt;Common mistakes that everyone makes&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#common-mistakes-that-everyone-makes&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;h3 id=&#34;mistake-1-expecting-read-after-write&#34;&gt;Mistake 1: expecting read-after-write&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#mistake-1-expecting-read-after-write&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;A familiar pattern:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;obj&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Replicas&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;ptr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;To&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int32&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Update&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ctx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;obj&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;ctrl&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Result&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{},&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// re-read and confirm it is now 5&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;fresh&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;appsv1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Deployment&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;_&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ctx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;fresh&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;fmt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Println&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;fresh&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Replicas&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// surprise: 3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is not a &lt;code&gt;controller-runtime&lt;/code&gt; bug. It is a property of an eventually consistent system:
the cache catches up asynchronously, through the watch.&lt;/p&gt;
&lt;p&gt;The right pattern is to never rely on instant freshness. &lt;code&gt;Reconcile&lt;/code&gt; must be idempotent and
must always look at the current state. If it does not match the desired state, the next
reconcile fixes it. You do not need to &amp;quot;wait 100ms&amp;quot; or &amp;quot;re-trigger&amp;quot;. You need to write the
logic so that one or two extra invocations break nothing.&lt;/p&gt;
&lt;p&gt;If a stale read is a genuine correctness problem for you, a live read does not fix it — a
concurrent write can be mid-commit anyway. See the
&lt;a href=&#34;https://github.com/kubernetes-sigs/controller-runtime/blob/820ed1a84f67c2f5c4ee4a104bc6c00faddb1384/FAQ.md#q-my-cache-might-be-stale-if-i-read-from-a-cache-how-should-i-deal-with-that&#34;&gt;controller-runtime FAQ&lt;/a&gt;
for patterns that do.&lt;/p&gt;
&lt;h3 id=&#34;mistake-2-deepcopy-and-who-owns-the-memory&#34;&gt;Mistake 2: &lt;code&gt;DeepCopy&lt;/code&gt; and who owns the memory&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#mistake-2-deepcopy-and-who-owns-the-memory&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;To make sense of this, a quick word on event mechanics inside a controller. When you register
a source via &lt;code&gt;Watches(...)&lt;/code&gt;, two layers sit between the indexer and your &lt;code&gt;Reconcile&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Predicate&lt;/strong&gt; — the filter. It looks at an event (&lt;code&gt;CreateEvent&lt;/code&gt;, &lt;code&gt;UpdateEvent&lt;/code&gt;,
&lt;code&gt;DeleteEvent&lt;/code&gt;, &lt;code&gt;GenericEvent&lt;/code&gt;) and decides whether to pass it through.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;EventHandler&lt;/strong&gt; — the transformer. It receives the object and turns it into one or more
&lt;code&gt;ctrl.Request&lt;/code&gt; values that go into the workqueue. The classic
&lt;code&gt;EnqueueRequestForObject&lt;/code&gt; enqueues the &lt;code&gt;namespace/name&lt;/code&gt; of the current object.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here is the critical part. Predicates and handlers receive &lt;strong&gt;the same objects that live in
the informer&#39;s shared store&lt;/strong&gt;. The same &lt;code&gt;*corev1.Pod&lt;/code&gt; is seen by every controller subscribed
to Pods.&lt;/p&gt;
&lt;p&gt;Because Go has no immutable structs, nothing prevents you from doing
&lt;code&gt;pod.Labels[&amp;quot;foo&amp;quot;] = &amp;quot;bar&amp;quot;&lt;/code&gt; directly inside a handler — and that Pod is the one in the store.
Raw &lt;code&gt;client-go&lt;/code&gt; listers have always worked this way; &lt;code&gt;ThreadSafeStore&lt;/code&gt;&#39;s own documentation puts
it bluntly: you must not modify anything returned by &lt;code&gt;Get&lt;/code&gt; or &lt;code&gt;List&lt;/code&gt; as it will break the indexing
feature. Patch a status &amp;quot;for convenience&amp;quot; in a handler and you break the world view of an
unrelated controller next door.&lt;/p&gt;
&lt;p&gt;The cache-backed client from &lt;code&gt;controller-runtime&lt;/code&gt; shields you from that on the read path: &lt;code&gt;Get&lt;/code&gt; and
&lt;code&gt;List&lt;/code&gt; deep-copy by default, and have since its earliest releases. You can opt out with
&lt;code&gt;UnsafeDisableDeepCopy&lt;/code&gt;, which is named that way on purpose. The event path is not shielded —
there is no &lt;code&gt;DeepCopy&lt;/code&gt; anywhere between the informer and your predicate. The simple rule:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Anything you receive from &lt;code&gt;r.Get&lt;/code&gt; / &lt;code&gt;r.List&lt;/code&gt; is yours; mutate freely.&lt;/li&gt;
&lt;li&gt;Anything you receive in a &lt;code&gt;Predicate&lt;/code&gt; or an &lt;code&gt;EventHandler&lt;/code&gt; is shared, not yours. If you
must mutate it, call &lt;code&gt;obj.DeepCopy()&lt;/code&gt; first; otherwise you are silently corrupting the
cache for every other controller subscribed to the same type.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A concrete review heuristic: if &lt;code&gt;predicate.Funcs{UpdateFunc: ...}&lt;/code&gt; or
&lt;code&gt;handler.EnqueueRequestsFromMapFunc(...)&lt;/code&gt; contains expressions like
&lt;code&gt;e.ObjectNew.SetLabels(...)&lt;/code&gt; or &lt;code&gt;obj.Status.X = Y&lt;/code&gt;, stop and ask whether a &lt;code&gt;DeepCopy&lt;/code&gt; is
missing before that mutation.&lt;/p&gt;
&lt;h3 id=&#34;mistake-3-resync-is-not-relist&#34;&gt;Mistake 3: resync is not relist&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#mistake-3-resync-is-not-relist&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;An informer has a resync period (&lt;code&gt;cache.Options.SyncPeriod&lt;/code&gt;, 10 hours by default in
&lt;code&gt;controller-runtime&lt;/code&gt;), and many people read it as meaning: &lt;em&gt;rebuild the cache from the API
server every n hours, fetching every resource once again&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;It does not. A resync does &lt;strong&gt;not&lt;/strong&gt; perform a &lt;strong&gt;list&lt;/strong&gt;. It &lt;em&gt;re-emits&lt;/em&gt; everything currently in
the indexer back through the delta queue, and the informer dispatches an update per object,
calling &lt;code&gt;OnUpdate(old, old)&lt;/code&gt; for each one. This is for controllers that manage state outside
the Kubernetes API (a cloud provider resource, for example): out-of-band changes produce no
watch event, and a periodic resync is the only way to notice them. It generates no traffic to
the API server.&lt;/p&gt;
&lt;p&gt;One caveat before you rely on resync as a safety net: because both sides of the synthetic
update are the same object, predicates that compare old and new — such as
&lt;code&gt;GenerationChangedPredicate&lt;/code&gt; — will drop it.&lt;/p&gt;
&lt;p&gt;A real &lt;code&gt;relist&lt;/code&gt; happens only in two cases: when the &lt;strong&gt;watch&lt;/strong&gt; died with &lt;code&gt;410 Gone&lt;/code&gt;, and when
you explicitly recreate the informer.&lt;/p&gt;
&lt;h3 id=&#34;mistake-4-do-not-confuse-requeueafter-with-a-timer&#34;&gt;Mistake 4: do not confuse &lt;code&gt;RequeueAfter&lt;/code&gt; with a timer&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#mistake-4-do-not-confuse-requeueafter-with-a-timer&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;A small note that often saves time. Sometimes you want to wait inside a reconciler — &amp;quot;we
just called the provider&#39;s API; if it is not ready yet, retry in a minute&amp;quot;. The temptation is
to spin up &lt;code&gt;time.Sleep&lt;/code&gt; or your own goroutine.&lt;/p&gt;
&lt;p&gt;Resist it. &lt;code&gt;controller-runtime&lt;/code&gt; already provides a built-in mechanism:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;ctrl&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Result&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;RequeueAfter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;30&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Second&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The controller puts your &lt;code&gt;req&lt;/code&gt; back into the workqueue with a delayed trigger 30 seconds out.
If a real event for the same object arrives within that window, the reconcile fires
immediately, without waiting for the timer (the key is deduplicated in the queue). This is
both cheaper and more correct than a hand-rolled timer: you do not hold a worker, and you do
not risk missing a real event.&lt;/p&gt;
&lt;h2 id=&#34;cache-index-almost-sql&#34;&gt;cache + index = almost SQL&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#cache-index-almost-sql&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Now you get to what is, arguably, the most useful capability of the cache — and the one most
controllers leave unused.&lt;/p&gt;
&lt;p&gt;By default, a &lt;code&gt;List&lt;/code&gt; from the cache looks like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;pods&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;corev1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;PodList&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;_&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;List&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ctx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;pods&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;_&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;p&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;range&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;pods&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Items&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;NodeName&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;node-1&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;// do something&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It works — until the cluster has 50,000 Pods and reconciles run hundreds of times per second.
Then the loop turns slow: every trigger walks all 50,000 Pods under the store&#39;s read lock,
then deep-copies each one after the lock is released, doing O(n) work per reconcile, and it is
the walk, not the copying, that blocks writers into the store.&lt;/p&gt;
&lt;p&gt;The Indexer in &lt;code&gt;client-go&lt;/code&gt; can do much better. You declare up front which field you want to
index on:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// Index by spec.nodeName for Pods&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;mgr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;GetFieldIndexer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;().&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;IndexField&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;ctx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;corev1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Pod&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s&#34;&gt;&amp;#34;spec.nodeName&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kd&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;obj&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Object&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nx&#34;&gt;pod&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;obj&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;corev1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Pod&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;pod&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;NodeName&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;pod&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;NodeName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Two things about that call are worth making explicit, because the tidy example hides
them behind a convention.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The index name is arbitrary.&lt;/strong&gt; That second argument, &lt;code&gt;&amp;quot;spec.nodeName&amp;quot;&lt;/code&gt;, is only a
string key the index is registered under. &lt;code&gt;controller-runtime&lt;/code&gt; does not parse it as
JSONPath and does not check it against the object&#39;s schema — you could write &lt;code&gt;&amp;quot;by-node&amp;quot;&lt;/code&gt;
or &lt;code&gt;&amp;quot;xyzzy&amp;quot;&lt;/code&gt; and it would behave identically. The only rule is that the &lt;em&gt;exact same
string&lt;/em&gt; comes back in &lt;code&gt;MatchingFields&lt;/code&gt; at query time. Naming the index after the field it
happens to read is a readability convention, nothing more.&lt;/p&gt;
&lt;p&gt;But remember: this only works for reads served from the cache.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The indexed value is computed, not read.&lt;/strong&gt; The function returns whatever strings you
build; they need not be the verbatim contents of any single field. You can lowercase a
value, join several fields into one composite key, bucket a timestamp (the &lt;em&gt;time-bucket&lt;/em&gt;
trick below does exactly this), or emit a string that appears nowhere in the object
literally. Whatever the function returns becomes a key in the inverted dictionary, and a
&lt;code&gt;MatchingFields&lt;/code&gt; lookup for that exact key is what finds the objects again. The only
constraint is that the value has to be &lt;em&gt;derivable from the object you are indexing&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;What is an &lt;em&gt;inverted index&lt;/em&gt;? The term comes from search engines. Normally you have
documents and each document has a list of words in it. &amp;quot;Inverted&amp;quot; means the relationship is
flipped: a dictionary in which the key is a word and the value is the list of documents that
contain it. Same idea here: the key is the value of a field (for example, &lt;code&gt;node-1&lt;/code&gt;), and the
value is the list of object keys whose field has that value:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;map[&amp;#34;node-1&amp;#34;] = {&amp;#34;default/pod-a&amp;#34;, &amp;#34;kube-system/pod-b&amp;#34;, ...}
map[&amp;#34;node-2&amp;#34;] = {&amp;#34;default/pod-c&amp;#34;, ...}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;What the indexer does:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;On every incoming event (&lt;code&gt;ADDED&lt;/code&gt;, &lt;code&gt;MODIFIED&lt;/code&gt;, &lt;code&gt;DELETED&lt;/code&gt;), the indexer runs the object
through your indexing function, gets back the set of index keys, and updates the inverted
dictionary. If a Pod migrates from &lt;code&gt;node-1&lt;/code&gt; to &lt;code&gt;node-2&lt;/code&gt;, the &lt;code&gt;node-1&lt;/code&gt; key loses its
reference to it and the &lt;code&gt;node-2&lt;/code&gt; key gains one.&lt;/li&gt;
&lt;li&gt;By the time you call &lt;code&gt;List&lt;/code&gt;, the index is &lt;strong&gt;already current&lt;/strong&gt;. You do not pay for a
rebuild at query time — no scan over all objects, no dictionary reconstruction. All the
work was done up front, at the moment the object changed.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And now you can write:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;pods&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;corev1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;PodList&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;_&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;List&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ctx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;pods&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;MatchingFields&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;spec.nodeName&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;node-1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is not &amp;quot;fetch the full list, then filter&amp;quot;. It is a lookup in the inverted index → a
ready set of keys → a fetch of the corresponding objects. A different code path entirely.&lt;/p&gt;
&lt;p&gt;The comparison to SQL is more accurate than it might look at first:&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;SQL&lt;/th&gt;
          &lt;th&gt;controller-runtime&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;CREATE INDEX idx_node ON pods(node_name)&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;IndexField(&amp;amp;Pod{}, &amp;quot;spec.nodeName&amp;quot;, fn)&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;SELECT * FROM pods WHERE node_name = &#39;node-1&#39;&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;List(&amp;amp;pods, MatchingFields{&amp;quot;spec.nodeName&amp;quot;: &amp;quot;node-1&amp;quot;})&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;SELECT * FROM obj WHERE owner_uid = $1&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;List(&amp;amp;list, MatchingFields{&amp;quot;metadata.ownerReferences.uid&amp;quot;: uid})&lt;/code&gt; (requires an &lt;code&gt;IndexField&lt;/code&gt; for that field)&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Note the last row: &lt;code&gt;MatchingFields&lt;/code&gt; does &lt;strong&gt;not&lt;/strong&gt; make magic out of thin air. For every field
you want to look up via &lt;code&gt;MatchingFields&lt;/code&gt; you need a corresponding &lt;code&gt;IndexField&lt;/code&gt; registered
during manager setup. Without one, &lt;code&gt;controller-runtime&lt;/code&gt; rejects the query and returns
an error.&lt;/p&gt;
&lt;p&gt;A few things worth keeping in mind:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Equality only.&lt;/strong&gt; No range queries, no &lt;code&gt;LIKE&lt;/code&gt;, no sorts, no aggregates. If you need
&amp;quot;everything older than five minutes&amp;quot;, either do a regular &lt;code&gt;List&lt;/code&gt; and filter in code, or
use a &lt;em&gt;time-bucket&lt;/em&gt; trick: instead of indexing the precise &lt;code&gt;time.Time&lt;/code&gt;, index a rounded
value (for example, &lt;code&gt;now.Truncate(5*time.Minute).Format(...)&lt;/code&gt;). You can then select objects
by a specific window.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;MatchingLabels&lt;/code&gt; is not an index.&lt;/strong&gt; Many people assume that since label-based lookups are
so common, there must be an optimization for them. There is not: &lt;code&gt;ThreadSafeStore&lt;/code&gt; keeps no
separate label dictionary. The only indexes the cache has are the namespace index and the
field indexes you register yourself.&lt;/p&gt;
&lt;p&gt;Two separate things follow, and they get conflated. The walk really is O(n): with no label
index, &lt;code&gt;List(..., MatchingLabels{...})&lt;/code&gt; still visits every cached
object of that kind, or whatever subset the namespace or a field index already narrowed it
to. But the selector is evaluated &lt;em&gt;before&lt;/em&gt; the deep copy, so objects that do not match are
skipped without ever being copied. Against 50,000 Pods with ten matches, that is 50,000
cheap comparisons and ten expensive copies — not 50,000 copies. Which is why a
label-filtered &lt;code&gt;List&lt;/code&gt; is still much better than fetching everything and filtering in your
own code afterwards: same walk either way, and the filtered version skips the copies you
were going to throw away.&lt;/p&gt;
&lt;p&gt;So &lt;code&gt;MatchingLabels&lt;/code&gt; is fine to use — just do not expect it to make the traversal cheaper.
To shrink the candidate set itself, use a namespace or a field selector backed by a
registered &lt;code&gt;IndexField&lt;/code&gt;. To avoid holding the objects at all, filter at &lt;strong&gt;cache population&lt;/strong&gt;
time via &lt;code&gt;cache.ByObject{Label: ...}&lt;/code&gt; or &lt;code&gt;DefaultLabelSelector&lt;/code&gt;, which pushes the selector
down to the &lt;strong&gt;watch&lt;/strong&gt; itself — covered in the next section on selective caches.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;An index costs memory.&lt;/strong&gt; An index maps each indexed value to a set of &lt;code&gt;namespace/name&lt;/code&gt;
keys — not to copies of the objects. Cheap per object, not free, and still not a reason to
index everything in sight speculatively.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;You can only index data that is in the object itself.&lt;/strong&gt; You cannot index a Pod by &amp;quot;has a
related PVC with such-and-such flag&amp;quot;. Either store that bit in the Pod itself, or index
the PVC, not the Pod.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; An index is built at registration time and is populated as part of the initial
snapshot. By the time the first &lt;code&gt;Reconcile&lt;/code&gt; runs, &lt;code&gt;List&lt;/code&gt; with &lt;code&gt;MatchingFields&lt;/code&gt; already works —
the index is not built lazily. (&lt;code&gt;Get&lt;/code&gt; never consults a field index; it is a direct lookup by
store key.)&lt;/p&gt;
&lt;h2 id=&#34;selective-cache-do-not-pull-the-whole-cluster-into-your-controller&#34;&gt;Selective cache: do not pull the whole cluster into your controller&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#selective-cache-do-not-pull-the-whole-cluster-into-your-controller&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;By default, an informer pulls every object of its type from every namespace. For Pod,
Secret, ConfigMap, and Event in a large cluster, that is a multi-gigabyte surprise
delivered on the first &lt;strong&gt;list&lt;/strong&gt; at startup.&lt;/p&gt;
&lt;p&gt;It hurts especially with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Secrets&lt;/strong&gt;, because Helm stores release state in them (&lt;code&gt;helm.sh/release.v1.*&lt;/code&gt;), and those
secrets are often a hundred kilobytes each.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;v1.Node&lt;/code&gt;&lt;/strong&gt; objects, whose &lt;code&gt;status.images&lt;/code&gt; field carries a list of every image that has
ever landed on the node — tens of kilobytes per node in busy clusters.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Events&lt;/strong&gt;, which can be very numerous and which you almost certainly do not need cached at
all.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In &lt;code&gt;controller-runtime&lt;/code&gt;, caching policy lives in &lt;code&gt;cache.Options&lt;/code&gt;, passed when constructing
the manager:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;mgr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;ctrl&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;NewManager&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;cfg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;ctrl&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Options&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;Cache&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;cache&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Options&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nx&#34;&gt;ByObject&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;map&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Object&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;cache&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ByObject&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;c1&#34;&gt;// Cache Secrets only from your own namespace, and only by label&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;corev1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Secret&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{}:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;nx&#34;&gt;Namespaces&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;map&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;cache&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Config&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    &lt;span class=&#34;s&#34;&gt;&amp;#34;my-controller&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;nx&#34;&gt;Label&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;SelectorFromSet&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    &lt;span class=&#34;s&#34;&gt;&amp;#34;app.kubernetes.io/managed-by&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;my-controller&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;p&#34;&gt;}),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;c1&#34;&gt;// Cache all Pods, but trim noise on the way into the store&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;corev1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Pod&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{}:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;nx&#34;&gt;Transform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;obj&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;any&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;any&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    &lt;span class=&#34;nx&#34;&gt;pod&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;obj&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;corev1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Pod&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    &lt;span class=&#34;nx&#34;&gt;pod&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ManagedFields&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;pod&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A subtle point: this is a &lt;strong&gt;manager-level&lt;/strong&gt; setting and it affects &lt;strong&gt;every controller in the
process&lt;/strong&gt; that reads the corresponding type. If you narrow the cache for Secrets to a single
namespace and another controller in the same binary needs all secrets in the cluster, that
controller will not see them. Before you tighten the scope, audit who else is reading
the type.&lt;/p&gt;
&lt;p&gt;A short tour of the options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;Namespaces&lt;/code&gt;&lt;/strong&gt; restricts the visible scope. If your controller only manages its own
namespace, there is no reason to keep other people&#39;s objects in memory.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;Label&lt;/code&gt; / &lt;code&gt;Field&lt;/code&gt;&lt;/strong&gt; become parameters of the &lt;strong&gt;watch&lt;/strong&gt; itself. The API server only sends
matching objects, saving network and memory.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;Transform&lt;/code&gt;&lt;/strong&gt; is invoked before the object lands in the store. It is the perfect place to
drop &lt;code&gt;managedFields&lt;/code&gt;, oversized &lt;code&gt;annotations&lt;/code&gt;, or the binary &lt;code&gt;data&lt;/code&gt; of ConfigMaps that
you do not need.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;DefaultLabelSelector&lt;/code&gt; / &lt;code&gt;DefaultNamespaces&lt;/code&gt;&lt;/strong&gt; apply the same restriction globally, when
every type needs the same scope.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Caveat:&lt;/strong&gt; A selector limits what is &lt;strong&gt;cached&lt;/strong&gt;, not what &lt;strong&gt;exists&lt;/strong&gt;. If an object does
not match your selector, then as far as your controller is concerned, it does not exist in
either &lt;code&gt;Get&lt;/code&gt; or &lt;code&gt;List&lt;/code&gt;. This bites people: somebody mislabels a single Secret and then
spends half a day figuring out why their controller &amp;quot;cannot see it&amp;quot;.&lt;/p&gt;
&lt;h2 id=&#34;metadata-only-when-spec-and-data-are-not-needed&#34;&gt;Metadata-only: when &lt;code&gt;spec&lt;/code&gt; and &lt;code&gt;data&lt;/code&gt; are not needed&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#metadata-only-when-spec-and-data-are-not-needed&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;A separate pattern: you need to know that an object exists, but you do not need its &lt;code&gt;spec&lt;/code&gt; or
&lt;code&gt;data&lt;/code&gt;. Typical examples: a controller that waits for a Secret with a particular name to
appear but never reads it; one that counts PersistentVolume objects by the
&lt;code&gt;topology.kubernetes.io/zone&lt;/code&gt; label; one that reacts to ConfigMap objects in a namespace
by name and does not care about contents.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Caveat:&lt;/strong&gt; &lt;code&gt;PartialObjectMetadata&lt;/code&gt; by definition gives you nothing from &lt;code&gt;spec&lt;/code&gt; or
&lt;code&gt;status&lt;/code&gt; — only &lt;code&gt;ObjectMeta&lt;/code&gt;. So you &lt;strong&gt;cannot&lt;/strong&gt; filter through it on &lt;code&gt;spec&lt;/code&gt; fields (such as
a PersistentVolume&#39;s &lt;code&gt;storageClassName&lt;/code&gt; or a Pod&#39;s &lt;code&gt;nodeName&lt;/code&gt;); those fields do not
exist in the local copy. Everything covered by metadata-only is &lt;code&gt;labels&lt;/code&gt;, &lt;code&gt;annotations&lt;/code&gt;,
&lt;code&gt;ownerReferences&lt;/code&gt;, &lt;code&gt;finalizers&lt;/code&gt;, &lt;code&gt;creationTimestamp&lt;/code&gt;, and the rest of &lt;code&gt;metadata&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For this case there is &lt;code&gt;PartialObjectMetadata&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;list&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;metav1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;PartialObjectMetadataList&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// controller-runtime infers the list shape from the variable type.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;SetGroupVersionKind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;schema&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;GroupVersionKind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;Group&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;   &lt;span class=&#34;s&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;Version&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;v1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;Kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;    &lt;span class=&#34;s&#34;&gt;&amp;#34;Secret&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;List&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ctx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;InNamespace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;my-ns&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Under the hood this is a separate watch that asks the API server for metadata only. The
store keeps such objects without &lt;code&gt;Data&lt;/code&gt;, &lt;code&gt;Spec&lt;/code&gt;, or &lt;code&gt;Status&lt;/code&gt; — only &lt;code&gt;ObjectMeta&lt;/code&gt;. For
Secrets the memory difference can reach an order of magnitude.&lt;/p&gt;
&lt;h2 id=&#34;apireader-when-the-cache-is-not-enough&#34;&gt;APIReader: when the cache is not enough&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#apireader-when-the-cache-is-not-enough&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;&lt;code&gt;mgr.GetAPIReader()&lt;/code&gt; returns a &lt;code&gt;client.Reader&lt;/code&gt; that goes straight to the API server, around
the cache. When you actually need it:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A one-off read of a resource for which you do not maintain an informer. Spinning up a watch
for a single operation is expensive.&lt;/li&gt;
&lt;li&gt;Reads &lt;strong&gt;before &lt;code&gt;mgr.Start()&lt;/code&gt;&lt;/strong&gt;, for instance during initialization. At that point the
cache-backed client fails with &lt;code&gt;ErrCacheNotStarted&lt;/code&gt; rather than returning data.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Paginated traversal of large result sets&lt;/strong&gt; through &lt;code&gt;client.Continue&lt;/code&gt;. The cache-backed
client rejects &lt;code&gt;Continue&lt;/code&gt; with an explicit error, and honors &lt;code&gt;Limit&lt;/code&gt; only as truncation — an
arbitrary N objects, not a stable &amp;quot;first N&amp;quot;. For genuine pagination you need &lt;code&gt;APIReader&lt;/code&gt; or
a direct client of your own.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The price is a real network request, and it is easy to underestimate: on top of the round trip
you pay to deserialize whatever comes back, which for a large collection is not cheap. So the
trade is less obvious than it looks — reading from the API server is not automatically cheaper
just because it avoids keeping objects in memory. Measure before you &amp;quot;optimize&amp;quot; a cached read
into a live one. One thing to avoid outright: do not build &amp;quot;look in the cache, and if missing,
fall back to the API&amp;quot; logic. That is exactly the split-brain pattern the cache is meant to
protect you from.&lt;/p&gt;
&lt;h3 id=&#34;disabling-the-cache-for-a-type-entirely&#34;&gt;Disabling the cache for a type entirely&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#disabling-the-cache-for-a-type-entirely&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;If you do not need a local cache for a given type at all — say, the type is &amp;quot;fat&amp;quot;, read
rarely, and the &lt;strong&gt;list&lt;/strong&gt; + &lt;strong&gt;watch&lt;/strong&gt; overhead is not worth paying — you can tell the manager not to
cache it. This is configured through &lt;code&gt;client.Options.Cache.DisableFor&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;mgr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;ctrl&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;NewManager&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;cfg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;ctrl&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Options&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;Client&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Options&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nx&#34;&gt;Cache&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;CacheOptions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nx&#34;&gt;DisableFor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Object&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;corev1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Secret&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;With this configuration, &lt;code&gt;mgr.GetClient().Get(...)&lt;/code&gt; and &lt;code&gt;List(...)&lt;/code&gt; for Secret go straight
to the API server, bypassing the cache. No informer is started for that type, which means no
&lt;strong&gt;list&lt;/strong&gt; at startup and no permanent memory pressure from a store. That also means no events:
nothing will trigger your controller when such an object changes. If you need those triggers,
pair the direct reads with a metadata-only watch. This is a more radical
alternative to &lt;code&gt;APIReader&lt;/code&gt;: where &lt;code&gt;APIReader&lt;/code&gt; is reached for ad hoc, individual requests,
&lt;code&gt;DisableFor&lt;/code&gt; turns the cache off for the type wholesale.&lt;/p&gt;
&lt;p&gt;Real-world projects use this: &lt;a href=&#34;https://github.com/external-secrets/external-secrets&#34;&gt;external-secrets&lt;/a&gt;,
for instance, has flags that disable caching for Secrets and ConfigMaps, trading memory for
API traffic.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Aside:&lt;/strong&gt; If you want to avoid a watch on the API server entirely, you can feed the
controller events from a source of your own design, bypassing &lt;strong&gt;list&lt;/strong&gt; + &lt;strong&gt;watch&lt;/strong&gt;. In
&lt;code&gt;controller-runtime&lt;/code&gt; this is done with &lt;code&gt;WatchesRawSource&lt;/code&gt; / &lt;code&gt;source.Channel&lt;/code&gt;: you can wire
the controller to events from any place — an internal queue, a kubelet, a custom watch.
Niche, but a perfectly valid pattern when the API server should not be touched.&lt;/p&gt;
&lt;h2 id=&#34;good-practices&#34;&gt;Good practices&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#good-practices&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;A short checklist worth running through before you ship a controller into a live cluster:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Constrain cache scope&lt;/strong&gt; (&lt;code&gt;Namespaces&lt;/code&gt;, &lt;code&gt;Label&lt;/code&gt;, &lt;code&gt;Field&lt;/code&gt; selectors), especially for &amp;quot;fat&amp;quot;
types: Secret, ConfigMap, Event, Pod, Node.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Remember that a constrained cache acts as if everything outside its scope does not
exist.&lt;/strong&gt; A mislabeled object &amp;quot;disappears&amp;quot; with no error anywhere.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Add a &lt;code&gt;Transform&lt;/code&gt;&lt;/strong&gt; for objects whose heavy fields you do not need —
&lt;code&gt;ManagedFields&lt;/code&gt; alone consume a noticeable share of memory.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Add an &lt;code&gt;IndexField&lt;/code&gt;&lt;/strong&gt; for every &lt;code&gt;List&lt;/code&gt; that uses &lt;code&gt;MatchingFields&lt;/code&gt;. Without a matching
index the query does not silently degrade — it fails with an error.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Do not mutate&lt;/strong&gt; objects you receive in an &lt;code&gt;EventHandler&lt;/code&gt; or a &lt;code&gt;Predicate&lt;/code&gt; without a prior
&lt;code&gt;DeepCopy&lt;/code&gt;. Mutations to the store break neighboring controllers silently and persistently.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Make &lt;code&gt;Reconcile&lt;/code&gt; idempotent.&lt;/strong&gt; It must behave correctly even if it is invoked five times
in a row with no real change.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Do not expect read-after-write&lt;/strong&gt; from the cache immediately after &lt;code&gt;Update&lt;/code&gt;. The cache
lags during that window.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;When the cache cannot serve a read&lt;/strong&gt; (initialization, deliberately uncached types), use
&lt;code&gt;APIReader&lt;/code&gt;, not the regular client.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use &lt;code&gt;PartialObjectMetadata&lt;/code&gt;&lt;/strong&gt; for types where you only need metadata. It can save
gigabytes.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Do not call &lt;code&gt;mgr.GetClient()&lt;/code&gt; before &lt;code&gt;mgr.Start()&lt;/code&gt;.&lt;/strong&gt; The cache is not running yet, so
reads fail with &lt;code&gt;ErrCacheNotStarted&lt;/code&gt; instead of returning data. Use &lt;code&gt;mgr.GetAPIReader()&lt;/code&gt;
when you genuinely need to read during initialization.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;For deferred actions, use &lt;code&gt;RequeueAfter&lt;/code&gt;,&lt;/strong&gt; not &lt;code&gt;time.Sleep&lt;/code&gt; and not your own goroutines.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;wrapping-up&#34;&gt;Wrapping up&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#wrapping-up&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;In one breath:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The cache in &lt;code&gt;controller-runtime&lt;/code&gt; is not an optimization, it is the operating model. Under
the hood it is &lt;code&gt;Reflector&lt;/code&gt; + a delta queue + &lt;code&gt;Indexer&lt;/code&gt; — exactly the same primitives that
power Kubernetes itself.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r.Get&lt;/code&gt; and &lt;code&gt;r.List&lt;/code&gt; go to memory; &lt;code&gt;Create&lt;/code&gt;, &lt;code&gt;Update&lt;/code&gt;, &lt;code&gt;Patch&lt;/code&gt;, and &lt;code&gt;Delete&lt;/code&gt; go straight
to the API server. Feedback flows in through the watch.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;IndexField&lt;/code&gt; plus &lt;code&gt;MatchingFields&lt;/code&gt; turn the cache into a near-complete query engine with
inverted indexes.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Namespaces&lt;/code&gt;, selectors, &lt;code&gt;PartialObjectMetadata&lt;/code&gt;, and &lt;code&gt;Transform&lt;/code&gt; are the levers that
control how much memory and traffic you actually consume.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;APIReader&lt;/code&gt; bypasses the cache for the rare read the cache cannot serve — but it is not a
fix for staleness races; see the
&lt;a href=&#34;https://github.com/kubernetes-sigs/controller-runtime/blob/820ed1a84f67c2f5c4ee4a104bc6c00faddb1384/FAQ.md#q-my-cache-might-be-stale-if-i-read-from-a-cache-how-should-i-deal-with-that&#34;&gt;controller-runtime FAQ&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And the single sentence to remember: &lt;code&gt;r.Get&lt;/code&gt; inside a reconciler reads from memory, not from the
API server — not even the first time. The exceptions are the ones you opt into yourself:
&lt;code&gt;APIReader&lt;/code&gt;, &lt;code&gt;Cache.DisableFor&lt;/code&gt;, and unstructured reads. Once that becomes a reflex, half the
questions on controller code reviews answer themselves.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Building a Custom Metrics Exporter for Kubernetes</title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/07/14/custom-metrics-exporter-kubernetes/</link>
      <pubDate>Tue, 14 Jul 2026 10:00:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/07/14/custom-metrics-exporter-kubernetes/</guid>
      <description>
        
        
        &lt;p&gt;Kubernetes ships with built-in awareness of CPU and memory, but most
real-world scaling decisions depend on signals that live entirely outside
that narrow window: how many messages are waiting in a queue, how long
the last batch job took, how many active WebSocket connections a pod is
holding. When the built-in metrics are not enough, a &lt;em&gt;metrics exporter&lt;/em&gt;
bridges that gap.&lt;/p&gt;
&lt;p&gt;This post walks through writing one from scratch, packaging it as a
container, and wiring it into a cluster so that Prometheus — and
ultimately the &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/&#34;&gt;HorizontalPodAutoscaler&lt;/a&gt; — can consume it.&lt;/p&gt;
&lt;h2 id=&#34;what-a-metrics-exporter-actually-does&#34;&gt;What a metrics exporter actually does&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#what-a-metrics-exporter-actually-does&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;An exporter is a small HTTP server with a single responsibility: expose
application state as text on a &lt;code&gt;/metrics&lt;/code&gt; endpoint. Prometheus &lt;em&gt;scrapes&lt;/em&gt;
that endpoint on a regular interval, stores the time-series data, and
makes it available for queries, alerts, and autoscaling rules.&lt;/p&gt;
&lt;p&gt;In some cases you can instrument your application directly — embedding
the Prometheus client library and exposing &lt;code&gt;/metrics&lt;/code&gt; from within the
same process — rather than running a separate exporter. A standalone
exporter makes more sense when the data source is external to your
application or when you do not control the application code.&lt;/p&gt;
&lt;p&gt;The format Prometheus expects is plain text — one metric per line, with
a name, optional labels, and a numeric value. Client libraries handle
the serialization for you, so in practice you only need to decide what
to measure and call the right function when that value changes.&lt;/p&gt;
&lt;h2 id=&#34;choosing-what-to-measure&#34;&gt;Choosing what to measure&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#choosing-what-to-measure&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Before writing any code, it helps to decide what kind of signal you are
dealing with. The Prometheus data model has three main types:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Counters&lt;/em&gt; only ever increase. They are the right tool for totals:
requests served, jobs processed, errors encountered. Never use a
counter for a value that can go down.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Gauges&lt;/em&gt; represent a current snapshot of a value that can rise and
fall freely. Queue depth, active connections, and cache size are all
gauges.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Histograms&lt;/em&gt; record the distribution of observed values, such as
request latency. They let you calculate percentiles (p99, p50) rather
than just averages.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Once you know which type fits your signal, choose a name that follows
the convention &lt;code&gt;&amp;lt;namespace&amp;gt;_&amp;lt;name&amp;gt;_&amp;lt;unit&amp;gt;&lt;/code&gt; in &lt;code&gt;snake_case&lt;/code&gt;. A job
processor might expose &lt;code&gt;worker_jobs_processed_total&lt;/code&gt; (counter),
&lt;code&gt;worker_queue_depth&lt;/code&gt; (gauge), and &lt;code&gt;worker_job_duration_seconds&lt;/code&gt;
(histogram). Clear names save everyone debugging time later.&lt;/p&gt;
&lt;h2 id=&#34;setting-up-the-project&#34;&gt;Setting up the project&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#setting-up-the-project&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The Go Prometheus client is the most common choice for exporters in the
Kubernetes ecosystem, largely because the same library powers most of
the official Kubernetes components. Start by creating a module and
pulling in the dependency:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;mkdir my-exporter &lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; my-exporter
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;go mod init example.com/my-exporter
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;go get github.com/prometheus/client_golang/prometheus
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;go get github.com/prometheus/client_golang/prometheus/promhttp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;registering-metrics&#34;&gt;Registering metrics&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#registering-metrics&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Create &lt;code&gt;main.go&lt;/code&gt;. The first thing to do is declare the metrics and
register them with Prometheus&#39;s default registry. Registration tells
the library that these metrics exist so they appear in the output even
before the first observation is recorded:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;package&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;main&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s&#34;&gt;&amp;#34;log&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s&#34;&gt;&amp;#34;net/http&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s&#34;&gt;&amp;#34;github.com/prometheus/client_golang/prometheus&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s&#34;&gt;&amp;#34;github.com/prometheus/client_golang/prometheus/promhttp&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;jobsProcessed&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;prometheus&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;NewCounterVec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nx&#34;&gt;prometheus&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;CounterOpts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nx&#34;&gt;Name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;worker_jobs_processed_total&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nx&#34;&gt;Help&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;Total number of jobs processed, partitioned by status.&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;status&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;queueDepth&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;prometheus&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;NewGauge&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;prometheus&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;GaugeOpts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nx&#34;&gt;Name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;worker_queue_depth&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nx&#34;&gt;Help&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;Current number of jobs waiting in the queue.&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;jobDuration&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;prometheus&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;NewHistogram&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;prometheus&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;HistogramOpts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nx&#34;&gt;Name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;    &lt;span class=&#34;s&#34;&gt;&amp;#34;worker_job_duration_seconds&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nx&#34;&gt;Help&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;    &lt;span class=&#34;s&#34;&gt;&amp;#34;Time spent processing a single job.&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nx&#34;&gt;Buckets&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;prometheus&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;DefBuckets&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;func&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;init&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;prometheus&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;MustRegister&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;jobsProcessed&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;queueDepth&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;jobDuration&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;prometheus.MustRegister&lt;/code&gt; panics on a duplicate registration, which
makes misconfigurations obvious at startup rather than silently at
runtime. If you are embedding this exporter inside a library that other
packages will also instrument, prefer &lt;code&gt;prometheus.Register&lt;/code&gt; and handle
the error yourself.&lt;/p&gt;
&lt;h2 id=&#34;collecting-real-values&#34;&gt;Collecting real values&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#collecting-real-values&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;With the metrics registered, the next step is to keep them current.
You can either continually update the data as the data change, or run
your own internal refresh loop.
The pattern below shows a polling loop — a goroutine that periodically
reads from whatever data source your application owns and updates the
registered metrics. Replace the simulated values with real calls to
your database, internal API, or message broker:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s&#34;&gt;&amp;#34;math/rand&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s&#34;&gt;&amp;#34;time&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;func&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;collectMetrics&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;// Replace these with real reads from your application.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nx&#34;&gt;depth&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;float64&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;rand&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Intn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;50&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nx&#34;&gt;queueDepth&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;depth&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nx&#34;&gt;start&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Now&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nx&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Sleep&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Duration&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;rand&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Intn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;200&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Millisecond&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nx&#34;&gt;jobDuration&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Observe&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Since&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;start&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Seconds&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nx&#34;&gt;jobsProcessed&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;WithLabelValues&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;success&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Inc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nx&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Sleep&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Second&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The polling interval (here five seconds) should be shorter than
Prometheus&#39;s scrape interval so that each scrape sees a fresh value.
The default scrape interval in most cluster deployments is fifteen
seconds, which gives you comfortable headroom.&lt;/p&gt;
&lt;h2 id=&#34;exposing-the-endpoint&#34;&gt;Exposing the endpoint&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#exposing-the-endpoint&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Wire the collection loop and the HTTP handler together in &lt;code&gt;main&lt;/code&gt;. A
&lt;code&gt;/healthz&lt;/code&gt; path alongside &lt;code&gt;/metrics&lt;/code&gt; gives Kubernetes a liveness probe
target without exposing metric data on the health route:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;func&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;go&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;collectMetrics&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;http&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Handle&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;/metrics&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;promhttp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Handler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;http&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;HandleFunc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;/healthz&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;w&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;http&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ResponseWriter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;r&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;http&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Request&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nx&#34;&gt;w&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;WriteHeader&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;http&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;StatusOK&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Println&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;Listening on :8080&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;http&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;ListenAndServe&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;:8080&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nx&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Fatalf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;server error: %v&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Verify the output locally before building the image:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;go run .
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;curl http://localhost:8080/metrics &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; grep worker_
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You should see three &lt;code&gt;# HELP&lt;/code&gt; and &lt;code&gt;# TYPE&lt;/code&gt; blocks followed by the
current metric values. If those lines appear, the exporter is working
correctly and is ready to be containerized.&lt;/p&gt;
&lt;h2 id=&#34;build-a-container-image&#34;&gt;Build a container image&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#build-a-container-image&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;A multi-stage build keeps the final image small and avoids shipping a
Go toolchain to production. The first stage compiles a statically linked
binary; the second stage copies only that binary into a minimal base.
The example below uses Docker, but the same pattern works with any
OCI-compatible build tool such as Buildah or Podman:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-dockerfile&#34; data-lang=&#34;dockerfile&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;&lt;span class=&#34;s&#34;&gt; golang:1.21-alpine AS builder&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;WORKDIR&lt;/span&gt;&lt;span class=&#34;s&#34;&gt; /src&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;COPY&lt;/span&gt; go.mod go.sum ./&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;RUN&lt;/span&gt; go mod download&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;COPY&lt;/span&gt; . .&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;RUN&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;CGO_ENABLED&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; go build -o /exporter .&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;&lt;span class=&#34;s&#34;&gt; gcr.io/distroless/static:nonroot&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;COPY&lt;/span&gt; --from&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;builder /exporter /exporter&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;EXPOSE&lt;/span&gt;&lt;span class=&#34;s&#34;&gt; 8080&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ENTRYPOINT&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;/exporter&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;distroless/static:nonroot&lt;/code&gt; contains no shell, no package manager, and
runs as a non-root user by default, which satisfies most cluster
security policies without extra configuration.&lt;/p&gt;
&lt;p&gt;Build and push the image, replacing &lt;code&gt;&amp;lt;registry&amp;gt;&lt;/code&gt; with your own registry
address:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;docker build -t &amp;lt;registry&amp;gt;/my-exporter:v1.0.0 .
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;docker push &amp;lt;registry&amp;gt;/my-exporter:v1.0.0
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;(Note: Using a CI/CD pipeline to automate this is generally a better pattern than running these commands manually.)&lt;/p&gt;
&lt;h2 id=&#34;deploying-to-the-cluster&#34;&gt;Deploying to the cluster&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#deploying-to-the-cluster&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Two manifests are enough to run the exporter: a Deployment that manages
the pod lifecycle, and a Service that gives Prometheus a stable address
to scrape.
(You might prefer to have Prometheus scrape from every Pod; if that makes
sense for your use case, then it&#39;s OK to configure instead).&lt;/p&gt;
&lt;p&gt;The examples below use the &lt;code&gt;monitoring&lt;/code&gt; namespace, which is a common
convention when running Prometheus and related components together. Adjust
the namespace to match your own cluster setup.&lt;/p&gt;
&lt;p&gt;The Deployment sets conservative resource limits appropriate for a
lightweight sidecar-style process, and uses the &lt;code&gt;/healthz&lt;/code&gt; route for
its liveness probe:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;apps/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Deployment&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;my-exporter&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;namespace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;monitoring&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;app.kubernetes.io/name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;my-exporter&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;replicas&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;selector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;matchLabels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;app.kubernetes.io/name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;my-exporter&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;template&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;app.kubernetes.io/name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;my-exporter&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;containers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;exporter&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;&amp;lt;registry&amp;gt;/my-exporter:v1.0.0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ports&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;metrics&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;containerPort&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;8080&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;livenessProbe&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;httpGet&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;/healthz&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;port&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;8080&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;initialDelaySeconds&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;periodSeconds&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;resources&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;requests&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;cpu&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;50m&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;memory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;32Mi&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;limits&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;cpu&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;100m&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;memory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;64Mi&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The Service names the port &lt;code&gt;metrics&lt;/code&gt;, which the ServiceMonitor in the
next section will reference by that name:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Service&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;my-exporter&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;namespace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;monitoring&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;app.kubernetes.io/name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;my-exporter&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;selector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;app.kubernetes.io/name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;my-exporter&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ports&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;metrics&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;port&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;8080&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;targetPort&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;metrics&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Apply both:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl apply -f deployment.yaml -f service.yaml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;telling-prometheus-where-to-look&#34;&gt;Telling Prometheus where to look&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#telling-prometheus-where-to-look&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;How you configure scraping depends on how Prometheus was installed.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Option 1: Prometheus Operator (ServiceMonitor)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If you installed Prometheus using the
&lt;a href=&#34;https://github.com/prometheus-operator/prometheus-operator&#34;&gt;Prometheus Operator&lt;/a&gt;
or the &lt;code&gt;kube-prometheus-stack&lt;/code&gt; Helm chart, the operator must be running
in your cluster before you create a ServiceMonitor. The &lt;code&gt;release&lt;/code&gt; label
must match the label selector configured on your Prometheus resource —
&lt;code&gt;kube-prometheus-stack&lt;/code&gt; is the default for a standard Helm install:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;monitoring.coreos.com/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ServiceMonitor&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;my-exporter&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;namespace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;monitoring&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;release&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;kube-prometheus-stack&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;selector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;matchLabels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;app.kubernetes.io/name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;my-exporter&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;endpoints&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;port&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;metrics&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;interval&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;15s&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;/metrics&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Option 2: Annotation-based discovery&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If your Prometheus uses annotation-based pod discovery instead, you will
need a matching &lt;code&gt;scrape_config&lt;/code&gt; rule in your Prometheus configuration —
check with whoever manages your Prometheus installation to confirm it is
in place.&lt;/p&gt;
&lt;p&gt;You can add the following three annotations to the Pod template regardless
of which scraping method you use. They are ignored by the Prometheus
Operator but picked up automatically by annotation-based setups:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;prometheus.io/scrape&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;true&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;prometheus.io/port&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;8080&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# omit if not using annotation-based discovery&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;prometheus.io/path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;/metrics&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# omit if not using annotation-based discovery&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If you are unsure which setup your cluster uses, the ServiceMonitor
approach is more explicit and easier to debug.&lt;/p&gt;
&lt;h2 id=&#34;verifying-the-scrape&#34;&gt;Verifying the scrape&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#verifying-the-scrape&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Port-forward to the Prometheus service and open the targets page to
confirm the exporter has been discovered:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl port-forward svc/prometheus-operated &lt;span class=&#34;m&#34;&gt;9090&lt;/span&gt; -n monitoring
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Navigate to &lt;code&gt;http://localhost:9090/targets&lt;/code&gt;. The &lt;code&gt;my-exporter&lt;/code&gt; target
should appear with state &lt;strong&gt;UP&lt;/strong&gt;. If it shows &lt;strong&gt;DOWN&lt;/strong&gt;, check that the
ServiceMonitor&#39;s &lt;code&gt;release&lt;/code&gt; label matches and that the pod is running:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl get pods -n monitoring -l app.kubernetes.io/name&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;my-exporter
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl describe servicemonitor my-exporter -n monitoring
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Once the target is healthy, run a quick query in the expression browser
to confirm data is flowing:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;rate(worker_jobs_processed_total{status=&amp;#34;success&amp;#34;}[2m])
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A non-zero result here means the full pipeline is working: your
application is producing data, Prometheus is scraping it, and the
time-series are stored and queryable.&lt;/p&gt;
&lt;h2 id=&#34;what-comes-next&#34;&gt;What comes next&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#what-comes-next&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;A working exporter is the foundation, not the destination. The natural
next step is surfacing these metrics to the
&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/workloads/autoscaling/horizontal-pod-autoscale/&#34;&gt;HorizontalPodAutoscaler&lt;/a&gt;
so that your workload scales on the signals that actually drive load,
not just CPU. That requires a metrics adapter — the Prometheus Adapter
is the most widely deployed option — which registers your custom metrics
with the Kubernetes Custom Metrics API. Once registered, any
HorizontalPodAutoscaler in the cluster can reference &lt;code&gt;worker_queue_depth&lt;/code&gt;
or &lt;code&gt;worker_jobs_processed_total&lt;/code&gt; directly in its &lt;code&gt;metrics&lt;/code&gt; block.&lt;/p&gt;
&lt;p&gt;For a walkthrough of that setup, see
&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/#autoscaling-on-multiple-metrics-and-custom-metrics&#34;&gt;Autoscaling on multiple metrics and custom metrics&lt;/a&gt;.
For a catalog of ready-made exporters covering databases, message
brokers, and cloud services, the
&lt;a href=&#34;https://prometheus.io/docs/instrumenting/exporters/&#34;&gt;Prometheus exporters and integrations&lt;/a&gt;
page is a good starting point.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Operating AI/ML Workloads on Kubernetes: A Headlamp Plugin for Kubeflow</title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/07/13/introducing-headlamp-plugin-for-kubeflow/</link>
      <pubDate>Mon, 13 Jul 2026 12:00:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/07/13/introducing-headlamp-plugin-for-kubeflow/</guid>
      <description>
        
        
        &lt;p&gt;Kubernetes has quietly become the default platform for AI and machine learning. Whether you run notebook servers for data scientists, schedule distributed training jobs, tune hyperparameters, or orchestrate multi-step ML pipelines, those workloads increasingly land on a Kubernetes cluster. &lt;a href=&#34;https://www.kubeflow.org/&#34;&gt;Kubeflow&lt;/a&gt; is one of the most popular ways to assemble that stack, and it does so the Kubernetes-native way: every capability is exposed as a Custom Resource Definition (CRD).&lt;/p&gt;
&lt;p&gt;That design is a gift to cluster operators, because it means ML workloads can be observed and managed with the same primitives as everything else in the cluster. But in practice the specialized ML dashboards that ship with these platforms hide the Kubernetes layer underneath. When a notebook is stuck or a training run fails, the operator is often left dropping back to &lt;code&gt;kubectl&lt;/code&gt; to find out what actually happened at the Pod level.&lt;/p&gt;
&lt;p&gt;This post introduces the &lt;strong&gt;Headlamp Kubeflow plugin&lt;/strong&gt;, which closes that gap by surfacing Kubeflow&#39;s custom resources directly inside a general-purpose Kubernetes UI. It is a worked example of a pattern any CRD-heavy platform can follow: meet operators where they already work, and show them the cluster-level truth.&lt;/p&gt;
&lt;p&gt;Headlamp itself is an extensible Kubernetes web UI maintained under &lt;a href=&#34;https://github.com/kubernetes-sigs/headlamp&#34;&gt;Kubernetes SIG UI&lt;/a&gt; and licensed under Apache 2.0. It runs as a desktop app or in-cluster, and its plugin system lets anyone add first-class views for custom resources.&lt;/p&gt;
&lt;h2 id=&#34;why-operators-need-a-different-view&#34;&gt;Why operators need a different view&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#why-operators-need-a-different-view&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Purpose-built ML dashboards help data scientists submit experiments, pipelines, and
notebooks. Cluster operators and site reliability engineers (SREs) troubleshoot the
Kubernetes resources underneath, and they ask different questions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Why is a notebook stuck? Is it &lt;code&gt;ImagePullBackOff&lt;/code&gt;, &lt;code&gt;OOMKilled&lt;/code&gt;, or a Pod waiting on a PersistentVolumeClaim?&lt;/li&gt;
&lt;li&gt;Which Run resources failed recently across namespaces?&lt;/li&gt;
&lt;li&gt;Which parameter set does a Katib Experiment report as optimal?&lt;/li&gt;
&lt;li&gt;Do TrainJob resources reference the expected TrainingRuntime resources?&lt;/li&gt;
&lt;li&gt;Which batch workloads are running, and what state does Kubernetes report?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The Headlamp Kubeflow plugin helps answer these questions by reading directly from
the Kubernetes API server. It shows Pod conditions, Kubernetes failure reasons, and
resources across namespaces without requiring an intermediary ML service or
database.&lt;/p&gt;
&lt;h2 id=&#34;what-the-plugin-covers&#34;&gt;What the plugin covers&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#what-the-plugin-covers&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Kubeflow is modular, and teams often install only the components they need. The
plugin discovers the Kubeflow API groups on a cluster and displays only the
corresponding sections.&lt;/p&gt;
&lt;p&gt;The plugin supports the following component families and API resources:&lt;/p&gt;


 





&lt;table&gt;&lt;caption style=&#34;display: none;&#34;&gt;Kubeflow components and API resources supported by the Headlamp plugin&lt;/caption&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th style=&#34;text-align: left&#34;&gt;Component&lt;/th&gt;
          &lt;th style=&#34;text-align: left&#34;&gt;Purpose&lt;/th&gt;
          &lt;th style=&#34;text-align: left&#34;&gt;API resources&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;&lt;strong&gt;Notebooks&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;Provides development environments such as Jupyter, VS Code, and RStudio&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;Notebook, Profile, PodDefault&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;&lt;strong&gt;Pipelines&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;Defines and tracks pipelines, versions, experiments, runs, and schedules&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;Pipeline, PipelineVersion, Run, RecurringRun, Experiment&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;&lt;strong&gt;Katib&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;Automates hyperparameter tuning and neural architecture search&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;Experiment, Trial, Suggestion&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;&lt;strong&gt;Training&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;Runs distributed training workloads such as PyTorch and TensorFlow jobs&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;TrainJob, TrainingRuntime, ClusterTrainingRuntime&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;&lt;strong&gt;Spark&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;Runs large-scale data processing with Apache Spark&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;SparkApplication, ScheduledSparkApplication&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h2 id=&#34;what-you-can-see&#34;&gt;What you can see&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#what-you-can-see&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;h3 id=&#34;inspect-notebook-pods&#34;&gt;Inspect notebook Pods&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#inspect-notebook-pods&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The Notebook detail view shows Pod conditions and their &lt;code&gt;reason&lt;/code&gt; and &lt;code&gt;message&lt;/code&gt;
fields. It also shows CPU, memory, and GPU requests and limits; volume mounts and
their backing types, such as PersistentVolumeClaim, ConfigMap, Secret, or
&lt;code&gt;emptyDir&lt;/code&gt;; environment variables that reference Secret or ConfigMap objects;
sidecar containers; and node tolerations. This view consolidates information that
would otherwise require several &lt;code&gt;kubectl describe&lt;/code&gt; commands.&lt;/p&gt;
&lt;h3 id=&#34;inspect-hyperparameter-tuning&#34;&gt;Inspect hyperparameter tuning&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#inspect-hyperparameter-tuning&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The Katib views show the tuning algorithm, search space, every Trial with its live
status, and the current best Trial with its metric values and parameter assignments.
They also show the early-stopping configuration and the number of Trial resources
that stopped early, so you can follow the search without leaving the cluster UI.&lt;/p&gt;
&lt;h3 id=&#34;inspect-pipeline-state-without-the-backend-database&#34;&gt;Inspect pipeline state without the backend database&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#inspect-pipeline-state-without-the-backend-database&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The Pipelines views read Kubernetes API resources directly and do not query the
Kubeflow Pipelines API service or backend database. You can inspect stored pipeline
state even when that service is unavailable. The Pipeline detail view compares the
latest and previous PipelineVersion specifications in a side-by-side YAML diff. Run
views show state and duration, RecurringRun views show human-readable schedules, and
the artifacts view aggregates &lt;code&gt;pipelineRoot&lt;/code&gt; values from recent Run resources.&lt;/p&gt;
&lt;h3 id=&#34;map-ml-resources&#34;&gt;Map ML resources&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#map-ml-resources&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The plugin registers a
&lt;a href=&#34;https://headlamp.dev/docs/latest/development/plugins/functionality/extending-the-map/&#34;&gt;Headlamp map source&lt;/a&gt;
that renders Notebook, Profile, PodDefault, Experiment, Pipeline, SparkApplication,
and TrainJob resources as graph nodes. It draws edges between supported resources
based on &lt;code&gt;.metadata.ownerReferences&lt;/code&gt;. Headlamp also shows inline summaries for these
resource types when you hover over them.&lt;/p&gt;
&lt;h2 id=&#34;try-it&#34;&gt;Try it&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#try-it&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The
&lt;a href=&#34;https://github.com/headlamp-k8s/plugins/blob/main/kubeflow/README.md&#34;&gt;Kubeflow plugin README&lt;/a&gt;
explains installation and local-cluster setup, including a lightweight CRD-only path
for evaluation. Because the plugin discovers installed API groups, you can use it
with an existing modular Kubeflow installation or create an evaluation cluster with
only the CRDs and sample resources.&lt;/p&gt;
&lt;h2 id=&#34;apply-the-pattern-to-other-platforms&#34;&gt;Apply the pattern to other platforms&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#apply-the-pattern-to-other-platforms&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Kubeflow illustrates a broader pattern. Platforms often model domain-specific
workflows with custom resources. Their dashboards focus on those workflows, while
Kubernetes operators also need the state of the underlying API resources and Pods.
A CRD-driven plugin in a general Kubernetes UI can expose that state without making
operators switch between unrelated tools.&lt;/p&gt;
&lt;p&gt;The plugin uses the Apache 2.0 license and is developed under Kubernetes SIG UI. To
report a problem or contribute an improvement, use the Headlamp plugins repository&#39;s
&lt;a href=&#34;https://github.com/headlamp-k8s/plugins/issues&#34;&gt;issue tracker&lt;/a&gt; or
&lt;a href=&#34;https://github.com/headlamp-k8s/plugins/pulls&#34;&gt;pull requests&lt;/a&gt;.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes Dashboard to Headlamp: A Step-by-Step Guide</title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/07/13/kubernetes-dashboard-to-headlamp/</link>
      <pubDate>Mon, 13 Jul 2026 10:00:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/07/13/kubernetes-dashboard-to-headlamp/</guid>
      <description>
        
        
        &lt;h2 id=&#34;1-before-you-start-know-what-is-changing&#34;&gt;1. Before you start: know what is changing&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#1-before-you-start-know-what-is-changing&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Kubernetes Dashboard and Headlamp both show what is running in a cluster, but they work differently. When Headlamp runs on the desktop, it uses your existing kubeconfig to connect to one or more clusters and can be extended with plugins. When Headlamp runs inside a cluster, it uses a Kubernetes ServiceAccount to access the API and follow RBAC rules. Kubernetes Dashboard, in contrast, only runs in-cluster and always relies on service account tokens. Understanding these models early helps you choose the right setup and permissions.&lt;/p&gt;
&lt;h3 id=&#34;1-1-how-kubernetes-dashboard-works&#34;&gt;1.1 How Kubernetes Dashboard works&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#1-1-how-kubernetes-dashboard-works&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Dashboard is a web app that runs inside your cluster.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You install it in the cluster, often with Helm.&lt;/li&gt;
&lt;li&gt;You usually run one Dashboard per cluster.&lt;/li&gt;
&lt;li&gt;You often reach it with &lt;code&gt;kubectl port-forward&lt;/code&gt; or an ingress.&lt;/li&gt;
&lt;li&gt;You log in with a Bearer token. That token is often from a service account.&lt;/li&gt;
&lt;li&gt;It includes forms that help you create resources.&lt;/li&gt;
&lt;li&gt;It leans on tables and lists for navigation.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It feels like this: a UI that lives with the cluster.&lt;/p&gt;
&lt;h3 id=&#34;1-2-how-headlamp-works&#34;&gt;1.2 How Headlamp works&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#1-2-how-headlamp-works&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Headlamp acts more like a Kubernetes client with a UI.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It can run on your desktop or in a cluster.&lt;/li&gt;
&lt;li&gt;It reads your kubeconfig, like kubectl does.&lt;/li&gt;
&lt;li&gt;It can show more than one cluster in one place.&lt;/li&gt;
&lt;li&gt;It favors YAML when you create or change resources.&lt;/li&gt;
&lt;li&gt;It includes list views and a visual map.&lt;/li&gt;
&lt;li&gt;You can add features with plugins.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Headlamp is a UI that follows your identity, not your cluster.&lt;/p&gt;
&lt;h3 id=&#34;1-3-what-stays-the-same&#34;&gt;1.3 What stays the same&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#1-3-what-stays-the-same&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Many workflows will feel familiar:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Browse workloads and resources&lt;/li&gt;
&lt;li&gt;Filter by namespace&lt;/li&gt;
&lt;li&gt;Inspect YAML, events, and status&lt;/li&gt;
&lt;li&gt;View logs&lt;/li&gt;
&lt;li&gt;Take actions your RBAC allows&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;1-4-what-changes&#34;&gt;1.4 What changes&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#1-4-what-changes&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;A few things will feel different:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Login shifts from pasted tokens to kubeconfig (and sometimes SSO).&lt;/li&gt;
&lt;li&gt;Creation shifts from forms to &amp;quot;apply YAML.&amp;quot;&lt;/li&gt;
&lt;li&gt;Multi-cluster becomes normal, not a special case.&lt;/li&gt;
&lt;li&gt;The map view helps you see how resources connect.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;2-pre-migration-checklist&#34;&gt;2. Pre-migration checklist&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#2-pre-migration-checklist&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;This checklist helps you avoid surprises during the switch. It makes sure Headlamp can use the same identity and permissions you already trust in Kubernetes. It also gives you a quick way to prove the migration worked before you turn off Dashboard.&lt;/p&gt;
&lt;h3 id=&#34;2-1-write-down-what-you-use-today&#34;&gt;2.1 Write down what you use today&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#2-1-write-down-what-you-use-today&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;List the basics:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Which clusters you use (dev, staging, prod)&lt;/li&gt;
&lt;li&gt;Which namespaces you touch most&lt;/li&gt;
&lt;li&gt;What you do most often (view, edit, scale, delete, debug)&lt;/li&gt;
&lt;li&gt;How you access Dashboard today (port-forward or ingress)&lt;/li&gt;
&lt;li&gt;How you log in (service account token, and which RBAC bindings)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is your baseline.&lt;/p&gt;
&lt;h3 id=&#34;2-2-check-that-kubeconfig-works&#34;&gt;2.2 Check that kubeconfig works&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#2-2-check-that-kubeconfig-works&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Headlamp uses kubeconfig, especially on desktop. Make sure yours works before you install anything.&lt;/p&gt;
&lt;p&gt;Run:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl config current-context
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then try:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl get nodes
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If you cannot list nodes, test in a namespace you can access:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl get pods -n &amp;lt;namespace&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If these work, Headlamp can use the same identity and RBAC.&lt;/p&gt;
&lt;h3 id=&#34;2-3-pick-a-rollout-plan&#34;&gt;2.3 Pick a rollout plan&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#2-3-pick-a-rollout-plan&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;There is no need to rush. Most teams choose one of these:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Parallel rollout (recommended)&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Install Headlamp&lt;/li&gt;
&lt;li&gt;Let people try it&lt;/li&gt;
&lt;li&gt;Keep Dashboard for a short time&lt;/li&gt;
&lt;li&gt;Remove Dashboard after the team is ready&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Cutover&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Install Headlamp&lt;/li&gt;
&lt;li&gt;Switch docs and links&lt;/li&gt;
&lt;li&gt;Remove Dashboard soon after&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Parallel rollout is safer for shared clusters.&lt;/p&gt;
&lt;h3 id=&#34;2-4-decide-where-headlamp-will-run&#34;&gt;2.4 Decide where Headlamp will run&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#2-4-decide-where-headlamp-will-run&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;You can use either option. Many teams use both.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Desktop&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Uses your kubeconfig&lt;/li&gt;
&lt;li&gt;Uses no cluster resources&lt;/li&gt;
&lt;li&gt;No port-forward needed&lt;/li&gt;
&lt;li&gt;Multi-cluster works out of the box&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;In-cluster&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Works well for shared, browser access&lt;/li&gt;
&lt;li&gt;Can be managed like other cluster apps&lt;/li&gt;
&lt;li&gt;Often paired with ingress and SSO&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;2-5-note-optional-dependencies&#34;&gt;2.5 Note optional dependencies&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#2-5-note-optional-dependencies&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;These are common. You can handle them later.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;metrics-server&lt;/code&gt; (for CPU and memory graphs)&lt;/li&gt;
&lt;li&gt;ingress (for an in-cluster URL)&lt;/li&gt;
&lt;li&gt;OIDC / SSO (for browser sign-in)&lt;/li&gt;
&lt;li&gt;cleanup of old Dashboard service accounts and RBAC&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;3-choose-where-headlamp-will-run-desktop-or-in-cluster&#34;&gt;3. Choose where Headlamp will run (desktop or in-cluster)&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#3-choose-where-headlamp-will-run-desktop-or-in-cluster&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Headlamp can run on your desktop or inside a cluster. Both work well, but they fit different needs. Desktop is the fastest way to start because it uses your kubeconfig and does not run in the cluster. In-cluster is best when you need a shared URL and want the platform team to manage upgrades and access.&lt;/p&gt;
&lt;h3 id=&#34;option-a-desktop-user-managed&#34;&gt;Option A: Desktop (user-managed)&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#option-a-desktop-user-managed&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Desktop Headlamp runs on each user&#39;s machine. It reads the same kubeconfig you use with kubectl. This keeps access tied to each user&#39;s identity and RBAC.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why teams pick it&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;No in-cluster service to deploy or expose.&lt;/li&gt;
&lt;li&gt;It uses no cluster CPU or memory.&lt;/li&gt;
&lt;li&gt;It uses your kubeconfig and RBAC.&lt;/li&gt;
&lt;li&gt;It works with many clusters in one app.&lt;/li&gt;
&lt;li&gt;You do not need port-forward for day-to-day use.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;option-b-in-cluster-best-for-shared-access&#34;&gt;Option B: In-cluster (best for shared access)&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#option-b-in-cluster-best-for-shared-access&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;In-cluster Headlamp is installed as a Kubernetes workload (often via Helm). This lets cluster admins manage it like other in-cluster apps.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Cluster admins manage install, upgrades, and configuration through the Helm chart and standard Kubernetes tooling.&lt;/li&gt;
&lt;li&gt;Admins control ingress and can set up OIDC login for shared access.&lt;/li&gt;
&lt;li&gt;It supports shared use in team environments.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;4-install-headlamp-desktop-and-in-cluster&#34;&gt;4. Install Headlamp (desktop and in-cluster)&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#4-install-headlamp-desktop-and-in-cluster&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;This section gets Headlamp running. Follow the path you chose in Section 3.&lt;/p&gt;
&lt;h3 id=&#34;4-1-desktop-install-fastest-way-to-start&#34;&gt;4.1 Desktop install (fastest way to start)&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#4-1-desktop-install-fastest-way-to-start&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Install Headlamp on your machine. Then open it like any other app. Headlamp reads your kubeconfig and uses the same identity and RBAC rules as kubectl.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Windows&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Install with WinGet:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;winget install headlamp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Or with Chocolatey:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;choco install headlamp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;macOS&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Install with Homebrew:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;brew install --cask headlamp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Linux&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Install with Flatpak (Flathub):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;flatpak install flathub io.kinvolk.Headlamp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Quick check&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Launch Headlamp.&lt;/li&gt;
&lt;li&gt;Confirm you can see a cluster context.&lt;/li&gt;
&lt;li&gt;Open a namespace you can access and confirm you can list workloads. Headlamp will only show actions your RBAC allows.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;4-2-in-cluster-install-shared-access&#34;&gt;4.2 In-cluster install (shared access)&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#4-2-in-cluster-install-shared-access&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Use this path when you want a shared UI that the platform team can manage. Headlamp supports in-cluster deployment with Helm or a YAML manifest.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Install with Helm&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Add the repo and update:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;helm repo add headlamp https://kubernetes-sigs.github.io/headlamp/
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;helm repo update
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Create a namespace (example):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl create namespace headlamp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Install the chart:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;helm install headlamp headlamp/headlamp --namespace headlamp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Install with a YAML manifest (optional)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Headlamp also provides a YAML manifest you can apply and then adjust to your needs.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Check the install&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Confirm the pod is running:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl get pods -n headlamp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Confirm the service exists:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl get svc -n headlamp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Access it (two common ways)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Quick test with port-forward&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;This is the fastest way to verify the service works:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl port-forward -n headlamp svc/headlamp 8080:80
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then open: http://localhost:8080&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Shared access with ingress&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;If you want a stable URL, expose the service through your ingress controller. Your exact ingress YAML depends on your setup. Headlamp&#39;s OIDC callback URL is your public URL plus &lt;code&gt;/oidc-callback&lt;/code&gt;, so ingress and TLS settings matter.&lt;/p&gt;
&lt;h3 id=&#34;4-3-updating-headlamp&#34;&gt;4.3 Updating Headlamp&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#4-3-updating-headlamp&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Updates depend on how you installed Headlamp. Package managers upgrade in place. DMG or EXE installs update by reinstalling the newer download.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;macOS&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If you installed with Homebrew, run:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;brew upgrade headlamp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If you installed from a DMG, download the newest DMG and drag Headlamp into &lt;code&gt;/Applications&lt;/code&gt;, replacing the old version. DMG installs do not auto upgrade.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Windows&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If you installed with WinGet, run:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;winget upgrade headlamp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If you installed with Chocolatey, run:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;choco upgrade headlamp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If you installed from the EXE, download the newest installer and run it again. EXE installs do not auto upgrade.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Linux&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If you installed with Flatpak, run:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;flatpak update io.kinvolk.Headlamp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If you installed with AppImage, download the newest AppImage and run that file instead.&lt;/p&gt;
&lt;p&gt;If you installed with a tarball, download the newest tarball, extract it, and run the new headlamp binary.&lt;/p&gt;
&lt;h3 id=&#34;4-4-notes-for-in-cluster-access-keep-it-safe&#34;&gt;4.4 Notes for in-cluster access (keep it safe)&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#4-4-notes-for-in-cluster-access-keep-it-safe&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Treat an in-cluster UI like any other cluster-facing service. Use TLS, lock down who can reach it, and rely on Kubernetes auth and RBAC to control what users can do.&lt;/p&gt;
&lt;h2 id=&#34;5-authentication-and-rbac&#34;&gt;5. Authentication and RBAC&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#5-authentication-and-rbac&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Headlamp uses the Kubernetes API the same way kubectl does. Your cluster still decides who can do what. Headlamp only shows actions your identity is allowed to take.&lt;/p&gt;
&lt;p&gt;This section covers two setups: desktop and in-cluster.&lt;/p&gt;
&lt;h3 id=&#34;5-1-desktop-use-kubeconfig&#34;&gt;5.1 Desktop: use kubeconfig&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#5-1-desktop-use-kubeconfig&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;On desktop, Headlamp reads your kubeconfig and uses the same credentials you use with kubectl. There is no separate token login flow to manage.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 1: Confirm your kubeconfig works&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Run:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl config current-context
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then test access:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl get nodes
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If you cannot list nodes, test a namespace you can access:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl get pods -n &amp;lt;namespace&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If these commands work, your kubeconfig and credentials are valid for Headlamp too.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 2: Point Headlamp at the right kubeconfig (if needed)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Headlamp can use the default kubeconfig path. It can also use a custom file path. You can set &lt;code&gt;KUBECONFIG&lt;/code&gt; to choose a specific file.&lt;/p&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;KUBECONFIG&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;/path/to/config headlamp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You can also use more than one kubeconfig file at once. On Unix systems, separate paths with &lt;code&gt;:&lt;/code&gt;. On Windows, separate paths with &lt;code&gt;;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What to expect in the UI&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Headlamp adapts to your RBAC permissions. If you do not have permission to edit or delete a resource, Headlamp will not offer those actions.&lt;/p&gt;
&lt;h3 id=&#34;5-2-in-cluster-shared-access-needs-a-sign-in-plan&#34;&gt;5.2 In-cluster: shared access needs a sign-in plan&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#5-2-in-cluster-shared-access-needs-a-sign-in-plan&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;In-cluster Headlamp is shared by many users. You need a clear plan for sign-in and access. Headlamp supports OpenID Connect (OIDC) for a &amp;quot;Sign in&amp;quot; flow.&lt;/p&gt;
&lt;p&gt;You will usually choose one of these patterns:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;A.&lt;/strong&gt; Configure Headlamp with OIDC (built-in).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;B.&lt;/strong&gt; Put an auth layer in front of Headlamp (common in enterprises).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;A. Built-in OIDC (Headlamp)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;To use OIDC, Headlamp needs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Client ID&lt;/li&gt;
&lt;li&gt;Client secret&lt;/li&gt;
&lt;li&gt;Issuer URL&lt;/li&gt;
&lt;li&gt;(Optional) scopes&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Your OIDC provider must also allow Headlamp&#39;s callback URL. The callback is your Headlamp URL plus:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/oidc-callback&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;https://headlamp.example.com/oidc-callback&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Ingress note&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If Headlamp is behind an ingress or load balancer, make sure it forwards &lt;code&gt;X-Forwarded-Proto&lt;/code&gt;. If it does not, Headlamp may generate an &lt;code&gt;http&lt;/code&gt; callback URL instead of &lt;code&gt;https&lt;/code&gt;. That can break login.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;B. Auth layer in front of Headlamp&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Some teams protect Headlamp with an identity-aware proxy or a platform auth system. This keeps sign-in consistent across tools. Headlamp docs include an example using OpenUnison, which can deploy Headlamp with hardened defaults and integrate with identity providers.&lt;/p&gt;
&lt;h3 id=&#34;5-3-rbac-keep-it-least-privilege&#34;&gt;5.3 RBAC: keep it least privilege&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#5-3-rbac-keep-it-least-privilege&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Kubernetes security starts with API authentication and authorization (RBAC). Headlamp respects those rules.&lt;/p&gt;
&lt;p&gt;Practical guidance:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Start with the lowest permissions that still let users do their job.&lt;/li&gt;
&lt;li&gt;If Dashboard used a high-privilege service account token, plan to remove or tighten that access after the move.&lt;/li&gt;
&lt;li&gt;For in-cluster, treat the UI like any other endpoint. Use TLS and limit network access.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;5-4-quick-troubleshooting&#34;&gt;5.4 Quick troubleshooting&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#5-4-quick-troubleshooting&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;Desktop: &amp;quot;I do not see my cluster&amp;quot;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Your kubeconfig may not be in the default location. Point Headlamp to the file with &lt;code&gt;KUBECONFIG&lt;/code&gt; or a file path.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;In-cluster: &amp;quot;OIDC login fails after redirect&amp;quot;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Confirm your provider allows &lt;code&gt;https://YOUR_URL/oidc-callback&lt;/code&gt;. If you use ingress, make sure it forwards &lt;code&gt;X-Forwarded-Proto&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;6-manage-multiple-clusters&#34;&gt;6. Manage multiple clusters&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#6-manage-multiple-clusters&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Kubernetes Dashboard is usually tied to one cluster at a time. Headlamp is built for multi-cluster work. It is a client that follows your kubeconfig, not a single cluster install. That means you can keep one UI open and switch clusters as you work.&lt;/p&gt;
&lt;h3 id=&#34;clusters-come-from-your-kubeconfig&#34;&gt;Clusters come from your kubeconfig&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#clusters-come-from-your-kubeconfig&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Headlamp reads clusters from your kubeconfig files. That means the clusters you can access with kubectl can also show up in Headlamp.&lt;/p&gt;
&lt;h3 id=&#34;switch-clusters-in-the-ui&#34;&gt;Switch clusters in the UI&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#switch-clusters-in-the-ui&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Once Headlamp loads your kubeconfig, you can switch clusters using the cluster selector. This makes it easier to move between dev, staging, and prod without changing tools.&lt;/p&gt;
&lt;h3 id=&#34;optional-use-more-than-one-kubeconfig-file&#34;&gt;Optional: use more than one kubeconfig file&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#optional-use-more-than-one-kubeconfig-file&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;If you keep separate kubeconfig files, you can load them together. Headlamp supports multiple kubeconfig paths in &lt;code&gt;KUBECONFIG&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Unix/macOS/Linux (&lt;code&gt;:&lt;/code&gt; separator):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;KUBECONFIG&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;~/.kube/dev:~/.kube/prod headlamp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Windows (&lt;code&gt;;&lt;/code&gt; separator):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;$env:KUBECONFIG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$HOME&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;\.kube\dev;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$HOME&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;\.kube\prod&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;optional-add-a-cluster-from-inside-headlamp&#34;&gt;Optional: add a cluster from inside Headlamp&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#optional-add-a-cluster-from-inside-headlamp&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;You can also add clusters by loading additional kubeconfig files from the UI.&lt;/p&gt;
&lt;h3 id=&#34;permissions-stay-the-same&#34;&gt;Permissions stay the same&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#permissions-stay-the-same&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Multi-cluster does not change security rules. Each cluster still enforces its own RBAC. Headlamp shows only what your identity can do in the selected cluster.&lt;/p&gt;
&lt;h2 id=&#34;7-navigate-and-understand-resources&#34;&gt;7. Navigate and understand resources&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#7-navigate-and-understand-resources&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;If you used Kubernetes Dashboard, this part will feel familiar. Headlamp keeps the same core resource views, but makes it easier to move around and understand what is connected.&lt;/p&gt;
&lt;h3 id=&#34;find-resources-in-familiar-places&#34;&gt;Find resources in familiar places&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#find-resources-in-familiar-places&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Headlamp groups resources in a way that maps closely to Dashboard:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Workloads&lt;/strong&gt; for Pods, Deployments, StatefulSets, and Jobs&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Network&lt;/strong&gt; for Services and Ingress&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Storage&lt;/strong&gt; for PersistentVolumes and Claims&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Configuration&lt;/strong&gt; for ConfigMaps and Secrets&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Nodes&lt;/strong&gt; for cluster infrastructure&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can filter by namespace at the top of the UI, just like in Dashboard.&lt;/p&gt;
&lt;h3 id=&#34;inspect-and-edit-resources&#34;&gt;Inspect and edit resources&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#inspect-and-edit-resources&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;From any list, you can click into a resource to see details:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Status and conditions&lt;/li&gt;
&lt;li&gt;Events&lt;/li&gt;
&lt;li&gt;Labels and annotations&lt;/li&gt;
&lt;li&gt;The full YAML definition&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If your RBAC allows it, you can edit YAML directly from the UI. If it does not, Headlamp shows the resource as read-only. This matches how kubectl behaves.&lt;/p&gt;
&lt;h3 id=&#34;use-search-and-filters-to-move-faster&#34;&gt;Use search and filters to move faster&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#use-search-and-filters-to-move-faster&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Headlamp adds faster search and filtering across lists. This helps when clusters or namespaces get large. You can narrow views without jumping between pages.&lt;/p&gt;
&lt;h3 id=&#34;understand-relationships-with-map-view&#34;&gt;Understand relationships with Map View&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#understand-relationships-with-map-view&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Dashboard mostly shows resources as lists. Headlamp also includes a Map View.&lt;/p&gt;
&lt;p&gt;Map View shows how resources relate to each other:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Deployments&lt;/li&gt;
&lt;li&gt;ReplicaSets&lt;/li&gt;
&lt;li&gt;Pods&lt;/li&gt;
&lt;li&gt;Services&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This helps when you are troubleshooting. Instead of clicking through several pages, you can see the connections at once. You can spot missing links or broken relationships faster.&lt;/p&gt;
&lt;h3 id=&#34;when-to-use-lists-vs-map-view&#34;&gt;When to use lists vs Map View&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#when-to-use-lists-vs-map-view&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;Use &lt;strong&gt;lists&lt;/strong&gt; when you know what resource you are looking for.&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;Map View&lt;/strong&gt; when you are trying to understand why something is not working.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Both views work on the same data. You are just choosing how much context you want at that moment.&lt;/p&gt;
&lt;h2 id=&#34;8-deploy-applications-with-yaml&#34;&gt;8. Deploy applications with YAML&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#8-deploy-applications-with-yaml&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;This is the biggest change for most Kubernetes Dashboard users. Dashboard relied on forms. Headlamp relies on manifests. The goal is not to slow you down. It is to align the UI with how Kubernetes is usually run in practice.&lt;/p&gt;
&lt;h3 id=&#34;from-forms-to-manifests&#34;&gt;From forms to manifests&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#from-forms-to-manifests&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;In Kubernetes Dashboard, you often deployed an app by filling in a form:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;container image&lt;/li&gt;
&lt;li&gt;replicas&lt;/li&gt;
&lt;li&gt;service type&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Headlamp does not include the same wizard. Instead, it lets you apply YAML directly from the UI.&lt;/p&gt;
&lt;p&gt;This matches how most teams deploy today:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;manifests live in Git&lt;/li&gt;
&lt;li&gt;CI/CD applies them&lt;/li&gt;
&lt;li&gt;Helm or GitOps tools manage changes&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Headlamp fits into that flow rather than replacing it.&lt;/p&gt;
&lt;h3 id=&#34;create-resources-using-yaml&#34;&gt;Create resources using YAML&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#create-resources-using-yaml&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;To deploy an application in Headlamp:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Select a cluster and namespace.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Create&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Paste or upload a YAML manifest.&lt;/li&gt;
&lt;li&gt;Review it.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Apply&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;img src=&#34;./create-highlight.png&#34; alt=&#34;Create button highlight&#34; style=&#34;display: block; margin-bottom: 0.5em;&#34; /&gt;
&lt;p&gt;The resource appears immediately in the UI.&lt;/p&gt;
&lt;p&gt;If the manifest is not valid, Headlamp shows the same errors you would see from the Kubernetes API.&lt;/p&gt;
&lt;h3 id=&#34;generate-yaml-the-easy-way&#34;&gt;Generate YAML the easy way&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#generate-yaml-the-easy-way&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;If you miss the Dashboard wizard, you can still generate YAML quickly.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl create deployment nginx &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;  --image&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;nginx &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;  --dry-run&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;client &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;  -o yaml &amp;gt; nginx.yaml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You can edit the file if needed, then paste it into Headlamp and apply it.&lt;/p&gt;
&lt;p&gt;This gives you a repeatable manifest instead of an object created only through a UI.&lt;/p&gt;
&lt;h3 id=&#34;what-if-you-use-helm-or-gitops&#34;&gt;What if you use Helm or GitOps?&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#what-if-you-use-helm-or-gitops&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;That works well with Headlamp.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Install with Helm as usual.&lt;/li&gt;
&lt;li&gt;Deploy with GitOps pipelines as usual.&lt;/li&gt;
&lt;li&gt;Use Headlamp to view, inspect, and debug what is running.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Headlamp does not replace those tools. It gives you visibility into what they create.&lt;/p&gt;
&lt;h3 id=&#34;what-to-expect-compared-to-dashboard&#34;&gt;What to expect compared to Dashboard&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#what-to-expect-compared-to-dashboard&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;You will not see a multi-step deploy form.&lt;/li&gt;
&lt;li&gt;You will work more with YAML.&lt;/li&gt;
&lt;li&gt;You gain clarity about what is actually applied to the cluster.&lt;/li&gt;
&lt;li&gt;The same manifest can be reused in CI, Git, or other tools.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;9-deploy-and-debug-workloads&#34;&gt;9. Deploy and debug workloads&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#9-deploy-and-debug-workloads&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;One of the main reasons people used Kubernetes Dashboard was day-to-day debugging. Headlamp covers the same tasks and adds a few useful upgrades.&lt;/p&gt;
&lt;h3 id=&#34;view-logs&#34;&gt;View logs&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#view-logs&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;You can view pod logs directly in the UI.&lt;/p&gt;
&lt;p&gt;To check logs:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open &lt;strong&gt;Workloads&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;Pods&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click a pod.&lt;/li&gt;
&lt;li&gt;Open the &lt;strong&gt;Logs&lt;/strong&gt; tab.&lt;/li&gt;
&lt;/ol&gt;
&lt;img src=&#34;./workloads.png&#34; alt=&#34;Workloads view&#34; style=&#34;display: block; margin-bottom: 0.5em;&#34; /&gt;
&lt;p&gt;If the pod has more than one container, you can switch between containers. Logs stream live, which helps during rollouts or active incidents.&lt;/p&gt;
&lt;h3 id=&#34;exec-into-running-pods&#34;&gt;Exec into running pods&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#exec-into-running-pods&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Headlamp also lets you open a shell inside a container.&lt;/p&gt;
&lt;p&gt;From a pod view:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Open the pod actions menu.&lt;/li&gt;
&lt;li&gt;Choose &lt;strong&gt;Terminal&lt;/strong&gt; or &lt;strong&gt;Exec&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This opens an interactive session inside the container. It replaces the need to switch back to the terminal for quick checks.&lt;/p&gt;
&lt;p&gt;This action follows RBAC rules. If you cannot run &lt;code&gt;kubectl exec&lt;/code&gt;, Headlamp will not allow it either.&lt;/p&gt;
&lt;h3 id=&#34;check-metrics-and-resource-usage&#34;&gt;Check metrics and resource usage&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#check-metrics-and-resource-usage&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Headlamp can show CPU and memory usage for pods and nodes. This works the same way it did in Dashboard.&lt;/p&gt;
&lt;p&gt;A few things to know:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Metrics require &lt;code&gt;metrics-server&lt;/code&gt; to be installed in the cluster.&lt;/li&gt;
&lt;li&gt;If metrics are missing, Headlamp shows a clear notice.&lt;/li&gt;
&lt;li&gt;Once metrics are available, usage appears on pod and node views.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This makes it easy to answer simple questions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Is this pod using too much memory?&lt;/li&gt;
&lt;li&gt;Is a node under pressure?&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;view-events-when-something-goes-wrong&#34;&gt;View events when something goes wrong&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#view-events-when-something-goes-wrong&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Events are often the fastest way to understand failures.&lt;/p&gt;
&lt;p&gt;In Headlamp, you can:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;View events on resource detail pages.&lt;/li&gt;
&lt;li&gt;See warnings and errors tied to pods, nodes, or deployments.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is often the first place to look when a workload is stuck or crashes.&lt;/p&gt;
&lt;h3 id=&#34;how-this-compares-to-dashboard&#34;&gt;How this compares to Dashboard&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#how-this-compares-to-dashboard&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;What stays the same:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Log viewing&lt;/li&gt;
&lt;li&gt;Event inspection&lt;/li&gt;
&lt;li&gt;RBAC-aware actions&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;What improves:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Built-in exec sessions&lt;/li&gt;
&lt;li&gt;Clearer layout and filtering&lt;/li&gt;
&lt;li&gt;Fewer context switches between UI and CLI&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;10-remove-kubernetes-dashboard&#34;&gt;10. Remove Kubernetes Dashboard&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#10-remove-kubernetes-dashboard&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;After Headlamp is working and your team is comfortable using it, you can remove Kubernetes Dashboard. This is the final cleanup step.&lt;/p&gt;
&lt;p&gt;Removing Dashboard reduces clutter and avoids keeping unused access paths around.&lt;/p&gt;
&lt;h3 id=&#34;confirm-headlamp-covers-your-needs&#34;&gt;Confirm Headlamp covers your needs&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#confirm-headlamp-covers-your-needs&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Before uninstalling anything, make sure:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Users can access the clusters they need in Headlamp.&lt;/li&gt;
&lt;li&gt;Common tasks work:
&lt;ul&gt;
&lt;li&gt;browse resources&lt;/li&gt;
&lt;li&gt;deploy with YAML&lt;/li&gt;
&lt;li&gt;view logs and events&lt;/li&gt;
&lt;li&gt;exec into pods (if allowed)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;RBAC behaves as expected for different roles.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Once these checks pass, you are ready to remove Dashboard.&lt;/p&gt;
&lt;h3 id=&#34;uninstall-the-dashboard&#34;&gt;Uninstall the Dashboard&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#uninstall-the-dashboard&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;If you installed Kubernetes Dashboard with Helm, remove it with:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;helm uninstall kubernetes-dashboard -n kubernetes-dashboard
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If Dashboard was installed by a manifest or addon, remove it using the same method you used to install it.&lt;/p&gt;
&lt;p&gt;After removal, confirm the resources are gone:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl get pods -n kubernetes-dashboard
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;clean-up-access-artifacts-recommended&#34;&gt;Clean up access artifacts (recommended)&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#clean-up-access-artifacts-recommended&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Many Dashboard setups used dedicated service accounts and cluster-wide roles.&lt;/p&gt;
&lt;p&gt;Review and remove anything that was created only for Dashboard access, such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;service accounts&lt;/li&gt;
&lt;li&gt;role bindings or cluster role bindings&lt;/li&gt;
&lt;li&gt;old documentation that points users to Dashboard URLs or port-forward commands&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This reduces long-lived credentials and unused permissions.&lt;/p&gt;
&lt;h3 id=&#34;communicate-the-change&#34;&gt;Communicate the change&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#communicate-the-change&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Make sure your team knows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Headlamp is now the primary Kubernetes UI.&lt;/li&gt;
&lt;li&gt;How to access it (desktop or URL).&lt;/li&gt;
&lt;li&gt;Where to go for help if something feels different.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;11-post-migration-checklist&#34;&gt;11. Post-migration checklist&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#11-post-migration-checklist&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;This final checklist helps you confirm the migration is complete. It gives you confidence that Headlamp is working as expected and that nothing important was left behind.&lt;/p&gt;
&lt;h3 id=&#34;access-and-visibility&#34;&gt;Access and visibility&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#access-and-visibility&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; Headlamp opens without errors.&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; Users can access the correct clusters.&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; Namespace filtering works as expected.&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; Multi-cluster switching behaves correctly.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;authentication-and-rbac&#34;&gt;Authentication and RBAC&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#authentication-and-rbac&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; Desktop users access clusters using kubeconfig.&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; In-cluster users can sign in using the chosen auth method.&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; Users only see actions their RBAC allows.&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; No unexpected permission errors appear during normal use.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;core-workflows&#34;&gt;Core workflows&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#core-workflows&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; Resources load under Workloads, Network, and Configuration.&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; YAML can be viewed and edited where permissions allow.&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; Applications can be deployed using Create and YAML.&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; Logs load correctly for running pods.&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; Exec works for users who are allowed to use it.&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; Metrics appear if metrics-server is installed.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;operational-confidence&#34;&gt;Operational confidence&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#operational-confidence&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; Teams can troubleshoot without switching tools.&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; Map View helps explain relationships during debugging.&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; Platform or DevOps teams know how Headlamp is installed and managed.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;cleanup-confirmation&#34;&gt;Cleanup confirmation&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#cleanup-confirmation&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; Kubernetes Dashboard is no longer running.&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; Dashboard-only service accounts and RBAC bindings are removed.&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; Internal docs no longer reference Dashboard URLs or port-forward commands.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;team-alignment&#34;&gt;Team alignment&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#team-alignment&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; The team knows Headlamp is the default Kubernetes UI.&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; Onboarding docs point new users to Headlamp.&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; There is a clear path for feedback or questions.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You&#39;ve now completed the move from Kubernetes Dashboard to Headlamp. Your team can use the same Kubernetes access model, work across clusters, and rely on workflows that match how Kubernetes is used today. From here, Headlamp becomes your default UI, whether on the desktop or in shared environments. As your needs grow, you can keep using it as-is or extend it with plugins and new views over time.&lt;/p&gt;
&lt;p&gt;If you want to help shape what comes next, join the Headlamp community and contribute at &lt;a href=&#34;https://headlamp.dev&#34;&gt;headlamp.dev&lt;/a&gt;.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Announcing etcd v3.7.0</title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/07/08/announcing-etcd-3.7/</link>
      <pubDate>Wed, 08 Jul 2026 20:00:00 +0800</pubDate>
      
      <guid>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/07/08/announcing-etcd-3.7/</guid>
      <description>
        
        
        &lt;p&gt;&lt;em&gt;This article is a mirror of the &lt;a href=&#34;https://etcd.io/blog/2026/announcing-etcd-3.7/&#34;&gt;original announcement&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Today, SIG etcd is releasing &lt;a href=&#34;https://github.com/etcd-io/etcd/releases/tag/v3.7.0&#34;&gt;etcd v3.7.0&lt;/a&gt;, the latest minor release of the popular distributed key-value store and core Kubernetes component. v3.7 ships the long-requested RangeStream feature, delivers several other performance improvements, removes the last remnants of the legacy v2store, and completes a major protobuf overhaul.&lt;/p&gt;
&lt;p&gt;You can download etcd v3.7.0 here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/etcd-io/etcd/archive/refs/tags/v3.7.0.tar.gz&#34;&gt;Source code&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/etcd-io/etcd/releases/tag/v3.7.0&#34;&gt;Binaries&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gcr.io/etcd-development/etcd&#34;&gt;Official container images&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This release also includes new versions of the two core etcd dependencies, &lt;a href=&#34;https://github.com/etcd-io/bbolt/releases/tag/v1.5.0&#34;&gt;bbolt v1.5.0&lt;/a&gt; and &lt;a href=&#34;https://github.com/etcd-io/raft/releases/tag/v3.7.0&#34;&gt;raft v3.7.0&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For instructions on installing etcd, see the &lt;a href=&#34;https://etcd.io/docs/v3.7/install/&#34;&gt;install documentation&lt;/a&gt;. For the full list of changes, see the &lt;a href=&#34;https://github.com/etcd-io/etcd/blob/main/CHANGELOG/CHANGELOG-3.7.md&#34;&gt;etcd v3.7 changelog&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;A heartfelt thank you to all the contributors who made this release possible!&lt;/p&gt;
&lt;h2 id=&#34;major-features&#34;&gt;Major features&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#major-features&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The most significant changes in v3.7.0 include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#rangestream&#34;&gt;&lt;strong&gt;RangeStream&lt;/strong&gt;&lt;/a&gt; — stream large result sets in chunks instead of buffering the whole response.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Keys-only range requests, faster and more reliable leases,&lt;/strong&gt; and several other &lt;a href=&#34;#performance-improvements&#34;&gt;&lt;strong&gt;performance improvements&lt;/strong&gt;&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;etcd now &lt;a href=&#34;#bootstrap-from-v3store&#34;&gt;boots entirely from v3store&lt;/a&gt;, eliminating a long-standing dependency on the legacy v2 store&lt;/li&gt;
&lt;li&gt;A completed &lt;a href=&#34;#protobuf-overhaul&#34;&gt;&lt;strong&gt;protobuf overhaul&lt;/strong&gt;&lt;/a&gt;, replacing outdated protobuf libraries with fully supported ones.&lt;/li&gt;
&lt;li&gt;etcd v3.7 ships with &lt;a href=&#34;#bbolt-v151&#34;&gt;bbolt v1.5.1&lt;/a&gt; and &lt;a href=&#34;#raft-v370&#34;&gt;raft v3.7.0&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;features&#34;&gt;Features&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#features&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;h3 id=&#34;rangestream&#34;&gt;RangeStream&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#rangestream&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;In etcd v3.6 and earlier, it is challenging to work with requests that return large result sets. The database would buffer the full result set before sending, leading to unpredictable latency and memory usage,  both on the server and the client. &lt;a href=&#34;https://github.com/kubernetes/enhancements/tree/master/keps/sig-etcd/5966-etcd-range-stream&#34;&gt;The RangeStream RPC&lt;/a&gt; lets calling applications accept result sets in chunks, reducing latency and making buffering memory usage more predictable.&lt;/p&gt;
&lt;p&gt;Instructions on how to use RangeStream &lt;a href=&#34;https://etcd.io/docs/v3.7/learning/api/#rangestream&#34;&gt;in gRPC calls&lt;/a&gt; and &lt;a href=&#34;https://etcd.io/docs/v3.7/dev-guide/interacting_v3/#read-keys&#34;&gt;in etcdctl&lt;/a&gt; can be found in the etcd documentation. Users should try it out for their own applications.&lt;/p&gt;
&lt;p&gt;In coordinated releases, the RangeStream feature will become available to users running the upcoming v1.37 of Kubernetes by enabling the &lt;code&gt;EtcdRangeStream&lt;/code&gt; feature gate.  This early and planned adoption is possible thanks to the merger of etcd and Kubernetes development in 2023.&lt;/p&gt;
&lt;h3 id=&#34;performance-improvements&#34;&gt;Performance improvements&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#performance-improvements&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;v3.7 delivers multiple specific performance improvements, both for the Kubernetes control plane and for other use cases.  Kubernetes users should see a significant decrease in overall CPU usage by the etcd members, compared with v3.6.&lt;/p&gt;
&lt;h4 id=&#34;keys-only-range-optimization&#34;&gt;Keys-only range optimization&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#keys-only-range-optimization&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;etcd v3.7.0 includes a keys-only Range optimization (&lt;a href=&#34;https://github.com/etcd-io/etcd/pull/21791&#34;&gt;#21791: keys-only Range optimization&lt;/a&gt;). When processing a keys_only Range request or &lt;code&gt;etcdctl get --keys-only&lt;/code&gt;, etcd reads solely from its in-memory index. It returns the matched keys without loading all serialized values from bbolt as it did previously.  The only exception where loading from bbolt is still required is when &lt;code&gt;keys_only&lt;/code&gt; Range requests must be sorted by value (i.e., when SortTarget is set to VALUE).&lt;/p&gt;
&lt;p&gt;This reduces unnecessary backend reads and memory use for workloads that only need key names, making large keys-only range requests more efficient.&lt;/p&gt;
&lt;h4 id=&#34;faster-more-reliable-etcd-leases&#34;&gt;Faster, more reliable etcd leases&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#faster-more-reliable-etcd-leases&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;v3.7 improves lease expiration and renewal:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;LeaseRevoke requests are now prioritized to ensure timely lease expiration during overload (&lt;a href=&#34;https://github.com/etcd-io/etcd/pull/20492&#34;&gt;#20492: stability enhancement during overload conditions&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;The new FastLeaseKeepAlive feature enables faster lease renewal by skipping the wait for the applied index (&lt;a href=&#34;https://github.com/etcd-io/etcd/pull/20589&#34;&gt;#20589: etcdserver: improve linearizable renew lease&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;faster-find-operations&#34;&gt;Faster find() operations&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#faster-find-operations&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;etcd 3.7 improves the performance of concurrent watches on keys by making find() operations faster (&lt;a href=&#34;https://github.com/etcd-io/etcd/pull/19768&#34;&gt;#19768: adt: split interval tree by right endpoint on matched left endpoints&lt;/a&gt;).&lt;/p&gt;
&lt;h3 id=&#34;other-features&#34;&gt;Other features&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#other-features&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;h4 id=&#34;protobuf-overhaul&#34;&gt;Protobuf overhaul&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#protobuf-overhaul&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;v3.7 migrates and replaces multiple outdated protobuf libraries with fully supported dependencies. This includes replacing &lt;code&gt;github.com/golang/protobuf&lt;/code&gt; and &lt;code&gt;github.com/gogo/protobuf&lt;/code&gt; with the fully-supported &lt;code&gt;google.golang.org/protobuf&lt;/code&gt; (&lt;a href=&#34;https://github.com/etcd-io/etcd/issues/14533&#34;&gt;#14533: Protobuf: cleanup both golang/protobuf and gogo/protobuf&lt;/a&gt;), and migrating grpc-logging to grpc-middleware v2 (&lt;a href=&#34;https://github.com/etcd-io/etcd/pull/20420&#34;&gt;#20420: Migrate grpc-logging to grpc-middleware v2&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;As well as improving security and maintainability, this refactor has been shown to reduce CPU usage by etcd components.&lt;/p&gt;
&lt;p&gt;While these changes are not expected to directly affect users running etcd via official binaries or container images, they may affect users who depend on etcd Go modules, such as the client SDK or packages under &lt;code&gt;api/&lt;/code&gt; or &lt;code&gt;pkg/&lt;/code&gt;. These consumers may need to update their code or dependencies due to protobuf and related API changes introduced in this release. More detailed information is available from &lt;a href=&#34;https://github.com/etcd-io/website/issues/1162&#34;&gt;the API change tracking issue&lt;/a&gt;.&lt;/p&gt;
&lt;h4 id=&#34;unix-socket-support&#34;&gt;Unix socket support&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#unix-socket-support&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;etcd now supports Unix socket endpoints (&lt;a href=&#34;https://github.com/etcd-io/etcd/pull/19760&#34;&gt;#19760: Add Support for Unix Socket endpoints&lt;/a&gt;), enabling local communication without a TCP port.  Since this is restricted to single-member clusters, it is mainly aimed at development, testing, and edge device use-cases.&lt;/p&gt;
&lt;h4 id=&#34;bootstrap-from-v3store&#34;&gt;Bootstrap from v3store&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#bootstrap-from-v3store&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;One of the major changes in etcd v3.7 is that the server now bootstraps entirely from the v3 store (&lt;a href=&#34;https://github.com/etcd-io/etcd/issues/20187&#34;&gt;#20187 Bootstrap etcdserver from v3store&lt;/a&gt;), eliminating its dependency on the legacy v2 store during startup.&lt;/p&gt;
&lt;p&gt;This milestone is the result of a long-term effort spanning multiple releases, from v3.4 through v3.7. It resolves a long-standing technical debt, significantly simplifies the bootstrap workflow, and lays the foundation for future improvements to etcd.&lt;/p&gt;
&lt;p&gt;To maintain backward compatibility, etcd v3.7 continues to generate v2 snapshots. As a result, the &lt;code&gt;--snapshot-count&lt;/code&gt; flag is also retained in v3.7. This is the last remaining dependency on the legacy v2 store, and both the v2 snapshot generation and the &lt;code&gt;--snapshot-count&lt;/code&gt; flag will be removed in v3.8.&lt;/p&gt;
&lt;h4 id=&#34;etcdutl-timeouts&#34;&gt;etcdutl timeouts&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#etcdutl-timeouts&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;All etcdutl commands now have a timeout command line argument (&lt;a href=&#34;https://github.com/etcd-io/etcd/pull/20708&#34;&gt;#20708: etcdutl: enable timeout functionality for all commands&lt;/a&gt;), so offline utility commands no longer block indefinitely when holding a lock.&lt;/p&gt;
&lt;h4 id=&#34;setting-the-authentication-token-directly&#34;&gt;Setting the authentication token directly&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#setting-the-authentication-token-directly&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;Client v3 now allows users to set the JWT directly, offering more flexibility in authentication options (&lt;a href=&#34;https://github.com/etcd-io/etcd/pull/16803&#34;&gt;#16803: clientv3: allow setting JWT directly&lt;/a&gt;, &lt;a href=&#34;https://github.com/etcd-io/etcd/pull/20747&#34;&gt;#20747: clientv3: disable auth retry when token is set&lt;/a&gt;),&lt;/p&gt;
&lt;h4 id=&#34;retrieve-authstatus-without-authenticating&#34;&gt;Retrieve AuthStatus without authenticating&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#retrieve-authstatus-without-authenticating&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;Clients can check their AuthStatus without attempting to authenticate first, eliminating some application overhead (&lt;a href=&#34;https://github.com/etcd-io/etcd/pull/20802&#34;&gt;#20802: etcdserver: remove permission check on AuthStatus api&lt;/a&gt;).&lt;/p&gt;
&lt;h4 id=&#34;new-watch-metrics&#34;&gt;New watch metrics&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#new-watch-metrics&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;v3.7 adds optional watch send-loop metrics (&lt;a href=&#34;https://github.com/etcd-io/etcd/pull/21030&#34;&gt;#21030: Instrument watchstream send loop&lt;/a&gt;) for better observability of the watch path:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;etcd_debugging_server_watch_send_loop_watch_stream_duration_seconds&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;etcd_debugging_server_watch_send_loop_watch_stream_duration_per_event_seconds&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;etcd_debugging_server_watch_send_loop_control_stream_duration_seconds&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;etcd_debugging_server_watch_send_loop_progress_duration_seconds&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There is also a new &lt;code&gt;etcd_server_request_duration_seconds&lt;/code&gt; metric (&lt;a href=&#34;https://github.com/etcd-io/etcd/pull/21038&#34;&gt;#21038: Add metric &lt;code&gt;etcd_server_request_duration_seconds&lt;/code&gt;&lt;/a&gt;).&lt;/p&gt;
&lt;h4 id=&#34;etcdctl-command-cleanup&#34;&gt;etcdctl command cleanup&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#etcdctl-command-cleanup&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;etcdctl commands were reorganized for clarity (&lt;a href=&#34;https://github.com/etcd-io/etcd/pull/20162&#34;&gt;#20162: etcdctl: organize etcdctl subcommand&lt;/a&gt;) and global command line arguments are now hidden to streamline help output (&lt;a href=&#34;https://github.com/etcd-io/etcd/pull/20493&#34;&gt;#20493: etcdctl: hide global flags&lt;/a&gt;).&lt;/p&gt;
&lt;h2 id=&#34;upgrading&#34;&gt;Upgrading&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#upgrading&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;This release contains breaking changes, particularly around the removal of legacy v2 components. Users should review the &lt;a href=&#34;https://etcd.io/docs/v3.7/upgrades/upgrade_3_7/&#34;&gt;upgrade guide&lt;/a&gt; before upgrading their nodes. As with all minor releases, perform a rolling upgrade one member at a time and confirm cluster health between steps.&lt;/p&gt;
&lt;h3 id=&#34;experimental-flags-removed&#34;&gt;Experimental flags removed&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#experimental-flags-removed&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;All deprecated experimental flags have been removed (&lt;a href=&#34;https://github.com/etcd-io/etcd/pull/19959&#34;&gt;#19959: Cleanup the deprecated experimental flags&lt;/a&gt;). Features in etcd now follow the Kubernetes-style feature-gate lifecycle (Alpha → Beta → GA) introduced in v3.6, rather than the old &lt;code&gt;--experimental&lt;/code&gt; prefix. If your configuration still relies on &lt;code&gt;--experimental-*&lt;/code&gt; command line arguments, migrate to using the corresponding feature gates or stable command line arguments before you upgrade to etcd 3.7.&lt;/p&gt;
&lt;h3 id=&#34;legacy-v2-api-packages-and-code-cleanup&#34;&gt;Legacy V2 API packages and code cleanup&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#legacy-v2-api-packages-and-code-cleanup&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;To remove the dependencies on v2store, the following components have been removed:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/etcd-io/etcd/pull/20109&#34;&gt;v2 discovery&lt;/a&gt; (&lt;a href=&#34;https://github.com/etcd-io/etcd/pull/20109&#34;&gt;#20109: Remove v2discovery&lt;/a&gt;) packages removed,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/etcd-io/etcd/pull/21263&#34;&gt;v2 request&lt;/a&gt; support (&lt;a href=&#34;https://github.com/etcd-io/etcd/pull/21263&#34;&gt;#21263: Remove v2 Request and apply_v2.go&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/etcd-io/etcd/pull/20117&#34;&gt;v2 client&lt;/a&gt; support (&lt;a href=&#34;https://github.com/etcd-io/etcd/pull/20117&#34;&gt;#20117: Remove client/internal/v2&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These changes may create some breakage for users, particularly those who have not already updated to v3.6.11 or later. Users should report any blockers encountered, or cases that need better upgrade documentation.&lt;/p&gt;
&lt;h3 id=&#34;non-blocking-client-creation&#34;&gt;Non-blocking client creation&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#non-blocking-client-creation&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;etcd no longer honors the deprecated &lt;code&gt;grpc.WithBlock&lt;/code&gt; dial option ( &lt;a href=&#34;https://github.com/etcd-io/etcd/pull/21942&#34;&gt;#21942: Make the etcd client creation non-blocking&lt;/a&gt;). To preserve the previous blocking behavior when needed, follow the guidance in grpc-go&#39;s &lt;a href=&#34;https://github.com/grpc/grpc-go/blob/master/Documentation/anti-patterns.md#especially-bad-using-deprecated-dialoptions&#34;&gt;anti-patterns documentation&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;multiarch-container-images-only&#34;&gt;Multiarch container images only&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#multiarch-container-images-only&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;For users relying on the official etcd container images, v3.7 will be distributed &lt;strong&gt;only&lt;/strong&gt; as multiarch containers.  Architecture-tagged images will not be available, so adjust deployments accordingly.&lt;/p&gt;
&lt;h3 id=&#34;api-changes&#34;&gt;API changes&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#api-changes&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;As with every etcd release, there are a number of API changes.  These are designed to be backwards-compatible to the extent possible, but may require adjustment by some users.  See our &lt;a href=&#34;https://etcd.io/docs/v3.7/learning/api/&#34;&gt;API documentation&lt;/a&gt; page for full information.&lt;/p&gt;
&lt;h2 id=&#34;bbolt-v1-5-1&#34;&gt;bbolt v1.5.1&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#bbolt-v1-5-1&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;etcd v3.7 depends on, and includes, &lt;a href=&#34;https://github.com/etcd-io/bbolt/blob/main/CHANGELOG/CHANGELOG-1.5.md&#34;&gt;v1.5.1&lt;/a&gt; of the bbolt storage engine.  v1.5 includes several improvements to functionality and performance, including:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/etcd-io/bbolt/pull/929&#34;&gt;Database file size limits&lt;/a&gt;: users may set, and bbolt will enforce, file size limits.  When a bolt database exceeds these limits it will refuse to accept writes until the database is compacted or the limit is changed.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/etcd-io/bbolt/pull/977&#34;&gt;Disable statistics for performance&lt;/a&gt;: users may set &lt;code&gt;NoStatistics&lt;/code&gt; to limit overhead from locks taken by the database statistics viewer.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/etcd-io/bbolt/pull/1179&#34;&gt;More efficient hashmap processing&lt;/a&gt;: merge spans faster and with less overhead.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;raft-v3-7-0&#34;&gt;raft v3.7.0&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#raft-v3-7-0&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;etcd 3.7 depends on, and includes, v3.7.0 of the raft consensus engine.  v3.7 includes several improvements, including:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/etcd-io/raft/pull/370&#34;&gt;Update the bootstrap process&lt;/a&gt;: v3.7 now allows booting from partly initialized snapshots, supporting etcd&#39;s initializing directly from v3store.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/etcd-io/raft/pull/397&#34;&gt;Improve the ReadIndex flow to prevent stale reads&lt;/a&gt; by injecting a unique identifier into the heartbeat context for read-only operations.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;raft v3.7.0 also includes the &lt;a href=&#34;https://github.com/etcd-io/etcd/issues/14533&#34;&gt;same protobuf library updates&lt;/a&gt; and refactoring as etcd does.&lt;/p&gt;
&lt;h2 id=&#34;dependency-updates&#34;&gt;Dependency updates&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#dependency-updates&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Other dependency updates include a bump to &lt;code&gt;golang.org/x/crypto&lt;/code&gt; v0.52.0 for CVE resolution (&lt;a href=&#34;https://github.com/etcd-io/etcd/pull/21903&#34;&gt;#21903: [release-3.7] Bump golang.org/x/crypto to v0.52.0&lt;/a&gt;), an OpenTelemetry contrib update to v0.61.0 (&lt;a href=&#34;https://github.com/etcd-io/etcd/pull/20017&#34;&gt;#20017: Update otelgrpc to v0.61.0&lt;/a&gt;), and compilation with Go 1.26.4 (&lt;a href=&#34;https://github.com/etcd-io/etcd/pull/21891&#34;&gt;#21891: [release-3.7] Update Go to 1.26.4&lt;/a&gt;).&lt;/p&gt;
&lt;h2 id=&#34;contributors&#34;&gt;Contributors&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#contributors&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;etcd v3.7.0 is the product of more than a hundred contributors across the community. Thank you to everyone who wrote code, reviewed PRs, filed and triaged issues, and helped test the alpha, beta, and release candidates.&lt;/p&gt;
&lt;h3 id=&#34;leads&#34;&gt;Leads&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#leads&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The SIG etcd leads for the v3.7 release are &lt;a href=&#34;https://github.com/ivanvc&#34;&gt;ivanvc&lt;/a&gt;, &lt;a href=&#34;https://github.com/serathius&#34;&gt;serathius&lt;/a&gt;, &lt;a href=&#34;https://github.com/ahrtr&#34;&gt;ahrtr&lt;/a&gt;, &lt;a href=&#34;https://github.com/fuweid&#34;&gt;fuweid&lt;/a&gt;, &lt;a href=&#34;https://github.com/siyuanfoundation&#34;&gt;siyuanfoundation&lt;/a&gt;, and &lt;a href=&#34;https://github.com/jberkus&#34;&gt;jberkus&lt;/a&gt;.  Ivan leads our release team.&lt;/p&gt;
&lt;h3 id=&#34;other-contributors&#34;&gt;Other contributors&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#other-contributors&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;a href=&#34;https://github.com/ah8ad3&#34;&gt;ah8ad3&lt;/a&gt;, &lt;a href=&#34;https://github.com/ajaysundark&#34;&gt;ajaysundark&lt;/a&gt;, &lt;a href=&#34;https://github.com/aladesawe&#34;&gt;aladesawe&lt;/a&gt;, &lt;a href=&#34;https://github.com/amosehiguese&#34;&gt;amosehiguese&lt;/a&gt;, &lt;a href=&#34;https://github.com/ArkaSaha30&#34;&gt;ArkaSaha30&lt;/a&gt;, &lt;a href=&#34;https://github.com/ashikjm&#34;&gt;ashikjm&lt;/a&gt;, &lt;a href=&#34;https://github.com/AwesomePatrol&#34;&gt;AwesomePatrol&lt;/a&gt;, &lt;a href=&#34;https://github.com/dims&#34;&gt;dims&lt;/a&gt;, &lt;a href=&#34;https://github.com/Elbehery&#34;&gt;Elbehery&lt;/a&gt;, &lt;a href=&#34;https://github.com/gangli113&#34;&gt;gangli113&lt;/a&gt;, &lt;a href=&#34;https://github.com/henrybear327&#34;&gt;henrybear327&lt;/a&gt;, &lt;a href=&#34;https://github.com/Jille&#34;&gt;Jille&lt;/a&gt;, &lt;a href=&#34;https://github.com/jmhbnz&#34;&gt;jmhbnz&lt;/a&gt;, &lt;a href=&#34;https://github.com/joshuazh-x&#34;&gt;joshuazh-x&lt;/a&gt;, &lt;a href=&#34;https://github.com/kishen-v&#34;&gt;kishen-v&lt;/a&gt;, &lt;a href=&#34;https://github.com/lavishpal&#34;&gt;lavishpal&lt;/a&gt;, &lt;a href=&#34;https://github.com/liggitt&#34;&gt;liggitt&lt;/a&gt;, &lt;a href=&#34;https://github.com/marcelfranca&#34;&gt;marcelfranca&lt;/a&gt;, &lt;a href=&#34;https://github.com/miancheng7&#34;&gt;miancheng7&lt;/a&gt;, &lt;a href=&#34;https://github.com/mmorel-35&#34;&gt;mmorel-35&lt;/a&gt;, &lt;a href=&#34;https://github.com/MrDXY&#34;&gt;MrDXY&lt;/a&gt;, &lt;a href=&#34;https://github.com/mrueg&#34;&gt;mrueg&lt;/a&gt;, &lt;a href=&#34;https://github.com/purpleidea&#34;&gt;purpleidea&lt;/a&gt;, &lt;a href=&#34;https://github.com/qsyqian&#34;&gt;qsyqian&lt;/a&gt;, &lt;a href=&#34;https://github.com/redwrasse&#34;&gt;redwrasse&lt;/a&gt;, &lt;a href=&#34;https://github.com/ronaldngounou&#34;&gt;ronaldngounou&lt;/a&gt;, &lt;a href=&#34;https://github.com/skitt&#34;&gt;skitt&lt;/a&gt;, &lt;a href=&#34;https://github.com/spzala&#34;&gt;spzala&lt;/a&gt;, &lt;a href=&#34;https://github.com/tcchawla&#34;&gt;tcchawla&lt;/a&gt;, &lt;a href=&#34;https://github.com/tjungblu&#34;&gt;tjungblu&lt;/a&gt;, &lt;a href=&#34;https://github.com/vivekpatani&#34;&gt;vivekpatani&lt;/a&gt;, &lt;a href=&#34;https://github.com/wenjiaswe&#34;&gt;wenjiaswe&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;new-contributors&#34;&gt;New contributors&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#new-contributors&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;A special welcome to the contributors who made their first etcd contribution in this cycle — including &lt;a href=&#34;https://github.com/jefftree&#34;&gt;Jeffrey Ying&lt;/a&gt;, whose work drove the RangeStream feature. New contributors can have a substantial impact on etcd; if you’d like to get involved, see the &lt;a href=&#34;https://github.com/etcd-io/etcd/blob/main/CONTRIBUTING.md&#34;&gt;contributor guide&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/1911860538&#34;&gt;1911860538&lt;/a&gt;, &lt;a href=&#34;https://github.com/4rivappa&#34;&gt;4rivappa&lt;/a&gt;, &lt;a href=&#34;https://github.com/aaronjzhang&#34;&gt;aaronjzhang&lt;/a&gt;, &lt;a href=&#34;https://github.com/abdurrehman107&#34;&gt;abdurrehman107&lt;/a&gt;, &lt;a href=&#34;https://github.com/ABin-Huang&#34;&gt;ABin-Huang&lt;/a&gt;, &lt;a href=&#34;https://github.com/adeptvin1&#34;&gt;adeptvin1&lt;/a&gt;, &lt;a href=&#34;https://github.com/aditya7880900936&#34;&gt;aditya7880900936&lt;/a&gt;, &lt;a href=&#34;https://github.com/AHBICJ&#34;&gt;AHBICJ&lt;/a&gt;, &lt;a href=&#34;https://github.com/akstron&#34;&gt;akstron&lt;/a&gt;, &lt;a href=&#34;https://github.com/alliasgher&#34;&gt;alliasgher&lt;/a&gt;, &lt;a href=&#34;https://github.com/aman4433&#34;&gt;aman4433&lt;/a&gt;, &lt;a href=&#34;https://github.com/aojea&#34;&gt;aojea&lt;/a&gt;, &lt;a href=&#34;https://github.com/apullo777&#34;&gt;apullo777&lt;/a&gt;, &lt;a href=&#34;https://github.com/AR21SM&#34;&gt;AR21SM&lt;/a&gt;, &lt;a href=&#34;https://github.com/arturmelanchyk&#34;&gt;arturmelanchyk&lt;/a&gt;, &lt;a href=&#34;https://github.com/AshrafAhmed9&#34;&gt;AshrafAhmed9&lt;/a&gt;, &lt;a href=&#34;https://github.com/asttool&#34;&gt;asttool&lt;/a&gt;, &lt;a href=&#34;https://github.com/asutorufa&#34;&gt;asutorufa&lt;/a&gt;, &lt;a href=&#34;https://github.com/BBQing&#34;&gt;BBQing&lt;/a&gt;, &lt;a href=&#34;https://github.com/beforetech&#34;&gt;beforetech&lt;/a&gt;, &lt;a href=&#34;https://github.com/boqishan&#34;&gt;boqishan&lt;/a&gt;, &lt;a href=&#34;https://github.com/caltechustc&#34;&gt;caltechustc&lt;/a&gt;, &lt;a href=&#34;https://github.com/carsontham&#34;&gt;carsontham&lt;/a&gt;, &lt;a href=&#34;https://github.com/christophsj&#34;&gt;christophsj&lt;/a&gt;, &lt;a href=&#34;https://github.com/chuanye-gao&#34;&gt;chuanye-gao&lt;/a&gt;, &lt;a href=&#34;https://github.com/cnuss&#34;&gt;cnuss&lt;/a&gt;, &lt;a href=&#34;https://github.com/cuiweixie&#34;&gt;cuiweixie&lt;/a&gt;, &lt;a href=&#34;https://github.com/dmvolod&#34;&gt;dmvolod&lt;/a&gt;, &lt;a href=&#34;https://github.com/Dogacel&#34;&gt;Dogacel&lt;/a&gt;, &lt;a href=&#34;https://github.com/dongjiang1989&#34;&gt;dongjiang1989&lt;/a&gt;, &lt;a href=&#34;https://github.com/EduardoVega&#34;&gt;EduardoVega&lt;/a&gt;, &lt;a href=&#34;https://github.com/evertrain&#34;&gt;evertrain&lt;/a&gt;, &lt;a href=&#34;https://github.com/eyupcanakman&#34;&gt;eyupcanakman&lt;/a&gt;, &lt;a href=&#34;https://github.com/gaganhr94&#34;&gt;gaganhr94&lt;/a&gt;, &lt;a href=&#34;https://github.com/goingforstudying-ctrl&#34;&gt;goingforstudying-ctrl&lt;/a&gt;, &lt;a href=&#34;https://github.com/greenblade29&#34;&gt;greenblade29&lt;/a&gt;, &lt;a href=&#34;https://github.com/Himanshu-370&#34;&gt;Himanshu-370&lt;/a&gt;, &lt;a href=&#34;https://github.com/HossamSaberX&#34;&gt;HossamSaberX&lt;/a&gt;, &lt;a href=&#34;https://github.com/huajianxiaowanzi&#34;&gt;huajianxiaowanzi&lt;/a&gt;, &lt;a href=&#34;https://github.com/hwdef&#34;&gt;hwdef&lt;/a&gt;, &lt;a href=&#34;https://github.com/ishan-gupta2005&#34;&gt;ishan-gupta2005&lt;/a&gt;, &lt;a href=&#34;https://github.com/ishan16696&#34;&gt;ishan16696&lt;/a&gt;, &lt;a href=&#34;https://github.com/ivangsm&#34;&gt;ivangsm&lt;/a&gt;, &lt;a href=&#34;https://github.com/JasonLove-Coding&#34;&gt;JasonLove-Coding&lt;/a&gt;, &lt;a href=&#34;https://github.com/Jefftree&#34;&gt;Jefftree&lt;/a&gt;, &lt;a href=&#34;https://github.com/jihogh&#34;&gt;jihogh&lt;/a&gt;, &lt;a href=&#34;https://github.com/jonathan-albrecht-ibm&#34;&gt;jonathan-albrecht-ibm&lt;/a&gt;, &lt;a href=&#34;https://github.com/joshjms&#34;&gt;joshjms&lt;/a&gt;, &lt;a href=&#34;https://github.com/kairosci&#34;&gt;kairosci&lt;/a&gt;, &lt;a href=&#34;https://github.com/kei01234kei&#34;&gt;kei01234kei&lt;/a&gt;, &lt;a href=&#34;https://github.com/kjgorman&#34;&gt;kjgorman&lt;/a&gt;, &lt;a href=&#34;https://github.com/kovan&#34;&gt;kovan&lt;/a&gt;, &lt;a href=&#34;https://github.com/kstrifonoff&#34;&gt;kstrifonoff&lt;/a&gt;, &lt;a href=&#34;https://github.com/Kunalbehbud&#34;&gt;Kunalbehbud&lt;/a&gt;, &lt;a href=&#34;https://github.com/letreturn&#34;&gt;letreturn&lt;/a&gt;, &lt;a href=&#34;https://github.com/lorenz&#34;&gt;lorenz&lt;/a&gt;, &lt;a href=&#34;https://github.com/m4l1c1ou5&#34;&gt;m4l1c1ou5&lt;/a&gt;, &lt;a href=&#34;https://github.com/madhav-murali&#34;&gt;madhav-murali&lt;/a&gt;, &lt;a href=&#34;https://github.com/madvimer&#34;&gt;madvimer&lt;/a&gt;, &lt;a href=&#34;https://github.com/majiayu000&#34;&gt;majiayu000&lt;/a&gt;, &lt;a href=&#34;https://github.com/marcus-hodgson-antithesis&#34;&gt;marcus-hodgson-antithesis&lt;/a&gt;, &lt;a href=&#34;https://github.com/mattsains&#34;&gt;mattsains&lt;/a&gt;, &lt;a href=&#34;https://github.com/mcrute&#34;&gt;mcrute&lt;/a&gt;, &lt;a href=&#34;https://github.com/mingl1&#34;&gt;mingl1&lt;/a&gt;, &lt;a href=&#34;https://github.com/MohanadKh03&#34;&gt;MohanadKh03&lt;/a&gt;, &lt;a href=&#34;https://github.com/mstrYoda&#34;&gt;mstrYoda&lt;/a&gt;, &lt;a href=&#34;https://github.com/NAM-MAN&#34;&gt;NAM-MAN&lt;/a&gt;, &lt;a href=&#34;https://github.com/neeraj542&#34;&gt;neeraj542&lt;/a&gt;, &lt;a href=&#34;https://github.com/nicknikolakakis&#34;&gt;nicknikolakakis&lt;/a&gt;, &lt;a href=&#34;https://github.com/nihalmaddala&#34;&gt;nihalmaddala&lt;/a&gt;, &lt;a href=&#34;https://github.com/niuyueyang1996&#34;&gt;niuyueyang1996&lt;/a&gt;, &lt;a href=&#34;https://github.com/notandruu&#34;&gt;notandruu&lt;/a&gt;, &lt;a href=&#34;https://github.com/ntdkhiem&#34;&gt;ntdkhiem&lt;/a&gt;, &lt;a href=&#34;https://github.com/nwnt&#34;&gt;nwnt&lt;/a&gt;, &lt;a href=&#34;https://github.com/olamilekan000&#34;&gt;olamilekan000&lt;/a&gt;, &lt;a href=&#34;https://github.com/pigeio&#34;&gt;pigeio&lt;/a&gt;, &lt;a href=&#34;https://github.com/pjsharath28&#34;&gt;pjsharath28&lt;/a&gt;, &lt;a href=&#34;https://github.com/progmem&#34;&gt;progmem&lt;/a&gt;, &lt;a href=&#34;https://github.com/Qian-Cheng-nju&#34;&gt;Qian-Cheng-nju&lt;/a&gt;, &lt;a href=&#34;https://github.com/quocvibui&#34;&gt;quocvibui&lt;/a&gt;, &lt;a href=&#34;https://github.com/ravisastryk&#34;&gt;ravisastryk&lt;/a&gt;, &lt;a href=&#34;https://github.com/robin-vidal&#34;&gt;robin-vidal&lt;/a&gt;, &lt;a href=&#34;https://github.com/robinkb&#34;&gt;robinkb&lt;/a&gt;, &lt;a href=&#34;https://github.com/rockswe&#34;&gt;rockswe&lt;/a&gt;, &lt;a href=&#34;https://github.com/roman-khimov&#34;&gt;roman-khimov&lt;/a&gt;, &lt;a href=&#34;https://github.com/rsafonseca&#34;&gt;rsafonseca&lt;/a&gt;, &lt;a href=&#34;https://github.com/sahilpatel09&#34;&gt;sahilpatel09&lt;/a&gt;, &lt;a href=&#34;https://github.com/SalehBorhani&#34;&gt;SalehBorhani&lt;/a&gt;, &lt;a href=&#34;https://github.com/SebTardif&#34;&gt;SebTardif&lt;/a&gt;, &lt;a href=&#34;https://github.com/seshachalam-yv&#34;&gt;seshachalam-yv&lt;/a&gt;, &lt;a href=&#34;https://github.com/shashwat010&#34;&gt;shashwat010&lt;/a&gt;, &lt;a href=&#34;https://github.com/shivamgcodes&#34;&gt;shivamgcodes&lt;/a&gt;, &lt;a href=&#34;https://github.com/shuan1026&#34;&gt;shuan1026&lt;/a&gt;, &lt;a href=&#34;https://github.com/silentred&#34;&gt;silentred&lt;/a&gt;, &lt;a href=&#34;https://github.com/sneaky-potato&#34;&gt;sneaky-potato&lt;/a&gt;, &lt;a href=&#34;https://github.com/socketpair&#34;&gt;socketpair&lt;/a&gt;, &lt;a href=&#34;https://github.com/srri&#34;&gt;srri&lt;/a&gt;, &lt;a href=&#34;https://github.com/subrajeet-maharana&#34;&gt;subrajeet-maharana&lt;/a&gt;, &lt;a href=&#34;https://github.com/sxllwx&#34;&gt;sxllwx&lt;/a&gt;, &lt;a href=&#34;https://github.com/tchap&#34;&gt;tchap&lt;/a&gt;, &lt;a href=&#34;https://github.com/tsujiri&#34;&gt;tsujiri&lt;/a&gt;, &lt;a href=&#34;https://github.com/tzfun&#34;&gt;tzfun&lt;/a&gt;, &lt;a href=&#34;https://github.com/upamanyus&#34;&gt;upamanyus&lt;/a&gt;, &lt;a href=&#34;https://github.com/uzairhameed&#34;&gt;uzairhameed&lt;/a&gt;, &lt;a href=&#34;https://github.com/varunu28&#34;&gt;varunu28&lt;/a&gt;, &lt;a href=&#34;https://github.com/vihasmakwana&#34;&gt;vihasmakwana&lt;/a&gt;, &lt;a href=&#34;https://github.com/wendy-ha18&#34;&gt;wendy-ha18&lt;/a&gt;, &lt;a href=&#34;https://github.com/xiaoxiangirl&#34;&gt;xiaoxiangirl&lt;/a&gt;, &lt;a href=&#34;https://github.com/xigang&#34;&gt;xigang&lt;/a&gt;, &lt;a href=&#34;https://github.com/xUser5000&#34;&gt;xUser5000&lt;/a&gt;, &lt;a href=&#34;https://github.com/yagikota&#34;&gt;yagikota&lt;/a&gt;, &lt;a href=&#34;https://github.com/yajianggroup&#34;&gt;yajianggroup&lt;/a&gt;, &lt;a href=&#34;https://github.com/yedou37&#34;&gt;yedou37&lt;/a&gt;, &lt;a href=&#34;https://github.com/Zanda256&#34;&gt;Zanda256&lt;/a&gt;, &lt;a href=&#34;https://github.com/zechariahkasina&#34;&gt;zechariahkasina&lt;/a&gt;, &lt;a href=&#34;https://github.com/zhijun42&#34;&gt;zhijun42&lt;/a&gt;, &lt;a href=&#34;https://github.com/zhoujiaweii&#34;&gt;zhoujiaweii&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Feedback can be shared through:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/etcd-io/etcd/issues&#34;&gt;GitHub issues&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kubernetes.slack.com/archives/C3HD8ARJ5&#34;&gt;#sig-etcd slack channel&lt;/a&gt; in &lt;a href=&#34;https://www.kubernetes.dev/docs/comms/slack/#joining-slack&#34;&gt;Kubernetes Slack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://groups.google.com/g/etcd-dev&#34;&gt;etcd-dev mailing list&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes Changed Block Tracking API - Beta Differences</title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/07/07/csi-changed-block-tracking-beta/</link>
      <pubDate>Tue, 07 Jul 2026 10:00:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/07/07/csi-changed-block-tracking-beta/</guid>
      <description>
        
        
        &lt;p&gt;Changed Block Tracking (CBT) support for CSI drivers
&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2025/09/25/csi-changed-block-tracking/&#34;&gt;shipped as Alpha&lt;/a&gt; in
September 2025. With the March &lt;code&gt;v1.0.0&lt;/code&gt; release of the
&lt;a href=&#34;https://github.com/kubernetes-csi/external-snapshot-metadata&#34;&gt;external-snapshot-metadata&lt;/a&gt;
project, the feature moved to &lt;strong&gt;Beta&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;If you aren&#39;t yet familiar with &lt;em&gt;changed block tracking&lt;/em&gt; for storage in
Kubernetes, the
&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2025/09/25/csi-changed-block-tracking/&#34;&gt;Alpha announcement&lt;/a&gt; covers
the motivation, the three primary components (the CSI &lt;code&gt;SnapshotMetadata&lt;/code&gt;
gRPC service, the SnapshotMetadataService CRD, and the
&lt;code&gt;external-snapshot-metadata&lt;/code&gt; sidecar), and a walkthrough of how to use the
API. This post focuses on what is different in Beta.&lt;/p&gt;
&lt;h2 id=&#34;what-s-new-in-beta&#34;&gt;What&#39;s new in Beta&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#what-s-new-in-beta&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The main change in this release is the promotion of the
SnapshotMetadataService CRD from &lt;code&gt;v1alpha1&lt;/code&gt; to &lt;code&gt;v1beta1&lt;/code&gt;. The CRD used to
advertise a driver&#39;s metadata service now serves
&lt;code&gt;cbt.storage.k8s.io/v1beta1&lt;/code&gt;. The schema itself is unchanged, but this
release &lt;strong&gt;removes&lt;/strong&gt; &lt;code&gt;v1alpha1&lt;/code&gt; (rather than serving it alongside the new version).
If you are upgrading from Alpha, you need to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Re-apply the CRD definition shipped with &lt;code&gt;v1.0.0&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Update SnapshotMetadataService manifests to use
&lt;code&gt;apiVersion: cbt.storage.k8s.io/v1beta1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Update any client or controller code that talks to the CRD.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is a one-time change. There is no automatic conversion between the two
versions.&lt;/p&gt;
&lt;h2 id=&#34;compatibility&#34;&gt;Compatibility&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#compatibility&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Minimum Kubernetes version: &lt;strong&gt;1.33&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;CSI spec: &lt;strong&gt;1.10 or newer&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Container image: &lt;code&gt;registry.k8s.io/sig-storage/csi-snapshot-metadata:v1.0.0&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;trying-it-out&#34;&gt;Trying it out&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#trying-it-out&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2025/09/25/csi-changed-block-tracking/#getting-started&#34;&gt;Getting Started section in the Alpha
blog&lt;/a&gt; still
applies. In short:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Make sure your CSI driver supports volume snapshots and ships the
&lt;code&gt;external-snapshot-metadata&lt;/code&gt; sidecar.&lt;/li&gt;
&lt;li&gt;Install the SnapshotMetadataService CRD (the &lt;code&gt;v1beta1&lt;/code&gt; definition from
the &lt;code&gt;v1.0.0&lt;/code&gt; release).&lt;/li&gt;
&lt;li&gt;Create a SnapshotMetadataService resource for your driver.&lt;/li&gt;
&lt;li&gt;Use a client — &lt;code&gt;snapshot-metadata-lister&lt;/code&gt;, or your own implementation —
to call &lt;code&gt;GetMetadataAllocated&lt;/code&gt; and &lt;code&gt;GetMetadataDelta&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If you want to see the full flow end-to-end, the
&lt;a href=&#34;https://github.com/kubernetes-csi/csi-driver-host-path/blob/master/docs/example-ephemeral.md&#34;&gt;hostpath driver example&lt;/a&gt;
is a good starting point.&lt;/p&gt;
&lt;h2 id=&#34;what-s-next&#34;&gt;What&#39;s next?&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#what-s-next&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The focus for the rest of the Beta cycle is wider CSI driver adoption and
operational feedback before the feature moves towards GA. If you maintain a
CSI driver, this is a good time to evaluate adding support. If you are
building a backup application on top of the API, feedback on the streaming
clients and the iterator package is very welcome.&lt;/p&gt;
&lt;h2 id=&#34;where-can-i-learn-more&#34;&gt;Where can I learn more?&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#where-can-i-learn-more&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;The &lt;a href=&#34;https://kubernetes-csi.github.io/docs/external-snapshot-metadata.html&#34;&gt;CSI developer
documentation&lt;/a&gt;
for snapshot metadata.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/enhancements/tree/master/keps/sig-storage/3314-csi-changed-block-tracking&#34;&gt;KEP-3314&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;The
&lt;a href=&#34;https://github.com/kubernetes-csi/external-snapshot-metadata&#34;&gt;external-snapshot-metadata&lt;/a&gt;
repository.&lt;/li&gt;
&lt;li&gt;The gRPC
&lt;a href=&#34;https://github.com/kubernetes-csi/external-snapshot-metadata/blob/main/proto/schema.proto&#34;&gt;schema&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;The
&lt;a href=&#34;https://github.com/kubernetes-csi/external-snapshot-metadata/tree/main/examples/snapshot-metadata-lister&#34;&gt;snapshot-metadata-lister&lt;/a&gt;
example client.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;how-do-i-get-involved&#34;&gt;How do I get involved?&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#how-do-i-get-involved&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;This work is the result of contributions from many people across SIG Storage.
A big thank you to everyone who helped review, code, and test the feature
through Alpha and into Beta:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ben Swartzlander (&lt;a href=&#34;https://github.com/bswartz&#34;&gt;bswartz&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Carl Braganza (&lt;a href=&#34;https://github.com/carlbraganza&#34;&gt;carlbraganza&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Daniil Fedotov (&lt;a href=&#34;https://github.com/hairyhum&#34;&gt;hairyhum&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Ivan Sim (&lt;a href=&#34;https://github.com/ihcsim&#34;&gt;ihcsim&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Nikhil Ladha (&lt;a href=&#34;https://github.com/Nikhil-Ladha&#34;&gt;Nikhil-Ladha&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Praveen M (&lt;a href=&#34;https://github.com/iPraveenParihar&#34;&gt;iPraveenParihar&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Rakshith R (&lt;a href=&#34;https://github.com/Rakshith-R&#34;&gt;Rakshith-R&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Xing Yang (&lt;a href=&#34;https://github.com/xing-yang&#34;&gt;xing-yang&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you would like to get involved with CSI or storage in Kubernetes,
&lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-storage&#34;&gt;SIG Storage&lt;/a&gt;
is the place to start. The &lt;a href=&#34;https://docs.google.com/document/d/15tLCV3csvjHbKb16DVk-mfUmFry_Rlwo-2uG6KNGsfw/edit&#34;&gt;Data Protection Working
Group&lt;/a&gt;
also holds regular meetings, and new attendees are always welcome.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Open source maintainership in the age of AI</title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/06/26/open-source-maintainership-in-the-age-of-ai/</link>
      <pubDate>Fri, 26 Jun 2026 10:00:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/06/26/open-source-maintainership-in-the-age-of-ai/</guid>
      <description>
        
        
        &lt;p&gt;AI has really changed the game around software development.
More people are leveraging AI than ever to contribute patches to projects they use.
To me, this is a good thing as more folks will contribute patches rather than fork or not fix them.
The main problem is that AI has made generating code fast but there has been very little improvement in maintaining code bases.
In this post, we will highlight the ways the Kubernetes community is adapting to the world of AI assisted coding.&lt;/p&gt;
&lt;p&gt;The first step of this journey was to develop an AI policy. This seems mundane and bureaucratic but there were many PRs that derailed into discussions around AI usage.
The AI policy helps steer the conversation around the project&#39;s stance on AI and provides a clear signal to contributors on how to use these tools responsibly.&lt;/p&gt;
&lt;h2 id=&#34;kubernetes-ai-policy&#34;&gt;Kubernetes AI policy&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#kubernetes-ai-policy&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The Kubernetes project has established &lt;a href=&#34;https://www.kubernetes.dev/docs/guide/pull-requests/#ai-guidance&#34;&gt;clear guidelines for AI-assisted contributions&lt;/a&gt; that balance innovation with accountability.
These policies are designed to maintain code quality and ensure human oversight while acknowledging that AI tools can be valuable aids in the development process.&lt;/p&gt;
&lt;h3 id=&#34;transparency-first&#34;&gt;Transparency first&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#transparency-first&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Contributors must disclose when AI tools have been used to assist with a pull request. A simple statement in the PR description such as &amp;quot;This PR was written in part with the assistance of generative AI&amp;quot; is sufficient. This transparency helps reviewers understand the context and apply appropriate scrutiny.&lt;/p&gt;
&lt;h3 id=&#34;human-accountability&#34;&gt;Human accountability&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#human-accountability&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;While AI tools can assist, the human contributor remains fully responsible for every change. The policy explicitly prohibits:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Listing AI as a co-author on commits&lt;/li&gt;
&lt;li&gt;Using AI co-signing on commits&lt;/li&gt;
&lt;li&gt;Adding trailers like &amp;quot;assisted-by&amp;quot; or &amp;quot;co-developed&amp;quot; that attribute work to AI&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This isn&#39;t about diminishing AI&#39;s role as a tool—it&#39;s about maintaining clear accountability. If something breaks, there needs to be a human who understands why and can fix it.&lt;/p&gt;
&lt;h3 id=&#34;cla-enforcement-for-co-authors&#34;&gt;CLA enforcement for co-authors&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#cla-enforcement-for-co-authors&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The CNCF provides a &lt;a href=&#34;https://github.com/cncf/cla&#34;&gt;tool&lt;/a&gt; for verifying the contributor license agreements on each pull request.
AI agents are not able to solve these contributor license agreements so one enforcement the project made is to enable the CLA check for co-authors.
This provides a flag to reviewers that the PR is not ready to merge.&lt;/p&gt;
&lt;h3 id=&#34;human-engagement-required&#34;&gt;Human engagement required&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#human-engagement-required&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Perhaps the most critical aspect of the policy: reviewers expect to engage with humans, not with AI.
Contributors cannot rely on AI to respond to review comments.
If you cannot personally explain changes that AI helped generate, your PR will be closed.
This requirement ensures that knowledge transfer happens and that contributors genuinely understand the code they&#39;re submitting.&lt;/p&gt;
&lt;h3 id=&#34;verification-obligations&#34;&gt;Verification obligations&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#verification-obligations&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Contributors must verify AI-generated changes through code review, testing, and personal understanding.
It&#39;s not enough for the code to work—you need to know why it works and be able to maintain it.&lt;/p&gt;
&lt;p&gt;These policies reflect a mature approach to AI: embrace it as a tool, but never let it replace human judgment, understanding, or responsibility.&lt;/p&gt;
&lt;h2 id=&#34;automated-ai-reviews&#34;&gt;Automated AI reviews&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#automated-ai-reviews&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;There exist many tools to aid in reviewing code. AI pull request tools introduce governance challenges so one of the first tasks the community took on was to &lt;a href=&#34;https://github.com/kubernetes/community/blob/main/github-management/ai-code-review-tools.md&#34;&gt;document the process&lt;/a&gt; for what is needed to bring in new AI tools.
One of the major evaluation criteria for these tools is to find maintainers willing to test drive them in kubernetes-sigs repositories. Kueue, JobSet and Agent-Sandbox have been experimenting with these tools to provide more support for maintainers.&lt;/p&gt;
&lt;h3 id=&#34;copilot&#34;&gt;Copilot&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#copilot&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;One tool that many maintainers started using was GitHub Copilot.
The CNCF provides &lt;a href=&#34;https://contribute.cncf.io/blog/2025/12/16/github-copilot-enterprise-for-maintainers/&#34;&gt;access for maintainers&lt;/a&gt; so this ended up being the first tool many started using.
It provides some good experience on tuning reviews but there were some growing pains with this tool.
The biggest blocker for community adoption is relying on contributors to have a copilot license. Only maintainers were able to request copilot reviews and automated reviews of pull requests was out of reach for the community.
One of the goals of AI review tools is to provide an automated review tool that maintainers don&#39;t need to request.
This demonstrated the need for organization control rather than relying on contributors having access.&lt;/p&gt;
&lt;h3 id=&#34;coderabbit&#34;&gt;CodeRabbit&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#coderabbit&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;In mid 2026, the Kubernetes community has rolled out CodeRabbit to a few projects.
As with copilot, some tuning has been required to provide better reviews but the overall feedback has been positive.
There is a lot of configuration available for this tool and one of the most interesting uses of this tool comes from agent-sandbox.&lt;/p&gt;
&lt;p&gt;AI pull request tools can be a quality gate. Contributors can at least get a quick spot check review without waiting for a maintainer.
Agent-sandbox has added a label on PRs to reflect that there is still a need to resolve some of the comments from AI tools.&lt;/p&gt;
&lt;h2 id=&#34;next-steps&#34;&gt;Next steps&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#next-steps&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The reality is that leveraging AI in open source projects is an area of active exploration.
The community could use your help in tuning reviews tools, evaluating tools or evaluating emerging technologies in the AI space.&lt;/p&gt;
&lt;p&gt;Some areas we are exploring more:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The use of AI skills to reduce maintainer burnout.&lt;/li&gt;
&lt;li&gt;AI assisted triage of failing tests.&lt;/li&gt;
&lt;li&gt;Skills to aid the operational aspects of Kubernetes.&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Introducing the Cluster API plugin for Headlamp</title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/06/25/headlamp-cluster-api-plugin/</link>
      <pubDate>Thu, 25 Jun 2026 14:00:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/06/25/headlamp-cluster-api-plugin/</guid>
      <description>
        
        
        &lt;p&gt;&lt;a href=&#34;https://headlamp.dev/&#34;&gt;Headlamp&lt;/a&gt; is an open-source, extensible Kubernetes SIG UI
project designed to let you explore, manage, and debug cluster resources directly
from a browser.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://cluster-api.sigs.k8s.io&#34;&gt;Cluster API (CAPI)&lt;/a&gt; is a Kubernetes sub-project
that brings declarative, Kubernetes-style APIs to cluster lifecycle management. It
lets platform teams provision, upgrade, and manage the lifecycle of Kubernetes
clusters using standard Kubernetes objects stored and reconciled in a management
cluster.&lt;/p&gt;
&lt;p&gt;Managing Cluster API resources has historically required raw &lt;code&gt;kubectl&lt;/code&gt; commands and
deep familiarity with ownership hierarchies. The Headlamp Cluster API plugin brings
visual clarity, faster debugging, and simplified operations for platform teams,
directly inside Headlamp.&lt;/p&gt;
&lt;h2 id=&#34;what-this-plugin-provides&#34;&gt;What this plugin provides&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#what-this-plugin-provides&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The Cluster API plugin adds a dedicated Cluster API section to Headlamp and brings
full visibility into core CAPI resources through consistent list and detail views.&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Feature&lt;/th&gt;
          &lt;th&gt;Description&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Cluster overview&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;View clusters with live control plane and worker replica status.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Machine visibility&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;Inspect MachineDeployments, MachineSets, Machines, and MachinePools with status and conditions.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Cluster API dashboard&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;Get a centralized view of Cluster API resource health, active condition issues, provider information, and remediation guidance.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Control plane monitoring&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;Track KubeadmControlPlane replicas, versions, and associated Machines.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Scale from the UI&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;Scale MachineDeployments and MachineSets directly from Headlamp.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Owned resource hierarchy&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;Trace relationships between clusters, deployments, sets, and machines.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;KubeadmConfig inspection&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;View bootstrap configs, files, kubelet args, and join/init settings.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Topology awareness&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;Automatically detect and label ClusterClass-managed resources.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Map view&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;Visualize Cluster, Control Plane, and Worker relationships.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Dynamic API versioning&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;Supports both v1beta1 and v1beta2 Cluster API versions.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;Prometheus metrics&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;View live metrics from the &lt;a href=&#34;https://github.com/headlamp-k8s/plugins/tree/main/prometheus&#34;&gt;Headlamp Prometheus plugin&lt;/a&gt; inline on Cluster API resource detail pages.&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;a-tour-of-the-plugin&#34;&gt;A tour of the plugin&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#a-tour-of-the-plugin&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The Headlamp Cluster API plugin brings core Cluster API resources into a consistent,
visual interface inside Headlamp. Here are some of the key views included in the
first release.&lt;/p&gt;
&lt;h3 id=&#34;cluster-api-dashboard&#34;&gt;Cluster API dashboard&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#cluster-api-dashboard&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The dashboard provides a centralized view of Cluster API resources and their
health across a management cluster.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/06/25/headlamp-cluster-api-plugin/cluster-api-dashboard.png&#34; alt=&#34;Cluster API dashboard showing overall resource health&#34;&gt;&lt;/p&gt;
&lt;p&gt;The overview summarizes the status of clusters, Machines, MachineDeployments,
MachinePools, MachineSets, and control planes. It also highlights active
condition issues, provider information, and configuration template counts to
help operators quickly identify degraded or unhealthy resources.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/06/25/headlamp-cluster-api-plugin/cluster-health-cards.png&#34; alt=&#34;Cluster details and remediation guidance&#34;&gt;&lt;/p&gt;
&lt;p&gt;Selecting a cluster opens a detailed health view showing control plane and
worker status, machine information, infrastructure details, and resource
conditions. When issues are detected, the dashboard provides remediation
guidance and diagnostic commands to assist with troubleshooting.&lt;/p&gt;
&lt;h3 id=&#34;bring-full-cluster-api-visibility-into-headlamp&#34;&gt;Bring full Cluster API visibility into Headlamp&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#bring-full-cluster-api-visibility-into-headlamp&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The cluster list view shows all Cluster resources in the management cluster,
including control plane and worker replica status. This gives you an at-a-glance
understanding of overall cluster health.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/06/25/headlamp-cluster-api-plugin/cluster-list-view.png&#34; alt=&#34;Cluster list view showing control plane and worker replica status&#34;&gt;&lt;/p&gt;
&lt;p&gt;The cluster detail view provides resource status, conditions, infrastructure
references, control plane references, and related Machines on a single page.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/06/25/headlamp-cluster-api-plugin/cluster-detail-overview.png&#34; alt=&#34;Cluster detail view showing resource status and conditions&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/06/25/headlamp-cluster-api-plugin/cluster-detail-machines.png&#34; alt=&#34;Cluster detail view showing related machines&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;explore-cluster-api-resources-in-a-visual-interface&#34;&gt;Explore Cluster API resources in a visual interface&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#explore-cluster-api-resources-in-a-visual-interface&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Dedicated views are available for MachineDeployments, MachineSets, Machines, and
MachinePools. These pages surface replica counts, ownership relationships, provider
IDs, versions, and conditions to support day-to-day operations and debugging.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/06/25/headlamp-cluster-api-plugin/machine-resources-view.png&#34; alt=&#34;MachineDeployment list view showing replica counts, ownership, and conditions&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;scale-workloads-directly-from-headlamp&#34;&gt;Scale workloads directly from Headlamp&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#scale-workloads-directly-from-headlamp&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;MachineDeployments and MachineSets include a built-in Scale action, allowing you to
adjust replica counts directly from Headlamp without using terminal commands.&lt;/p&gt;
&lt;p&gt;For topology-managed clusters, the plugin also indicates when scaling should be
performed at the Cluster level.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/06/25/headlamp-cluster-api-plugin/scale-machine-deployments.png&#34; alt=&#34;Scale dialog for a MachineDeployment&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/06/25/headlamp-cluster-api-plugin/scale-machine-sets.png&#34; alt=&#34;Topology-managed cluster showing scaling guidance at the Cluster level&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;inspect-bootstrap-configuration-without-raw-yaml&#34;&gt;Inspect bootstrap configuration without raw YAML&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#inspect-bootstrap-configuration-without-raw-yaml&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Bootstrap configurations can be viewed in a structured format, including inline
files, kubelet arguments, extra volumes, and join or init settings. This removes
the need to inspect raw YAML or secrets manually.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/06/25/headlamp-cluster-api-plugin/bootstrap-config-view.png&#34; alt=&#34;KubeadmConfig detail view showing bootstrap configuration in structured format&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;visualize-cluster-relationships-with-map-view&#34;&gt;Visualize cluster relationships with map view&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#visualize-cluster-relationships-with-map-view&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;A visual map view displays the relationships between Cluster, control plane, and
worker resources. It offers a faster way to understand ownership hierarchies and
overall cluster structure.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/06/25/headlamp-cluster-api-plugin/topology-map-view.png&#34; alt=&#34;Map view showing Cluster, Control Plane, and Worker resource relationships&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;prometheus-metrics-integration&#34;&gt;Prometheus metrics integration&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#prometheus-metrics-integration&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The Cluster API plugin integrates with the
&lt;a href=&#34;https://github.com/headlamp-k8s/plugins/tree/main/prometheus&#34;&gt;Headlamp Prometheus plugin&lt;/a&gt;
to surface metrics directly inside Cluster API resource detail pages.&lt;/p&gt;
&lt;p&gt;When the Prometheus plugin is installed and configured, metrics are embedded inline
on the detail pages for Clusters, MachineDeployments, MachineSets, and Machines.
You can view resource health and performance data alongside status conditions and
ownership relationships, without switching to a separate dashboard.&lt;/p&gt;
&lt;p&gt;This makes it easier to correlate infrastructure state with live metrics during
debugging or day-to-day cluster operations, all from within Headlamp.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/06/25/headlamp-cluster-api-plugin/prometheus-metrics-view.png&#34; alt=&#34;Prometheus metrics embedded inline on a Cluster detail page&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;how-to-use&#34;&gt;How to use&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#how-to-use&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;See the
&lt;a href=&#34;https://github.com/headlamp-k8s/plugins/blob/main/cluster-api/README.md&#34;&gt;&lt;code&gt;plugins/cluster-api/README.md&lt;/code&gt;&lt;/a&gt;
for installation and usage instructions.&lt;/p&gt;
&lt;h2 id=&#34;developed-during-lfx-mentorship&#34;&gt;Developed during LFX Mentorship&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#developed-during-lfx-mentorship&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;This plugin was developed as part of the CNCF LFX Mentorship program under the
Headlamp project. The mentorship provided an opportunity to work closely with the
Headlamp community while building features to improve the Cluster API management
experience.&lt;/p&gt;
&lt;p&gt;The focus was not only on implementing features but also on understanding real-world
usability challenges around Cluster API operations. Discussions with mentors and
community members helped shape the plugin&#39;s direction, improve the user experience,
and prioritize features most useful to platform teams.&lt;/p&gt;
&lt;p&gt;The mentorship also provided valuable experience contributing to large open-source
projects: collaborating with maintainers, participating in design discussions,
handling release feedback, and iterating on features based on community input.&lt;/p&gt;
&lt;p&gt;Work on the plugin is ongoing, with additional improvements and features planned
beyond the initial Alpha release.&lt;/p&gt;
&lt;h2 id=&#34;feedback-and-questions&#34;&gt;Feedback and questions&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#feedback-and-questions&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;This is an Alpha release, and community feedback directly shapes what comes next.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Bug reports:&lt;/strong&gt; &lt;a href=&#34;https://github.com/kubernetes-sigs/headlamp/issues&#34;&gt;Open an issue&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Feature requests:&lt;/strong&gt; &lt;a href=&#34;https://github.com/kubernetes-sigs/headlamp/discussions&#34;&gt;Start a discussion&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Contributing:&lt;/strong&gt; &lt;a href=&#34;https://github.com/kubernetes-sigs/headlamp/pulls&#34;&gt;PRs are welcome&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Kubernetes Slack:&lt;/strong&gt; &lt;a href=&#34;https://slack.k8s.io/&#34;&gt;Join the #headlamp channel&lt;/a&gt; for questions and discussion&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Inspect Volcano workloads faster with Headlamp</title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/06/25/visual-context-volcano-headlamp-plugin/</link>
      <pubDate>Thu, 25 Jun 2026 12:00:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/06/25/visual-context-volcano-headlamp-plugin/</guid>
      <description>
        
        
        &lt;p&gt;&lt;a href=&#34;https://volcano.sh/&#34;&gt;Volcano&lt;/a&gt; is a cloud native batch scheduler for Kubernetes, built for high-performance computing, AI/ML, and other batch workloads.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://headlamp.dev/&#34;&gt;Headlamp&lt;/a&gt; is an extensible Kubernetes web UI. With its plugin system, Headlamp can surface APIs and workflows beyond the built-in Kubernetes resources. The Volcano plugin brings core Volcano resources into Headlamp so you can inspect workload state, queue behavior, and gang scheduling details in one place.&lt;/p&gt;
&lt;p&gt;Kubernetes was originally designed around long-running services, where applications are expected to start and remain available over time. Batch, AI/ML, and HPC workloads often behave differently: jobs arrive dynamically, compete for limited resources, and may need multiple workers to start together before useful work can begin.&lt;/p&gt;
&lt;p&gt;Volcano extends Kubernetes with concepts such as queues, priorities, quotas, and gang scheduling. Instead of treating every Pod independently, Volcano schedules workloads with awareness of the job as a whole and the resources it needs to make progress.&lt;/p&gt;
&lt;p&gt;To make these workloads easier to operate and troubleshoot, the Volcano plugin brings that scheduling context directly into Headlamp.&lt;/p&gt;
&lt;p&gt;Watch this short walkthrough to see the Volcano plugin in Headlamp:&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&#34; allowfullscreen=&#34;allowfullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/Mqm1EyAa7TY?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;Volcano plugin for Headlamp walkthrough&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;h2 id=&#34;visual-context-helps-teams-understand-volcano-jobs-queues-and-podgroups-faster&#34;&gt;Visual context helps teams understand Volcano jobs, queues, and PodGroups faster&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#visual-context-helps-teams-understand-volcano-jobs-queues-and-podgroups-faster&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Working with Volcano often means moving across several related resources while trying to understand a batch workload. You might start with a Job, then look at the related PodGroup, inspect the Pods behind it, check the Queue, and finally return to the Job again. All of that is possible with CLI tools like &lt;code&gt;kubectl&lt;/code&gt; and the Volcano CLI, but it can become fragmented very quickly.&lt;/p&gt;
&lt;p&gt;The Volcano plugin for Headlamp makes that workflow easier by bringing the key resources together in a single UI. Instead of reconstructing relationships manually, you can move directly between Jobs, Queues, PodGroups, Pods, and events from the same interface.&lt;/p&gt;
&lt;p&gt;Volcano introduces its own resources on top of core Kubernetes objects:&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;Job&lt;/dt&gt;
&lt;dd&gt;Describes a batch workload as a set of tasks and the Pods they create.&lt;/dd&gt;
&lt;dt&gt;Queue&lt;/dt&gt;
&lt;dd&gt;Divides cluster capacity between teams or workloads using quotas and priorities.&lt;/dd&gt;
&lt;dt&gt;PodGroup&lt;/dt&gt;
&lt;dd&gt;Ties a group of Pods together so the scheduler can treat them as a single unit for gang scheduling.&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;The plugin surfaces all three resource types directly in Headlamp, providing dedicated list and detail views for each of them under a Volcano section in the sidebar.&lt;/p&gt;
&lt;h2 id=&#34;jobs-workload-status-actions-and-logs&#34;&gt;Jobs: workload status, actions, and logs&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#jobs-workload-status-actions-and-logs&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The Job view is the center of the plugin experience. In the list view, you can quickly understand the basics of a workload, including its status, queue, running versus minimum-available values, task count, and age.&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/06/25/visual-context-volcano-headlamp-plugin/volcano-jobs-list.png&#34;
         alt=&#34;Volcano Jobs list in Headlamp&#34;/&gt; 
&lt;/figure&gt;
&lt;p&gt;The detail view goes further by surfacing the information you usually need while debugging a Job: task details, Pod status, related Queue and PodGroup links, conditions, events, and more. Instead of forcing you to jump between several CLI commands, the plugin keeps that context together in a single page.&lt;/p&gt;
&lt;p&gt;The Job page also adds supported lifecycle actions for appropriate states, including &lt;strong&gt;Suspend&lt;/strong&gt; and &lt;strong&gt;Resume&lt;/strong&gt;, so you can act on a Job directly from the UI.&lt;/p&gt;
&lt;p&gt;Another useful addition is direct &lt;strong&gt;Job logs&lt;/strong&gt; access. You can open logs for Pods created by a Volcano Job without leaving the Job detail page. The logs viewer supports both single-Pod and all-Pods views, along with container selection and common log controls such as line count, previous logs, timestamps, and follow.&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/06/25/visual-context-volcano-headlamp-plugin/volcano-job-logs.png&#34;
         alt=&#34;Volcano Job logs in Headlamp&#34;/&gt; 
&lt;/figure&gt;
&lt;h2 id=&#34;queues-scheduling-capacity-and-resource-context&#34;&gt;Queues: scheduling capacity and resource context&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#queues-scheduling-capacity-and-resource-context&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The Queue view provides much more than a small set of top-level fields. It helps you understand how resources are being allocated and constrained by surfacing capacity, allocated resources, deserved and guaranteed resources, reservation details, child queues, and more.&lt;/p&gt;
&lt;p&gt;This makes the Queue page much more useful when trying to understand how resources are being shared and limited across queues.&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/06/25/visual-context-volcano-headlamp-plugin/volcano-queue-detail.png&#34;
         alt=&#34;Volcano Queue details in Headlamp&#34;/&gt; 
&lt;/figure&gt;
&lt;h2 id=&#34;podgroups-gang-scheduling-state-and-blockers&#34;&gt;PodGroups: gang scheduling state and blockers&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#podgroups-gang-scheduling-state-and-blockers&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;PodGroups are central to understanding gang scheduling in Volcano, and the plugin makes that state easier to inspect. The PodGroup view highlights progress, conditions, minimum resource requirements, and more.&lt;/p&gt;
&lt;p&gt;This also gives you a clearer picture of whether a workload is blocked because it has not yet met the scheduling conditions required to run as a group.&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/06/25/visual-context-volcano-headlamp-plugin/volcano-podgroup-detail.png&#34;
         alt=&#34;Volcano PodGroup details in Headlamp&#34;/&gt; 
&lt;/figure&gt;
&lt;h2 id=&#34;map-view-jobs-queues-podgroups-and-pods-in-one-place&#34;&gt;Map view: jobs, queues, PodGroups, and pods in one place&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#map-view-jobs-queues-podgroups-and-pods-in-one-place&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The map view shows how Volcano resources are connected. Instead of inspecting each resource separately, you can see how Jobs, PodGroups, Queues, and Pods relate to one another.&lt;/p&gt;
&lt;p&gt;This is especially useful when a workload is pending or not progressing as expected. The map can show the Job, its related PodGroup, the Pods created for the workload, and the Queue context around it. Warning and error states also make it easier to spot resources that need attention.&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/06/25/visual-context-volcano-headlamp-plugin/volcano-map-view.png&#34;
         alt=&#34;Volcano resources in the Headlamp map view&#34;/&gt; 
&lt;/figure&gt;
&lt;h2 id=&#34;why-use-this-alongside-cli-tools&#34;&gt;Why use this alongside CLI tools&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#why-use-this-alongside-cli-tools&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The plugin is not trying to replace &lt;code&gt;kubectl&lt;/code&gt; or the Volcano CLI. Those remain important for automation, scripting, and raw object inspection. What the plugin improves is the interactive troubleshooting experience: discovering related resources more quickly, understanding structured detail pages, and moving from scheduling state to runtime output without switching tools constantly.&lt;/p&gt;
&lt;h2 id=&#34;what-s-next&#34;&gt;What’s next&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#what-s-next&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;This work brings the main Volcano workflow into Headlamp, including Jobs, Queues, PodGroups, and the map view. Possible future work includes Prometheus integration, richer scheduling insights, and more workflow-oriented visibility across Volcano workloads.&lt;/p&gt;
&lt;h2 id=&#34;try-it-and-share-feedback&#34;&gt;Try it and share feedback&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#try-it-and-share-feedback&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;To try the plugin:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Install Headlamp.&lt;/li&gt;
&lt;li&gt;Open the Plugin Catalog from the Headlamp UI.&lt;/li&gt;
&lt;li&gt;Search for Volcano.&lt;/li&gt;
&lt;li&gt;Install the Volcano plugin.&lt;/li&gt;
&lt;li&gt;Connect Headlamp to a Kubernetes cluster where Volcano is already installed.&lt;/li&gt;
&lt;/ol&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/06/25/visual-context-volcano-headlamp-plugin/volcano-plugin-catalog.png&#34;
         alt=&#34;Volcano plugin in the Headlamp Plugin Catalog&#34;/&gt; 
&lt;/figure&gt;
&lt;p&gt;If you have ideas, feature requests, or bug reports, open an issue in the &lt;a href=&#34;https://github.com/headlamp-k8s/plugins&#34;&gt;Headlamp plugins repository&lt;/a&gt;. Feedback from real Volcano users will help shape what comes next.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>See your serverless: introducing the Headlamp plugin for Knative</title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/06/25/headlamp-knative-plugin/</link>
      <pubDate>Thu, 25 Jun 2026 10:00:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/06/25/headlamp-knative-plugin/</guid>
      <description>
        
        
        &lt;p&gt;&lt;a href=&#34;https://headlamp.dev/&#34;&gt;Headlamp&lt;/a&gt; is an open-source, extensible Kubernetes SIG UI project designed to let you explore, manage, and debug cluster resources.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://knative.dev/&#34;&gt;Knative&lt;/a&gt; brings serverless workloads to Kubernetes, handling traffic routing, autoscaling, and revision management so teams can deploy and iterate without fighting infrastructure. But operating Knative workloads day-to-day can be difficult, there&#39;s still a lot of jumping between the &lt;code&gt;kn&lt;/code&gt; CLI, &lt;code&gt;kubectl&lt;/code&gt;, and the Kubernetes UI to get a full picture of what&#39;s running.&lt;/p&gt;
&lt;p&gt;We built the &lt;a href=&#34;https://github.com/headlamp-k8s/plugins/tree/main/knative&#34;&gt;Headlamp Knative plugin&lt;/a&gt; to bridge that very gap, allowing operators to inspect, understand and act on their workloads all from a single place. This plugin was built as part of the LFX mentorship. Here&#39;s a tour of what we shipped.&lt;/p&gt;
&lt;p&gt;Here is a short walkthrough of the Knative plugin for Headlamp:&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&#34; allowfullscreen=&#34;allowfullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/9HAcUsopSYE?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;Headlamp Knative plugin walkthrough&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;h2 id=&#34;integrating-knative-resources-with-headlamp-s-map-view&#34;&gt;Integrating Knative resources with Headlamp&#39;s map view&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#integrating-knative-resources-with-headlamp-s-map-view&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Headlamp&#39;s resource mapping works for Knative CRDs too. You can see how KServices, Revisions, and DomainMappings relate to each other in a single graph view.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/06/25/headlamp-knative-plugin/knative-map-view.png&#34; alt=&#34;Knative resources in Headlamp Map View&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;kservice-management-edit-traffic-splits-restart-pods-and-view-logs&#34;&gt;KService management: edit traffic splits, restart pods, and view logs&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#kservice-management-edit-traffic-splits-restart-pods-and-view-logs&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;A KService is the top-level resource in Knative: it manages the lifecycle of Routes, Configurations, Revisions, and everything needed to run and expose your application.&lt;/p&gt;
&lt;p&gt;The plugin gives KServices a full detail view with an &lt;strong&gt;Edit Mode&lt;/strong&gt; toggle for making live changes to traffic splits, autoscaling annotations, and more. Common actions like viewing the YAML, opening logs, triggering a redeploy, or restarting backing pods are surfaced in the header, gated by your current RBAC permissions.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/06/25/headlamp-knative-plugin/knative-kservice-view.png&#34; alt=&#34;Knative Service Detail View&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;traffic-splitting-route-across-revisions-for-gradual-rollouts-and-testing&#34;&gt;Traffic splitting: route across revisions for gradual rollouts and testing&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#traffic-splitting-route-across-revisions-for-gradual-rollouts-and-testing&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Knative makes it possible to route traffic across multiple Revisions of the same service. This is useful for canary releases, gradual rollouts, tagged preview URLs, and A/B testing.&lt;/p&gt;
&lt;p&gt;The plugin shows the traffic assigned to each Revision, the latest ready Revision, readiness status, age, and configured tags. In edit mode, you can adjust percentages and tags inline. The plugin validates that traffic sums to 100% and that tags are unique before saving. Tagged routes with a reported URL render as clickable links.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/06/25/headlamp-knative-plugin/knative-traffic-view.png&#34; alt=&#34;Traffic Splitting between Revisions&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;autoscaling-configuration-view-effective-settings-and-cluster-defaults&#34;&gt;Autoscaling configuration: view effective settings and cluster defaults&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#autoscaling-configuration-view-effective-settings-and-cluster-defaults&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Knative&#39;s autoscaler supports a range of settings: concurrency targets, target utilization, RPS targets, min/max scale, initial scale, stable window, scale-down delay, and more. The effective value for any workload is a combination of KService-level annotations and cluster-wide ConfigMaps.&lt;/p&gt;
&lt;p&gt;The plugin reads &lt;code&gt;config-autoscaler&lt;/code&gt; and &lt;code&gt;config-defaults&lt;/code&gt; and shows the effective configuration per KService in context, so you can see at a glance whether a setting is explicitly configured or falling back to the cluster default.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/06/25/headlamp-knative-plugin/knative-autoscaling-view.png&#34; alt=&#34;Autoscaling and Concurrency View&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;prometheus-metrics-monitor-request-rates-latency-and-resource-utilization&#34;&gt;Prometheus metrics: monitor request rates, latency, and resource utilization&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#prometheus-metrics-monitor-request-rates-latency-and-resource-utilization&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;When paired with the &lt;a href=&#34;https://github.com/headlamp-k8s/plugins/tree/main/plugins/prometheus&#34;&gt;Prometheus plugin for Headlamp&lt;/a&gt;, the plugin renders request rate, latency, and resource utilization graphs on KService and Revision detail pages. The per-revision request rate breakdown is particularly useful when validating a traffic split in progress.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/06/25/headlamp-knative-plugin/knative-revision-metrics-graph.png&#34; alt=&#34;Knative metrics filtered by revision&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;dashboard-for-other-crds&#34;&gt;Dashboard for other CRDs&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#dashboard-for-other-crds&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The plugin also includes list and detail views for Revisions, DomainMappings, ClusterDomainClaims, and a cluster-level Networking overview (reading &lt;code&gt;config-network&lt;/code&gt; and &lt;code&gt;config-gateway&lt;/code&gt; to surface the effective ingress class, gateway settings, and backing services). These give operators a complete picture of Knative&#39;s state without leaving Headlamp.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/06/25/headlamp-knative-plugin/knative-revisions-view.png&#34; alt=&#34;Knative Revision List View&#34;&gt;
&lt;img src=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/06/25/headlamp-knative-plugin/knative-domain-mapping-view.png&#34; alt=&#34;Knative Domain Mapping List View&#34;&gt;
&lt;img src=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/06/25/headlamp-knative-plugin/knative-cluster-domain-claim-view.png&#34; alt=&#34;Knative Cluster Domain Claim List View&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;how-to-install-the-knative-plugin-in-headlamp&#34;&gt;How to install the Knative plugin in Headlamp&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#how-to-install-the-knative-plugin-in-headlamp&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;Make sure &lt;a href=&#34;https://knative.dev/docs/install/&#34;&gt;Knative is installed&lt;/a&gt; in your cluster.&lt;/li&gt;
&lt;li&gt;In Headlamp Desktop, open the &lt;strong&gt;Plugin Catalog&lt;/strong&gt;, search for Knative, and click Install.&lt;/li&gt;
&lt;li&gt;Reload Headlamp, a new Knative entry will appear in the sidebar.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For development or source-level setup, see the &lt;a href=&#34;https://github.com/headlamp-k8s/plugins/tree/main/plugins/knative&#34;&gt;Knative plugin README&lt;/a&gt;. The current release is &lt;a href=&#34;https://github.com/headlamp-k8s/plugins/releases/tag/knative-0.3.0-beta&#34;&gt;&lt;strong&gt;0.3.0-beta&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;share-your-feedback&#34;&gt;Share your feedback&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#share-your-feedback&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;We&#39;d love feedback from Knative operators and users. If you hit a bug or want support for a workflow we haven&#39;t covered, &lt;a href=&#34;https://github.com/headlamp-k8s/plugins/issues&#34;&gt;please open an issue&lt;/a&gt;. You can also find us in the &lt;a href=&#34;https://kubernetes.slack.com/archives/headlamp&#34;&gt;Kubernetes Slack #headlamp channel&lt;/a&gt;.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Spotlight on WG Device Management</title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/06/24/wg-device-management-spotlight-2026/</link>
      <pubDate>Wed, 24 Jun 2026 10:00:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/06/24/wg-device-management-spotlight-2026/</guid>
      <description>
        
        
        &lt;p&gt;The rising popularity of AI, Edge, and Telecommunications workloads on Kubernetes has led to new requirements for hardware management. We now need hardware specification beyond CPU time and memory allocations.  This includes allocating GPUs, TPUs, network interfaces, and other hardware, sometimes after pod start and occasionally through time-sharing.&lt;/p&gt;
&lt;p&gt;Efficiently managing this specialized hardware is the mission of the &lt;strong&gt;&lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/wg/device-management/&#34;&gt;Device Management Working Group&lt;/a&gt;&lt;/strong&gt;. Their cornerstone project, &lt;strong&gt;&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/scheduling-eviction/dynamic-resource-allocation/&#34;&gt;Dynamic Resource Allocation (DRA)&lt;/a&gt;&lt;/strong&gt;, recently graduated to GA, marking a fundamental shift in how the project handles hardware-intensive workloads at scale.&lt;/p&gt;
&lt;p&gt;In this spotlight, we sit down with working group chairs &lt;strong&gt;&lt;a href=&#34;https://github.com/klueska&#34;&gt;Kevin Klues&lt;/a&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;a href=&#34;https://github.com/pohly&#34;&gt;Patrick Ohly&lt;/a&gt;&lt;/strong&gt;, and
&lt;strong&gt;&lt;a href=&#34;https://github.com/johnbelamaric&#34;&gt;John Belamaric&lt;/a&gt;&lt;/strong&gt; to discuss the limitations of the legacy device model,
the &lt;em&gt;NP-hard&lt;/em&gt; challenges of scheduling, and how they’re building a more programmable, hardware-aware future for Kubernetes.&lt;/p&gt;
&lt;h2 id=&#34;introducing-device-management&#34;&gt;Introducing Device Management&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#introducing-device-management&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Natalie Fisher: Can you introduce yourself, your role, and how you got involved in the Device Management Working Group?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Kevin Klues:&lt;/strong&gt; My name is Kevin Klues. I am a Distinguished Engineer at NVIDIA. I have been a co-chair of the device management working group since its inception at Kubecon EU 2024. I have also been involved with DRA (the working group&#39;s primary deliverable) since its inception in 2019 / 2020.
I have also been a kubelet maintainer since 2019, with a focus on its device manager, CPU manager, and topology manager subcomponents. The challenges we saw with using these components for workloads that relied on external accelerators (e.g., GPUs) are what triggered us to start working on DRA in the first place.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Patrick Ohly:&lt;/strong&gt; I am a Principal Engineer at Intel. In Kubernetes, I am a Tech Lead for &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/testing/&#34;&gt;SIG Testing&lt;/a&gt; and &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/instrumentation/&#34;&gt;SIG Instrumentation&lt;/a&gt; and co-chair of the Device Management WG. I was co-chair of the WG Structured Logging and a member of the Steering Committee. Some of my early contributions to Kubernetes include &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/storage/ephemeral-volumes/&#34;&gt;ephemeral CSI volumes&lt;/a&gt; and storage capacity tracking, so I had some experience with API design, implementation, and scheduling. We knew that introducing a major new API for accelerators would be hard. Somewhat foolishly, I accepted that challenge in 2020, wrote the initial DRA KEP (now known as “classic DRA”) and implemented most of it, then started over with a second KEP for today’s &amp;quot;structured parameters DRA&amp;quot;. Initially, it was an uphill battle to convince maintainers that this work was necessary. It was only around 2023 that interest in DRA picked up, leading to the formation of the working group.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;John Belamaric:&lt;/strong&gt; I am a Senior Staff SWE at Google, and the third co-chair of WG Device Management, also since its inception. I am also a co-chair of &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/architecture/&#34;&gt;SIG Architecture&lt;/a&gt; since 2019. As Patrick mentioned, in late 2023, interest in DRA really picked up. The initial implementation, made autoscaling very challenging, and so there was some concern in the community about advancing it to beta. I got involved to try to help address some of those concerns, and the three of us, along with Tim Hockin, worked hard over the next few months to build a consensus around a new design. To facilitate this collaboration, we formed the working group after discussion at KubeCon in Paris in 2024.&lt;/p&gt;
&lt;h2 id=&#34;the-problem-and-the-solution&#34;&gt;The problem and the solution&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#the-problem-and-the-solution&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The working group emerged from a fundamental rethink of how Kubernetes interacts with specialized hardware. At the heart of this evolution is &lt;strong&gt;Dynamic Resource Allocation (DRA)&lt;/strong&gt;. Rather than treating devices as simple integers, DRA provides a structured framework that breaks device management into four distinct stages:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Modeling:&lt;/strong&gt; Vendors use the &lt;strong&gt;ResourceSlice API&lt;/strong&gt; to advertise the granular capabilities and capacity of their hardware.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Requesting:&lt;/strong&gt; Users define their specific hardware needs—such as GPU memory or interconnect requirements—through the &lt;strong&gt;&lt;code&gt;ResourceClaim&lt;/code&gt; API&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Scheduling:&lt;/strong&gt; The Kubernetes scheduler uses these APIs to match workload requirements against available hardware intelligently.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Actuation:&lt;/strong&gt; Once a match is made, the system handles the &amp;quot;handshake&amp;quot; that prepares and secures the device for the Pod&#39;s use.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;NF: For readers who may not be familiar, what is the Device Management Working Group, and what problems is it trying to solve?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;KK:&lt;/strong&gt; The Device Management Working Group was chartered to enable simple and efficient configuration, sharing, and allocation of accelerators and other specialized hardware across Kubernetes workloads. Think GPUs, TPUs, FPGAs, and similar devices that don&#39;t fit neatly into Kubernetes&#39; traditional resource model.&lt;/p&gt;
&lt;p&gt;The problem we set out to solve is that the legacy Device Plugin API  (which has been the primary mechanism for exposing hardware accelerators in Kubernetes) is fundamentally limited. It treats devices as opaque integers: you can request &amp;quot;2 GPUs,&amp;quot; but you can&#39;t say anything meaningful about which GPUs you need, how they should be connected to each other, whether they can be shared, or how they should be partitioned. That was fine for simple cases, but modern AI/ML workloads are anything but simple. They span multiple nodes, require specific interconnect topologies, and increasingly need to share or partition hardware dynamically.&lt;/p&gt;
&lt;p&gt;The working group&#39;s primary deliverable is Dynamic Resource Allocation (DRA), a new framework that replaces the rigid device plugin model with a flexible, declarative API.
With DRA, workloads can describe their hardware requirements (e.g., GPU type, memory capacity, interconnect topology, desired partitioning) and drivers can publish fine-grained device attributes that the scheduler can act on.
DRA &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2025/09/01/kubernetes-v1-34-dra-updates/&#34;&gt;graduated&lt;/a&gt; to GA in Kubernetes 1.34, and the ecosystem around it (e.g., drivers, tooling, and new API extensions) is growing rapidly.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;PO:&lt;/strong&gt; As Kevin said, the working group was formed around the existing effort to develop DRA. The initial work was done with only a handful of people actively involved, and perhaps also could only be done successfully in such a setup. But because it touches on so many different areas of Kubernetes, we also needed a place to discuss that and get the broader community of Kubernetes maintainers, device vendors, and, to a lesser extent, also end-users involved. The working group provides that place, with regular meetings online (one slot for Americas/EMEA, one for EMEA/Asia) and at KubeCon.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;JB:&lt;/strong&gt; DRA is the first problem the WG has addressed. It is focused on selection, allocation, and configuration of the devices. We broke the problem down into four parts: how does the vendor model the device and advertise capacity, how does the user request it, how do we schedule that request on top of the advertised capacity, and how do we actuate that result (that is, how do we make the device ready and available to the Pod).&lt;/p&gt;
&lt;p&gt;One thing that is fundamental to the approach we took is an awareness of the incredible diversity of hardware and the rapid rate of change in the hardware industry. We knew that we couldn’t keep up with the change if the Kubernetes APIs had to change for every type of hardware. Instead, we created a general approach where we address the hardware aspects that are important to Kubernetes. What we have done so far is focus on the scheduling and configuration aspects of devices. We build a device modeling API (the ResourceSlice API) that vendors use to model the scheduling characteristics of their devices, and allow users to pass through arbitrary configurations to those devices. By doing this, Kubernetes can be “programmed” to understand these aspects of the devices, without needing to be modified.&lt;/p&gt;
&lt;p&gt;But DRA, as it stands right now, is very focused on scheduling. There are other aspects of Device Management that are in scope for the WG. In particular, we are looking into device failure detection and mitigation, and whether there is some better support we can build into Kubernetes to help.&lt;/p&gt;
&lt;p&gt;Also, as Kevin alluded to, devices are often allocated and used in groups, rather than individually. Choosing the right devices to work together in a group depends on how they are interconnected; for example, NVIDIA GPUs may be in an any-to-any fabric arrangement in an NVLINK domain, whereas TPUs may have a 3D torus interconnect. This affects the “selection, allocation and configuration” of devices, and we have a lot more work to do to address these use cases.&lt;/p&gt;
&lt;h2 id=&#34;a-cross-sig-effort&#34;&gt;A cross-SIG effort&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#a-cross-sig-effort&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Because device management touches scheduling, node operations, autoscaling, networking, and API design, the work naturally spans multiple SIGs across the Kubernetes project.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NF: How does collaboration across these SIGs work in practice, and why is it necessary?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;KK:&lt;/strong&gt; Device management touches nearly every layer of the Kubernetes stack, which is why the working group was chartered as a cross-SIG effort from the start. We have five stakeholder SIGs: sig-node, sig-scheduling, sig-autoscaling, sig-network, and sig-architecture.&lt;/p&gt;
&lt;p&gt;In practice, the working group serves as a coordination layer. We don&#39;t own code directly; instead, our deliverables take the form of KEPs and implementations that live in the respective SIGs. What we provide is a unified forum where the people building the scheduler, the kubelet, the autoscaler, and the network plane can design together rather than in isolation.&lt;/p&gt;
&lt;p&gt;Why is this necessary? Consider a simple example: a user requests a set of GPUs that need to communicate via NVLink. That requirement involves the scheduler (place the pods on the right nodes), the kubelet (configure the devices and expose them to the container), and potentially autoscaling (provision the right node type if none exists).&lt;/p&gt;
&lt;p&gt;If those three groups design independently, you end up with inconsistent abstractions, duplicated logic, and integration bugs that only surface in production. The working group ensures that a single coherent API and data model flows through all of these components.&lt;/p&gt;
&lt;p&gt;The cross-SIG model also means that design decisions are reviewed from multiple angles. Someone from sig-scheduling will catch scheduler complexity that a sig-node contributor might overlook, and vice versa. It slows down individual decisions slightly, but produces much more robust outcomes.&lt;/p&gt;
&lt;h2 id=&#34;current-focus-areas&#34;&gt;Current focus areas&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#current-focus-areas&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;With DRA now generally available, the working group’s focus has expanded to enable more advanced scheduling models, shared semantics, operational visibility, and support for increasingly complex hardware topologies.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NF: What are some of the key initiatives or deliverables the working group is currently focused on?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;KK:&lt;/strong&gt; We maintain a project board at &lt;a href=&#34;https://github.com/orgs/kubernetes/projects/95&#34;&gt;Kubernetes Project Board&lt;/a&gt; with real-time tracking of our initiatives and their progress.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;PO:&lt;/strong&gt; The scope and feature set of core DRA were intentionally limited to enable graduation to GA within a reasonable time. Additional KEPs add more features, on their own schedule. Those fall roughly into three categories:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Extend the expressiveness of DRA to support more complex devices and scheduling scenarios.&lt;/li&gt;
&lt;li&gt;Support &lt;em&gt;day two&lt;/em&gt; operations like health monitoring.&lt;/li&gt;
&lt;li&gt;Improve multi-node support, primarily by integrating with workload-aware scheduling.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In addition to the project board, we also maintain a table which summarizes all the &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/&#34;&gt;KEPs&lt;/a&gt; which are currently in flight. This is the status for 1.36; more are likely to be added for 1.37:&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;KEP&lt;/th&gt;
          &lt;th style=&#34;text-align: left&#34;&gt;Description&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;Release&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;strong&gt;1.32&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;strong&gt;1.33&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;strong&gt;1.34&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;strong&gt;1.35&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;strong&gt;1.36&lt;/strong&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;a href=&#34;https://www.kubernetes.dev/resources/keps/4381&#34;&gt;4381&lt;/a&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;DRA: Structured Parameters&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Beta&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Beta&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Stable&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5004&#34;&gt;5004&lt;/a&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;DRA: Extended Resource Requests via DRA&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Alpha&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Alpha&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Beta&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;a href=&#34;https://www.kubernetes.dev/resources/keps/4817&#34;&gt;4817&lt;/a&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;DRA: Resource Claim Status&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Alpha&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Beta&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Beta&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Beta&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Beta&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5018&#34;&gt;5018&lt;/a&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;DRA: Namespace Controlled Admin Access&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Alpha&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Beta&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Beta&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Stable&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5055&#34;&gt;5055&lt;/a&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;DRA: Device Taints and Tolerations&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Alpha&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Alpha&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Alpha&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Beta&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;a href=&#34;https://www.kubernetes.dev/resources/keps/4816&#34;&gt;4816&lt;/a&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;DRA: Prioritized Alternatives in Device Requests&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Alpha&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Beta&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Beta&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Stable&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5075&#34;&gt;5075&lt;/a&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;DRA: Consumable Capacity&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Alpha&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Alpha&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Beta&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;a href=&#34;https://www.kubernetes.dev/resources/keps/4815&#34;&gt;4815&lt;/a&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;DRA: Partitionable Devices&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Alpha&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Alpha&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Alpha&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Beta&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5304&#34;&gt;5304&lt;/a&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;DRA: Attributes Downward API&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Alpha&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5729&#34;&gt;5729&lt;/a&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;DRA: ResourceClaim Support for Workloads&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Alpha&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;a href=&#34;https://www.kubernetes.dev/resources/keps/4680&#34;&gt;4680&lt;/a&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;Resource Health Status in Pod Status&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Alpha&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Alpha&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Alpha&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Alpha&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Beta&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5517&#34;&gt;5517&lt;/a&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;DRA: Native Resource Requests&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Alpha&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5677&#34;&gt;5677&lt;/a&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;DRA: Resource Availability Visibility&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Alpha&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5007&#34;&gt;5007&lt;/a&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;DRA: Device Binding Conditions&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Alpha&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Alpha&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Beta&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;a href=&#34;https://www.kubernetes.dev/resources/keps/5491&#34;&gt;5491&lt;/a&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;DRA: List Types for Attributes&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Alpha&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;NF: One of the core challenges is efficient device utilization and sharing. What progress is being made in this area?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;JB:&lt;/strong&gt; Good question. One way to think about it is what we are doing in the two primary APIs: ResourceClaim and ResourceSlice.&lt;/p&gt;
&lt;p&gt;The ResourceClaim API is how the user asks for devices. We have built some features that allow the user to be more flexible in their requests. For example, instead of asking for a specific model of GPU, they can ask for a GPU with at least a certain amount of memory. Or they can ask for a list of alternatives: &amp;quot;I’d like one A100 (80GB) GPU, but if you don’t have it, I’ll take 2 A100 (40 GB) GPUs.&amp;quot; This gives the scheduler some options to satisfy the request, which can lead to better obtainability and utilization of hardware that otherwise would not be selected.&lt;/p&gt;
&lt;p&gt;The ResourceClaim API allows users to explicitly share devices. You can point multiple containers (in the same or different Pods) at a ResourceClaim; this allows the devices allocated by that claim to be used in all of those containers, &lt;em&gt;if the device supports it&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The ResourceSlice API is how vendors model and advertise their devices. This is where we implement support for other sharing models. For example, we have a way to represent &amp;quot;overlapping partitions&amp;quot;, enabling the scheduler to dynamically select a MIG partition, and make any overlapping MIG partitions unavailable automatically. This works well in combination with a request like “give me any GPU with 20GB or more of memory” - the scheduler can satisfy that with a MIG or a real GPU.&lt;/p&gt;
&lt;p&gt;Some features require changes in both. We have another sharing method we call “consumable capacity”. In the explicit sharing case described above, a user needs to point containers at the same ResourceClaim; there is one ResourceClaim shared amongst several containers and Pods. With consumable capacity, the device sharing works more like how Pods share a Node. The user creates a ResourceClaim that asks for a certain amount of resources, for example, “I need a NIC with 2Gbps of bandwidth”. The scheduler knows that there is a NIC with 40Gbps of bandwidth available, and so it allocates 2Gbps out of that 40Gbps and gives it to that ResourceClaim. In this case, each Pod has its own ResourceClaim, but the underlying device is shared between those claims. It’s up to the on-node DRA driver to properly set up the device for this sort of sharing (in the NIC case, likely by creating a subinterface). We call this “platform-mediated sharing” to differentiate it from the explicit &amp;quot;user-mediated sharing&amp;quot;.&lt;/p&gt;
&lt;h2 id=&#34;real-world-impact&#34;&gt;Real-world impact&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#real-world-impact&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;While much of the work is deeply technical, the underlying goal is practical: enabling Kubernetes to better support real-world AI/ML and hardware-intensive workloads at scale.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NF: What are the biggest challenges users face today when running hardware-intensive workloads (like AI/ML) on Kubernetes?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;PO:&lt;/strong&gt; Such workloads depart from traditional container workloads in several ways: they may consist of multiple communicating pods which all need to run at the same time (“gang scheduling”). They are often long-running and expensive to initialize, and their performance is sensitive to where they run (topology within a node and interconnects between nodes for multiple pods). The Kubernetes scheduler traditionally has not supported either of this well because it schedules one pod at a time and is unaware of the topology within a node. Several external schedulers try to fill this gap, which often isn’t ideal, in particular when the Kubernetes scheduler schedules other pods to the same cluster.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NF: How should platform engineers think about device management when designing their Kubernetes platforms?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;JB:&lt;/strong&gt; We’re still learning here, but one idea of DRA is to enable a shift to more &amp;quot;requirements driven&amp;quot; specifications. This can allow less coupling between end users that write the workload specification and the cluster administrators that set up the clusters. Instead of agreeing on labeling conventions and requiring users to understand the cluster topology, the users can specify what their workload needs, and the scheduler can figure out how to satisfy it. If we can make this work, it can make even complex workloads more portable across clusters.&lt;/p&gt;
&lt;h2 id=&#34;challenges-and-trade-offs&#34;&gt;Challenges and trade-offs&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#challenges-and-trade-offs&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;As with many areas of Kubernetes, increasing flexibility and expressiveness also introduces new layers of complexity, particularly around scheduling and optimization.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NF: What are some of the hardest technical challenges the working group is tackling today?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;PO:&lt;/strong&gt; There’s an inherent conflict between flexibility and scheduling complexity. The current implementation is focused on finding some solution that satisfies the requested resources, but it’s not necessarily the best one, whatever “best” means, which is also not always clear. The other big challenge is exposing node-allocatable resources (RAM, CPU) as devices with additional metadata; this is necessary to fine-tune scheduling of workloads which need perfect alignment on a node for optimal performance.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;JB:&lt;/strong&gt; Patrick’s list is good. Complex device modeling is hard, and making sure that we build the right semantics such that they apply to lots of different hardware is always tricky.&lt;/p&gt;
&lt;p&gt;On top of that, scheduling in general is very complex and is an NP-hard problem. All the metadata and flexibility DRA adds gives the scheduler more options, which has pros and cons. More options are helpful if you are constrained in your choices, as it means you can schedule something that you otherwise could not. But it also means it is even harder to find an optimal solution when there are many possibilities in a given cluster. DRA works well in our common use cases so far, but we have a lot of work to do to improve the optimality of the chosen scheduling solution and ensure the performance of making that choice.&lt;/p&gt;
&lt;h2 id=&#34;looking-ahead&#34;&gt;Looking ahead&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#looking-ahead&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Despite the challenges, contributors across the working group remain excited about the pace of innovation and the growing community forming around device management in Kubernetes.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NF: Looking ahead, what are you most excited about in the future of device management in Kubernetes?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;KK:&lt;/strong&gt; NVIDIA recently donated its DRA driver for GPUs to the Kubernetes project. I’m personally excited for more community members to start contributing to the project and defining its future direction.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;PO:&lt;/strong&gt; For me, it’s primarily the number of new contributors and people stepping up to help out. This poses new challenges around reviewing proposals and helping developers get those implemented and merged. It’s nice and rewarding to see others succeed, and it bodes well for the future because more people are familiar with the topic.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;JB:&lt;/strong&gt; I am excited about a lot of things. The community really has grown and has so many interesting features in the works to enable modeling of more complex devices, and to better model multi-node devices.&lt;/p&gt;
&lt;p&gt;I am really excited to see the creative ways people will use these APIs. They were primarily designed to address &amp;quot;devices&amp;quot;, but just like how &amp;quot;everything is a file&amp;quot; in Unix/Linux, the APIs themselves are quite flexible as to what they model. They really build out a more programmable scheduler, which can have interesting applications. For example, I recently prototyped using DRA to schedule pods to nodes where a large AI model is already locally cached. It’s really quite flexible, and I have great confidence in the creativity of our community, so I think we’ll see some unexpected solutions in the ecosystem.&lt;/p&gt;
&lt;h2 id=&#34;getting-involved&#34;&gt;Getting involved&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#getting-involved&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;NF: How can contributors get involved with the Device Management Working Group?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;KK:&lt;/strong&gt; The easiest first step is to join our mailing list at &lt;a href=&#34;mailto:wg-device-management@kubernetes.io&#34;&gt;wg-device-management@kubernetes.io&lt;/a&gt;. Subscribing will automatically add calendar invites for our biweekly meetings to your calendar.&lt;/p&gt;
&lt;p&gt;We have two meeting slots to accommodate different time zones:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Europe/Americas: Tuesdays at 8:30 AM PT (biweekly)&lt;/li&gt;
&lt;li&gt;Asia/Europe: Wednesdays at 9:00 AM CET (biweekly)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Meeting notes, agendas, and recordings are all publicly accessible (links available from &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/wg/device-management/#meetings&#34;&gt;Device Management page&lt;/a&gt;). You can get a feel for the work in progress before attending your first meeting.&lt;/p&gt;
&lt;p&gt;On Slack, find us in &lt;code&gt;#wg-device-management&lt;/code&gt; on the Kubernetes Slack workspace. That&#39;s the best place for quick questions or to introduce yourself.&lt;/p&gt;
&lt;p&gt;For more hands-on contributions, the DRA Driver for NVIDIA GPUs is now a community project and a great place to start. It&#39;s a real-world, production-grade implementation that the broader community is now shaping together.&lt;/p&gt;
&lt;p&gt;We welcome contributors at all levels – whether you&#39;re interested in the API design, the scheduler internals, driver development, or documentation. Come say hello.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#summary&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;As Kubernetes evolves to support the AI/ML revolution and high-performance computing, the work happening within WG Device Management is becoming the foundation for how modern workloads are scheduled and operated at scale.&lt;/p&gt;
&lt;p&gt;From the graduation of Dynamic Resource Allocation (DRA) to the next frontiers of health monitoring and topology-aware scheduling, this group is effectively rewriting the &amp;quot;handshake&amp;quot; between software and hardware.&lt;/p&gt;
&lt;p&gt;If you’re interested in shaping the future of hardware-aware orchestration, now is the perfect time to get involved. Whether you want to help refine the API, build out drivers, or improve documentation, the working group welcomes all levels of experience and perspectives from across the community.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Spotlight on SIG Storage</title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/06/15/sig-storage-spotlight-2026/</link>
      <pubDate>Mon, 15 Jun 2026 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/06/15/sig-storage-spotlight-2026/</guid>
      <description>
        
        
        &lt;p&gt;In our ongoing SIG Spotlight series, we shine a light on the groups that keep the Kubernetes project
moving forward. This time, we catch up with &lt;strong&gt;&lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-storage&#34;&gt;SIG
Storage&lt;/a&gt;&lt;/strong&gt;, the group responsible
for persistent data, volume management, and the interfaces that connect Kubernetes workloads to the
storage systems beneath them.&lt;/p&gt;
&lt;p&gt;We spoke with &lt;a href=&#34;https://github.com/xing-yang&#34;&gt;Xing Yang&lt;/a&gt;, Co-Chair of SIG Storage and Software
Engineer at VMware by Broadcom, about the SIG&#39;s history, the features shipping in recent Kubernetes
releases, and where storage in Kubernetes is headed as AI workloads become the norm.&lt;/p&gt;
&lt;h2 id=&#34;introductions&#34;&gt;Introductions&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#introductions&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Could you introduce yourself and share your role(s) within SIG Storage?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;My name is &lt;a href=&#34;https://github.com/xing-yang&#34;&gt;Xing Yang&lt;/a&gt;, a software engineer at VMware by Broadcom. I&#39;m a co-chair in SIG Storage,
alongside another co-chair &lt;a href=&#34;https://github.com/saad-ali&#34;&gt;Saad Ali&lt;/a&gt; from Google. There are also two Tech Leads in SIG Storage:
&lt;a href=&#34;https://github.com/msau42&#34;&gt;Michelle Au&lt;/a&gt; from Google and &lt;a href=&#34;https://github.com/jsafrane&#34;&gt;Jan Šafránek&lt;/a&gt; from Red Hat.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What first drew you to storage in Kubernetes, and how did you start contributing?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I have always been working in the storage domain, so SIG Storage was a natural place for me to get
started when I began to learn Kubernetes. I started attending &lt;a href=&#34;https://github.com/kubernetes/community/blob/main/sig-storage/README.md#meetings&#34;&gt;SIG Storage meetings&lt;/a&gt;, trying to figure
out what I could do to help. This was before the first &lt;a href=&#34;https://github.com/container-storage-interface/spec/blob/master/spec.md&#34;&gt;Container Storage Interface&lt;/a&gt; (CSI) release —
lots of things were still evolving. It was a very exciting time.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What subprojects or areas do you actively maintain or review today?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I&#39;m a maintainer in Kubernetes CSI. There are multiple CSI sidecars — such as &lt;code&gt;csi-provisioner&lt;/code&gt;,
&lt;code&gt;csi-attacher&lt;/code&gt;, &lt;code&gt;csi-resizer&lt;/code&gt;, and &lt;code&gt;csi-snapshotter&lt;/code&gt; — that we need to release following every
Kubernetes release. I&#39;m also a co-chair for a &lt;a href=&#34;https://github.com/kubernetes/community/blob/main/wg-data-protection/README.md&#34;&gt;Data Protection Working Group&lt;/a&gt; co-sponsored by SIG
Storage and &lt;a href=&#34;https://github.com/kubernetes/community/tree/main/sig-apps&#34;&gt;SIG Apps&lt;/a&gt;. Several features have come out of that WG aimed at filling gaps in data
protection support within Kubernetes. One is &lt;a href=&#34;https://kubernetes.io/docs/concepts/storage/volume-group-snapshots/&#34;&gt;Volume Group
Snapshot&lt;/a&gt;, which provides
crash-consistent group snapshots for multiple volumes used by an application. &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/3314&#34;&gt;Changed Block
Tracking&lt;/a&gt; (CBT) is another critical feature
from the DP WG designed to support efficient backups.&lt;/p&gt;
&lt;h2 id=&#34;about-sig-storage&#34;&gt;About SIG Storage&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#about-sig-storage&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;For folks who are new: what is SIG Storage, in your own words? What problems in Kubernetes are
you trying to solve?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;SIG Storage is a &lt;a href=&#34;https://github.com/kubernetes/community/blob/main/governance.md&#34;&gt;Special Interest Group&lt;/a&gt; focused on how to provide storage to containers running in
your Kubernetes cluster. We define standard interfaces so that a storage vendor can write a driver
and have its underlying storage system consumed by containers in Kubernetes.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why does Kubernetes need a dedicated storage SIG? What makes storage hard in a distributed
system?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;When Kubernetes was first introduced, it was meant for stateless workloads only. Container
applications were regarded as ephemeral and therefore did not need to persist data. However, that
changed drastically. Stateful workloads started running in Kubernetes, and we needed a dedicated
SIG to tackle the associated storage challenges. PersistentVolumeClaims, PersistentVolumes, and
StorageClasses were all introduced to provision data volumes for applications running in Kubernetes.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How did SIG Storage originally form, and how has its mission changed over time?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;SIG Storage was formed to address the challenges of handling persistent data within Kubernetes.
Initially, PersistentVolumes were implemented as in-tree plugins, and the SIG managed those plugins
while developing core storage primitives like PersistentVolumes and PersistentVolumeClaims.&lt;/p&gt;
&lt;p&gt;Container Storage Interface (CSI) was introduced later and played a crucial role in simplifying
storage integration, enabling third-party storage providers to develop and maintain their own
out-of-tree plugins without modifying Kubernetes core code.&lt;/p&gt;
&lt;p&gt;With basic integration addressed by CSI, the SIG&#39;s mission expanded to include advanced storage
features that leverage the new interface. The SIG has also expanded its scope to support object
storage through the &lt;a href=&#34;https://github.com/kubernetes-sigs/container-object-storage-interface&#34;&gt;Container Object Storage Interface&lt;/a&gt; (COSI).&lt;/p&gt;
&lt;h2 id=&#34;current-work-and-roadmap&#34;&gt;Current work and roadmap&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#current-work-and-roadmap&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;What are the top features SIG Storage is actively working on right now?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The Data Protection WG has been working on a couple of exciting features:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;VolumeGroupSnapshot&lt;/strong&gt; is a Kubernetes feature enabling a crash-consistent, point-in-time
snapshot of multiple PersistentVolumes simultaneously. This ensures data integrity for
applications — like databases — that rely on multiple volumes by capturing all volumes in the
group atomically, at the exact same point in time. It just moved to GA in Kubernetes v1.36.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;CSI Changed Block Tracking (CBT)&lt;/strong&gt; enables efficient, incremental backups. By allowing storage
systems to report only the blocks that have changed since the last snapshot, it significantly
reduces the amount of data that needs to be transferred. It just moved to Beta in Kubernetes v1.36.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Another feature worth highlighting is &lt;strong&gt;Container Object Storage Interface (COSI)&lt;/strong&gt;. COSI provides
a standard interface for provisioning and consuming object storage buckets in Kubernetes —
standardizing object storage for containerized applications much like CSI did for block and file
storage. COSI is now transitioning to &lt;code&gt;v1alpha2&lt;/code&gt;, with plans for promotion to Beta in a future
release.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What recent work from SIG Storage do you consider a &amp;quot;win&amp;quot; for users?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The graduation of &lt;a href=&#34;https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/&#34;&gt;VolumeAttributesClass&lt;/a&gt;
to GA in Kubernetes v1.34 is a major win for users managing stateful workloads. Previously,
changing volume attributes like IOPS or throughput required out-of-band actions or disruptive
operations. Now, users can dynamically tune storage properties such as IOPS or throughput directly
through the Kubernetes API — scaling up for peak loads or down to optimize costs — without external
processes or downtime.&lt;/p&gt;
&lt;p&gt;VolumeAttributesClass enables dynamic modification of storage characteristics without recreating
the volume. This completes the picture by allowing users to tune both capacity and other storage
properties dynamically, just as they can now tune both CPU and memory for compute.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Looking ahead one or two releases, what&#39;s on the roadmap that people should watch for?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I&#39;d like to draw attention to the &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/1432&#34;&gt;Volume Health&lt;/a&gt; feature. This feature is designed to offer
critical visibility into the operational status and integrity of persistent volumes. By enabling
storage drivers and the Kubernetes control plane to report issues, it allows for proactive
monitoring and identification of volume-related problems.&lt;/p&gt;
&lt;p&gt;Currently, volume health information is reported via non-persistent events. We are actively
investigating enhancements to this feature with the goal of supporting automated remediation
capabilities in the future.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Are there areas where you&#39;d really like more discussion or help from the community?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;We always need help from the community to fix bugs, add tests, and help with reviews.&lt;/p&gt;
&lt;p&gt;We&#39;d also like to get feedback on the Alpha feature &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/4762&#34;&gt;Mutable PV
Affinity&lt;/a&gt;, which was introduced in
Kubernetes v1.35. Use cases include migrating volumes from zonal to regional storage or migrating
from one disk type to another.&lt;/p&gt;
&lt;p&gt;Another topic is &lt;strong&gt;volume replication&lt;/strong&gt;. It was raised at &lt;a href=&#34;https://www.cncf.io/reports/kubecon-cloudnativecon-north-america-2025/&#34;&gt;KubeCon Atlanta&lt;/a&gt; and has been discussed
in the Data Protection WG. Community members interested in this topic are encouraged to join the DP
WG meetings.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What are the biggest challenges users face today when running stateful workloads on Kubernetes?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;While Kubernetes has moved stateful workloads — like databases and AI pipelines — into the
mainstream, managing &amp;quot;state&amp;quot; in a system designed for ephemerality remains difficult:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Data Gravity and Storage Locality&lt;/strong&gt;: Pods move in seconds, but data has gravity. If a node
fails, a pod using local storage is stuck. Operators must decide whether the failure is transient
or permanent — a high-stakes call. This is why we are enhancing the Volume Health feature to
provide the visibility needed to automate recovery choices.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Day 2 Complexity&lt;/strong&gt;: Setting up a database is easy; maintaining its health over time is the real
challenge. Standard Kubernetes objects like StatefulSets offer a baseline, but they lack the
operational logic needed for tasks such as schema upgrades, engine patching, or cluster-wide
Kubernetes upgrades.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Data Mobility&lt;/strong&gt;: Moving persistent data remains a significant hurdle — whether migrating between
storage tiers, shifting workloads across availability zones, or moving to a different cluster.
This challenge includes ongoing synchronization and replication for high availability and disaster
recovery across a distributed system.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;storage-and-ai&#34;&gt;Storage and AI&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#storage-and-ai&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;How do you see storage evolving in Kubernetes over the next few years, especially as AI/ML
workloads grow?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I see several trends shaping storage in Kubernetes as it evolves from a container orchestrator into
the &amp;quot;Operating System&amp;quot; for AI:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;More Intelligent Data Management&lt;/strong&gt;: We&#39;ll see a shift toward smarter CSI drivers and data
management tools offering advanced features like automatic tiering, snapshots, migration, and
replication — optimized specifically for high-performance AI/ML workflows and large data
platforms.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Object Storage as a First-Class Citizen&lt;/strong&gt;: AI datasets now frequently reach exabyte scale,
making object storage the preferred choice for AI workloads. COSI is standardizing bucket
management just as CSI did for disks, allowing data scientists to use a BucketClaim to
provision S3-compatible storage natively and unifying object, file, and block storage into a
single workflow.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Performance and Low Latency&lt;/strong&gt;: For AI/ML, storage needs to keep up with GPU processing speeds.
This will accelerate adoption of high-performance parallel file systems and NVMe-over-Fabrics
(NVMe-oF) technologies managed natively via Kubernetes. The line between traditional block/file
and memory-speed storage will continue to blur.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Data-Aware Scheduling&lt;/strong&gt;: Instead of just considering CPU and RAM, the Kubernetes scheduler will
increasingly prioritize placing Pods based on data locality — calculating the cost of moving data
versus moving compute to keep massive data platforms performant.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;SIG Storage continues to tackle some of the hardest problems in Kubernetes: keeping stateful
applications running reliably, making storage operations transparent and composable, and now
scaling up to meet the demands of AI-era workloads. Whether you&#39;re a user managing databases in
production or a developer curious about storage internals, there&#39;s a place for you in SIG Storage.&lt;/p&gt;
&lt;p&gt;If you&#39;d like to get involved, check out the &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/storage/&#34;&gt;SIG Storage community
page&lt;/a&gt; and join the &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-storage#meetings&#34;&gt;bi-weekly
meetings&lt;/a&gt;. You can also
find the SIG on Slack at
&lt;a href=&#34;https://kubernetes.slack.com/messages/sig-storage&#34;&gt;#sig-storage&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://groups.google.com/a/kubernetes.io/g/sig-storage&#34;&gt;SIG Storage Mailing List&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kubernetes.slack.com/messages/sig-storage&#34;&gt;SIG Storage on Slack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/community/blob/master/wg-data-protection/README.md&#34;&gt;Data Protection WG&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>From Kubernetes Dashboard to Headlamp: Understanding the Transition</title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/06/01/dashboard-to-headlamp/</link>
      <pubDate>Mon, 01 Jun 2026 10:00:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/06/01/dashboard-to-headlamp/</guid>
      <description>
        
        
        &lt;p&gt;For many people, Kubernetes Dashboard was their first window into Kubernetes. It offered a simple visual way to see what was running in a cluster, inspect resources, and build confidence without relying on the command line. For years, it helped developers, students, and operators make sense of Kubernetes, and it served as an important onramp into the ecosystem.&lt;/p&gt;
&lt;p&gt;The Kubernetes Dashboard project has now been archived. We deeply respect the work the team did and the role Dashboard played in making Kubernetes more approachable for so many users.&lt;/p&gt;
&lt;p&gt;Headlamp builds on that foundation and carries it forward. It keeps the clarity of a visual interface while adding capabilities that match how Kubernetes is used today. This includes multi-cluster visibility, application-centric views, extensibility through plugins, and flexible deployment options that work both in-cluster and on the desktop.&lt;/p&gt;
&lt;p&gt;This guide is meant to help you navigate that transition with confidence. Before diving into the mechanics of migration, we start with familiar ground by looking at how common Kubernetes Dashboard workflows map to Headlamp. We also cover what stays the same and what improves after the switch. The goal is not just to replace a tool, but to honor a user-centered legacy and help you land in a UI that can grow with you as your Kubernetes usage evolves.&lt;/p&gt;
&lt;h2 id=&#34;mapping-kubernetes-dashboard-workloads-to-headlamp&#34;&gt;Mapping Kubernetes Dashboard workloads to Headlamp&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#mapping-kubernetes-dashboard-workloads-to-headlamp&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;If you have used Kubernetes Dashboard before, many workflows in Headlamp will feel familiar. Headlamp does not introduce a new way of thinking. Instead, it builds on workloads users already know and extends them in practical ways. The focus is continuity. What worked before still works, with more room to grow.&lt;/p&gt;
&lt;h3 id=&#34;viewing-workloads-and-resources&#34;&gt;Viewing workloads and resources&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#viewing-workloads-and-resources&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;In Kubernetes Dashboard, most users started by browsing workloads like pods, deployments, services, and namespaces. Headlamp keeps this same starting point. Workloads are easy to find and inspect, and moving between namespaces and clusters is simpler. Resources are still organized in familiar ways, and navigation feels smoother, especially when you work across multiple environments.&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/06/01/dashboard-to-headlamp/view-workloads-resources-2.png&#34;
         alt=&#34;Viewing Kubernetes workloads and resources in the Headlamp interface&#34;/&gt; 
&lt;/figure&gt;
&lt;h3 id=&#34;editing-and-interacting-with-resources&#34;&gt;Editing and interacting with resources&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#editing-and-interacting-with-resources&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Like Kubernetes Dashboard, Headlamp lets you view and edit manifests directly in the UI based on your permissions. You can delete resources, scale workloads, or update configurations from the interface. All actions follow standard Kubernetes RBAC. If you could perform an action in Dashboard, you will find the same capability in Headlamp, with the same respect for access controls.&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/06/01/dashboard-to-headlamp/editing-interacting-resources.png&#34;
         alt=&#34;Editing and interacting with Kubernetes resources in the Headlamp user interface&#34;/&gt; 
&lt;/figure&gt;
&lt;h3 id=&#34;understanding-relationships&#34;&gt;Understanding relationships&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#understanding-relationships&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Where Headlamp begins to expand the experience is in how it presents relationships between resources. In addition to list views, Headlamp offers visual ways to see how workloads, services, and configurations connect. This helps provide context without changing the underlying workloads users already rely on.&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/06/01/dashboard-to-headlamp/understanding-relationships.png&#34;
         alt=&#34;Visualizing relationships between Kubernetes workloads and services in Headlamp&#34;/&gt; 
&lt;/figure&gt;
&lt;p&gt;At a high level, the tasks you performed in Kubernetes Dashboard are still there. Headlamp keeps familiar workflows while making it easier to scale as clusters, teams, and applications grow.&lt;/p&gt;
&lt;h2 id=&#34;where-headlamp-goes-beyond-kubernetes-dashboard&#34;&gt;Where Headlamp goes beyond Kubernetes Dashboard&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#where-headlamp-goes-beyond-kubernetes-dashboard&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;h3 id=&#34;expanding-from-single-cluster-to-multi-cluster-workflows&#34;&gt;Expanding from single cluster to multi-cluster workflows&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#expanding-from-single-cluster-to-multi-cluster-workflows&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Kubernetes Dashboard was designed to work with one cluster at a time. That model worked well for simple setups, but it became limiting as teams adopted multiple environments. Headlamp expands this view by letting you work with multiple clusters from a single interface without switching tools or losing context. This makes it easier to manage development, staging, and production environments side by side.&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/06/01/dashboard-to-headlamp/expanding-multicluster.png&#34;
         alt=&#34;Expanding from single cluster to multi-cluster workflows using Headlamp&#34;/&gt; 
&lt;/figure&gt;
&lt;p&gt;For teams running Kubernetes in more than one place, this shift reduces friction. You can stay oriented and move between clusters with confidence.&lt;/p&gt;
&lt;h3 id=&#34;from-resource-lists-to-application-context-with-projects&#34;&gt;From resource lists to application context with Projects&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#from-resource-lists-to-application-context-with-projects&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Projects give you an application-centered way to view Kubernetes. Instead of jumping between lists, you can group related workloads, services, and supporting resources in one place. This makes applications easier to understand. You can see what belongs together, track changes in context, and troubleshoot without scanning the cluster piece by piece.&lt;/p&gt;
&lt;p&gt;Projects are built on native Kubernetes concepts. Namespaces, labels, and RBAC continue to work the same way they always have. Headlamp adds a visual layer that brings related resources together.&lt;/p&gt;
&lt;p&gt;Projects are optional. You can still work at the individual resource level when that fits your task. When you need more context, Projects help you step back and see the bigger picture.&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/06/01/dashboard-to-headlamp/application-projects.png&#34;
         alt=&#34;Application Projects view in Headlamp grouping related Kubernetes resources&#34;/&gt; 
&lt;/figure&gt;
&lt;h3 id=&#34;plugins&#34;&gt;Extend the Headlamp UI with plugins&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#plugins&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Headlamp can be extended through plugins that bring common workflows directly into the UI. Instead of switching tools, you work in one place with the same context.&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/06/01/dashboard-to-headlamp/add-plugin-catalog.png&#34;
         alt=&#34;Adding plugins from the plugin catalog in the Headlamp interface&#34;/&gt; 
&lt;/figure&gt;
&lt;p&gt;For example, the Flux plugin brings GitOps workflows into Headlamp. It allows teams to view application state alongside the Kubernetes resources that Flux manages, making it easier to understand how changes in Git relate to what is running in the cluster.&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/06/01/dashboard-to-headlamp/add-gitops.png&#34;
         alt=&#34;Viewing and managing GitOps resources in Headlamp using the Flux plugin&#34;/&gt; 
&lt;/figure&gt;
&lt;p&gt;The AI Assistant follows a similar pattern. It adds a conversational layer to the UI that helps users understand what they are seeing, troubleshoot issues, or take action. All of this happens in the same screen where the problem appears.&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/06/01/dashboard-to-headlamp/add-ai-assistant.png&#34;
         alt=&#34;Using the AI assistant in Headlamp to understand and troubleshoot Kubernetes resources&#34;/&gt; 
&lt;/figure&gt;
&lt;h3 id=&#34;building-your-own-plugins&#34;&gt;Building your own plugins&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#building-your-own-plugins&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Plugins are optional and not limited to community-built extensions. Platform and project teams can also create their own plugins. This allows organizations to add custom integrations that match their specific workflows and internal tooling, while keeping the user experience consistent.&lt;/p&gt;
&lt;h2 id=&#34;choosing-how-and-where-headlamp-runs&#34;&gt;Choosing how and where Headlamp runs&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#choosing-how-and-where-headlamp-runs&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Headlamp gives teams flexibility in how they use a Kubernetes UI. You can run it directly in a cluster, use it as a desktop application, or combine both approaches based on your needs.&lt;/p&gt;
&lt;p&gt;Running Headlamp in-cluster works well for shared environments. It provides a centrally managed UI with controlled access and fits naturally into Kubernetes setups, following the same authentication and RBAC rules as other in-cluster components.&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/06/01/dashboard-to-headlamp/browser-app.png&#34;
         alt=&#34;Running Headlamp as an in-cluster browser-based application&#34;/&gt; 
&lt;/figure&gt;
&lt;p&gt;The desktop application is often a better fit for local development and onboarding. It also works well when you need to manage multiple clusters from one place. Users can connect using their existing kubeconfig without deploying anything into the cluster.&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/06/01/dashboard-to-headlamp/desktop-app.png&#34;
         alt=&#34;Using Headlamp as a desktop application to manage Kubernetes clusters locally&#34;/&gt; 
&lt;/figure&gt;
&lt;p&gt;These options are not mutually exclusive. Many teams use the desktop app for day-to-day work, while relying on an in-cluster deployment for shared or production environments.&lt;/p&gt;
&lt;h2 id=&#34;preparing-for-the-migration&#34;&gt;Preparing for the Migration&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#preparing-for-the-migration&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Before moving from Kubernetes Dashboard to Headlamp, it can be helpful to pause and take stock of how you use the Dashboard today. A little reflection up front can go a long way toward making the transition feel smooth and familiar.&lt;/p&gt;
&lt;p&gt;Start by noting which clusters and namespaces you access and how authentication works. Headlamp relies on standard Kubernetes authentication and RBAC. In most cases, existing access models carry over without change. If users already connect using kubeconfig files or service accounts, they will be able to access the same resources in Headlamp.&lt;/p&gt;
&lt;p&gt;It is also useful to think about the workflows that matter most to your team. Some users rely on Dashboard for quick inspection or troubleshooting, while others use it for lightweight edits or validation. Headlamp supports these same workflows and adds optional capabilities on top. Knowing what you rely on today helps the transition feel predictable and confidence building.&lt;/p&gt;
&lt;p&gt;If you would like to explore Headlamp or try it out before migrating, you can learn more at &lt;a href=&#34;https://headlamp.dev&#34;&gt;headlamp.dev&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This blog focused on understanding the transition and what to expect. A step by step migration guide is coming soon and will walk through installation and migration in detail.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Reconciling the Past: Correcting Records for Unfixed Kubernetes CVEs</title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/05/26/reconciling-unfixed-kubernetes-cves/</link>
      <pubDate>Tue, 26 May 2026 09:30:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/05/26/reconciling-unfixed-kubernetes-cves/</guid>
      <description>
        
        
        &lt;p&gt;The Kubernetes project relies on transparency to empower cluster administrators and security
researchers. One important way we do that is by publishing CVE records into the Common
Vulnerabilities and Exposures database. As part of our ongoing effort to mature the official
&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/reference/issues-security/official-cve-feed/index.json&#34;&gt;Kubernetes CVE Feed&lt;/a&gt;, we have identified
some discrepancies. CVE records for a few older, unfixed issues incorrectly include a
&lt;em&gt;fixed version&lt;/em&gt; field.&lt;/p&gt;
&lt;p&gt;The Kubernetes Security Response Committee (SRC) will correct the affected CVE records on June 1, 2026.
This may result in vulnerability scanners identifying these vulnerabilities in places where
they were previously not detected.&lt;/p&gt;
&lt;p&gt;To help reduce confusion, this post provides a technical update on three vulnerabilities that
were disclosed in previous years but remain unfixed: &lt;strong&gt;CVE-2020-8561&lt;/strong&gt;, &lt;strong&gt;CVE-2020-8562&lt;/strong&gt;,
and &lt;strong&gt;CVE-2021-25740&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&#34;why-we-are-updating-these-records-now&#34;&gt;Why we are updating these records now&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#why-we-are-updating-these-records-now&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;While these vulnerabilities have been public for several years, the recent work to generate
official Open Source Vulnerabilities (OSV) files revealed that their corresponding CVE records
did not accurately reflect their status. Specifically, some records suggested a &lt;em&gt;fixed&lt;/em&gt; version
existed, when in reality, these issues are architectural design trade-offs that cannot be
fully remediated through code without breaking fundamental Kubernetes functionality.&lt;/p&gt;
&lt;p&gt;Correcting these records is vital for the community for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Automation Fidelity&lt;/strong&gt;: Modern vulnerability scanners depend on precise version ranges. Inaccurate &lt;em&gt;fixed&lt;/em&gt; tags lead to false negatives, giving users a false sense of security.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Risk Documentation&lt;/strong&gt;: By formalizing these as &lt;em&gt;unfixed&lt;/em&gt;, we ensure that platform providers and administrators are aware of the persistent need for administrative mitigations.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For completeness, we should also mention that
&lt;a href=&#34;https://www.cve.org/cverecord?id=CVE-2020-8554&#34;&gt;CVE-2020-8554&lt;/a&gt; is an unfixed CVE with a
correct CVE record stating that it affects all versions. That record will also be updated to
use a more-standardized version number format.&lt;/p&gt;
&lt;h2 id=&#34;technical-analysis-of-unfixed-architectural-risks&#34;&gt;Technical analysis of unfixed architectural risks&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#technical-analysis-of-unfixed-architectural-risks&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The following vulnerabilities will not be fixed by the Kubernetes project. GitHub issues remain
the best reference for the technical mechanics of these flaws.&lt;/p&gt;
&lt;h3 id=&#34;cve-2020-8561-webhook-redirect-in-kube-apiserver&#34;&gt;&lt;a href=&#34;https://github.com/kubernetes/kubernetes/issues/104720&#34;&gt;CVE-2020-8561&lt;/a&gt;: Webhook redirect in kube-apiserver&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#cve-2020-8561-webhook-redirect-in-kube-apiserver&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Severity&lt;/strong&gt;: Medium (4.1).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Issue&lt;/strong&gt;: The kube-apiserver follows HTTP redirects when communicating with admission webhooks.
An actor capable of configuring an AdmissionWebhookConfiguration can redirect API server requests to internal, private networks.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Why it remains unfixed&lt;/strong&gt;: Restricting this behavior would require breaking the standard HTTP client behavior
that many legitimate integrations rely on.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mitigation&lt;/strong&gt;: Set the API server log level to less than 10 (to prevent logging response bodies) and disable
dynamic profiling (&lt;code&gt;--profiling=false&lt;/code&gt;) to prevent unauthorized log-level changes.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;cve-2020-8562-proxy-bypass-via-dns-toctou&#34;&gt;&lt;a href=&#34;https://github.com/kubernetes/kubernetes/issues/101493&#34;&gt;CVE-2020-8562&lt;/a&gt;: Proxy bypass via DNS TOCTOU&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#cve-2020-8562-proxy-bypass-via-dns-toctou&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Severity&lt;/strong&gt;: Low (3.1).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Issue&lt;/strong&gt;: A Time-of-Check to Time-of-Use (TOCTOU) race condition in the API server proxy allows users
to bypass IP restrictions. The system performs a DNS check to validate an IP, but then performs a second
resolution for the actual connection, which an attacker can manipulate.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Why it remains unfixed&lt;/strong&gt;: Fixing this requires pinning resolved IPs in a way that breaks complex
split-horizon DNS or dynamic IP environments.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mitigation&lt;/strong&gt;: Use a local DNS caching server like dnsmasq for the API server and configure &lt;code&gt;min-cache-ttl&lt;/code&gt;
to enforce consistent responses between the check and the connection.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;cve-2021-25740-cross-namespace-forwarding-via-endpoints&#34;&gt;&lt;a href=&#34;https://github.com/kubernetes/kubernetes/issues/103675&#34;&gt;CVE-2021-25740&lt;/a&gt;: Cross-namespace forwarding via Endpoints&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#cve-2021-25740-cross-namespace-forwarding-via-endpoints&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Severity&lt;/strong&gt;: Low (3.1).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Issue&lt;/strong&gt;: A design flaw in the Endpoints and EndpointSlice API objects allows users to manually specify
IP addresses, which can be used to point a LoadBalancer or Ingress toward backends in other namespaces.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Why it remains unfixed&lt;/strong&gt;: This is a fundamental feature of the Endpoints API used by many networking tools
and operators.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mitigation&lt;/strong&gt;: Restrict write access to Endpoints (legacy) and EndpointSlices. Since Kubernetes 1.22,
Kubernetes RBAC authorization mode no longer includes those permissions in the default &lt;em&gt;edit&lt;/em&gt; and &lt;em&gt;admin&lt;/em&gt;
ClusterRoles. That removal applies to clusters created using Kubernetes v1.22; for clusters upgraded from
older versions, administrators should manually audit and reconcile the &lt;code&gt;system:aggregate-to-edit&lt;/code&gt; ClusterRole.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&#34;alert alert-info&#34; role=&#34;note&#34;&gt;&lt;h4 class=&#34;alert-heading&#34;&gt;Note:&lt;/h4&gt;On June 1, 2026, these CVE records will be updated to correctly reflect the fact that all versions are affected.
You may see them begin to appear in vulnerability scanner results.&lt;/div&gt;

&lt;h2 id=&#34;required-actions-for-administrators&#34;&gt;Required actions for administrators&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#required-actions-for-administrators&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The Kubernetes project recommends a &lt;em&gt;secure by configuration&lt;/em&gt; approach to manage these persistent risks:&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th style=&#34;text-align: left&#34;&gt;Vulnerability&lt;/th&gt;
          &lt;th style=&#34;text-align: left&#34;&gt;Action item&lt;/th&gt;
          &lt;th style=&#34;text-align: left&#34;&gt;Severity score (Rating)&lt;/th&gt;
          &lt;th style=&#34;text-align: left&#34;&gt;Command / configuration&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;&lt;strong&gt;CVE-2020-8561&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;Restrict Log Verbosity&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;4.1 (Medium)&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;Ensure &lt;code&gt;--v&lt;/code&gt; is set to &lt;code&gt;&amp;lt; 10&lt;/code&gt; and &lt;code&gt;--profiling=false&lt;/code&gt;.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;&lt;strong&gt;CVE-2020-8562&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;Enforce DNS Consistency&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;3.1 (Low)&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;Deploy dnsmasq or a similar caching resolver on control plane nodes.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;&lt;strong&gt;CVE-2021-25740&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;Hardened RBAC&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;3.1 (Low)&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;kubectl auth reconcile&lt;/code&gt; to remove Endpoints write access from broad roles.&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The RBAC action for CVE-2021-25740 applies when your cluster uses RBAC authorization mode,
which is the default for clusters created with standard Kubernetes tooling. Administrators
should independently test and validate these configurations in a non-production environment,
assessing the architectural risks against their specific threat model and risk tolerance.&lt;/p&gt;
&lt;h2 id=&#34;conclusion-maturity-through-transparency&#34;&gt;Conclusion: maturity through transparency&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#conclusion-maturity-through-transparency&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The effort to reconcile these records is a sign of a maturing security ecosystem. By moving away
from the &amp;quot;patch-only&amp;quot; mindset and accurately documenting architectural debt, the Kubernetes
project provides the community with the high-fidelity data needed to secure modern cloud
native infrastructure.&lt;/p&gt;
&lt;p&gt;We would like to thank the security researchers—QiQi Xu, Javier Provecho, and others—who
identified these risks, and the SIG Security Tooling contributors who continue to refine our
official feeds. Special shoutout to Rory McCune for sharing information around these CVEs
through his blog posts.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Update 2026/06/01: Today, the Kubernetes SRC has updated the CVE records for CVE-2020-8554, CVE-2020-8561, CVE-2020-8562, and CVE-2021-25740.&lt;/em&gt;&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Announcing etcd 3.7.0-beta.0</title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/05/20/etcd-370-beta/</link>
      <pubDate>Wed, 20 May 2026 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/05/20/etcd-370-beta/</guid>
      <description>
        
        
        &lt;p&gt;SIG-Etcd announces the availability of the &lt;a href=&#34;https://github.com/etcd-io/etcd/releases/tag/v3.7.0-beta.0&#34;&gt;first beta release of etcd v3.7.0&lt;/a&gt;.  This new version of the popular distributed database and key Kubernetes component includes the long-requested RangeStream feature, as well as a refactoring and cleanup of multiple legacy components and interfaces.  v3.7 will deliver improved security, better operational reliability, and an improved experience for working with large resultsets.&lt;/p&gt;
&lt;p&gt;First, however, the project needs users to test the beta.  You can find v3.7.0-beta.0 here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/etcd-io/etcd/archive/refs/tags/v3.7.0-beta.0.tar.gz&#34;&gt;Source code&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/etcd-io/etcd/releases/download/v3.7.0-beta.0/etcd-v3.7.0-beta.0-linux-arm64.tar.gz&#34;&gt;Binaries&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://console.cloud.google.com/artifacts/docker/etcd-development/us/gcr.io/etcd/sha256:b121286da5bfd4de3596e436e449da44e5a31314a6eb19780a6fc477410c8dfa&#34;&gt;Official container images&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Please try it out and report issues &lt;a href=&#34;https://github.com/etcd-io/etcd/issues&#34;&gt;in the etcd repo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This beta also determines the EOL of version 3.4.&lt;/p&gt;
&lt;h2 id=&#34;rangestream&#34;&gt;RangeStream&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#rangestream&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;In etcd v3.6 and earlier, it is challenging to work with requests that return large resultsets.  The client or requesting application is forced to wait for the full result set, leading to unpredictable latency and memory usage.  &lt;a href=&#34;https://github.com/kubernetes/enhancements/tree/master/keps/sig-etcd/5966-etcd-range-stream&#34;&gt;The RangeStream RPC&lt;/a&gt; lets calling applications accept result sets in chunks, reducing latency and making buffering memory usage more predictable.&lt;/p&gt;
&lt;p&gt;Much of the work on RangeStream was done by a relatively new contributor to etcd, &lt;a href=&#34;https://github.com/jefftree&#34;&gt;Jeffrey Ying&lt;/a&gt;, a software engineer at Google.  New contributors can have a substantial impact on etcd development.&lt;/p&gt;
&lt;p&gt;&amp;quot;I&#39;ve always been fascinated by database internals, and building RangeStream was a great opportunity to solve a bottleneck we were hitting in production with Kubernetes. It was the perfect opportunity to collaborate across projects and improve the ecosystem as a whole. Jumping into etcd as a new contributor had a bit of a learning curve, but the community is incredibly welcoming. The leads were very receptive to my ideas and helped me iterate quickly, while maintaining the project&#39;s high bar for reliability and code quality,&amp;quot; said Jeffrey.&lt;/p&gt;
&lt;p&gt;Instructions on how to use RangeStream &lt;a href=&#34;https://etcd.io/docs/v3.7/learning/api/#rangestream&#34;&gt;in gRPC calls&lt;/a&gt; and &lt;a href=&#34;https://etcd.io/docs/v3.7/dev-guide/interacting_v3/#read-keys&#34;&gt;in etcdctl&lt;/a&gt; can be found in the etcd documentation. Users should try it out for their own applications.&lt;/p&gt;
&lt;h2 id=&#34;removal-of-v2store&#34;&gt;Removal of v2store&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#removal-of-v2store&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The last vestiges of etcd v2store have been removed in v3.7, making this the first release that is 100% on v3store.  This includes &lt;a href=&#34;https://github.com/etcd-io/etcd/pull/20109&#34;&gt;discovery&lt;/a&gt;, &lt;a href=&#34;https://github.com/etcd-io/etcd/issues/20187&#34;&gt;bootstrap&lt;/a&gt;, &lt;a href=&#34;https://github.com/etcd-io/etcd/pull/21263&#34;&gt;v2 requests&lt;/a&gt;, and the &lt;a href=&#34;https://github.com/etcd-io/etcd/pull/20117&#34;&gt;v2 client&lt;/a&gt;.  Our team has also removed multiple &lt;a href=&#34;https://github.com/etcd-io/etcd/pull/19959&#34;&gt;deprecated experimental flags&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;All of these changes may create some breakage for users, particularly those who have not already updated to v3.6.11. We are interested in hearing about blockers encountered by users and dependent applications; please report anything you find that can&#39;t be remedied or needs better upgrade documentation.&lt;/p&gt;
&lt;p&gt;etcd v3.7.0-beta.0 also includes &lt;a href=&#34;https://github.com/etcd-io/bbolt/issues/1190&#34;&gt;bbolt v1.5.0&lt;/a&gt; and &lt;a href=&#34;https://github.com/etcd-io/raft/issues/409&#34;&gt;raft v3.7.0&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;3-4-eol&#34;&gt;3.4 EOL&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#3-4-eol&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;According to our community &lt;a href=&#34;https://etcd.io/docs/v3.7/op-guide/versioning/&#34;&gt;support policy&lt;/a&gt;, we typically maintain only the latest two minor versions, currently v3.6 and v3.5. Etcd v3.5 will be supported for 1 year after v3.7.0 final release.&lt;/p&gt;
&lt;p&gt;As mentioned in &lt;a href=&#34;https://etcd.io/blog/2025/announcing-etcd-3.6/#extended-support-for-v34&#34;&gt;extended support for v3.4&lt;/a&gt; in the etcd v3.6.0 release announcement, etcd v3.4 has been EOL since May 15, 2026. SIG-etcd may release one more security patch for that version at the end of May, if warranted by patched vulnerabilities. In any case, it will cease being updated after the end of May. Users on v3.4 should be planning &lt;a href=&#34;https://etcd.io/docs/v3.6/upgrades/upgrade_3_5/&#34;&gt;to upgrade their clusters&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;feedback-and-future-betas&#34;&gt;Feedback and Future Betas&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#feedback-and-future-betas&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Reach the etcd contributors with your feedback about v3.7.0-beta.0 in any of the following places:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/etcd-io/etcd/issues&#34;&gt;Github issues&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kubernetes.slack.com/archives/C3HD8ARJ5&#34;&gt;#SIG-etcd slack channel&lt;/a&gt; in &lt;a href=&#34;https://www.kubernetes.dev/docs/comms/slack/#joining-slack&#34;&gt;Kubernetes Slack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://groups.google.com/g/etcd-dev&#34;&gt;etcd-dev mailing list&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;SIG-etcd may release additional betas of version v3.7.0 with additional refactoring, particularly of our use of protobuf libraries.  Release candidates and the final release will probably happen through June, possibly into early July.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes v1.36: New Metric for Route Sync in the Cloud Controller Manager</title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/05/15/ccm-new-metric-route-sync-total/</link>
      <pubDate>Fri, 15 May 2026 10:35:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/05/15/ccm-new-metric-route-sync-total/</guid>
      <description>
        
        
        &lt;p&gt;&lt;em&gt;This article was originally published with the wrong date. It was later republished, dated the 15th of
May 2026.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Kubernetes v1.36 introduces a new alpha counter metric &lt;code&gt;route_controller_route_sync_total&lt;/code&gt;
to the Cloud Controller Manager (CCM) route controller implementation at
&lt;a href=&#34;https://github.com/kubernetes/cloud-provider&#34;&gt;&lt;code&gt;k8s.io/cloud-provider&lt;/code&gt;&lt;/a&gt;. This metric
increments each time routes are synced with the cloud provider.&lt;/p&gt;
&lt;h2 id=&#34;a-b-testing-watch-based-route-reconciliation&#34;&gt;A/B testing watch-based route reconciliation&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#a-b-testing-watch-based-route-reconciliation&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;This metric was added to help operators validate the
&lt;code&gt;CloudControllerManagerWatchBasedRoutesReconciliation&lt;/code&gt; feature gate introduced in
&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2025/12/30/kubernetes-v1-35-watch-based-route-reconciliation-in-ccm/&#34;&gt;Kubernetes v1.35&lt;/a&gt;.
That feature gate switches the route controller from a fixed-interval loop to a watch-based
approach that only reconciles when nodes actually change. This reduces unnecessary API calls
to the infrastructure provider, lowering pressure on rate-limited APIs and allowing operators
to make more efficient use of their available quota.&lt;/p&gt;
&lt;p&gt;To A/B test this, compare &lt;code&gt;route_controller_route_sync_total&lt;/code&gt; with the feature gate
disabled (default) versus enabled. In clusters where node changes are infrequent, you should
see a significant drop in the sync rate with the feature gate turned on.&lt;/p&gt;
&lt;h3 id=&#34;example-expected-behavior&#34;&gt;Example: expected behavior&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#example-expected-behavior&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;With the feature gate disabled&lt;/strong&gt; (the default fixed-interval loop), the counter increments
steadily regardless of whether any node changes occurred:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# After 10 minutes with no node changes
route_controller_route_sync_total 60
# After 20 minutes, still no node changes
route_controller_route_sync_total 120
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;With the feature gate enabled&lt;/strong&gt; (watch-based reconciliation), the counter only increments
when nodes are actually added, removed, or updated:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# After 10 minutes with no node changes
route_controller_route_sync_total 1
# After 20 minutes, still no node changes — counter unchanged
route_controller_route_sync_total 1
# A new node joins the cluster — counter increments
route_controller_route_sync_total 2
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The difference is especially visible in stable clusters where nodes rarely change.&lt;/p&gt;
&lt;h2 id=&#34;where-can-i-give-feedback&#34;&gt;Where can I give feedback?&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#where-can-i-give-feedback&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;If you have feedback, feel free to reach out through any of the following channels:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;a href=&#34;https://kubernetes.slack.com/messages/sig-cloud-provider&#34;&gt;#sig-cloud-provider&lt;/a&gt; channel on &lt;a href=&#34;https://slack.k8s.io/&#34;&gt;Kubernetes Slack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;The &lt;a href=&#34;https://kep.k8s.io/5237&#34;&gt;KEP-5237 issue&lt;/a&gt; on GitHub&lt;/li&gt;
&lt;li&gt;The &lt;a href=&#34;https://github.com/kubernetes/community/tree/05223ecbd2d6f960edb40684dc83d053d49f8b68/sig-cloud-provider&#34;&gt;SIG Cloud Provider community page&lt;/a&gt; for other communication channels&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;how-can-i-learn-more&#34;&gt;How can I learn more?&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#how-can-i-learn-more&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;For more details, refer to &lt;a href=&#34;https://kep.k8s.io/5237&#34;&gt;KEP-5237&lt;/a&gt;.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes v1.36: Mixed Version Proxy Graduates to Beta </title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/05/15/kubernetes-1-36-feature-mixed-version-proxy-beta/</link>
      <pubDate>Fri, 15 May 2026 10:00:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/05/15/kubernetes-1-36-feature-mixed-version-proxy-beta/</guid>
      <description>
        
        
        &lt;p&gt;Back in Kubernetes 1.28, we introduced the &lt;code&gt;Mixed Version Proxy (MVP)&lt;/code&gt; as an Alpha feature (under the feature gate &lt;code&gt;UnknownVersionInteroperabilityProxy&lt;/code&gt;) in a &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2023/08/28/kubernetes-1-28-feature-mixed-version-proxy-alpha/&#34;&gt;previous blog post&lt;/a&gt;. The goal was simple but critical: make cluster upgrades safer by ensuring that requests for resources not yet known to an older API server are correctly routed to a newer peer API server, instead of returning an incorrect &lt;code&gt;404 Not Found&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;We are excited to announce that the Mixed Version Proxy is moving to Beta in Kubernetes 1.36 and will be enabled by default! The feature has evolved significantly since its initial release, addressing key gaps and modernizing its architecture.&lt;/p&gt;
&lt;p&gt;Here is a look at how the feature has evolved and what you need to know to leverage it in your clusters.&lt;/p&gt;
&lt;h2 id=&#34;what-problem-are-we-solving&#34;&gt;What problem are we solving?&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#what-problem-are-we-solving&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;In a highly available control plane undergoing an upgrade, you often have API servers running different versions. These servers might serve different sets of APIs (Groups, Versions, Resources).
Without MVP, if a client request lands on an API server that does not serve the requested resource (e.g., a new API version introduced in the upgrade), that server returns a &lt;code&gt;404 Not Found&lt;/code&gt;. This is technically incorrect because the resource is available in the cluster, just not on that specific server. This can lead to serious side effects, such as mistaken garbage collection or blocked namespace deletions.
MVP solves this by proxying the request to a peer API server that can serve it.&lt;/p&gt;


&lt;pre class=&#34;mermaid&#34;&gt;
sequenceDiagram
    participant Client
    participant API_Server_A as API Server A (Older/Different)
    participant API_Server_B as API Server B (Newer/Capable)
    
    Client-&gt;&gt;API_Server_A: 1. Request for Resource (e.g., v2)
    Note over API_Server_A: Determines it cannot serve locally
    API_Server_A-&gt;&gt;API_Server_A: 2. Looks up capable peer in Discovery Cache
    API_Server_A-&gt;&gt;API_Server_B: 3. Proxies request (adds x-kubernetes-peer-proxied header)
    API_Server_B-&gt;&gt;API_Server_B: 4. Processes request locally
    API_Server_B--&gt;&gt;API_Server_A: 5. Returns Response
    API_Server_A--&gt;&gt;Client: 6. Forwards Response
&lt;/pre&gt;

&lt;h2 id=&#34;how-has-it-evolved-since-1-28&#34;&gt;How has it evolved since 1.28&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#how-has-it-evolved-since-1-28&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The initial Alpha implementation was a great proof of concept, but it had some limitations and relied on older mechanisms. Here is how we have modernized it for Beta:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;From StorageVersion API to Aggregated Discovery
In the Alpha version, API servers relied on the &lt;code&gt;StorageVersion API&lt;/code&gt; to figure out which peers served which resources. While functional, this approach had a significant limitation: the &lt;code&gt;StorageVersion API&lt;/code&gt; is not yet supported for CRDs and aggregated APIs.
For Beta, we have replaced the reliance on &lt;code&gt;StorageVersion API&lt;/code&gt; calls with the use of &lt;code&gt;Aggregated Discovery&lt;/code&gt;. API servers now use the aggregated discovery data to dynamically understand the capabilities of their peers.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The Missing Piece: Peer-Aggregated Discovery
The &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2023/08/28/kubernetes-1-28-feature-mixed-version-proxy-alpha/&#34;&gt;1.28 blog post&lt;/a&gt; noted a significant gap: while we could proxy resource requests, discovery requests still only showed what the local API server knew about.
In 1.36, we have added &lt;code&gt;Peer-Aggregated Discovery&lt;/code&gt; support! Now, when a client performs discovery (e.g., listing available APIs), the API server merges its local view with the discovery data from all active peers. This provides clients with a complete, unified view of all APIs available across the entire cluster, regardless of which API server they connected to.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;


&lt;pre class=&#34;mermaid&#34;&gt;
sequenceDiagram
    participant Client
    participant API_Server_A as API Server A
    participant API_Server_B as API Server B
    
    Client-&gt;&gt;API_Server_A: 1. Request Discovery Document
    API_Server_A-&gt;&gt;API_Server_A: 2. Gets Local APIs
    API_Server_A-&gt;&gt;API_Server_B: 3. Gets Peer APIs (Cached or Direct)
    API_Server_A-&gt;&gt;API_Server_A: 4. Merges and sorts lists deterministically
    API_Server_A--&gt;&gt;Client: 5. Returns Unified Discovery Document
&lt;/pre&gt;

&lt;p&gt;While peer-aggregated discovery will be the default behavior (note that peer-aggregated discovery is enabled if the &lt;code&gt;--peer-ca-file&lt;/code&gt; flag is set, otherwise the server will fallback to showing only its local APIs), there may be cases where you need to inspect only the resources served by the specific API server you are connected to. You can request this non-aggregated view by including the &lt;code&gt;profile=nopeer&lt;/code&gt; parameter in your request&#39;s &lt;code&gt;Accept&lt;/code&gt; header (e.g., &lt;code&gt;Accept: application/json;g=apidiscovery.k8s.io;v=v2;as=APIGroupDiscoveryList;profile=nopeer&lt;/code&gt;).&lt;/p&gt;
&lt;h2 id=&#34;required-configuration&#34;&gt;Required configuration&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#required-configuration&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;While the feature gate will be enabled by default, it requires certain flags to be set to allow for secure communication between peer API servers. To function correctly, make sure your API server is configured with the following flags:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--feature-gates=UnknownVersionInteroperabilityProxy=true&lt;/code&gt;: This will be default in 1.36, but it is good to verify&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--peer-ca-file=&amp;lt;path-to-ca&amp;gt;&lt;/code&gt;: [CRITICAL] This is a required flag. You must provide the CA bundle that the source API server will use to authenticate the serving certificates of destination peer API servers. Without this, proxying will fail due to TLS verification errors.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--peer-advertise-ip&lt;/code&gt; and &lt;code&gt;--peer-advertise-port&lt;/code&gt;: These flags are used to set the network address that peers should use to reach this API server. If unset, the values from &lt;code&gt;--advertise-address&lt;/code&gt; or &lt;code&gt;--bind-address&lt;/code&gt; are used. If you have complex network topologies where API servers communicate over a specific internal interface, setting these flags explicitly is highly recommended.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;configuring-with-kubeadm&#34;&gt;Configuring with &lt;code&gt;kubeadm&lt;/code&gt;&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#configuring-with-kubeadm&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;If you manage your cluster with &lt;code&gt;kubeadm&lt;/code&gt;, you can configure these flags in your &lt;code&gt;ClusterConfiguration&lt;/code&gt; file:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;kubeadm.k8s.io/v1beta4&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ClusterConfiguration&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;apiServer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;extraArgs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;peer-ca-file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;/etc/kubernetes/pki/ca.crt&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# peer-advertise-ip and port if needed&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;call-to-action&#34;&gt;Call to action&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#call-to-action&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;If you are running multi-master clusters and upgrading them regularly, the Mixed Version Proxy is a major safety improvement. With it becoming default in 1.36, we encourage you to:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Review your API server flags to ensure &lt;code&gt;--peer-ca-file&lt;/code&gt; is set properly.&lt;/li&gt;
&lt;li&gt;Test the feature in your staging environments as you prepare for the 1.36 upgrade.&lt;/li&gt;
&lt;li&gt;Provide feedback to SIG API Machinery (&lt;a href=&#34;https://kubernetes.slack.com/messages/sig-api-machinery/&#34;&gt;Slack&lt;/a&gt;, &lt;a href=&#34;https://groups.google.com/g/kubernetes-sig-api-machinery&#34;&gt;mailing list&lt;/a&gt;, or by &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-api-machinery#meetings&#34;&gt;attending SIG API Machinery meetings&lt;/a&gt;) on your experience.&lt;/li&gt;
&lt;/ol&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes v1.36: Deprecation and removal of Service ExternalIPs</title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/05/14/kubernetes-v1-36-deprecation-and-removal-of-service-externalips/</link>
      <pubDate>Thu, 14 May 2026 10:35:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/05/14/kubernetes-v1-36-deprecation-and-removal-of-service-externalips/</guid>
      <description>
        
        
        &lt;p&gt;The &lt;code&gt;.spec.externalIPs&lt;/code&gt; field for &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/services-networking/service/&#34;&gt;Service&lt;/a&gt; was an early attempt to provide
cloud-load-balancer-like functionality for non-cloud clusters.
Unfortunately, the API assumes that every user in the cluster is fully
trusted, and in any situation where that is not the case, it enables
various security exploits, as described in
&lt;a href=&#34;https://www.cvedetails.com/cve/CVE-2020-8554/&#34;&gt;CVE-2020-8554&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Since Kubernetes 1.21, the Kubernetes project has recommended that all users disable
&lt;code&gt;.spec.externalIPs&lt;/code&gt;. To make that easier, Kubernetes also added an admission controller
(&lt;code&gt;DenyServiceExternalIPs&lt;/code&gt;) that can be enabled to do this. At the time,
SIG Network felt that blocking the functionality by default was too large a
breaking change to consider.&lt;/p&gt;
&lt;p&gt;However, the security problems are still there, and as a project we&#39;re increasingly
unhappy with the &amp;quot;insecure by default&amp;quot; state of the feature.
Additionally, there are now several better alternatives for non-cloud
clusters wanting load-balancer-like functionality.&lt;/p&gt;
&lt;p&gt;As a result, the &lt;code&gt;.spec.externalIPs&lt;/code&gt; field for Service is now formally deprecated in Kubernetes 1.36.
We expect that a future minor release of Kubernetes will drop
implementation of the behavior from &lt;code&gt;kube-proxy&lt;/code&gt;, and will update the
Kubernetes &lt;a href=&#34;https://www.cncf.io/training/certification/software-conformance/&#34;&gt;conformance&lt;/a&gt; criteria to require that conforming implementations
&lt;strong&gt;do not&lt;/strong&gt; provide support.&lt;/p&gt;
&lt;h2 id=&#34;terminology&#34;&gt;A note on terminology, and what hasn&#39;t been deprecated&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#terminology&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The phrase &lt;em&gt;external IP&lt;/em&gt; is somewhat overloaded in Kubernetes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The Service API has a field &lt;code&gt;.spec.externalIPs&lt;/code&gt; that can be used
to add additional IP addresses that a Service will respond on.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The Node API&#39;s &lt;code&gt;.status.addresses&lt;/code&gt; field can list addresses of
several different types, one of which is called &lt;code&gt;ExternalIP&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;kubectl&lt;/code&gt; tool, when displaying information about a Service of type
LoadBalancer in the default output format, will show the load
balancer IP address under the column heading &lt;code&gt;EXTERNAL-IP&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This deprecation is about the first of those. If you are not setting
the field &lt;code&gt;externalIPs&lt;/code&gt; in any of your Services, then it does not
apply to you.&lt;/p&gt;
&lt;p&gt;That said, as a precaution, you may still want to enable the &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/reference/access-authn-authz/admission-controllers/#denyserviceexternalips&#34;&gt;DenyServiceExternalIPs&lt;/a&gt; admission controller to
block any future use of the &lt;code&gt;externalIPs&lt;/code&gt; field.&lt;/p&gt;
&lt;h2 id=&#34;alternatives&#34;&gt;Alternatives to &lt;code&gt;externalIPs&lt;/code&gt;&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#alternatives&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;If you are using &lt;code&gt;.spec.externalIPs&lt;/code&gt;, then there are several alternatives.&lt;/p&gt;
&lt;p&gt;Consider a Service like the following:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Service&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;my-example-service&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ClusterIP&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;selector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;app.kubernetes.io/name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;my-example-app&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ports&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;protocol&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;TCP&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;port&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;80&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;targetPort&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;8080&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;externalIPs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;s2&#34;&gt;&amp;#34;192.0.2.4&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;alternative-LoadBalancer&#34;&gt;Using manually-managed LoadBalancer Services instead of &lt;code&gt;externalIPs&lt;/code&gt;&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#alternative-LoadBalancer&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The easiest (but also worst) option is to just switch from using
&lt;code&gt;externalIPs&lt;/code&gt; to using a &lt;code&gt;type: LoadBalancer&lt;/code&gt; service, and assigning a
load balancer IP by hand. This is, essentially, exactly the same as
&lt;code&gt;externalIPs&lt;/code&gt;, with one important difference: the load balancer IP is
part of the Service&#39;s &lt;code&gt;.status&lt;/code&gt;, not its &lt;code&gt;.spec&lt;/code&gt;, and in a cluster
with RBAC enabled, it can&#39;t be edited by ordinary users by default.
Thus, this replacement for &lt;code&gt;externalIPs&lt;/code&gt; would only be available to
users who were given permission by the admins (although those users
would then be fully empowered to replicate CVE-2020-8554; there would
still not be any further checks to ensure that one user wasn&#39;t
stealing another user&#39;s IPs, etc.)&lt;/p&gt;
&lt;p&gt;Because of the way that &lt;code&gt;.status&lt;/code&gt; works in Kubernetes, you must create the
Service without a load balancer IP, and then add the IP as a second step:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gp&#34;&gt;$&lt;/span&gt; cat loadbalancer-service.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;go&#34;&gt;apiVersion: v1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;go&#34;&gt;kind: Service
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;go&#34;&gt;metadata:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;go&#34;&gt;  name: my-example-service
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;go&#34;&gt;spec:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;go&#34;&gt;  # prevent any real load balancer controllers from managing this service
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;go&#34;&gt;  # by using a non-existent loadBalancerClass
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;go&#34;&gt;  loadBalancerClass: non-existent-class
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;go&#34;&gt;  type: LoadBalancer
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;go&#34;&gt;  selector:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;go&#34;&gt;    app.kubernetes.io/name: my-example-app
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;go&#34;&gt;  ports:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;go&#34;&gt;    - protocol: TCP
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;go&#34;&gt;      port: 80
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;go&#34;&gt;      targetPort: 8080
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;go&#34;&gt;&lt;/span&gt;&lt;span class=&#34;gp&#34;&gt;$&lt;/span&gt; kubectl apply -f loadbalancer-service.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;go&#34;&gt;service/my-example-service created
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;go&#34;&gt;&lt;/span&gt;&lt;span class=&#34;gp&#34;&gt;$&lt;/span&gt; kubectl patch service my-example-service --subresource&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;status --type&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;merge -p &lt;span class=&#34;s1&#34;&gt;&amp;#39;{&amp;#34;status&amp;#34;:{&amp;#34;loadBalancer&amp;#34;:{&amp;#34;ingress&amp;#34;:[{&amp;#34;ip&amp;#34;:&amp;#34;192.0.2.4&amp;#34;}]}}}&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;alternative-load-balancer-controller&#34;&gt;Using a non-cloud based load balancer controller&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#alternative-load-balancer-controller&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Although &lt;code&gt;LoadBalancer&lt;/code&gt; services were originally designed to be backed by
cloud load balancers, Kubernetes can also support them on non-cloud platforms
by using a third-party load balancer controller such as &lt;a href=&#34;https://metallb.io/&#34;&gt;MetalLB&lt;/a&gt;.
This solves the security problems associated with &lt;code&gt;externalIPs&lt;/code&gt; because the
administrator can configure what ranges of IP addresses the controller will assign
to services, and the controller will ensure that two services can&#39;t both use the same
IP.&lt;/p&gt;
&lt;p&gt;So, for example, after &lt;a href=&#34;https://metallb.io/installation/&#34;&gt;installing&lt;/a&gt; and
&lt;a href=&#34;https://metallb.io/configuration/&#34;&gt;configuring&lt;/a&gt; MetalLB, a cluster administrator
could configure a pool of IP addresses for use in the cluster:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;metallb.io/v1beta1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;IPAddressPool&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;production&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;namespace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;metallb-system&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;addresses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;m&#34;&gt;192.0.2.0&lt;/span&gt;&lt;span class=&#34;l&#34;&gt;/24&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;autoAssign&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;avoidBuggyIPs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;After which a user can create a &lt;code&gt;type: LoadBalancer&lt;/code&gt; Service and MetalLB will handle the
assignment of the IP address. MetalLB even supports the deprecated &lt;code&gt;loadBalancerIP&lt;/code&gt;
field in Service, so the end user can request a specific IP (assuming it is available)
for backward-compatibility with the &lt;code&gt;externalIPs&lt;/code&gt; approach, rather than being
assigned one at random:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Service&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;my-example-service&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;LoadBalancer&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;selector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;app.kubernetes.io/name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;my-example-app&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ports&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;protocol&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;TCP&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;port&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;80&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;targetPort&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;8080&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;loadBalancerIP&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;192.0.2.4&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Similar approaches would work with other load balancer controllers.
This approach can allow cluster administrators to have control over which IP addresses are assigned,
rather than users.&lt;/p&gt;
&lt;h3 id=&#34;alternative-gateway-api&#34;&gt;Using Gateway API&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#alternative-gateway-api&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Another potential solution is to use an implementation of the
&lt;a href=&#34;https://gateway-api.sigs.k8s.io/&#34;&gt;Gateway API&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Gateway API allows cluster administrators to define a Gateway resource, which can have an IP address
attached to it via the &lt;code&gt;.spec.addresses&lt;/code&gt; field. Since Gateway resources are designed to be managed by
&lt;a href=&#34;https://gateway-api.sigs.k8s.io/concepts/security/&#34;&gt;cluster administrators&lt;/a&gt;, RBAC rules can be put in place to only allow privileged users to manage them.&lt;/p&gt;
&lt;p&gt;An example of how this could look is:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;gateway.networking.k8s.io/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Gateway&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;example-gateway&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;gatewayClassName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;example-gateway-class&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;addresses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;IPAddress&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;192.0.2.4&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;gateway.networking.k8s.io/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;HTTPRoute&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;example-route&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;parentRefs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;example-gateway&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;rules&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;backendRefs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;example-svc&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;port&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;80&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Service&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;example-svc&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ClusterIP&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;selector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;app.kubernetes.io/name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;example-app&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ports&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;protocol&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;TCP&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;port&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;80&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;targetPort&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;8080&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The Gateway API project is the next generation of Kubernetes Ingress, Load Balancing, and Service Mesh APIs within Kubernetes.
Gateway API was designed to fix the shortcomings of the Service and Ingress resource, making it a very reliable robust solution
that is under active development.&lt;/p&gt;
&lt;h2 id=&#34;timeline-for-externalips-deprecation&#34;&gt;Timeline for &lt;code&gt;externalIPs&lt;/code&gt; deprecation&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#timeline-for-externalips-deprecation&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The rough timeline for this deprecation is as follows:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;With the release of Kubernetes 1.36, the field was deprecated;
Kubernetes now emits &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2020/09/03/warnings/&#34;&gt;warnings&lt;/a&gt; when a user uses this field&lt;/li&gt;
&lt;li&gt;About a year later (v1.40 at the earliest) support for &lt;code&gt;.spec.externalIPs&lt;/code&gt; will be disabled in kube-proxy, but users will have a way to opt back in should they require more time to migrate away&lt;/li&gt;
&lt;li&gt;About another year later - (v1.43 at the earliest) support will be disabled completely; users won&#39;t have a way to opt back in&lt;/li&gt;
&lt;/ol&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes v1.36: Advancing Workload-Aware Scheduling</title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/05/13/kubernetes-v1-36-advancing-workload-aware-scheduling/</link>
      <pubDate>Wed, 13 May 2026 10:35:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/05/13/kubernetes-v1-36-advancing-workload-aware-scheduling/</guid>
      <description>
        
        
        &lt;p&gt;AI/ML and batch workloads introduce unique scheduling challenges that go beyond simple Pod-by-Pod scheduling.
In Kubernetes v1.35, we introduced the first tranche of &lt;em&gt;workload-aware scheduling&lt;/em&gt; improvements,
featuring the foundational Workload API alongside basic &lt;em&gt;gang scheduling&lt;/em&gt; support built on a Pod-based framework,
and an &lt;em&gt;opportunistic batching&lt;/em&gt; feature to efficiently process identical Pods.&lt;/p&gt;
&lt;p&gt;Kubernetes v1.36 introduces a significant architectural evolution by cleanly separating API concerns:
the Workload API acts as a static template, while the new PodGroup API handles the runtime state.
To support this, the &lt;code&gt;kube-scheduler&lt;/code&gt; features a new &lt;em&gt;PodGroup scheduling cycle&lt;/em&gt; that enables atomic workload processing
and paves the way for future enhancements. This release also debuts the first iterations of &lt;em&gt;topology-aware scheduling&lt;/em&gt;
and &lt;em&gt;workload-aware preemption&lt;/em&gt; to advance scheduling capabilities. Additionally,
&lt;em&gt;ResourceClaim support for workloads&lt;/em&gt; unlocks &lt;em&gt;Dynamic Resource Allocation
(&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/scheduling-eviction/dynamic-resource-allocation/&#34;&gt;DRA&lt;/a&gt;)&lt;/em&gt; for PodGroups. Finally,
to demonstrate real-world readiness, v1.36 delivers the first phase of integration between the Job controller and the new API.&lt;/p&gt;
&lt;h2 id=&#34;workload-and-podgroup-api-updates&#34;&gt;Workload and PodGroup API updates&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#workload-and-podgroup-api-updates&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The Workload API now serves as a static template, while the new PodGroup API describes the runtime object.
Kubernetes v1.36 introduces the Workload and PodGroup APIs as part of the
&lt;code&gt;scheduling.k8s.io/v1alpha2&lt;/code&gt; &lt;a class=&#39;glossary-tooltip&#39; title=&#39;A set of related paths in the Kubernetes API.&#39; data-bs-toggle=&#39;tooltip&#39; data-bs-placement=&#39;top&#39; href=&#39;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/overview/kubernetes-api/#api-groups-and-versioning&#39; target=&#39;_blank&#39; aria-label=&#39;API group&#39;&gt;API group&lt;/a&gt;,
completely replacing the previous &lt;code&gt;v1alpha1&lt;/code&gt; API version.&lt;/p&gt;
&lt;p&gt;In v1.35, Pod groups and their runtime states were embedded within the Workload resource.
The new model decouples these concepts: the Workload now serves as a static template object,
while the PodGroup manages the runtime state. This separation also improves performance and scalability
as the PodGroup API allows per-replica sharding of status updates.&lt;/p&gt;
&lt;p&gt;Because the Workload API acts merely as a template, the &lt;code&gt;kube-scheduler&lt;/code&gt;&#39;s logic is streamlined.
The scheduler can directly read the PodGroup, which contains all the information required by the scheduler,
without needing to watch or parse the Workload object itself.&lt;/p&gt;
&lt;p&gt;Here is what the updated configuration looks like. Workload controllers (such as the Job controller)
define the Workload object, which now acts as a static template for your Pod groups:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;scheduling.k8s.io/v1alpha2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Workload&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;training-job-workload&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;namespace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;some-ns&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# Pod groups are now defined as templates,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# which contains the PodGroup objects&amp;#39; spec fields.&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;podGroupTemplates&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;workers&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;schedulingPolicy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;gang&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# The gang is schedulable only if 4 pods can run at once&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;minCount&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Controllers then stamp out runtime PodGroup instances based on those templates.
The PodGroup runtime object holds the actual scheduling policy and references the template from which it was created.
It also has a status containing conditions that mirror the states of individual Pods,
reflecting the overall scheduling state of the group:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;scheduling.k8s.io/v1alpha2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;PodGroup&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;training-job-workers-pg&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;namespace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;some-ns&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# The PodGroup references the Workload template it originated from.&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# In comparison, .metadata.ownerReferences points to the &amp;#34;true&amp;#34; workload object,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# e.g., a Job. &lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;podGroupTemplateRef&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;workload&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;workloadName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;training-job-workload&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;podGroupTemplateName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;workers&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# The actual scheduling policy is placed inside the runtime PodGroup&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;schedulingPolicy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;gang&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;minCount&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;status&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# The status contains conditions mirroring individual Pod conditions.&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;conditions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;PodGroupScheduled&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;status&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;True&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;lastTransitionTime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;ld&#34;&gt;2026-04-03T00:00:00Z&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Finally, to bridge this new architecture with individual Pods, the &lt;code&gt;workloadRef&lt;/code&gt; field in the Pod API has been replaced
with the &lt;code&gt;schedulingGroup&lt;/code&gt; field. When creating Pods, you link them directly to the runtime PodGroup:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Pod&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;worker-0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;namespace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;some-ns&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# The workloadRef field has been replaced by schedulingGroup&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;schedulingGroup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;podGroupName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;training-job-workers-pg&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;...&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;By keeping the Workload as a static template and elevating the PodGroup to a first-class, standalone API,
we establish a robust foundation for building advanced workload scheduling capabilities in future Kubernetes releases.&lt;/p&gt;
&lt;h2 id=&#34;podgroup-scheduling-cycle-and-gang-scheduling&#34;&gt;PodGroup scheduling cycle and gang scheduling&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#podgroup-scheduling-cycle-and-gang-scheduling&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;To efficiently manage these workloads, the kube-scheduler now features a dedicated &lt;em&gt;PodGroup scheduling cycle&lt;/em&gt;.
Instead of evaluating and reserving resources sequentially Pod-by-Pod, which risks scheduling deadlocks,
the scheduler evaluates the group as a unified operation.&lt;/p&gt;
&lt;p&gt;When the scheduler pops a PodGroup member from the scheduling queue, regardless of the group&#39;s specific policy,
it fetches the rest of the queued Pods for that group, sorts them deterministically,
and executes an atomic scheduling cycle as follows:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;The scheduler takes a single snapshot of the cluster state to prevent race conditions and ensure consistency
while evaluating the entire group.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;It then attempts to find valid Node placements for all Pods in the group using a PodGroup scheduling algorithm,
which leverages the standard Pod-based filtering and scoring phases.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Based on the algorithm&#39;s outcome, the scheduling decision is applied atomically for the entire PodGroup.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Success: If the placement is found and group constraints are met, the schedulable member Pods
are moved directly to the binding phase together. Any remaining unschedulable Pods are returned
to the scheduling queue to wait for available resources so they can join the already scheduled Pods.&lt;/p&gt;
&lt;p&gt;(Note: If new Pods are added to a PodGroup after others are already scheduled,
the cycle evaluates the new Pods while accounting for the existing ones.
Crucially, Pods already assigned to Nodes remain running. The scheduler will not unassign
or evict them, even if the group fails to meet its requirements in subsequent cycles.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Failure: If the group fails to meet its requirements, the entire group is considered unschedulable.
None of the Pods are bound, and they are returned to the scheduling queue to retry later after a backoff period.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This cycle acts as the foundation for &lt;em&gt;gang scheduling&lt;/em&gt;. When your workload requires strict &lt;em&gt;all-or-nothing&lt;/em&gt; placement,
the &lt;code&gt;gang&lt;/code&gt; policy leverages this cycle to prevent partial deployments that lead to resource wastage and potential deadlocks.&lt;/p&gt;
&lt;p&gt;While the scheduler still holds the Pods in the &lt;code&gt;PreEnqueue&lt;/code&gt; until the &lt;code&gt;minCount&lt;/code&gt; requirement is met, the actual scheduling phase now relies entirely
on the new PodGroup cycle. Specifically, during the algorithm&#39;s execution, the scheduler verifies
that the number of schedulable Pods satisfies the &lt;code&gt;minCount&lt;/code&gt;. If the cluster cannot accommodate the required minimum,
none of the pods are bound. The group fails and waits for sufficient resources to free up.&lt;/p&gt;
&lt;h3 id=&#34;limitations&#34;&gt;Limitations&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#limitations&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The first version of the PodGroup scheduling cycle comes with certain limitations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;For basic &lt;em&gt;homogeneous&lt;/em&gt; Pod groups (i.e., those where all Pods have identical scheduling requirements
and lack inter-Pod dependencies like affinity, anti-affinity, or topology spread constraints),
the algorithm is expected to find a placement if one exists.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;For &lt;em&gt;heterogeneous&lt;/em&gt; Pod groups, finding a valid placement if one exists is not guaranteed,
even when the solution might seem trivial.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;For Pod groups with &lt;em&gt;inter-Pod dependencies&lt;/em&gt;, finding a valid placement if one exists is not guaranteed.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In addition to the above, for cases involving &lt;em&gt;intra-group dependencies&lt;/em&gt;
(e.g., when the schedulability of one Pod depends on another group member via inter-Pod affinity),
this algorithm may fail to find a placement regardless of cluster state due to its deterministic processing order.&lt;/p&gt;
&lt;h2 id=&#34;topology-aware-scheduling&#34;&gt;Topology-aware scheduling&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#topology-aware-scheduling&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;For complex distributed workloads like AI/ML training or batch processing, placing Pods randomly across a cluster
can introduce significant network latency and bottleneck overall performance.&lt;/p&gt;
&lt;p&gt;Topology-aware scheduling addresses this problem by allowing you to define topology constraints directly on a PodGroup,
ensuring its Pods are co-located within specific physical or logical domains:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;scheduling.k8s.io/v1alpha2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;PodGroup&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;topology-aware-workers-pg&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;schedulingPolicy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;gang&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;minCount&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# Enforce that the pods are co-located based on the rack topology&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;schedulingConstraints&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;topology&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;topology.kubernetes.io/rack&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In this example, the &lt;code&gt;kube-scheduler&lt;/code&gt; attempts to schedule the Pods across various combinations of Nodes
that match the &lt;code&gt;rack&lt;/code&gt; topology constraint. It then selects the optimal placement based on how efficiently
the PodGroup utilizes resources and how many Pods can successfully be scheduled within that domain.&lt;/p&gt;
&lt;p&gt;To achieve this, the scheduler extends the PodGroup scheduling cycle with a dedicated placement-based algorithm
consisting of three phases:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Generate candidate placements (subsets of Nodes that are theoretically feasible for the PodGroup&#39;s assignment)
based on the group&#39;s scheduling constraints. The topology-aware scheduling plugin uses the new &lt;code&gt;PlacementGenerate&lt;/code&gt;
extension point to create these placements.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Evaluate each proposed placement to confirm whether the entire PodGroup can actually fit there.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Score all feasible placements to select the best fit for the PodGroup. The topology-aware scheduling plugins
use the new &lt;code&gt;PlacementScore&lt;/code&gt; extension point to score these placements.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Currently, topology-aware scheduling does not trigger Pod preemption to satisfy constraints.
However, we plan to integrate workload-aware preemption with topology constraints in the upcoming release.&lt;/p&gt;
&lt;p&gt;While Kubernetes v1.36 delivers this foundational topology-aware scheduling, the Kubernetes project is planning
expand its capabilities soon. Future updates will introduce support for multiple topology levels,
soft constraints (preferences), deeper integration with Dynamic Resource Allocation (DRA),
and more robust behavior when paired with the &lt;code&gt;basic&lt;/code&gt; scheduling policy.&lt;/p&gt;
&lt;h2 id=&#34;workload-aware-preemption&#34;&gt;Workload-aware preemption&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#workload-aware-preemption&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;To support the new PodGroup scheduling cycle, Kubernetes v1.36 introduces a new type of preemption mechanism
called &lt;em&gt;workload-aware preemption&lt;/em&gt;. When a PodGroup cannot be scheduled, the scheduler utilizes this mechanism
to try making a scheduling of this PodGroup possible.&lt;/p&gt;
&lt;p&gt;Compared to the default preemption used in the standard Pod-by-Pod scheduling cycle, this new mechanism
treats the entire PodGroup as a single preemptor unit. Instead of evaluating preemption victims on each Node separately,
it searches across the entire cluster. This allows the scheduler to preempt Pods from multiple Nodes simultaneously,
making enough space to schedule the whole PodGroup afterwards.&lt;/p&gt;
&lt;p&gt;Workload-aware preemption also introduces two additional concepts directly to the PodGroup API:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;PodGroup &lt;code&gt;priority&lt;/code&gt; that overrides the priority of the individual Pods forming the PodGroup.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;PodGroup &lt;code&gt;disruptionMode&lt;/code&gt; that dictates whether the Pods within a PodGroup can be preempted independently,
or if they have to be preempted together in an &lt;em&gt;all-or-nothing&lt;/em&gt; fashion.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In Kubernetes v1.36, these fields are only respected by the workload-aware preemption mechanism.
The people working on this set of features are hoping to extend support for these fields
to other disruption sources, including default preemption used in the Pod-by-Pod scheduling cycle, in future releases.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;scheduling.k8s.io/v1alpha2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;PodGroup&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;victim-pg&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;priorityClassName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;high-priority&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;priority&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1000&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;disruptionMode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;PodGroup&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In this example, when the scheduler evaluates &lt;code&gt;victim-pg&lt;/code&gt; as a potential preemption victim
during a workload-aware preemption cycle, it will use 1000 as its priority and preempt the PodGroup
in a strictly &lt;em&gt;all-or-nothing&lt;/em&gt; fashion.&lt;/p&gt;
&lt;h2 id=&#34;dra-resourceclaim-support-for-workloads&#34;&gt;DRA ResourceClaim support for workloads&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#dra-resourceclaim-support-for-workloads&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Since its general availability in Kubernetes v1.34, &lt;a class=&#39;glossary-tooltip&#39; title=&#39;A Kubernetes feature for requesting and sharing resources, like hardware accelerators, among Pods.&#39; data-bs-toggle=&#39;tooltip&#39; data-bs-placement=&#39;top&#39; href=&#39;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/scheduling-eviction/dynamic-resource-allocation/&#39; target=&#39;_blank&#39; aria-label=&#39;DRA&#39;&gt;DRA&lt;/a&gt;
has enabled Pods to make detailed requests for &lt;a class=&#39;glossary-tooltip&#39; title=&#39;Any resource that&amp;#39;s directly or indirectly attached your cluster&amp;#39;s nodes, like GPUs or circuit boards.&#39; data-bs-toggle=&#39;tooltip&#39; data-bs-placement=&#39;top&#39; href=&#39;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/reference/glossary/?all=true#term-device&#39; target=&#39;_blank&#39; aria-label=&#39;devices&#39;&gt;devices&lt;/a&gt;
like GPUs, TPUs, and NICs. Requested devices can be shared by multiple Pods
requesting the same &lt;a class=&#39;glossary-tooltip&#39; title=&#39;Describes the resources that a workload needs, such as devices. ResourceClaims can request devices from DeviceClasses.&#39; data-bs-toggle=&#39;tooltip&#39; data-bs-placement=&#39;top&#39; href=&#39;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/scheduling-eviction/dynamic-resource-allocation/#resourceclaims-templates&#39; target=&#39;_blank&#39; aria-label=&#39;ResourceClaim&#39;&gt;ResourceClaim&lt;/a&gt;
by name. Other requests can be replicated through a &lt;a class=&#39;glossary-tooltip&#39; title=&#39;Defines a template for Kubernetes to create ResourceClaims. Used to provide per-Pod or per-PodGroup access to separate, similar resources.&#39; data-bs-toggle=&#39;tooltip&#39; data-bs-placement=&#39;top&#39; href=&#39;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/scheduling-eviction/dynamic-resource-allocation/#resourceclaims-templates&#39; target=&#39;_blank&#39; aria-label=&#39;ResourceClaimTemplate&#39;&gt;ResourceClaimTemplate&lt;/a&gt;,
in which Kubernetes generates one ResourceClaim with a non-deterministic name
for each Pod referencing the template. However, large-scale workloads that require
certain Pods to share certain devices are currently left to manage creating
individual ResourceClaims themselves.&lt;/p&gt;
&lt;p&gt;Now, in addition to Pods, PodGroups can represent the replicable unit for a
ResourceClaimTemplate. For ResourceClaimTemplates referenced by one of a
PodGroup&#39;s &lt;code&gt;spec.resourceClaims&lt;/code&gt;, Kubernetes generates one ResourceClaim for the
entire PodGroup, no matter how many Pods are in the group. When one of a Pod&#39;s
&lt;code&gt;spec.resourceClaims&lt;/code&gt; for a ResourceClaimTemplate matches one of its PodGroup&#39;s
&lt;code&gt;spec.resourceClaims&lt;/code&gt;, the Pod&#39;s claim resolves to the ResourceClaim generated
for the PodGroup and a ResourceClaim will not be generated for that individual
Pod. A single PodGroupTemplate in a Workload object can express resource
requests which are both copied for each distinct PodGroup and shareable by the
Pods within each group.&lt;/p&gt;
&lt;p&gt;The following example shows two Pods requesting the same ResourceClaim generated
from a ResourceClaimTemplate for their PodGroup:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;scheduling.k8s.io/v1alpha2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;PodGroup&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;training-job-workers-pg&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;...&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;resourceClaims&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;pg-claim&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;resourceClaimTemplateName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;my-claim-template&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Pod&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;topology-aware-workers-pg-pod-1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;...&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;schedulingGroup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;podGroupName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;training-job-workers-pg&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;resourceClaims&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;pg-claim&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;resourceClaimTemplateName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;my-claim-template&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Pod&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;topology-aware-workers-pg-pod-2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;...&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;schedulingGroup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;podGroupName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;training-job-workers-pg&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;resourceClaims&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;pg-claim&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;resourceClaimTemplateName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;my-claim-template&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In addition, ResourceClaims referenced by PodGroups, either through
&lt;code&gt;resourceClaimName&lt;/code&gt; or the claim generated from &lt;code&gt;resourceClaimTemplateName&lt;/code&gt;,
become reserved for the entire PodGroup. Previously, kube-scheduler could only
list individual Pods in a ResourceClaim&#39;s &lt;code&gt;status.reservedFor&lt;/code&gt; field which is
limited to 256 items. Now, a single PodGroup reference in &lt;code&gt;status.reservedFor&lt;/code&gt;
can represent many more than 256 Pods, allowing high-cardinality sharing of
devices.&lt;/p&gt;
&lt;p&gt;Together, these changes enable massive workloads with complex topologies to
utilize DRA for scalable device management.&lt;/p&gt;
&lt;h2 id=&#34;integration-with-the-job-controller&#34;&gt;Integration with the Job controller&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#integration-with-the-job-controller&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;In Kubernetes v1.36, the Job controller can create and manage Workload and PodGroup objects on your behalf,
so that Jobs representing a tightly coupled parallel application, such as distributed AI training,
are gang-scheduled without any additional tooling. Without this integration, you would have to
create the Workload and PodGroup yourself and wire their references into the Pod template.
Now, the Job controller automates this process natively.&lt;/p&gt;
&lt;p&gt;When the &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/reference/command-line-tools-reference/feature-gates/#WorkloadWithJob&#34;&gt;&lt;code&gt;WorkloadWithJob&lt;/code&gt;&lt;/a&gt;
feature gate is enabled, the Job controller automatically:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;creates a Workload and a corresponding runtime PodGroup for each qualifying Job,&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;sets &lt;code&gt;.spec.schedulingGroup&lt;/code&gt; onto every Pod the Job creates
so the scheduler treats them as a single gang, and&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;sets the Job as the owner of the generated objects,
so they are garbage-collected when the Job is deleted.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;when-does-the-integration-kick-in&#34;&gt;When does the integration kick in?&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#when-does-the-integration-kick-in&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;To keep the first feature iteration predictable, the Job controller only creates a
Workload and PodGroup when the Job has a well-defined, fixed shape:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;.spec.parallelism&lt;/code&gt; is greater than 1&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/workloads/controllers/job/#completion-mode&#34;&gt;&lt;code&gt;.spec.completionMode&lt;/code&gt;&lt;/a&gt; is set to &lt;code&gt;Indexed&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;.spec.completions&lt;/code&gt; is equal to &lt;code&gt;.spec.parallelism&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;schedulingGroup&lt;/code&gt; is not already set on the Pod template.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These conditions describe the class of Jobs that gang scheduling can reason about:
each Pod has a stable identity (&lt;code&gt;Indexed&lt;/code&gt;), the gang size is known and fixed at admission time
(&lt;code&gt;parallelism&lt;/code&gt; == &lt;code&gt;completions&lt;/code&gt;), and no other controller has already claimed scheduling responsibility
(&lt;code&gt;schedulingGroup&lt;/code&gt; field is unset). Jobs that do not meet these conditions are scheduled Pod-by-Pod,
exactly as before.&lt;/p&gt;
&lt;p&gt;If you set &lt;code&gt;schedulingGroup&lt;/code&gt; on the Pod template yourself (for example,
because a higher-level controller is managing the workload), the Job controller leaves
the Pod template alone and does not create its own Workload or PodGroup. This makes the feature
safe to enable in clusters that already use an external batch system.&lt;/p&gt;
&lt;p&gt;Here is an example of a Job that qualifies for gang scheduling:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;batch/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Job&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;training-job&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;namespace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;job-ns&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;completionMode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Indexed&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;parallelism&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;completions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;template&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;restartPolicy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Never&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;containers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;worker&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;registry.example/trainer:latest&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The Job controller creates a Workload and a PodGroup owned by this Job,
and every Pod it creates carries a &lt;code&gt;.spec.schedulingGroup&lt;/code&gt; that points at the generated PodGroup.
The Pods are then scheduled together once all four can be placed at the same time using
the PodGroup scheduling cycle described earlier in this post.&lt;/p&gt;
&lt;h3 id=&#34;what-s-not-covered-yet&#34;&gt;What&#39;s not covered yet&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#what-s-not-covered-yet&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The current constraints limit this integration to static, indexed, fully-parallel Jobs.
Support for additional workload shapes, including elastic Jobs and other built-in controllers,
is tracked in &lt;a href=&#34;https://kep.k8s.io/5547&#34;&gt;KEP-5547&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In future Kubernetes releases, this integration will expand to support additional workload controllers,
and the current constraints for Jobs may be relaxed.&lt;/p&gt;
&lt;h2 id=&#34;what-s-next&#34;&gt;What&#39;s next?&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#what-s-next&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The journey for workload-aware scheduling doesn&#39;t stop here.
For v1.37, the community is actively working on:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Graduating Workload and PodGroup APIs to Beta:&lt;/strong&gt; Our primary goal is to mature the Workload and PodGroup APIs to the Beta stage,
solidifying their foundational role in the Kubernetes ecosystem. As part of this graduation process, we also plan to introduce &lt;code&gt;minCount&lt;/code&gt; mutability
to unlock elastic jobs and allow dynamic workloads to scale efficiently.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Multi-level Workload hierarchies:&lt;/strong&gt; To support complex modern AI workloads like JobSet or Disaggregated Inference via LeaderWorkerSet (LWS),
we are working on expanding the architecture to support multi-level hierarchies. We aim to introduce a new API
that allows grouping multiple PodGroups into hierarchical structures, directly reflecting the organization of real-world workload controllers.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Graduating advanced scheduling features:&lt;/strong&gt; We are focused on driving the maturity of the broader workload-aware scheduling ecosystem.
This includes bringing existing features, such as topology-aware scheduling and workload-aware preemption, to the Beta stage.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Unified controller integration API:&lt;/strong&gt; To streamline adoption, we’re working on a controller integration API.
This will provide real-world workload controllers with a unified, standardized method for consuming workload-aware scheduling capabilities.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The priority and implementation order of these focus areas are subject to change. Stay tuned for further updates.&lt;/p&gt;
&lt;h2 id=&#34;getting-started&#34;&gt;Getting started&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#getting-started&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;All below workload-aware scheduling improvements are available as Alpha features in v1.36.
To try them out, you must configure the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Prerequisite: Workload and PodGroup API support: Enable the
&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/reference/command-line-tools-reference/feature-gates/#GenericWorkload&#34;&gt;&lt;code&gt;GenericWorkload&lt;/code&gt;&lt;/a&gt;
feature gate on both the &lt;code&gt;kube-apiserver&lt;/code&gt; and &lt;code&gt;kube-scheduler&lt;/code&gt;, and ensure the &lt;code&gt;scheduling.k8s.io/v1alpha2&lt;/code&gt;
&lt;a class=&#39;glossary-tooltip&#39; title=&#39;A set of related paths in the Kubernetes API.&#39; data-bs-toggle=&#39;tooltip&#39; data-bs-placement=&#39;top&#39; href=&#39;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/overview/kubernetes-api/#api-groups-and-versioning&#39; target=&#39;_blank&#39; aria-label=&#39;API group&#39;&gt;API group&lt;/a&gt; is enabled.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Once the prerequisite is met, you can enable specific features:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Gang scheduling: Enable the
&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/reference/command-line-tools-reference/feature-gates/#GangScheduling&#34;&gt;&lt;code&gt;GangScheduling&lt;/code&gt;&lt;/a&gt;
feature gate on the &lt;code&gt;kube-scheduler&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Topology-aware scheduling: Enable the
&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/reference/command-line-tools-reference/feature-gates/#TopologyAwareWorkloadScheduling&#34;&gt;&lt;code&gt;TopologyAwareWorkloadScheduling&lt;/code&gt;&lt;/a&gt;
feature gate on the &lt;code&gt;kube-scheduler&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Workload-aware preemption: Enable the
&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/reference/command-line-tools-reference/feature-gates/#WorkloadAwarePreemption&#34;&gt;&lt;code&gt;WorkloadAwarePreemption&lt;/code&gt;&lt;/a&gt;
feature gate on the &lt;code&gt;kube-scheduler&lt;/code&gt; (requires &lt;code&gt;GangScheduling&lt;/code&gt; to also be enabled).&lt;/li&gt;
&lt;li&gt;DRA ResourceClaim support for workloads: Enable the
&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/reference/command-line-tools-reference/feature-gates/#DRAWorkloadResourceClaims&#34;&gt;&lt;code&gt;DRAWorkloadResourceClaims&lt;/code&gt;&lt;/a&gt;
feature gate on the &lt;code&gt;kube-apiserver&lt;/code&gt;, &lt;code&gt;kube-controller-manager&lt;/code&gt;, &lt;code&gt;kube-scheduler&lt;/code&gt; and &lt;code&gt;kubelet&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Workload API integration with the Job controller: Enable the
&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/reference/command-line-tools-reference/feature-gates/#EnableWorkloadWithJob&#34;&gt;&lt;code&gt;WorkloadWithJob&lt;/code&gt;&lt;/a&gt;
feature gate on the &lt;code&gt;kube-apiserver&lt;/code&gt; and &lt;code&gt;kube-controller-manager&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We encourage you to try out workload-aware scheduling in your test clusters
and share your experiences to help shape the future of Kubernetes scheduling.
You can send your feedback by:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Reaching out via &lt;a href=&#34;https://kubernetes.slack.com/archives/C0AHLJ0EAEL&#34;&gt;Slack (#workload-aware-scheduling)&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Joining the &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/scheduling/#meetings&#34;&gt;SIG Scheduling&lt;/a&gt; meetings.&lt;/li&gt;
&lt;li&gt;Filing a new &lt;a href=&#34;https://github.com/kubernetes/kubernetes/issues&#34;&gt;issue&lt;/a&gt; in the Kubernetes repository.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;learn-more&#34;&gt;Learn more&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#learn-more&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;To dive deeper into the architecture and design of these features, read the KEPs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/4671&#34;&gt;Workload API and gang scheduling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/5732&#34;&gt;Topology-aware scheduling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/5710&#34;&gt;Workload-aware preemption&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/5729&#34;&gt;DRA ResourceClaim support for workloads&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/5547&#34;&gt;Workload API support in Job controller&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes v1.36: PSI Metrics for Kubernetes Graduates to GA</title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/05/12/kubernetes-v1-36-psi-metrics-ga/</link>
      <pubDate>Tue, 12 May 2026 10:35:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/05/12/kubernetes-v1-36-psi-metrics-ga/</guid>
      <description>
        
        
        &lt;p&gt;Since its original implementation in the Linux kernel in 2018,
&lt;em&gt;Pressure Stall Information&lt;/em&gt; (PSI) has provided users
with the high-fidelity signals needed to identify resource saturation before it becomes an outage.
Unlike traditional utilization metrics, PSI tells the story of tasks stalled and time lost, all in nicely-packaged percentages of time across the CPU, memory, and I/O.&lt;/p&gt;
&lt;p&gt;With the recent release of Kubernetes v1.36, users across the ecosystem have a stable, reliable interface to observe resource contention at the node, pod, and container levels. In this post, we will dive into the improvements and performance testing that proved its readiness for production.&lt;/p&gt;
&lt;h2 id=&#34;beyond-utilization-why-psi&#34;&gt;Beyond utilization: why PSI?&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#beyond-utilization-why-psi&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Monitoring CPU or memory usage alone can be misleading. A node may report XX% (below 100%) CPU utilization while certain tasks are experiencing severe latency due to scheduling delays. PSI fills this gap by providing:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Cumulative Totals&lt;/strong&gt;: Absolute time spent in a stalled state.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Moving Averages&lt;/strong&gt;: 10s, 60s, and 300s windows that allow operators to distinguish between transient spikes and sustained resource tension.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;proving-stability-performance-testing-at-scale&#34;&gt;Proving stability: performance testing at scale&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#proving-stability-performance-testing-at-scale&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;A common concern when graduating telemetry features is the resource overhead required to collect and serve the metrics. To address this, SIG Node conducted extensive performance validation on high-density workloads (80+ pods) across various machine types.&lt;/p&gt;
&lt;p&gt;Our testing focused on two primary scenarios to isolate the impact of the Kubelet and kernel-level collection respectively:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Kernel PSI ON / Kubelet Feature OFF&lt;/strong&gt; vs &lt;strong&gt;Kernel PSI ON / Kubelet Feature ON&lt;/strong&gt; (Kubelet overhead)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Kernel PSI OFF / Kubelet Feature ON&lt;/strong&gt; vs &lt;strong&gt;Kernel PSI ON / Kubelet Feature ON&lt;/strong&gt; (Kernel overhead)&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;scenario-1-the-kubelet-overhead&#34;&gt;Scenario 1: The Kubelet Overhead&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#scenario-1-the-kubelet-overhead&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;First, we looked at the kubelet usage on 4 core machines (Case 1). For these, the Linux kernel was already tracking pressure on both clusters by default(&lt;code&gt;psi=1&lt;/code&gt;), but we toggled the &lt;code&gt;KubeletPSI&lt;/code&gt; feature gate to see if the Kubelet actively querying and exposing these metrics impacted the resource usage. The synchronized bursts seen in the graph are practically identical in both magnitude and frequency, confirming that the Kubelet&#39;s collection logic is highly lightweight and blends seamlessly into standard housekeeping cycles. There is no issue about the feature affecting the pre-existing resource use, staying within the normal 0.1 cores or &lt;strong&gt;2.5% of the total node capacity&lt;/strong&gt;, and is therefore safe for production-scale deployments.&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/images/kubeletPSI_kubelet_cpu_usage_rate_graph.png&#34;
         alt=&#34;A line graph comparing the kubelet CPU usage rate over elapsed time with the Kubelet PSI feature turned off versus on and kernel PSI always on.&#34;/&gt; &lt;figcaption&gt;
            &lt;h4&gt;(Case 1) Kubelet CPU Usage Rate Comparison&lt;/h4&gt;&lt;p&gt;Figure 2: Kubelet CPU Usage Rate Comparison.&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Next, we evaluated the system overhead in the same run. As seen in the following graph, the &lt;strong&gt;System CPU&lt;/strong&gt; usage lines for the Kubelet PSI-enabled (red) follows the same pattern as the Kubelet PSI-disabled (blue) clusters, with a slight expected increase from the baseline. This visualizes that once the OS is tracking PSI, at around &lt;strong&gt;2.5 cores&lt;/strong&gt;, the act of Kubernetes reading those cgroup metrics is negligible to performance.&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/images/kubeletPSI_sys_cpu_usage_rate_graph.png&#34;
         alt=&#34;A line graph comparing the system CPU usage rate over elapsed time with the PSI feature turned off versus on and kernel PSI default ON.&#34;/&gt; &lt;figcaption&gt;
            &lt;h4&gt;(Case 1) System CPU Usage Rate Comparison&lt;/h4&gt;&lt;p&gt;Figure 1: Node System CPU Usage Rate Comparison.&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h4 id=&#34;scenario-2-the-kernel-overhead&#34;&gt;Scenario 2: The Kernel Overhead&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#scenario-2-the-kernel-overhead&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;Shifting gears, we evaluated the underlying overhead of enabling PSI on the Linux kernel also on a 4 core machine. By comparing a cluster booted with &lt;code&gt;psi=1&lt;/code&gt; (COS default) against a cluster with &lt;code&gt;psi=0&lt;/code&gt;, we isolated the exact cost of the OS-level bookkeeping. Even under heavy I/O and CPU load at an 80-pod density, the &lt;strong&gt;System CPU&lt;/strong&gt; delta between the kernel-enabled and kernel-disabled clusters remained consistently between &lt;strong&gt;0.037 cores&lt;/strong&gt; and &lt;strong&gt;0.125 cores&lt;/strong&gt; or &lt;strong&gt;0.925% - 3.125%&lt;/strong&gt; of the total node capacity. There was a single spike to &lt;strong&gt;0.225 cores&lt;/strong&gt;, or &lt;strong&gt;5.6%&lt;/strong&gt;, but was controlled back down within a few seconds. This confirms that the internal kernel tracking is highly efficient under load.&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/images/node_sys_cpu_usage_rate_comparison.png&#34;
         alt=&#34;A line graph comparing the Node System (Kernel) CPU usage rate with Kernel PSI ON and OFF over elapsed time.&#34;/&gt; &lt;figcaption&gt;
            &lt;h4&gt;(Case 2) Node System CPU Usage Rate Comparison&lt;/h4&gt;&lt;p&gt;Figure 3: Node System CPU Usage Rate Comparison.&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Figure 4 zooms in on the kubelet process itself, which serves as the primary collector for these metrics. . The results show that even while the kubelet performs periodic &lt;em&gt;sweeps&lt;/em&gt; to aggregate data from the cgroup hierarchy, its CPU usage remains remarkably low with interchangeable spikes and nothing exceeding &lt;strong&gt;0.25 cores&lt;/strong&gt; or &lt;strong&gt;6.25%&lt;/strong&gt; of total capacity for longer than a second.&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/images/kubelet_cpu_usage_rate_comparison.png&#34;
         alt=&#34;A line graph comparing the kubelet CPU usage rate over elapsed time with the Kernel PSI feature turned off versus on.&#34;/&gt; &lt;figcaption&gt;
            &lt;h4&gt;(Case 2) Kubelet CPU Usage Rate Comparison&lt;/h4&gt;&lt;p&gt;Figure 4: Kubelet CPU Usage Rate Comparison.&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&#34;improvements-between-beta-1-34-and-stable-1-36&#34;&gt;Improvements between beta (1.34) and stable (1.36)&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#improvements-between-beta-1-34-and-stable-1-36&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Smarter Metric Emission for GA:&lt;/strong&gt; We improved how the Kubelet handles underlying OS support for PSI. Previously, if the feature was enabled in Kubernetes but the underlying Linux kernel didn&#39;t support PSI (&lt;code&gt;psi=0&lt;/code&gt;), the Kubelet would emit misleading zero-valued metrics. These could trigger false alarms when read as real metrics instead of missing values. In v1.36, the Kubelet now detects OS-level PSI support via cgroup configurations before reporting. This ensures that pressure metrics are only collected and emitted when they are actually supported by the node, providing cleaner data for monitoring and alerting systems.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;getting-started&#34;&gt;Getting started&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#getting-started&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;To use PSI metrics in your Kubernetes cluster, your nodes must meet the following requirements:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Ensure your nodes are running a Linux kernel version 4.20 or later and are using cgroup v2.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ensure PSI is enabled at the OS level&lt;/strong&gt; (your kernel must be compiled with &lt;code&gt;CONFIG_PSI=y&lt;/code&gt; and must not be booted with the &lt;code&gt;psi=0&lt;/code&gt; parameter).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;As of v1.36, Kubelet PSI metrics are generally available and you do not need to opt in to any feature gate.&lt;/p&gt;
&lt;p&gt;Once the OS prerequisites are met, you can start scraping the &lt;code&gt;/metrics/cadvisor&lt;/code&gt; endpoint with your Prometheus-compatible monitoring solution or query the Summary API to collect and visualize the new PSI metrics. Note that PSI is a Linux-kernel feature, so these metrics are not available on Windows nodes. Your cluster can contain a mix of Linux and Windows nodes, and on the Windows nodes, the kubelet will simply omit the PSI metrics.&lt;/p&gt;
&lt;p&gt;If your cluster is running a recent enough version of Kubernetes and you are a privileged node administrator, you can also proxy to the kubelet&#39;s HTTP API via the control plane&#39;s API server to see real-time pressure data from the Summary API.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Caution:&lt;/strong&gt; Proxying to the kubelet is a privileged operation. Granting access to it is a security risk, so ensure you have the appropriate administrative permissions before executing these commands.&lt;/p&gt;&lt;/blockquote&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;CONTAINER_NAME&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;example-container&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl get --raw &lt;span class=&#34;s2&#34;&gt;&amp;#34;/api/v1/nodes/&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;kubectl get nodes -o &lt;span class=&#34;nv&#34;&gt;jsonpath&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;{.items[0].metadata.name}&amp;#39;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/proxy/stats/summary&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; jq &lt;span class=&#34;s1&#34;&gt;&amp;#39;.pods[].containers[] | select(.name==&amp;#34;&amp;#39;&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$CONTAINER_NAME&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;&amp;#34;) | {name, cpu: .cpu.psi, memory: .memory.psi, io: .io.psi}&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;further-reading&#34;&gt;Further reading&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#further-reading&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;If you want to dive deeper into how these metrics are calculated and exposed, check out these resources:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.kernel.org/accounting/psi.html&#34;&gt;The official Kernel documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/reference/instrumentation/understand-psi-metrics/&#34;&gt;Understanding PSI&lt;/a&gt; in the Kubernetes documentation&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/google/cadvisor/blob/master/metrics/prometheus.go&#34;&gt;cAdvisor Metrics Implementation&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;acknowledgements&#34;&gt;Acknowledgements&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#acknowledgements&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Support for PSI metrics was developed through the collaborative efforts of &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/node/&#34;&gt;SIG Node&lt;/a&gt;. Special thanks to all contributors who helped design, implement, test, review, and document this feature across its journey from alpha in v1.33, through beta in v1.34, to GA in v1.36.&lt;/p&gt;
&lt;p&gt;To provide feedback on this feature, join the &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-node&#34;&gt;Kubernetes Node Special Interest Group&lt;/a&gt;, participate in discussions on the &lt;a href=&#34;http://slack.k8s.io/&#34;&gt;public Slack channel&lt;/a&gt; (#sig-node), or file an issue on &lt;a href=&#34;https://github.com/kubernetes/kubernetes/issues&#34;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;feedback&#34;&gt;Feedback&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#feedback&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;If you have feedback and want to share your experience using this feature, join the discussion:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-node&#34;&gt;SIG Node community page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://slack.k8s.io/&#34;&gt;Kubernetes Slack&lt;/a&gt; in the #sig-node channel&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://groups.google.com/forum/#!forum/kubernetes-sig-node&#34;&gt;SIG Node mailing list&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;SIG Node would love to hear about your experiences using this feature in production!&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes v1.36: Moving Volume Group Snapshots to GA</title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/05/08/kubernetes-v1-36-volume-group-snapshot-ga/</link>
      <pubDate>Fri, 08 May 2026 10:35:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/05/08/kubernetes-v1-36-volume-group-snapshot-ga/</guid>
      <description>
        
        
        &lt;p&gt;Volume group snapshots were &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2023/05/08/kubernetes-1-27-volume-group-snapshot-alpha/&#34;&gt;introduced&lt;/a&gt; as an Alpha feature with the Kubernetes v1.27 release, moved to &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2024/12/18/kubernetes-1-32-volume-group-snapshot-beta/&#34;&gt;Beta&lt;/a&gt; in v1.32, and to a &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2025/09/16/kubernetes-v1-34-volume-group-snapshot-beta-2/&#34;&gt;second Beta&lt;/a&gt; in v1.34. We are excited to announce that in the Kubernetes v1.36 release, support for volume group snapshots has reached &lt;strong&gt;General Availability (GA)&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The support for volume group snapshots relies on a set of &lt;a href=&#34;https://kubernetes-csi.github.io/docs/group-snapshot-restore-feature.html#volume-group-snapshot-apis&#34;&gt;extension APIs for group snapshots&lt;/a&gt;. These APIs allow users to take crash-consistent snapshots for a set of volumes. Behind the scenes, Kubernetes uses a label selector to group multiple &lt;code&gt;PersistentVolumeClaim&lt;/code&gt; objects for snapshotting. A key aim is to allow you to restore that set of snapshots to new volumes and recover your workload based on a crash-consistent recovery point.&lt;/p&gt;
&lt;p&gt;This feature is only supported for &lt;a href=&#34;https://kubernetes-csi.github.io/docs/&#34;&gt;CSI&lt;/a&gt; volume drivers.&lt;/p&gt;
&lt;h2 id=&#34;an-overview-of-volume-group-snapshots&#34;&gt;An overview of volume group snapshots&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#an-overview-of-volume-group-snapshots&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Some storage systems provide the ability to create a crash-consistent snapshot of multiple volumes. A group snapshot represents &lt;em&gt;copies&lt;/em&gt; made from multiple volumes that are taken at the same point-in-time. A group snapshot can be used either to rehydrate new volumes (pre-populated with the snapshot data) or to restore existing volumes to a previous state (represented by the snapshots).&lt;/p&gt;
&lt;h3 id=&#34;why-add-volume-group-snapshots-to-kubernetes&#34;&gt;Why add volume group snapshots to Kubernetes?&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#why-add-volume-group-snapshots-to-kubernetes&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The Kubernetes volume plugin system already provides a powerful abstraction that automates the provisioning, attaching, mounting, resizing, and snapshotting of block and file storage. Underpinning all these features is the Kubernetes goal of workload portability.&lt;/p&gt;
&lt;p&gt;There was already a &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/storage/volume-snapshots/&#34;&gt;VolumeSnapshot&lt;/a&gt; API that provides the ability to take a snapshot of a persistent volume to protect against data loss or data corruption. However, some storage systems support consistent group snapshots that allow a snapshot to be taken from multiple volumes at the same point-in-time to achieve write order consistency. This is extremely useful for applications that contain multiple volumes. For example, an application may have data stored in one volume and logs stored in another. If snapshots for these volumes are taken at different times, the application will not be consistent and will not function properly if restored from those snapshots.&lt;/p&gt;
&lt;p&gt;While you can quiesce the application first and take individual snapshots sequentially, this process can be time-consuming or sometimes impossible. Consistent group support provides crash consistency across all volumes in the group without the need for application quiescence.&lt;/p&gt;
&lt;h3 id=&#34;kubernetes-apis-for-volume-group-snapshots&#34;&gt;Kubernetes APIs for volume group snapshots&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#kubernetes-apis-for-volume-group-snapshots&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Kubernetes&#39; support for volume group snapshots relies on three API kinds that are used for managing snapshots:&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;VolumeGroupSnapshot&lt;/dt&gt;
&lt;dd&gt;Created by a Kubernetes user (or automation) to request creation of a volume group snapshot for multiple persistent volume claims.&lt;/dd&gt;
&lt;dt&gt;VolumeGroupSnapshotContent&lt;/dt&gt;
&lt;dd&gt;Created by the snapshot controller for a dynamically created VolumeGroupSnapshot. It contains information about the provisioned cluster resource (a group snapshot). The object binds to the VolumeGroupSnapshot for which it was created with a one-to-one mapping.&lt;/dd&gt;
&lt;dt&gt;VolumeGroupSnapshotClass&lt;/dt&gt;
&lt;dd&gt;Created by cluster administrators to describe how volume group snapshots should be created, including the driver information, the deletion policy, etc.&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;These three API kinds are defined as CustomResourceDefinitions (CRDs). For the GA release, the API version has been promoted to &lt;code&gt;v1&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;what-s-new-in-ga&#34;&gt;What&#39;s new in GA?&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#what-s-new-in-ga&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;The API version for &lt;code&gt;VolumeGroupSnapshot&lt;/code&gt;, &lt;code&gt;VolumeGroupSnapshotContent&lt;/code&gt;, and &lt;code&gt;VolumeGroupSnapshotClass&lt;/code&gt; is promoted to &lt;code&gt;groupsnapshot.storage.k8s.io/v1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Enhanced stability and bug fixes based on feedback from the beta releases, including the improvements introduced in v1beta2 for accurate &lt;code&gt;restoreSize&lt;/code&gt; reporting.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;how-do-i-use-kubernetes-volume-group-snapshots&#34;&gt;How do I use Kubernetes volume group snapshots&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#how-do-i-use-kubernetes-volume-group-snapshots&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;h3 id=&#34;creating-a-new-group-snapshot-with-kubernetes&#34;&gt;Creating a new group snapshot with Kubernetes&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#creating-a-new-group-snapshot-with-kubernetes&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Once a &lt;code&gt;VolumeGroupSnapshotClass&lt;/code&gt; object is defined and you have volumes you want to snapshot together, you may request a new group snapshot by creating a &lt;code&gt;VolumeGroupSnapshot&lt;/code&gt; object.&lt;/p&gt;
&lt;p&gt;Label the PVCs you wish to group:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gp&#34;&gt;%&lt;/span&gt; kubectl label pvc pvc-0 &lt;span class=&#34;nv&#34;&gt;group&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;myGroup
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;go&#34;&gt;persistentvolumeclaim/pvc-0 labeled
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;go&#34;&gt;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;&lt;/span&gt;&lt;span class=&#34;gp&#34;&gt;%&lt;/span&gt; kubectl label pvc pvc-1 &lt;span class=&#34;nv&#34;&gt;group&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;myGroup
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;go&#34;&gt;persistentvolumeclaim/pvc-1 labeled
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For dynamic provisioning, a selector must be set so that the snapshot controller can find PVCs with the matching labels to be snapshotted together.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;groupsnapshot.storage.k8s.io/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;VolumeGroupSnapshot&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;snapshot-daily-20260422&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;namespace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;demo-namespace&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;volumeGroupSnapshotClassName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;csi-groupSnapclass&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;source&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;selector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;matchLabels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;group&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;myGroup&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;VolumeGroupSnapshotClass&lt;/code&gt; is required for dynamic provisioning:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;groupsnapshot.storage.k8s.io/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;VolumeGroupSnapshotClass&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;csi-groupSnapclass&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;driver&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;example.csi.k8s.io&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;deletionPolicy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Delete&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;how-to-use-group-snapshot-for-restore&#34;&gt;How to use group snapshot for restore&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#how-to-use-group-snapshot-for-restore&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;At restore time, request a new &lt;code&gt;PersistentVolumeClaim&lt;/code&gt; to be created from a &lt;code&gt;VolumeSnapshot&lt;/code&gt; object that is part of a &lt;code&gt;VolumeGroupSnapshot&lt;/code&gt;. Repeat this for all volumes that are part of the group snapshot.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;PersistentVolumeClaim&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;examplepvc-restored-2026-04-22&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;namespace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;demo-namespace&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;storageClassName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;example-sc&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;dataSource&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;snapshot-0962a745b2bf930bb385b7b50c9b08af471f1a16780726de19429dd9c94eaca0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;VolumeSnapshot&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;apiGroup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;snapshot.storage.k8s.io&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;accessModes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;ReadWriteOncePod&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;resources&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;requests&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;storage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;100Mi&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;as-a-storage-vendor-how-do-i-add-support-for-group-snapshots&#34;&gt;As a storage vendor, how do I add support for group snapshots?&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#as-a-storage-vendor-how-do-i-add-support-for-group-snapshots&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;To implement the volume group snapshot feature, a CSI driver &lt;strong&gt;must&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Implement a new group controller service.&lt;/li&gt;
&lt;li&gt;Implement group controller RPCs: &lt;code&gt;CreateVolumeGroupSnapshot&lt;/code&gt;, &lt;code&gt;DeleteVolumeGroupSnapshot&lt;/code&gt;, and &lt;code&gt;GetVolumeGroupSnapshot&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Add group controller capability &lt;code&gt;CREATE_DELETE_GET_VOLUME_GROUP_SNAPSHOT&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;See the &lt;a href=&#34;https://github.com/container-storage-interface/spec/blob/master/spec.md&#34;&gt;CSI spec&lt;/a&gt; and the &lt;a href=&#34;https://kubernetes-csi.github.io/docs/&#34;&gt;Kubernetes-CSI Driver Developer Guide&lt;/a&gt; for more details.&lt;/p&gt;
&lt;h2 id=&#34;how-can-i-learn-more&#34;&gt;How can I learn more?&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#how-can-i-learn-more&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;The &lt;a href=&#34;https://github.com/kubernetes/enhancements/tree/master/keps/sig-storage/3476-volume-group-snapshot&#34;&gt;design spec&lt;/a&gt; for the volume group snapshot feature.&lt;/li&gt;
&lt;li&gt;The &lt;a href=&#34;https://github.com/kubernetes-csi/external-snapshotter&#34;&gt;code repository&lt;/a&gt; for volume group snapshot APIs and controller.&lt;/li&gt;
&lt;li&gt;CSI &lt;a href=&#34;https://kubernetes-csi.github.io/docs/&#34;&gt;documentation&lt;/a&gt; on the group snapshot feature.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;how-do-i-get-involved&#34;&gt;How do I get involved?&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#how-do-i-get-involved&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;This project, like all of Kubernetes, is the result of hard work by many contributors from diverse backgrounds working together. On behalf of SIG Storage, I would like to offer a huge thank you to all the contributors who stepped up over the years to help the project reach GA:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ben Swartzlander (&lt;a href=&#34;https://github.com/bswartz&#34;&gt;bswartz&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Cici Huang (&lt;a href=&#34;https://github.com/cici37&#34;&gt;cici37&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Darshan Murthy (&lt;a href=&#34;https://github.com/darshansreenivas&#34;&gt;darshansreenivas&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Hemant Kumar (&lt;a href=&#34;https://github.com/gnufied&#34;&gt;gnufied&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;James Defelice (&lt;a href=&#34;https://github.com/jdef&#34;&gt;jdef&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Jan Šafránek (&lt;a href=&#34;https://github.com/jsafrane&#34;&gt;jsafrane&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Madhu Rajanna (&lt;a href=&#34;https://github.com/Madhu-1&#34;&gt;Madhu-1&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Manish M Yathnalli (&lt;a href=&#34;https://github.com/manishym&#34;&gt;manishym&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Michelle Au (&lt;a href=&#34;https://github.com/msau42&#34;&gt;msau42&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Niels de Vos (&lt;a href=&#34;https://github.com/nixpanic&#34;&gt;nixpanic&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Leonardo Cecchi (&lt;a href=&#34;https://github.com/leonardoce&#34;&gt;leonardoce&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Rakshith R (&lt;a href=&#34;https://github.com/Rakshith-R&#34;&gt;Rakshith-R&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Raunak Shah (&lt;a href=&#34;https://github.com/RaunakShah&#34;&gt;RaunakShah&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Saad Ali (&lt;a href=&#34;https://github.com/saad-ali&#34;&gt;saad-ali&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Wei Duan (&lt;a href=&#34;https://github.com/duanwei33&#34;&gt;duanwei33&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Xing Yang (&lt;a href=&#34;https://github.com/xing-yang&#34;&gt;xing-yang&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Yati Padia (&lt;a href=&#34;https://github.com/yati1998&#34;&gt;yati1998&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For those interested in getting involved with the design and development of CSI or any part of the Kubernetes Storage system, join the &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-storage&#34;&gt;Kubernetes Storage Special Interest Group&lt;/a&gt; (SIG). We always welcome new contributors.&lt;/p&gt;
&lt;p&gt;We also hold regular &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/wg-data-protection&#34;&gt;Data Protection Working Group meetings&lt;/a&gt;. New attendees are welcome to join our discussions.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes v1.36: More Drivers, New Features, and the Next Era of DRA</title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/05/07/kubernetes-v1-36-dra-136-updates/</link>
      <pubDate>Thu, 07 May 2026 10:35:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/05/07/kubernetes-v1-36-dra-136-updates/</guid>
      <description>
        
        
        &lt;p&gt;Dynamic Resource Allocation (DRA) has fundamentally changed how platform administrators handle hardware
accelerators and specialized resources in Kubernetes. In the v1.36 release, DRA
continues to mature, bringing a wave of feature graduations, critical usability
improvements, and new capabilities that extend the flexibility of DRA to native
resources like memory and CPU, and support for ResourceClaims in PodGroups.&lt;/p&gt;
&lt;p&gt;Driver availability continues to expand. Beyond specialized compute accelerators,
the ecosystem includes support for networking and other hardware types,
reflecting a move toward a more robust, hardware-agnostic infrastructure.&lt;/p&gt;
&lt;p&gt;Whether you are managing massive fleets of GPUs, need better handling of failures,
or simply looking for better ways to define resource fallback options, the upgrades
to DRA in 1.36 have something for you. Let&#39;s dive into the new features and graduations!&lt;/p&gt;
&lt;h2 id=&#34;feature-graduations&#34;&gt;Feature graduations&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#feature-graduations&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The community has been hard at work stabilizing core DRA concepts. In Kubernetes 1.36,
several highly anticipated features have graduated to Beta and Stable.&lt;/p&gt;
&lt;h3 id=&#34;prioritized-list&#34;&gt;Prioritized list (stable)&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#prioritized-list&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Hardware heterogeneity is a reality in most clusters. With the
&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/scheduling-eviction/dynamic-resource-allocation/#prioritized-list&#34;&gt;Prioritized list&lt;/a&gt;
feature, you can confidently define fallback preferences when requesting
devices. Instead of hardcoding a request for a specific device model, you can specify an
ordered list of preferences (e.g., &amp;quot;Give me an H100, but if none are available, fall back
to an A100&amp;quot;). The scheduler will evaluate these requests in order, drastically improving
scheduling flexibility and cluster utilization.&lt;/p&gt;
&lt;h3 id=&#34;extended-resource&#34;&gt;Extended resource support (beta)&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#extended-resource&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;As DRA becomes the standard for resource allocation, bridging the gap with legacy systems
is crucial. The DRA
&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/scheduling-eviction/dynamic-resource-allocation/#extended-resource&#34;&gt;Extended resource&lt;/a&gt;
feature allows users to request resources via traditional extended resources on a Pod.
This allows for a gradual transition to DRA, meaning cluster operators can migrate clusters
to DRA but let application developers adopt the ResourceClaim API on their own schedule.&lt;/p&gt;
&lt;h3 id=&#34;partitionable-devices&#34;&gt;Partitionable devices (beta)&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#partitionable-devices&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Hardware accelerators are powerful, and sometimes a single workload doesn&#39;t need an
entire device. The
&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/scheduling-eviction/dynamic-resource-allocation/#partitionable-devices&#34;&gt;Partitionable devices&lt;/a&gt;
feature, provides native DRA support for dynamically carving physical hardware into smaller,
logical instances (such as Multi-Instance GPUs) based on workload demands. This allows
administrators to safely and efficiently share expensive accelerators across multiple Pods.&lt;/p&gt;
&lt;h3 id=&#34;device-taints&#34;&gt;Device taints (beta)&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#device-taints&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Just as you can taint a Kubernetes Node, you can apply taints directly to specific DRA
devices.
&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/scheduling-eviction/dynamic-resource-allocation/#device-taints-and-tolerations&#34;&gt;Device taints and tolerations&lt;/a&gt;
empower cluster administrators to manage hardware more effectively. You can taint faulty
devices to prevent them from being allocated to standard claims, or reserve specific hardware
for dedicated teams, specialized workloads, and experiments. Ultimately, only Pods with
matching tolerations are permitted to claim these tainted devices.&lt;/p&gt;
&lt;h3 id=&#34;device-binding-conditions&#34;&gt;Device binding conditions (beta)&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#device-binding-conditions&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;To improve scheduling reliability, the Kubernetes scheduler can use the
&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/scheduling-eviction/dynamic-resource-allocation/#device-binding-conditions&#34;&gt;Binding conditions&lt;/a&gt;
feature to delay committing a Pod to a Node until its required external resources—such as attachable
devices or FPGAs—are fully prepared. By explicitly modeling resource readiness, this
prevents premature assignments that can lead to Pod failures, ensuring a much more robust
and predictable deployment process.&lt;/p&gt;
&lt;h3 id=&#34;device-health-monitoring&#34;&gt;Resource health status (beta)&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#device-health-monitoring&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Knowing when a device has failed or become unhealthy is critical for workloads running on
specialized hardware. With
&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/scheduling-eviction/dynamic-resource-allocation/#device-health-monitoring&#34;&gt;Resource health status&lt;/a&gt;,
Kubernetes expose device health information directly in the Pod status, giving users and
controllers crucial visibility to quickly identify and react to hardware failures. The
feature includes support for human-readable health status messages, making it
significantly easier to diagnose issues without the need to dive into complex driver logs.&lt;/p&gt;
&lt;h2 id=&#34;new-features&#34;&gt;New Features&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#new-features&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Beyond stabilizing existing capabilities, v1.36 introduces foundational new features
that expand what DRA can do. These are alpha features, so they are behind feature gates
that are disabled by default.&lt;/p&gt;
&lt;h3 id=&#34;workload-resourceclaims&#34;&gt;ResourceClaim support for workloads&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#workload-resourceclaims&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;To optimize large-scale AI/ML workloads that rely on strict topological scheduling, the
&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/scheduling-eviction/dynamic-resource-allocation/#workload-resourceclaims&#34;&gt;ResourceClaim support for workloads&lt;/a&gt;
feature enables Kubernetes to seamlessly manage shared resources across massive sets
of Pods. By associating ResourceClaims or ResourceClaimTemplates with PodGroups,
this feature eliminates previous scaling bottlenecks, such as the limit on the
number of pods that can share a claim, and removes the burden of manual claim
management from specialized orchestrators.&lt;/p&gt;
&lt;h3 id=&#34;node-allocatable-resources&#34;&gt;Node allocatable resources&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#node-allocatable-resources&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Why should DRA only be for external accelerators? In v1.36, we are introducing the first
iteration of using the DRA APIs to manage &lt;em&gt;node allocatable&lt;/em&gt; infrastructure resources (like CPU and
memory). By bringing CPU and memory allocation under the DRA umbrella with the DRA
&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/scheduling-eviction/dynamic-resource-allocation/#node-allocatable-resources&#34;&gt;Node allocatable resources&lt;/a&gt;
feature, users can leverage DRA&#39;s advanced placement, NUMA-awareness, and prioritization
semantics for standard compute resources, paving the way for incredibly fine-grained
performance tuning.&lt;/p&gt;
&lt;h3 id=&#34;resource-pool-status&#34;&gt;DRA resource availability visibility&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#resource-pool-status&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;One of the most requested features from cluster administrators has been better visibility
into hardware capacity. The new
&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/scheduling-eviction/dynamic-resource-allocation/#resource-pool-status&#34;&gt;Resource pool status&lt;/a&gt;
feature allows you to query the availability of devices in DRA resource pools. By creating a
&lt;code&gt;ResourcePoolStatusRequest&lt;/code&gt; object, you get a point-in-time snapshot of device counts
— total, allocated, available, and unavailable — for each pool managed by a given
driver. This enables better integration with dashboards and capacity planning tools.&lt;/p&gt;
&lt;h3 id=&#34;list-type-attributes&#34;&gt;List types for attributes&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#list-type-attributes&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;ResourceClaim constraint evaluation has changed to work better with scalar
and list values:
&lt;code&gt;matchAttribute&lt;/code&gt; now checks for a non-empty intersection, and
&lt;code&gt;distinctAttribute&lt;/code&gt; checks for pairwise disjoint values.&lt;/p&gt;
&lt;p&gt;An &lt;code&gt;includes()&lt;/code&gt; function in CEL has also been introduced,
that lets device selectors keep working more easily when an attribute
changes between scalar and list representations.
(The &lt;code&gt;includes()&lt;/code&gt; function is only available in DRA
contexts for expression evaluation).&lt;/p&gt;
&lt;h3 id=&#34;deterministic-device-selection&#34;&gt;Deterministic device selection&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#deterministic-device-selection&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The Kubernetes scheduler has been updated to evaluate devices using lexicographical
ordering based on resource pool and ResourceSlice names. This change empowers drivers
to proactively influence the scheduling process, leading to improved throughput and
more optimal scheduling decisions. The ResourceSlice controller toolkit automatically
generates names that reflect the exact device ordering specified by the driver author.&lt;/p&gt;
&lt;h3 id=&#34;device-metadata&#34;&gt;Discoverable device metadata in containers&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#device-metadata&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Workloads running on nodes with DRA devices often need to discover details about
their allocated devices, such as PCI bus addresses or network
interface configuration, without querying the Kubernetes API. With
&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/scheduling-eviction/dynamic-resource-allocation/#device-metadata&#34;&gt;Device metadata&lt;/a&gt;,
Kubernetes defines a standard protocol for how DRA drivers expose device
attributes to containers as versioned JSON files at well-known paths. Drivers
built with the
&lt;a href=&#34;https://pkg.go.dev/k8s.io/dynamic-resource-allocation/kubeletplugin&#34;&gt;DRA kubelet plugin library&lt;/a&gt;
get this behavior transparently; they just provide the metadata and the
library handles file layout, CDI bind-mounts, versioning, and lifecycle. This
gives applications a consistent, driver-independent way to discover and
consume device metadata, eliminating the need for custom controllers or
looking up ResourceSlice objects to get metadata via attributes.&lt;/p&gt;
&lt;h2 id=&#34;what-s-next&#34;&gt;What’s next?&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#what-s-next&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;This release introduced a wealth of new Dynamic Resource Allocation (DRA) features,
and the momentum is only building. As we look ahead, our roadmap focuses on maturing
existing features toward beta and stable releases while hardening DRA’s performance,
scalability, and reliability. A key priority over the coming cycles will be deep
integration with &lt;em&gt;workload aware&lt;/em&gt; and &lt;em&gt;topology aware scheduling&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;A big goal for us is to migrate users from Device Plugin to DRA, and we want
you involved. Whether you are currently maintaining a driver or are just beginning
to explore the possibilities, your input is vital. Partner with us to shape the next
generation of resource management. Reach out today to collaborate on development,
share feedback, or start building your first DRA driver.&lt;/p&gt;
&lt;h2 id=&#34;getting-involved&#34;&gt;Getting involved&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#getting-involved&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;A good starting point is joining the WG Device Management
&lt;a href=&#34;https://kubernetes.slack.com/archives/C0409NGC1TK&#34;&gt;Slack channel&lt;/a&gt; and
&lt;a href=&#34;https://docs.google.com/document/d/1qxI87VqGtgN7EAJlqVfxx86HGKEAc2A3SKru8nJHNkQ/edit?tab=t.0#heading=h.tgg8gganowxq&#34;&gt;meetings&lt;/a&gt;,
which happen at Americas/EMEA and EMEA/APAC friendly time slots.&lt;/p&gt;
&lt;p&gt;Not all enhancement ideas are tracked as issues yet, so come talk to us if you want to help or have some ideas yourself!
We have work to do at all levels, from difficult core changes to usability enhancements in kubectl, which could be picked up by newcomers.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes v1.36: Server-Side Sharded List and Watch</title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/05/06/kubernetes-v1-36-server-side-sharded-list-and-watch/</link>
      <pubDate>Wed, 06 May 2026 10:35:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/05/06/kubernetes-v1-36-server-side-sharded-list-and-watch/</guid>
      <description>
        
        
        &lt;p&gt;As Kubernetes clusters grow to tens of thousands of nodes, controllers that watch
high-cardinality resources like Pods face a scaling wall. Every replica of a
horizontally scaled controller receives the full stream of events from the API
server, paying the CPU, memory, and network cost to deserialize everything, only
to discard the objects it is not responsible for. Scaling out the controller
does not reduce per-replica cost; it multiplies it.&lt;/p&gt;
&lt;p&gt;Kubernetes v1.36 introduces &lt;strong&gt;server-side sharded list and watch&lt;/strong&gt; as an alpha
feature (&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/5866&#34;&gt;KEP-5866&lt;/a&gt;).
With this feature enabled, the API server filters events at the source so that
each controller replica receives only the slice of the resource collection it
owns.&lt;/p&gt;
&lt;h2 id=&#34;the-problem-with-client-side-sharding&#34;&gt;The problem with client-side sharding&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#the-problem-with-client-side-sharding&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Some controllers, such as &lt;a href=&#34;https://github.com/kubernetes/kube-state-metrics&#34;&gt;kube-state-metrics&lt;/a&gt;,
already support horizontal sharding. Each replica is assigned a portion of the
keyspace and discards objects that do not belong to it. While this works
functionally, it does not reduce the volume of data flowing from the API server:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;N replicas x full event stream&lt;/strong&gt;: every replica deserializes and processes
every event, then throws away what it does not need.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Network bandwidth scales with replicas&lt;/strong&gt;, not with shard size.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CPU spent on deserialization&lt;/strong&gt; is wasted for the discarded fraction.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Server-side sharded list and watch solves this by moving the filtering upstream
into the API server. Each replica tells the API server which hash range it owns,
and the API server only sends matching events.&lt;/p&gt;
&lt;h2 id=&#34;how-it-works&#34;&gt;How it works&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#how-it-works&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The feature adds a &lt;code&gt;shardSelector&lt;/code&gt; field to &lt;code&gt;ListOptions&lt;/code&gt;. Clients specify a
hash range using the &lt;code&gt;shardRange()&lt;/code&gt; function:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;shardRange(object.metadata.uid, &amp;#39;0x0000000000000000&amp;#39;, &amp;#39;0x8000000000000000&amp;#39;)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The API server computes a deterministic 64-bit
&lt;a href=&#34;https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function&#34;&gt;FNV-1a&lt;/a&gt;
hash of the specified field and returns only objects whose hash falls within the
range &lt;code&gt;[start, end)&lt;/code&gt;. This applies to both list responses and watch event
streams. The hash function produces the same result across all API server
instances, so the feature is safe to use with multiple API server replicas.&lt;/p&gt;
&lt;p&gt;Currently supported field paths are &lt;code&gt;object.metadata.uid&lt;/code&gt; and
&lt;code&gt;object.metadata.namespace&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;using-sharded-watches-in-controllers&#34;&gt;Using sharded watches in controllers&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#using-sharded-watches-in-controllers&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Controllers typically use informers to list and watch resources. To shard the
workload, each replica injects the &lt;code&gt;shardSelector&lt;/code&gt; into the &lt;code&gt;ListOptions&lt;/code&gt; used
by its informers via &lt;code&gt;WithTweakListOptions&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;metav1&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;k8s.io/apimachinery/pkg/apis/meta/v1&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s&#34;&gt;&amp;#34;k8s.io/client-go/informers&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;shardSelector&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;shardRange(object.metadata.uid, &amp;#39;0x0000000000000000&amp;#39;, &amp;#39;0x8000000000000000&amp;#39;)&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;factory&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;informers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;NewSharedInformerFactoryWithOptions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;resyncPeriod&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;informers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;WithTweakListOptions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;opts&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;metav1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ListOptions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nx&#34;&gt;opts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ShardSelector&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;shardSelector&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For a 2-replica deployment, the selectors split the hash space in half:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// Replica 0: lower half of the hash space&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;shardRange(object.metadata.uid, &amp;#39;0x0000000000000000&amp;#39;, &amp;#39;0x8000000000000000&amp;#39;)&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// Replica 1: upper half of the hash space&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;shardRange(object.metadata.uid, &amp;#39;0x8000000000000000&amp;#39;, &amp;#39;0x10000000000000000&amp;#39;)&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A single replica can also cover non-contiguous ranges using &lt;code&gt;||&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;shardRange(object.metadata.uid, &amp;#39;0x0000000000000000&amp;#39;, &amp;#39;0x4000000000000000&amp;#39;) || &amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s&#34;&gt;&amp;#34;shardRange(object.metadata.uid, &amp;#39;0x8000000000000000&amp;#39;, &amp;#39;0xc000000000000000&amp;#39;)&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;verifying-server-support&#34;&gt;Verifying server support&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#verifying-server-support&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;When the API server honors a shard selector, the list response includes a
&lt;code&gt;shardInfo&lt;/code&gt; field in the response metadata that echoes back the applied
selector:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;kind&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;PodList&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;apiVersion&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;v1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;metadata&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;resourceVersion&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;10245&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;shardInfo&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;selector&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;shardRange(object.metadata.uid, &amp;#39;0x0000000000000000&amp;#39;, &amp;#39;0x8000000000000000&amp;#39;)&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;items&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;...&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If &lt;code&gt;shardInfo&lt;/code&gt; is absent, the server did not honor the shard selector and the
client received the complete, unfiltered collection. In this case, the client
should be prepared to handle the full result set, for example by applying
client-side filtering to discard objects outside its assigned shard range.&lt;/p&gt;
&lt;h2 id=&#34;getting-involved&#34;&gt;Getting involved&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#getting-involved&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;This feature is in alpha and requires enabling the &lt;code&gt;ShardedListAndWatch&lt;/code&gt; feature
gate on the API server. We are looking for feedback from controller authors and
operators running large clusters.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/5866&#34;&gt;KEP-5866: Server-Side Sharded List and Watch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/reference/using-api/api-concepts/#sharded-list-and-watch&#34;&gt;API Concepts: Sharded list and watch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-api-machinery&#34;&gt;SIG API Machinery&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you have questions or feedback, join the &lt;code&gt;#sig-api-machinery&lt;/code&gt; channel on
&lt;a href=&#34;https://slack.k8s.io/&#34;&gt;Kubernetes Slack&lt;/a&gt;.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes v1.36: Declarative Validation Graduates to GA</title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/05/05/kubernetes-v1-36-declarative-validation-ga/</link>
      <pubDate>Tue, 05 May 2026 10:35:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/05/05/kubernetes-v1-36-declarative-validation-ga/</guid>
      <description>
        
        
        &lt;p&gt;In Kubernetes v1.36, &lt;strong&gt;Declarative Validation&lt;/strong&gt; for Kubernetes native types has reached General Availability (GA).&lt;/p&gt;
&lt;p&gt;For users, this means more reliable, predictable, and better-documented APIs. By moving to a declarative model, the project also unlocks the future ability to publish validation rules via OpenAPI and integrate with ecosystem tools like Kubebuilder. For contributors and ecosystem developers, this replaces thousands of lines of handwritten validation code with a unified, maintainable framework.&lt;/p&gt;
&lt;p&gt;This post covers why this migration was necessary, how the declarative validation framework works, and what new capabilities come with this GA release.&lt;/p&gt;
&lt;h2 id=&#34;the-motivation-escaping-the-handwritten-technical-debt&#34;&gt;The Motivation: Escaping the &amp;quot;Handwritten&amp;quot; Technical Debt&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#the-motivation-escaping-the-handwritten-technical-debt&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;For years, the validation of Kubernetes native APIs relied almost entirely on handwritten Go code. If a field needed to be bounded by a minimum value, or if two fields needed to be mutually exclusive, developers had to write explicit Go functions to enforce those constraints.&lt;/p&gt;
&lt;p&gt;As the Kubernetes API surface expanded, this approach led to several systemic issues:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Technical Debt:&lt;/strong&gt; The project accumulated roughly 18,000 lines of boilerplate validation code. This code was difficult to maintain, error-prone, and required intense scrutiny during code reviews.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Inconsistency:&lt;/strong&gt; Without a centralized framework, validation rules were sometimes applied inconsistently across different resources.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Opaque APIs:&lt;/strong&gt; Handwritten validation logic was difficult to discover or analyze programmatically. This meant clients and tooling couldn&#39;t predictably know validation rules without consulting the source code or encountering errors at runtime.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The solution proposed by SIG API Machinery was &lt;strong&gt;Declarative Validation&lt;/strong&gt;: using Interface Definition Language (IDL) tags (specifically &lt;code&gt;+k8s:&lt;/code&gt; marker tags) directly within &lt;code&gt;types.go&lt;/code&gt; files to define validation rules.&lt;/p&gt;
&lt;h2 id=&#34;enter-validation-gen&#34;&gt;Enter &lt;code&gt;validation-gen&lt;/code&gt;&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#enter-validation-gen&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;At the core of the declarative validation feature is a new code generator called &lt;code&gt;validation-gen&lt;/code&gt;. Just as Kubernetes uses generators for deep copies, conversions, and defaulting, &lt;code&gt;validation-gen&lt;/code&gt; parses &lt;code&gt;+k8s:&lt;/code&gt; tags and automatically generates the corresponding Go validation functions.&lt;/p&gt;
&lt;p&gt;These generated functions are then registered seamlessly with the API scheme. The generator is designed as an extensible framework, allowing developers to plug in new &amp;quot;Validators&amp;quot; by describing the tags they parse and the Go logic they should produce.&lt;/p&gt;
&lt;h3 id=&#34;a-comprehensive-suite-of-k8s-tags&#34;&gt;A Comprehensive Suite of +k8s: Tags&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#a-comprehensive-suite-of-k8s-tags&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The declarative validation framework introduces a comprehensive suite of marker tags that provide rich validation capabilities highly optimized for Go types. For a full list of supported tags, check out the &lt;a href=&#34;https://kubernetes.io/docs/reference/using-api/declarative-validation/#declarative-validation-tag-reference&#34;&gt;official documentation&lt;/a&gt;. Here is a catalog of some of the most common tags you will now see in the Kubernetes codebase:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Presence:&lt;/strong&gt; &lt;code&gt;+k8s:optional&lt;/code&gt;, &lt;code&gt;+k8s:required&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Basic Constraints:&lt;/strong&gt; &lt;code&gt;+k8s:minimum=0&lt;/code&gt;, &lt;code&gt;+k8s:maximum=100&lt;/code&gt;, &lt;code&gt;+k8s:maxLength=16&lt;/code&gt;, &lt;code&gt;+k8s:format=k8s-short-name&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Collections:&lt;/strong&gt; &lt;code&gt;+k8s:listType=map&lt;/code&gt;, &lt;code&gt;+k8s:listMapKey=type&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Unions:&lt;/strong&gt; &lt;code&gt;+k8s:unionMember&lt;/code&gt;, &lt;code&gt;+k8s:unionDiscriminator&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Immutability:&lt;/strong&gt; &lt;code&gt;+k8s:immutable&lt;/code&gt;, &lt;code&gt;+k8s:update=[NoSet, NoModify, NoClear]&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Example Usage:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;ReplicationControllerSpec&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;struct&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// +k8s:optional&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// +k8s:minimum=0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;Replicas&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int32&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;`json:&amp;#34;replicas,omitempty&amp;#34;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;By placing these tags directly above the field definitions, the constraints are self-documenting and immediately visible to anyone reading the type definitions.&lt;/p&gt;
&lt;h2 id=&#34;advanced-capabilities-ambient-ratcheting&#34;&gt;Advanced Capabilities: &amp;quot;Ambient Ratcheting&amp;quot;&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#advanced-capabilities-ambient-ratcheting&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;One of the most substantial outcomes of this work is that validation ratcheting is now a standard, ambient part of the API. In the past, if we needed to tighten validation, we had to first add handwritten ratcheting code, wait a release, and then tighten the validation to avoid breaking existing objects.&lt;/p&gt;
&lt;p&gt;With declarative validation, this safety mechanism is built-in. If a user updates an existing object, the validation framework compares the incoming object with the &lt;code&gt;oldObject&lt;/code&gt;. If a specific field&#39;s value is semantically equivalent to its prior state (i.e., the user didn&#39;t change it), the new validation rule is bypassed. This &amp;quot;ambient ratcheting&amp;quot; means we can loosen or tighten validation immediately and in the least disruptive way possible.&lt;/p&gt;
&lt;h2 id=&#34;scaling-api-reviews-with-kube-api-linter&#34;&gt;Scaling API Reviews with &lt;code&gt;kube-api-linter&lt;/code&gt;&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#scaling-api-reviews-with-kube-api-linter&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Reaching GA required absolute confidence in the generated code, but our vision extends beyond just validation. Declarative validation is a key part of a comprehensive approach to making API review easier, more consistent, and highly scalable.&lt;/p&gt;
&lt;p&gt;By moving validation rules out of opaque Go functions and into structured markers, we are empowering tools like &lt;code&gt;kube-api-linter&lt;/code&gt;. This linter can now statically analyze API types and enforce API conventions automatically, significantly reducing the manual burden on SIG API Machinery reviewers and providing immediate feedback to contributors.&lt;/p&gt;
&lt;h2 id=&#34;what-s-next&#34;&gt;What&#39;s next?&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#what-s-next&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;With the release of Kubernetes v1.36, Declarative Validation graduates to General Availability (GA). As a stable feature, the associated &lt;code&gt;DeclarativeValidation&lt;/code&gt; feature gate is now enabled by default. It has become the primary mechanism for adding new validation rules to Kubernetes native types.&lt;/p&gt;
&lt;p&gt;Looking forward, the project is committed to adopting declarative validation even more extensively. This includes migrating the remaining legacy handwritten validation code for established APIs and requiring its use for all new APIs and new fields. This ongoing transition will continue to shrink the codebase&#39;s complexity while enhancing the consistency and reliability of the entire Kubernetes API surface.&lt;/p&gt;
&lt;p&gt;Beyond the core migration, declarative validation also unlocks an exciting future for the broader ecosystem. Because validation rules are now defined as structured markers rather than opaque Go code, they can be parsed and reflected in the OpenAPI schemas published by the Kubernetes API server. This paves the way for tools like &lt;code&gt;kubectl&lt;/code&gt;, client libraries, and IDEs to perform rich client-side validation before a request is ever sent to the cluster. The same declarative framework can also be consumed by ecosystem tools like Kubebuilder, enabling a more consistent developer experience for authors of Custom Resource Definitions (CRDs).&lt;/p&gt;
&lt;h2 id=&#34;getting-involved&#34;&gt;Getting involved&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#getting-involved&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The migration to declarative validation is an ongoing effort. While the framework itself is GA, there is still work to be done migrating older APIs to the new declarative format.&lt;/p&gt;
&lt;p&gt;If you are interested in contributing to the core of Kubernetes API Machinery, this is a fantastic place to start. Check out the &lt;code&gt;validation-gen&lt;/code&gt; documentation, look for issues tagged with &lt;code&gt;sig/api-machinery&lt;/code&gt;, and join the conversation in the &lt;a href=&#34;https://kubernetes.slack.com/messages/sig-api-machinery&#34;&gt;#sig-api-machinery&lt;/a&gt; and &lt;a href=&#34;https://kubernetes.slack.com/messages/sig-api-machinery-dev-tools&#34;&gt;#sig-api-machinery-dev-tools&lt;/a&gt; channels on Kubernetes Slack (for an invitation, visit &lt;a href=&#34;https://slack.k8s.io/&#34;&gt;https://slack.k8s.io/&lt;/a&gt;). You can also attend the &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-api-machinery#meetings&#34;&gt;SIG API Machinery meetings&lt;/a&gt; to get involved directly.&lt;/p&gt;
&lt;h2 id=&#34;acknowledgments&#34;&gt;Acknowledgments&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#acknowledgments&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;A huge thank you to everyone who helped bring this feature to GA:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/thockin&#34;&gt;Tim Hockin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/jpbetz&#34;&gt;Joe Betz&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/aaron-prindle&#34;&gt;Aaron Prindle&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/lalitc375&#34;&gt;Lalit Chauhan&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/deads2k&#34;&gt;David Eads&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/darshansreenivas&#34;&gt;Darshan Murthy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/liggitt&#34;&gt;Jordan Liggitt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/pohly&#34;&gt;Patrick Ohly&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/soltysh&#34;&gt;Maciej Szulik&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/wojtek-t&#34;&gt;Wojciech Tyczynski&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/JoelSpeed&#34;&gt;Joel Speed&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/everettraven&#34;&gt;Bryce Palmer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And the many others across the Kubernetes community who contributed along the way.&lt;/p&gt;
&lt;p&gt;Welcome to the declarative future of Kubernetes validation!&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes v1.36: Admission Policies That Can&#39;t Be Deleted</title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/05/04/kubernetes-v1-36-manifest-based-admission-control/</link>
      <pubDate>Mon, 04 May 2026 10:35:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/05/04/kubernetes-v1-36-manifest-based-admission-control/</guid>
      <description>
        
        
        &lt;p&gt;If you&#39;ve ever tried to enforce a security policy across a fleet of
Kubernetes clusters, you&#39;ve probably run into a frustrating chicken-and-egg
problem. Your admission policies are API objects, which means they don&#39;t
exist until someone creates them, and they can be deleted by anyone with
the right permissions. There&#39;s always a window during cluster bootstrap
where your policies aren&#39;t active yet, and there&#39;s no way to prevent a
privileged user from removing them.&lt;/p&gt;
&lt;p&gt;Kubernetes v1.36 introduces an alpha feature that addresses this:
&lt;em&gt;manifest-based admission control&lt;/em&gt;. It lets you define admission webhooks
and &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/reference/using-api/cel/&#34;&gt;CEL&lt;/a&gt;-based policies as files on disk, loaded by the API server at
startup, before it serves any requests.&lt;/p&gt;
&lt;h2 id=&#34;the-gap-we-re-closing&#34;&gt;The gap we&#39;re closing&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#the-gap-we-re-closing&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Most Kubernetes policy enforcement today works through the API. You create
a ValidatingAdmissionPolicy or a webhook configuration as an API object,
and the admission controller picks it up. This works well in steady state,
but it has some fundamental limitations.&lt;/p&gt;
&lt;p&gt;During cluster bootstrap, there&#39;s a gap between when the API server starts
serving requests and when your policies are created and active. If you&#39;re
restoring from a backup or recovering from an etcd failure, that gap can be
significant.&lt;/p&gt;
&lt;p&gt;There&#39;s also a self-protection problem. Admission webhooks and policies
can&#39;t intercept operations on their own configuration resources. Kubernetes
skips invoking webhooks on types like ValidatingWebhookConfiguration to
avoid circular dependencies. That means a sufficiently privileged user can
delete your critical admission policies, and there&#39;s nothing in the
admission chain to stop them.&lt;/p&gt;
&lt;p&gt;We - Kubernetes SIG API Machinery - wanted a way to say &amp;quot;these policies are always on, full stop.&amp;quot;&lt;/p&gt;
&lt;h2 id=&#34;how-it-works&#34;&gt;How it works&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#how-it-works&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;You add a &lt;code&gt;staticManifestsDir&lt;/code&gt; field to the &lt;code&gt;AdmissionConfiguration&lt;/code&gt; file
that you already pass to the API server via &lt;code&gt;--admission-control-config-file&lt;/code&gt;.
Point it at a directory, drop your policy YAML files in there, and the API
server loads them before it starts serving.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;apiserver.config.k8s.io/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;AdmissionConfiguration&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;plugins&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ValidatingAdmissionPolicy&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;configuration&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;apiserver.config.k8s.io/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ValidatingAdmissionPolicyConfiguration&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;staticManifestsDir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;/etc/kubernetes/admission/validating-policies/&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The manifest files are standard Kubernetes resource definitions. The only
requirement is that all the objects that these manifests define &lt;strong&gt;must&lt;/strong&gt; have names ending in &lt;code&gt;.static.k8s.io&lt;/code&gt;.
This reserved suffix prevents collisions with API-based configurations and
makes it easy to tell where an admission decision came from when you&#39;re
looking at metrics or audit logs.&lt;/p&gt;
&lt;p&gt;Here&#39;s a complete example that denies privileged containers outside
kube-system:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;admissionregistration.k8s.io/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ValidatingAdmissionPolicy&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;deny-privileged.static.k8s.io&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kubernetes.io/description&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Deny launching privileged pods, anywhere this policy is applied&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;failurePolicy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Fail&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;matchConstraints&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;resourceRules&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;apiGroups&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;apiVersions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;v1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;operations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;CREATE&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;UPDATE&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;resources&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;pods&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;variables&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;allContainers&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expression&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;-&lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sd&#34;&gt;      object.spec.containers +
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sd&#34;&gt;      (has(object.spec.initContainers) ? object.spec.initContainers : []) +
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sd&#34;&gt;      (has(object.spec.ephemeralContainers) ? object.spec.ephemeralContainers : [])&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;validations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;expression&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;-&lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sd&#34;&gt;      !variables.allContainers.exists(c,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sd&#34;&gt;      has(c.securityContext) &amp;amp;&amp;amp; has(c.securityContext.privileged) &amp;amp;&amp;amp;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sd&#34;&gt;      c.securityContext.privileged == true)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Privileged containers are not allowed&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;admissionregistration.k8s.io/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ValidatingAdmissionPolicyBinding&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;deny-privileged-binding.static.k8s.io&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kubernetes.io/description&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Bind deny-privileged policy to all namespaces except kube-system&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;policyName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;deny-privileged.static.k8s.io&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;validationActions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;Deny&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;matchResources&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;namespaceSelector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;matchExpressions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;kubernetes.io/metadata.name&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;operator&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;NotIn&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;values&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;kube-system&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;protecting-what-couldn-t-be-protected-before&#34;&gt;Protecting what couldn&#39;t be protected before&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#protecting-what-couldn-t-be-protected-before&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The part we&#39;re most excited about is the ability to intercept operations on
admission configuration resources themselves.&lt;/p&gt;
&lt;p&gt;With API-based admission, webhooks and policies are never invoked on types
like ValidatingAdmissionPolicy or ValidatingWebhookConfiguration. That
restriction exists for good reason: if a webhook could reject changes to
its own configuration, you could end up locked out with no way to fix it
through the API.&lt;/p&gt;
&lt;p&gt;Manifest-based policies don&#39;t have that problem. If a bad policy is
blocking something it shouldn&#39;t, you fix the file on disk and the API
server picks up the change. There&#39;s no circular dependency because the
recovery path doesn&#39;t go through the API.&lt;/p&gt;
&lt;p&gt;This means you can write a manifest-based policy that prevents deletion of
your critical API-based admission policies. For platform teams managing
shared clusters, this is a significant improvement. You can now guarantee
that your baseline security policies can&#39;t be removed by a cluster admin,
accidentally or otherwise.&lt;/p&gt;
&lt;p&gt;Here&#39;s what that looks like in practice. This policy prevents any
modification or deletion of admission resources that carry the
&lt;code&gt;platform.example.com/protected: &amp;quot;true&amp;quot;&lt;/code&gt; label:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;admissionregistration.k8s.io/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ValidatingAdmissionPolicy&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;protect-policies.static.k8s.io&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kubernetes.io/description&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Prevent modification or deletion of protected admission resources&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;failurePolicy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Fail&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;matchConstraints&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;resourceRules&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;apiGroups&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;admissionregistration.k8s.io&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;apiVersions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;*&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;operations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;DELETE&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;UPDATE&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;resources&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;s2&#34;&gt;&amp;#34;validatingadmissionpolicies&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;s2&#34;&gt;&amp;#34;validatingadmissionpolicybindings&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;s2&#34;&gt;&amp;#34;validatingwebhookconfigurations&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;s2&#34;&gt;&amp;#34;mutatingwebhookconfigurations&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;validations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;expression&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;-&lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sd&#34;&gt;      !has(oldObject.metadata.labels) ||
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sd&#34;&gt;      !(&amp;#39;platform.example.com/protected&amp;#39; in oldObject.metadata.labels) ||
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sd&#34;&gt;      oldObject.metadata.labels[&amp;#39;platform.example.com/protected&amp;#39;] != &amp;#39;true&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Protected admission resources cannot be modified or deleted&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;admissionregistration.k8s.io/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ValidatingAdmissionPolicyBinding&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;protect-policies-binding.static.k8s.io&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kubernetes.io/description&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Bind protect-policies policy to all admission resources&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;policyName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;protect-policies.static.k8s.io&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;validationActions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;Deny&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;With this in place, any API-based admission policy or webhook configuration
labeled &lt;code&gt;platform.example.com/protected: &amp;quot;true&amp;quot;&lt;/code&gt; is shielded from tampering.
The protection itself lives on disk and can&#39;t be removed through the API.&lt;/p&gt;
&lt;h2 id=&#34;a-few-things-to-know&#34;&gt;A few things to know&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#a-few-things-to-know&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Manifest-based configurations are intentionally self-contained. They can&#39;t
reference API resources, which means no &lt;code&gt;paramKind&lt;/code&gt; for policies, no
Service references for admission webhooks (instead they are URL-only),
and bindings may only reference
policies in the same manifest set. These restrictions exist because the
configurations need to work without any cluster state, including at startup
before etcd is available.&lt;/p&gt;
&lt;p&gt;If you run multiple API server instances, each one loads its own manifest
files independently. There&#39;s no cross-server synchronization built in. This
is the same model as other file-based API server configurations like
encryption at rest. When this feature is enabled, Kubernetes exposes a configuration hash as a label on relevant metrics, so you can
detect drift.&lt;/p&gt;
&lt;p&gt;Files are watched for changes at runtime, so you don&#39;t need to restart the
API server to update policies. If you update a manifest file, the API
server validates the new configuration and swaps it in atomically. If
validation fails, it keeps the previous good configuration and logs the
error. This means you can roll out policy changes across your fleet using
standard configuration management tools (Ansible, Puppet, or even mounted
ConfigMaps) without any API server downtime.&lt;/p&gt;
&lt;p&gt;The initial load at startup is stricter: if any manifest is invalid, the
API server won&#39;t start. This is intentional. At startup, failing fast is
safer than running without your expected policies.&lt;/p&gt;
&lt;h2 id=&#34;try-it-out&#34;&gt;Try it out&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#try-it-out&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;To try this in Kubernetes v1.36:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Enable the &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/reference/command-line-tools-reference/feature-gates/#ManifestBasedAdmissionControlConfig&#34;&gt;&lt;code&gt;ManifestBasedAdmissionControlConfig&lt;/code&gt;&lt;/a&gt;
feature gate for each kube-apiserver.&lt;/li&gt;
&lt;li&gt;Create a directory with your static manifest files.
If you need to mount that in to the Pod where the API server runs, do that too. Read-only is fine.&lt;/li&gt;
&lt;li&gt;Configure &lt;code&gt;staticManifestsDir&lt;/code&gt; in your &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/reference/access-authn-authz/admission-controllers/&#34;&gt;&lt;code&gt;AdmissionConfiguration&lt;/code&gt;&lt;/a&gt;
with the directory path.&lt;/li&gt;
&lt;li&gt;Start the API server with &lt;code&gt;--admission-control-config-file&lt;/code&gt; pointing to
your &lt;code&gt;AdmissionConfiguration&lt;/code&gt; file.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The full documentation is at
&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/reference/access-authn-authz/manifest-admission-control/&#34;&gt;Manifest-Based Admission Control&lt;/a&gt;,
and you can follow
&lt;a href=&#34;https://kep.k8s.io/5793&#34;&gt;KEP-5793&lt;/a&gt;
for ongoing progress.&lt;/p&gt;
&lt;p&gt;We&#39;d love to hear your feedback. Reach out on the
&lt;a href=&#34;https://kubernetes.slack.com/archives/C0EG7JC6T&#34;&gt;#sig-api-machinery&lt;/a&gt;
channel on Kubernetes Slack
(for an invitation, visit &lt;a href=&#34;https://slack.k8s.io/&#34;&gt;https://slack.k8s.io/&lt;/a&gt;).&lt;/p&gt;
&lt;h2 id=&#34;how-to-get-involved&#34;&gt;How to get involved&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#how-to-get-involved&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;If you&#39;re interested in contributing to this feature or other
SIG API Machinery projects, join us on
&lt;a href=&#34;https://kubernetes.slack.com/archives/C0EG7JC6T&#34;&gt;#sig-api-machinery&lt;/a&gt;
on Kubernetes Slack. You&#39;re also welcome to attend the
&lt;a href=&#34;https://github.com/kubernetes/community/blob/master/sig-api-machinery/README.md#meetings&#34;&gt;SIG API Machinery meetings&lt;/a&gt;,
held every other Wednesday.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes v1.36: Pod-Level Resource Managers (Alpha)</title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/05/01/kubernetes-v1-36-feature-pod-level-resource-managers-alpha/</link>
      <pubDate>Fri, 01 May 2026 10:35:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/05/01/kubernetes-v1-36-feature-pod-level-resource-managers-alpha/</guid>
      <description>
        
        
        &lt;p&gt;Kubernetes v1.36 introduces
&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/workloads/resource-managers/#pod-level-resource-managers&#34;&gt;Pod-Level Resource Managers&lt;/a&gt;
as an alpha feature, bringing a more flexible and powerful resource management
model to performance-sensitive workloads. This enhancement extends the kubelet&#39;s
Topology, CPU, and Memory Managers to support pod-level resource specifications
(&lt;code&gt;.spec.resources&lt;/code&gt;), evolving them from a strictly per-container allocation
model to a pod-centric one.&lt;/p&gt;
&lt;h2 id=&#34;why-do-we-need-pod-level-resource-managers&#34;&gt;Why do we need pod-level resource managers?&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#why-do-we-need-pod-level-resource-managers&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;When running performance-critical workloads such as machine learning (ML)
training, high-frequency trading applications, or low-latency databases, you
often need exclusive, NUMA-aligned resources for your primary application
containers to ensure predictable performance.&lt;/p&gt;
&lt;p&gt;However, modern Kubernetes pods rarely consist of just one container. They
frequently include sidecar containers for logging, monitoring, service meshes,
or data ingestion.&lt;/p&gt;
&lt;p&gt;Before this feature, this created a trade-off, to get NUMA-aligned, exclusive
resources for your main application, you had to allocate exclusive,
integer-based CPU resources to &lt;em&gt;every&lt;/em&gt; container in the pod. This might be
wasteful for lightweight sidecars. If you didn&#39;t do this, you forfeited the
pod&#39;s Guaranteed Quality of Service (QoS) class entirely, losing the performance
benefits.&lt;/p&gt;
&lt;h2 id=&#34;introducing-pod-level-resource-managers&#34;&gt;Introducing pod-level resource managers&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#introducing-pod-level-resource-managers&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Enabling pod-level resources support for the resource managers (via the
&lt;code&gt;PodLevelResourceManagers&lt;/code&gt; and &lt;code&gt;PodLevelResources&lt;/code&gt; feature gates) allows the
kubelet to create &lt;strong&gt;hybrid resource allocation models&lt;/strong&gt;. This brings flexibility
and efficiency to high-performance workloads without sacrificing NUMA alignment.&lt;/p&gt;
&lt;h3 id=&#34;real-world-use-cases&#34;&gt;Real-world use cases&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#real-world-use-cases&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Here are a few practical scenarios demonstrating how this feature can be
applied, depending on the configured Topology Manager scope:&lt;/p&gt;
&lt;h4 id=&#34;1-tightly-coupled-database-topology-manager-s-pod-scope&#34;&gt;1. Tightly-coupled database (Topology manager&#39;s pod scope)&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#1-tightly-coupled-database-topology-manager-s-pod-scope&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;Consider a latency-sensitive database pod that includes a main database
container, a local metrics exporter, and a backup agent sidecar.&lt;/p&gt;
&lt;p&gt;When configured with the &lt;code&gt;pod&lt;/code&gt; Topology Manager scope, the kubelet performs a
single NUMA alignment based on the entire pod&#39;s budget. The database container
gets its exclusive CPU and memory slices from that NUMA node. The remaining
resources from the pod&#39;s budget form a new &lt;strong&gt;pod shared pool&lt;/strong&gt;. The metrics
exporter and backup agent run in this pod shared pool. They share resources with
each other, but they are strictly isolated from the database&#39;s exclusive slices
and the rest of the node.&lt;/p&gt;
&lt;p&gt;This allows you to safely co-locate auxiliary containers on the same NUMA node
as your primary workload without wasting dedicated cores on them.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Pod&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;tightly-coupled-database&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# Pod-level resources establish the overall budget and NUMA alignment size.&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;resources&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;requests&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;cpu&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;8&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;memory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;16Gi&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;limits&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;cpu&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;8&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;memory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;16Gi&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;initContainers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;metrics-exporter&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;metrics-exporter:v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;restartPolicy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Always&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;backup-agent&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;backup-agent:v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;restartPolicy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Always&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;containers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;database&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;database:v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# This Guaranteed container gets an exclusive 6 CPU slice from the pod&amp;#39;s budget.&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# The remaining 2 CPUs and 4Gi memory form the pod shared pool for the sidecars.&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;resources&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;requests&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;cpu&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;6&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;memory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;12Gi&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;limits&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;cpu&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;6&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;memory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;12Gi&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;2-ml-workload-with-infrastructure-sidecars-topology-manager-s-container-scope&#34;&gt;2. ML workload with infrastructure sidecars (Topology manager&#39;s container scope)&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#2-ml-workload-with-infrastructure-sidecars-topology-manager-s-container-scope&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;Imagine a pod running a GPU-accelerated ML training workload alongside a generic
service mesh sidecar.&lt;/p&gt;
&lt;p&gt;Under the &lt;code&gt;container&lt;/code&gt; Topology Manager scope, the kubelet evaluates each
container individually. You can grant the ML container exclusive, NUMA-aligned
CPUs and Memory for maximum performance. Meanwhile, the service mesh sidecar
doesn&#39;t need to be NUMA-aligned; it can run in the general node-wide shared
pool. The collective resource consumption is still safely bounded by the overall
pod limits, but you only allocate NUMA-aligned, exclusive resources to the
specific containers that actually require them.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Pod&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ml-workload&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# Pod-level resources establish the overall budget constraint.&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;resources&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;requests&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;cpu&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;4&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;memory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;8Gi&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;limits&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;cpu&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;4&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;memory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;8Gi&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;initContainers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;service-mesh-sidecar&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;service-mesh:v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;restartPolicy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Always&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;containers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ml-training&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ml-training:v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# Under the &amp;#39;container&amp;#39; scope, this Guaranteed container receives exclusive,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# NUMA-aligned resources, while the sidecar runs in the node&amp;#39;s shared pool.&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;resources&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;requests&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;cpu&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;3&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;memory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;6Gi&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;limits&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;cpu&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;3&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;memory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;6Gi&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;cpu-quotas-cfs-and-isolation&#34;&gt;CPU quotas (CFS) and isolation&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#cpu-quotas-cfs-and-isolation&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;When running these mixed workloads within a pod, isolation is enforced
differently depending on the allocation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Exclusive containers:&lt;/strong&gt; Containers granted exclusive CPU slices have their
CPU CFS quota enforcement disabled at the container level, allowing them to
run without being throttled by the Linux scheduler.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pod shared pool containers:&lt;/strong&gt; Containers falling into the pod shared pool
have CPU CFS quotas enforced at the pod level, ensuring they do not consume
more than the leftover pod budget.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;how-to-enable-pod-level-resource-managers&#34;&gt;How to enable Pod-Level Resource Managers&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#how-to-enable-pod-level-resource-managers&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Using this feature requires Kubernetes v1.36 or newer. To enable it, you must
configure the kubelet with the appropriate feature gates and policies:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Enable the &lt;code&gt;PodLevelResources&lt;/code&gt; and &lt;code&gt;PodLevelResourceManagers&lt;/code&gt;
&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/reference/command-line-tools-reference/feature-gates/&#34;&gt;feature gates&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Configure the
&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/tasks/administer-cluster/topology-manager/#topology-manager-policies&#34;&gt;Topology Manager&lt;/a&gt;
with a policy other than &lt;code&gt;none&lt;/code&gt; (i.e., &lt;code&gt;best-effort&lt;/code&gt;, &lt;code&gt;restricted&lt;/code&gt;, or
&lt;code&gt;single-numa-node&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Set the
&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/tasks/administer-cluster/topology-manager/#topology-manager-scopes&#34;&gt;Topology Manager scope&lt;/a&gt;
to either &lt;code&gt;pod&lt;/code&gt; or &lt;code&gt;container&lt;/code&gt; using the &lt;code&gt;topologyManagerScope&lt;/code&gt; field in the
&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/reference/config-api/kubelet-config.v1beta1/&#34;&gt;&lt;code&gt;KubeletConfiguration&lt;/code&gt;&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Configure the
&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/tasks/administer-cluster/cpu-management-policies/&#34;&gt;CPU Manager&lt;/a&gt; with
the &lt;code&gt;static&lt;/code&gt; policy.&lt;/li&gt;
&lt;li&gt;Configure the
&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/tasks/administer-cluster/memory-manager/&#34;&gt;Memory Manager&lt;/a&gt; with the
&lt;code&gt;Static&lt;/code&gt; policy.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;observability&#34;&gt;Observability&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#observability&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;To help cluster administrators monitor and debug these new allocation models, we
have introduced several new kubelet metrics when the feature gate is enabled:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;resource_manager_allocations_total&lt;/code&gt;: Counts the total number of exclusive
resource allocations performed by a manager. The &lt;code&gt;source&lt;/code&gt; label (&amp;quot;pod&amp;quot; or
&amp;quot;node&amp;quot;) distinguishes between allocations drawn from the node-level pool
versus a pre-allocated pod-level pool.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;resource_manager_allocation_errors_total&lt;/code&gt;: Counts errors encountered during
exclusive resource allocation, distinguished by the intended allocation
&lt;code&gt;source&lt;/code&gt; (&amp;quot;pod&amp;quot; or &amp;quot;node&amp;quot;).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;resource_manager_container_assignments&lt;/code&gt;: Tracks the cumulative number of
containers running with specific assignment types. The &lt;code&gt;assignment_type&lt;/code&gt;
label (&amp;quot;node_exclusive&amp;quot;, &amp;quot;pod_exclusive&amp;quot;, &amp;quot;pod_shared&amp;quot;) provides visibility
into how workloads are distributed.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;current-limitations-and-caveats&#34;&gt;Current limitations and caveats&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#current-limitations-and-caveats&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;While this feature opens up new possibilities, there are a few things to keep in
mind during its alpha phase. Be sure to review the
&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/workloads/resource-managers/#limitations-and-caveats&#34;&gt;Limitations and caveats&lt;/a&gt;
in the official documentation for full details on compatibility, requirements,
and downgrade instructions.&lt;/p&gt;
&lt;h2 id=&#34;getting-started-and-providing-feedback&#34;&gt;Getting started and providing feedback&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#getting-started-and-providing-feedback&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;For a deep dive into the technical details and configuration of this feature,
check out the official concept documentation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/workloads/resource-managers/#pod-level-resource-managers&#34;&gt;Pod-level resource managers&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To learn more about the overall pod-level resources feature and how to assign
resources to pods, see:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/tasks/configure-pod-container/assign-pod-level-resources/&#34;&gt;Assign Pod-level CPU and memory resources&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As this feature moves through Alpha, your feedback is invaluable. Please report
any issues or share your experiences via the standard Kubernetes communication
channels:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Slack: &lt;a href=&#34;https://kubernetes.slack.com/messages/sig-node&#34;&gt;#sig-node&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://groups.google.com/forum/#!forum/kubernetes-sig-node&#34;&gt;Mailing list&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/community/labels/sig%2Fnode&#34;&gt;Open Community Issues/PRs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes v1.36: In-Place Vertical Scaling for Pod-Level Resources Graduates to Beta</title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/04/30/kubernetes-v1-36-inplace-pod-level-resources-beta/</link>
      <pubDate>Thu, 30 Apr 2026 10:35:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/04/30/kubernetes-v1-36-inplace-pod-level-resources-beta/</guid>
      <description>
        
        
        &lt;p&gt;Following the graduation of Pod-Level Resources to Beta in v1.34 and the General Availability (GA) of In-Place Pod Vertical Scaling in v1.35, the Kubernetes community is thrilled to announce that &lt;strong&gt;In-Place Pod-Level Resources Vertical Scaling has graduated to Beta in v1.36!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This feature is now enabled by default via the &lt;code&gt;InPlacePodLevelResourcesVerticalScaling&lt;/code&gt; feature gate. It allows users to update the aggregate Pod resource budget (&lt;code&gt;.spec.resources&lt;/code&gt;) for a running Pod, &lt;strong&gt;often without requiring a container restart.&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;why-pod-level-in-place-resize&#34;&gt;Why Pod-level in-place resize?&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#why-pod-level-in-place-resize&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The Pod-level resource model simplified management for complex Pods (such as those with sidecars) by allowing containers to share a collective pool of resources. In v1.36, you can now adjust this aggregate boundary on-the-fly.&lt;/p&gt;
&lt;p&gt;This is particularly useful for Pods where containers do not have individual limits defined. These containers automatically scale their effective boundaries to fit the newly resized Pod-level dimensions, allowing you to expand the shared pool during peak demand without manual per-container recalculations.&lt;/p&gt;
&lt;h2 id=&#34;resource-inheritance-and-the-resizepolicy&#34;&gt;Resource inheritance and the &lt;code&gt;resizePolicy&lt;/code&gt;&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#resource-inheritance-and-the-resizepolicy&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;When a Pod-level resize is initiated, the Kubelet treats the change as a resize event for every container that inherits its limits from the Pod-level budget. To determine whether a restart is required, the Kubelet consults the &lt;code&gt;resizePolicy&lt;/code&gt; defined within individual containers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Non-disruptive Updates:&lt;/strong&gt; If a container&#39;s &lt;code&gt;restartPolicy&lt;/code&gt; is set to &lt;code&gt;NotRequired&lt;/code&gt;, the Kubelet attempts to update the cgroup limits dynamically via the Container Runtime Interface (CRI).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Disruptive Updates:&lt;/strong&gt; If set to &lt;code&gt;RestartContainer&lt;/code&gt;, the container will be restarted to apply the new aggregate boundary safely.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Currently, &lt;code&gt;resizePolicy&lt;/code&gt; is not supported at the Pod level. The Kubelet always defers to individual container settings to decide if an update can be applied in-place or requires a restart.&lt;/p&gt;&lt;/blockquote&gt;
&lt;h2 id=&#34;example-scaling-a-shared-resource-pool&#34;&gt;Example: Scaling a shared resource pool&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#example-scaling-a-shared-resource-pool&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;In this scenario, a Pod is defined with a 2 CPU pod-level limit. Because the individual containers do not have their own limits defined, they share this total pool.&lt;/p&gt;
&lt;h3 id=&#34;1-initial-pod-specification&#34;&gt;1. Initial Pod specification&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#1-initial-pod-specification&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Pod&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;shared-pool-app&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;resources&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# Pod-level limits&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;limits&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;cpu&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;2&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;memory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;4Gi&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;containers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;main-app&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;my-app:v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;resizePolicy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;{&lt;span class=&#34;nt&#34;&gt;resourceName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;cpu&amp;#34;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;, restartPolicy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;NotRequired&amp;#34;&lt;/span&gt;}&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;sidecar&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;logger:v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;resizePolicy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;{&lt;span class=&#34;nt&#34;&gt;resourceName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;cpu&amp;#34;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;, restartPolicy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;NotRequired&amp;#34;&lt;/span&gt;}&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;2-the-resize-operation&#34;&gt;2. The resize operation&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#2-the-resize-operation&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;To double the CPU capacity to 4 CPUs, apply a patch using the &lt;code&gt;resize&lt;/code&gt; subresource:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl patch pod shared-pool-app --subresource resize --patch &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;s1&#34;&gt;&amp;#39;{&amp;#34;spec&amp;#34;:{&amp;#34;resources&amp;#34;:{&amp;#34;limits&amp;#34;:{&amp;#34;cpu&amp;#34;:&amp;#34;4&amp;#34;}}}}&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;node-level-reality-feasibility-and-safety&#34;&gt;Node-Level reality: feasibility and safety&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#node-level-reality-feasibility-and-safety&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Applying a resize patch is only the first step. The Kubelet performs several checks and follows a specific sequence to ensure node stability:&lt;/p&gt;
&lt;h3 id=&#34;1-the-feasibility-check&#34;&gt;1. The feasibility check&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#1-the-feasibility-check&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Before admitting a resize, the Kubelet verifies if the new aggregate request fits within the Node&#39;s allocatable capacity. If the Node is overcommitted, the resize is not ignored; instead, the &lt;code&gt;PodResizePending&lt;/code&gt; condition will reflect a &lt;code&gt;Deferred&lt;/code&gt; or &lt;code&gt;Infeasible&lt;/code&gt; status, providing immediate feedback on why the &amp;quot;envelope&amp;quot; hasn&#39;t grown.&lt;/p&gt;
&lt;h3 id=&#34;2-update-sequencing&#34;&gt;2. Update sequencing&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#2-update-sequencing&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;To prevent resource &amp;quot;overshoot&amp;quot;, the Kubelet coordinates the cgroup updates in a specific order:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;When Increasing:&lt;/strong&gt; The Pod-level cgroup is expanded first, creating the &amp;quot;room&amp;quot; before the individual container cgroups are enlarged.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;When Decreasing:&lt;/strong&gt; The container cgroups are throttled first, and only then is the aggregate Pod-level cgroup shrunken.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;observability-tracking-resize-status&#34;&gt;Observability: tracking resize status&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#observability-tracking-resize-status&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;With the move to Beta, Kubernetes uses &lt;strong&gt;Pod Conditions&lt;/strong&gt; to track the lifecycle of a resize:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;PodResizePending&lt;/code&gt;&lt;/strong&gt;: The spec is updated, but the Node hasn&#39;t admitted the change (e.g., due to capacity).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;PodResizeInProgress&lt;/code&gt;&lt;/strong&gt;: The Node has admitted the resize (&lt;code&gt;status.allocatedResources&lt;/code&gt;) but the changes aren&#39;t yet fully applied to the cgroups (&lt;code&gt;status.resources&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;status&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;allocatedResources&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;cpu&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;4&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;resources&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;limits&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;cpu&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;4&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;conditions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;PodResizeInProgress&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;status&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;True&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;constraints-and-requirements&#34;&gt;Constraints and requirements&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#constraints-and-requirements&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;cgroup v2 Only:&lt;/strong&gt; Required for accurate aggregate enforcement.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CRI Support:&lt;/strong&gt; Requires a container runtime that supports the &lt;code&gt;UpdateContainerResources&lt;/code&gt; CRI call (e.g., containerd v2.0+ or CRI-O).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Feature Gates:&lt;/strong&gt; Requires &lt;code&gt;PodLevelResources&lt;/code&gt;, &lt;code&gt;InPlacePodVerticalScaling&lt;/code&gt;, &lt;code&gt;InPlacePodLevelResourcesVerticalScaling&lt;/code&gt;, and &lt;code&gt;NodeDeclaredFeatures&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Linux Only:&lt;/strong&gt; Currently exclusive to Linux-based nodes.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;what-s-next&#34;&gt;What&#39;s next?&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#what-s-next&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;As we move toward General Availability (GA), the community is focusing on &lt;strong&gt;Vertical Pod Autoscaler (VPA) Integration&lt;/strong&gt;, enabling VPA to issue Pod-level resource recommendations and trigger in-place actuation automatically.&lt;/p&gt;
&lt;h2 id=&#34;getting-started-and-providing-feedback&#34;&gt;Getting started and providing feedback&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#getting-started-and-providing-feedback&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;We encourage you to test this feature and provide feedback via the standard Kubernetes communication channels:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Slack: &lt;a href=&#34;https://kubernetes.slack.com/messages/sig-node&#34;&gt;#sig-node&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://groups.google.com/forum/#!forum/kubernetes-sig-node&#34;&gt;Mailing list&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/community/labels/sig%2Fnode&#34;&gt;Open Community Issues/PRs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes v1.36: Tiered Memory Protection with Memory QoS</title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/04/29/kubernetes-v1-36-memory-qos-tiered-protection/</link>
      <pubDate>Wed, 29 Apr 2026 10:35:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/04/29/kubernetes-v1-36-memory-qos-tiered-protection/</guid>
      <description>
        
        
        &lt;p&gt;On behalf of SIG Node, we are pleased to announce updates to the Memory QoS
feature (alpha) in Kubernetes v1.36. Memory QoS uses the cgroup v2 memory
controller to give the kernel better guidance on how to treat container memory.
It was first introduced in v1.22 and updated in v1.27. In Kubernetes v1.36, we&#39;re introducing: opt-in memory reservation, tiered
protection by QoS class, observability metrics, and kernel-version warning for &lt;code&gt;memory.high&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;what-s-new-in-v1-36&#34;&gt;What&#39;s new in v1.36&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#what-s-new-in-v1-36&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;h3 id=&#34;opt-in-memory-reservation-with-memoryreservationpolicy&#34;&gt;Opt-in memory reservation with &lt;code&gt;memoryReservationPolicy&lt;/code&gt;&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#opt-in-memory-reservation-with-memoryreservationpolicy&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;v1.36 separates throttling from reservation. Enabling the feature gate turns on
&lt;code&gt;memory.high&lt;/code&gt; throttling (the kubelet sets &lt;code&gt;memory.high&lt;/code&gt; based on
&lt;code&gt;memoryThrottlingFactor&lt;/code&gt;, default 0.9), but memory reservation is now controlled
by a separate kubelet configuration field:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;None&lt;/code&gt;&lt;/strong&gt; (default): no &lt;code&gt;memory.min&lt;/code&gt; or &lt;code&gt;memory.low&lt;/code&gt; is written. Throttling
via &lt;code&gt;memory.high&lt;/code&gt; still works.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;TieredReservation&lt;/code&gt;&lt;/strong&gt;: the kubelet writes tiered memory protection based on the Pod&#39;s
&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/workloads/pods/pod-qos/&#34;&gt;QoS class&lt;/a&gt;:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Guaranteed&lt;/strong&gt; Pods get hard protection via &lt;code&gt;memory.min&lt;/code&gt;. For example, a
Guaranteed Pod requesting 512 MiB of memory results in:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-none&#34; data-lang=&#34;none&#34;&gt;$ cat /sys/fs/cgroup/kubepods.slice/kubepods-pod6a4f2e3b_1c9d_4a5e_8f7b_2d3e4f5a6b7c.slice/memory.min
536870912
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The kernel will not reclaim this memory under any circumstances. If it cannot
honor the guarantee, it invokes the OOM killer on other processes to free pages.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Burstable&lt;/strong&gt; Pods get soft protection via &lt;code&gt;memory.low&lt;/code&gt;. For the same 512 MiB
request on a Burstable Pod:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-none&#34; data-lang=&#34;none&#34;&gt;$ cat /sys/fs/cgroup/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod8b3c7d2e_4f5a_6b7c_9d1e_3f4a5b6c7d8e.slice/memory.low
536870912
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The kernel avoids reclaiming this memory under normal pressure, but may reclaim
it if the alternative is a system-wide OOM.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;BestEffort&lt;/strong&gt; Pods get neither &lt;code&gt;memory.min&lt;/code&gt; nor &lt;code&gt;memory.low&lt;/code&gt;. Their memory
remains fully reclaimable.&lt;/p&gt;
&lt;h4 id=&#34;comparison-with-v1-27-behavior&#34;&gt;Comparison with v1.27 behavior&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#comparison-with-v1-27-behavior&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;In earlier versions, enabling the MemoryQoS feature gate immediately set &lt;code&gt;memory.min&lt;/code&gt; for every container with a memory request. &lt;code&gt;memory.min&lt;/code&gt; is a hard reservation that the kernel will not reclaim, regardless of memory pressure.&lt;/p&gt;
&lt;p&gt;Consider a node with 8 GiB of RAM where Burstable Pod requests total 7 GiB. In earlier versions, that 7 GiB would be locked as &lt;code&gt;memory.min&lt;/code&gt;, leaving little headroom for the kernel, system daemons, or BestEffort workloads and increasing the risk of OOM kills.&lt;/p&gt;
&lt;p&gt;With v1.36 tiered reservation, those Burstable requests map to &lt;code&gt;memory.low&lt;/code&gt; instead of &lt;code&gt;memory.min&lt;/code&gt;. Under normal pressure, the kernel still protects that memory, but under extreme pressure it can reclaim part of it to avoid system-wide OOM. Only Guaranteed Pods use &lt;code&gt;memory.min&lt;/code&gt;, which keeps hard reservation lower.&lt;/p&gt;
&lt;p&gt;With &lt;code&gt;memoryReservationPolicy&lt;/code&gt; in v1.36, you can enable throttling first, observe workload behavior, and opt into reservation when your node has enough headroom.&lt;/p&gt;
&lt;h3 id=&#34;observability-metrics&#34;&gt;Observability metrics&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#observability-metrics&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Two alpha-stability metrics are exposed on the kubelet &lt;code&gt;/metrics&lt;/code&gt; endpoint:&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Metric&lt;/th&gt;
          &lt;th&gt;Description&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;kubelet_memory_qos_node_memory_min_bytes&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;Total &lt;code&gt;memory.min&lt;/code&gt; across Guaranteed Pods&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;kubelet_memory_qos_node_memory_low_bytes&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;Total &lt;code&gt;memory.low&lt;/code&gt; across Burstable Pods&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;These are useful for capacity planning. If &lt;code&gt;kubelet_memory_qos_node_memory_min_bytes&lt;/code&gt;
is creeping toward your node&#39;s physical memory, you know hard reservation is
getting tight.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-none&#34; data-lang=&#34;none&#34;&gt;$ curl -sk https://localhost:10250/metrics | grep memory_qos
# HELP kubelet_memory_qos_node_memory_min_bytes [ALPHA] Total memory.min in bytes for Guaranteed pods
kubelet_memory_qos_node_memory_min_bytes 5.36870912e+08
# HELP kubelet_memory_qos_node_memory_low_bytes [ALPHA] Total memory.low in bytes for Burstable pods
kubelet_memory_qos_node_memory_low_bytes 2.147483648e+09
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;kernel-version-check&#34;&gt;Kernel version check&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#kernel-version-check&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;On kernels older than 5.9, &lt;code&gt;memory.high&lt;/code&gt; throttling can trigger the
&lt;a href=&#34;https://lore.kernel.org/all/a4e23b59e9ef499b575ae73a8120ee089b7d3373.1594640214.git.chris@chrisdown.name/&#34;&gt;kernel livelock&lt;/a&gt; issue. The bug was fixed
in kernel 5.9. In v1.36, when the feature gate is enabled, the kubelet checks the
kernel version at startup and logs a warning if it is below 5.9. The feature
continues to work — this is informational, not a hard block.&lt;/p&gt;
&lt;h3 id=&#34;how-kubernetes-maps-memory-qos-to-cgroup-v2&#34;&gt;How Kubernetes maps Memory QoS to cgroup v2&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#how-kubernetes-maps-memory-qos-to-cgroup-v2&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Memory QoS uses four cgroup v2 memory controller interfaces:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;memory.max&lt;/code&gt;&lt;/strong&gt;: hard memory limit — unchanged from previous versions&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;memory.min&lt;/code&gt;&lt;/strong&gt;: hard memory protection — with &lt;code&gt;TieredReservation&lt;/code&gt;, set only for Guaranteed Pods&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;memory.low&lt;/code&gt;&lt;/strong&gt;: soft memory protection — set for Burstable Pods with &lt;code&gt;TieredReservation&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;memory.high&lt;/code&gt;&lt;/strong&gt;: memory throttling threshold — unchanged from previous versions&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The following table shows how Kubernetes container resources map to cgroup v2
interfaces when &lt;code&gt;memoryReservationPolicy: TieredReservation&lt;/code&gt; is configured.
With the default &lt;code&gt;memoryReservationPolicy: None&lt;/code&gt;, no &lt;code&gt;memory.min&lt;/code&gt; or
&lt;code&gt;memory.low&lt;/code&gt; values are set.&lt;/p&gt;
&lt;table&gt;
    &lt;tr&gt;
        &lt;th&gt;QoS Class&lt;/th&gt;
        &lt;th&gt;&lt;tt&gt;memory.min&lt;/tt&gt;&lt;/th&gt;
        &lt;th&gt;&lt;tt&gt;memory.low&lt;/tt&gt;&lt;/th&gt;
        &lt;th&gt;&lt;tt&gt;memory.high&lt;/tt&gt;&lt;/th&gt;
        &lt;th&gt;&lt;tt&gt;memory.max&lt;/tt&gt;&lt;/th&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;&lt;b&gt;Guaranteed&lt;/b&gt;&lt;/td&gt;
        &lt;td&gt;Set to &lt;code&gt;requests.memory&lt;/code&gt;&lt;br&gt;(hard protection)&lt;/td&gt;
        &lt;td&gt;Not set&lt;/td&gt;
        &lt;td&gt;Not set&lt;br&gt;(requests == limits, so throttling is not useful)&lt;/td&gt;
        &lt;td&gt;Set to &lt;code&gt;limits.memory&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;&lt;b&gt;Burstable&lt;/b&gt;&lt;/td&gt;
        &lt;td&gt;Not set&lt;/td&gt;
        &lt;td&gt;Set to &lt;code&gt;requests.memory&lt;/code&gt;&lt;br&gt;(soft protection)&lt;/td&gt;
        &lt;td&gt;Calculated based on&lt;br&gt;formula with throttling factor&lt;/td&gt;
        &lt;td&gt;Set to &lt;code&gt;limits.memory&lt;/code&gt;&lt;br&gt;(if specified)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;&lt;b&gt;BestEffort&lt;/b&gt;&lt;/td&gt;
        &lt;td&gt;Not set&lt;/td&gt;
        &lt;td&gt;Not set&lt;/td&gt;
        &lt;td&gt;Calculated based on&lt;br&gt;node allocatable memory&lt;/td&gt;
        &lt;td&gt;Not set&lt;/td&gt;
    &lt;/tr&gt;
&lt;/table&gt;
&lt;h3 id=&#34;cgroup-hierarchy&#34;&gt;Cgroup hierarchy&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#cgroup-hierarchy&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;cgroup v2 requires that a parent cgroup&#39;s memory protection is at least as
large as the sum of its children&#39;s. The kubelet maintains this by setting
&lt;code&gt;memory.min&lt;/code&gt; on the kubepods root cgroup to the sum of all Guaranteed and
Burstable Pod memory requests, and &lt;code&gt;memory.low&lt;/code&gt; on the Burstable QoS cgroup
to the sum of all Burstable Pod memory requests. This way the kernel can
enforce the per-container and per-pod protection values correctly.&lt;/p&gt;
&lt;p&gt;The kubelet manages pod-level and QoS-class cgroups directly using the runc
libcontainer library, while container-level cgroups are managed by the
container runtime (containerd or CRI-O).&lt;/p&gt;
&lt;h2 id=&#34;how-do-i-use-it&#34;&gt;How do I use it?&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#how-do-i-use-it&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;h3 id=&#34;prerequisites&#34;&gt;Prerequisites&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#prerequisites&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;Kubernetes v1.36 or later&lt;/li&gt;
&lt;li&gt;Linux with cgroup v2. Kernel 5.9 or higher is recommended — earlier kernels
work but may experience the livelock issue. You can verify cgroup v2 is
active by running &lt;code&gt;mount | grep cgroup2&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;A container runtime that supports cgroup v2 (containerd 1.6+, CRI-O 1.22+)&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;configuration&#34;&gt;Configuration&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#configuration&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;To enable Memory QoS with tiered protection:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;kubelet.config.k8s.io/v1beta1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;KubeletConfiguration&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;featureGates&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;MemoryQoS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;memoryReservationPolicy: TieredReservation  # Options&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;None (default), TieredReservation&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;memoryThrottlingFactor: 0.9  # Optional&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;default is 0.9&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If you want &lt;code&gt;memory.high&lt;/code&gt; throttling without memory protection, omit
&lt;code&gt;memoryReservationPolicy&lt;/code&gt; or set it to &lt;code&gt;None&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;kubelet.config.k8s.io/v1beta1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;KubeletConfiguration&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;featureGates&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;MemoryQoS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;memoryReservationPolicy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;None &lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# This is the default&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;how-can-i-learn-more&#34;&gt;How can I learn more?&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#how-can-i-learn-more&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/2570&#34;&gt;KEP-2570: Memory QoS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/workloads/pods/pod-qos/&#34;&gt;Pod Quality of Service Classes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/configuration/manage-resources-containers/&#34;&gt;Managing Resources for Containers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/architecture/cgroups/&#34;&gt;Kubernetes cgroups v2 support&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.kernel.org/admin-guide/cgroup-v2.html&#34;&gt;Linux kernel cgroups v2 documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;getting-involved&#34;&gt;Getting involved&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#getting-involved&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;This feature is driven by &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-node&#34;&gt;SIG Node&lt;/a&gt;.
If you are interested in contributing or have feedback, you can find us on
&lt;a href=&#34;https://kubernetes.slack.com/messages/sig-node&#34;&gt;Slack&lt;/a&gt; (#sig-node), the
&lt;a href=&#34;https://groups.google.com/forum/#!forum/kubernetes-sig-node&#34;&gt;mailing list&lt;/a&gt;,
or at the regular
&lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-node#meetings&#34;&gt;SIG Node meetings&lt;/a&gt;.
Please file bugs at &lt;a href=&#34;https://github.com/kubernetes/kubernetes/issues&#34;&gt;kubernetes/kubernetes&lt;/a&gt;
and enhancement proposals at
&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/2570&#34;&gt;kubernetes/enhancements&lt;/a&gt;.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes v1.36: Staleness Mitigation and Observability for Controllers</title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/04/28/kubernetes-v1-36-staleness-mitigation-for-controllers/</link>
      <pubDate>Tue, 28 Apr 2026 10:35:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/04/28/kubernetes-v1-36-staleness-mitigation-for-controllers/</guid>
      <description>
        
        
        &lt;p&gt;Staleness in Kubernetes controllers is a problem that affects many controllers, and is something may affect controller behavior
in subtle ways. It is usually not until it is too late, when a controller in production has already taken incorrect action, that
staleness is found to be an issue due to some underlying assumption made by the controller author. Some issues caused by staleness
include controllers taking incorrect actions, controllers not taking action when they should, and controllers taking too long to
take action. I am excited to announce that Kubernetes v1.36 includes new features that help mitigate staleness in controllers
and provide better observability into controller behavior.&lt;/p&gt;
&lt;h2 id=&#34;what-is-staleness&#34;&gt;What is staleness?&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#what-is-staleness&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Staleness in controllers comes from an outdated view of the world inside of the controller cache. In order to provide a fast user
experience, controllers typically maintain a local cache of the state of the cluster. This cache is populated by watching the
Kubernetes API server for changes to objects that the controller cares about. When the controller needs to take action, it will
first check its cache to see if it has the latest information. If it does not, it will then update its cache by watching the API
server for changes to objects that the controller cares about. This process is known as &lt;em&gt;reconciliation&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;However, there are some cases where the controller&#39;s cache may be outdated. For example, if the controller is restarted, it will
need to rebuild its cache by watching the API server for changes to objects that the controller cares about. During this time, the
controller&#39;s cache will be outdated, and it will not be able to take action. Additionally, if the API server is down, the controller&#39;s
cache will not be updated, and it will not be able to take action. These are just a few examples of cases where the controller&#39;s
cache may be outdated.&lt;/p&gt;
&lt;h2 id=&#34;improvements-in-1-36&#34;&gt;Improvements in 1.36&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#improvements-in-1-36&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Kubernetes v1.36 includes improvements in both client-go as well as implementations of highly contended controllers in
kube-controller-manager, using those client-go improvements.&lt;/p&gt;
&lt;h3 id=&#34;client-go-improvements&#34;&gt;client-go improvements&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#client-go-improvements&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;In client-go, the project added &lt;em&gt;atomic FIFO processing&lt;/em&gt; (feature gate
name &lt;code&gt;AtomicFIFO&lt;/code&gt;), which is on top of the existing FIFO queue implementation. The new approach allows for
the queue to atomically handle operations that are received in batches, such as the initial set of objects from a
&lt;em&gt;list&lt;/em&gt; operation that an informer uses to populate its cache. This ensures that the queue is always in a consistent state,
even when events come out of order. Prior to this, events were added to the queue
in the order that they were received, which could lead to an inconsistent state in the cache that does not accurately reflect
the state of the cluster.&lt;/p&gt;
&lt;p&gt;With this change, you can now ensure that the queue is always in a consistent state, even when events come out of order. To take
advantage of this, clients using client-go can now introspect into the cache to determine the latest resource version that the
controller cache has seen. This is done with the newly added function &lt;code&gt;LastStoreSyncResourceVersion()&lt;/code&gt; implemented on the &lt;code&gt;Store&lt;/code&gt;
interface &lt;a href=&#34;https://pkg.go.dev/k8s.io/client-go@v0.36.0/tools/cache#Store&#34;&gt;here&lt;/a&gt;. This function is the basis for the staleness mitigation
features in kube-controller-manager.&lt;/p&gt;
&lt;h3 id=&#34;kube-controller-manager-improvements&#34;&gt;kube-controller-manager improvements&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#kube-controller-manager-improvements&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;In kube-controller-manager, the v1.36 release has added the ability for 4 different controllers to use this new capability. The controllers are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;DaemonSet controller&lt;/li&gt;
&lt;li&gt;StatefulSet controller&lt;/li&gt;
&lt;li&gt;ReplicaSet controller&lt;/li&gt;
&lt;li&gt;Job controller&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;These controllers all act on pods, which in most cases are under the highest amount of contention in a cluster. The changes are
on by default for these controllers, and can be disabled by setting the feature gates &lt;code&gt;StaleControllerConsistency&amp;lt;API type&amp;gt;&lt;/code&gt;
to &lt;code&gt;false&lt;/code&gt; for the specific controller you wish to disable it for. For example, to disable the feature for the DaemonSet controller,
you would set the feature gate &lt;code&gt;StaleControllerConsistencyDaemonSet&lt;/code&gt; to &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;When the relevant feature gate is enabled, the controller will first check the latest
&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/reference/using-api/api-concepts/#resource-versions&#34;&gt;resource version&lt;/a&gt; of the cache before taking action. If the
latest resource version of the cache is lower than what the controller has written to the API server for the object it is trying to
reconcile, the controller will not take action. This is because the controller&#39;s cache is outdated, and it does not have the latest
information about the state of the cluster.&lt;/p&gt;
&lt;h3 id=&#34;use-for-informer-authors&#34;&gt;Use for informer authors&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#use-for-informer-authors&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Informer authors using client-go can also immediately take advantage of these improvements. See an example of how to use this feature
in the &lt;a href=&#34;https://github.com/kubernetes/kubernetes/pull/137212&#34;&gt;ReplicaSet informer&lt;/a&gt;. This PR shows how to use the new feature to check
if the informer&#39;s cache is stale before taking action. The client-go library provides a &lt;code&gt;ConsistencyStore&lt;/code&gt; data structure that queries the store
and compares the latest resource version of the cache with the written resource version of the object.&lt;/p&gt;
&lt;p&gt;The ReplicaSet controller tracks both the ReplicaSet&#39;s resource version and the resource version of the pods that the ReplicaSet
manages. For a specific ReplicaSet, it tracks the latest written resource version of the pods that the ReplicaSet owns as well as
any writes to the ReplicaSet itself. If the latest resource version of the cache is lower than what the controller has
written to the API server for the object it is trying to reconcile, the controller will not take action. This is because the
controller&#39;s cache is outdated, and it does not have the latest information about the state of the cluster.&lt;/p&gt;
&lt;p&gt;An informer author can use the &lt;code&gt;ConsistencyStore&lt;/code&gt; to track the latest resource version of the objects that the informer cares about.
It provides 3 main functions:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;ConsistencyStore&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;interface&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;c1&#34;&gt;// WroteAt records that the given object was written at the given resource version.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;nf&#34;&gt;WroteAt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;owningObj&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;runtime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Object&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;uid&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;types&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;UID&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;groupResource&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;schema&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;GroupResource&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;resourceVersion&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;c1&#34;&gt;// EnsureReady returns true if the cache is up to date for the given object.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;c1&#34;&gt;// It is used prior to reconciliation to decide whether to reconcile or not.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;nf&#34;&gt;EnsureReady&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;namespacedName&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;types&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;NamespacedName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;bool&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;c1&#34;&gt;// Clear removes the given object from the consistency store.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;c1&#34;&gt;// It is used when an object is deleted.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;nf&#34;&gt;Clear&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;namespacedName&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;types&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;NamespacedName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;uid&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;types&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;UID&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol&gt;
&lt;li&gt;&lt;code&gt;WroteAt&lt;/code&gt;: This function is called by the controller when it writes to the API server for an object. It is used to record the
latest resource version of the object that the controller has written to the API server. The &lt;code&gt;owningObj&lt;/code&gt; is the object that the
controller is reconciling, and the &lt;code&gt;uid&lt;/code&gt; is the UID of that object. The resource version and GroupResource are the resource version
and GroupResource of the object that the controller has written to the API server. The object is not explicitly tracked, since the
controller only cares about waiting to catch up to the latest resource version of the written object.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;EnsureReady&lt;/code&gt;: This function is called by the controller to ensure that the cache is up to date for the object. It is used prior
to reconciliation to decide whether to reconcile or not. It returns true if the cache is up to date for the object, and false
otherwise. It will use the information provided by &lt;code&gt;WroteAt&lt;/code&gt; to determine if the cache is up to date.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Clear&lt;/code&gt;: This function is called by the controller when an object is deleted. It is used to remove the object from the consistency
store. This is mostly used for cleanup when an object is deleted to prevent the consistency store from growing indefinitely.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The UID is used to distinguish between different objects that have the same name, such as when an object is deleted and then
recreated. It is not needed for EnsureReady because the consistency store is only concerned with catching up to the latest resource
version of the object, not the specific object. It is primarily used to ensure that the controller doesn&#39;t delete the entry for
an object when it is recreated with a new UID.&lt;/p&gt;
&lt;p&gt;With these 3 functions, an informer author can implement staleness mitigation in their controller.&lt;/p&gt;
&lt;h2 id=&#34;observability&#34;&gt;Observability&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#observability&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;In addition to the staleness mitigation features, the Kubernetes project has also added related instrumentation to kube-controller-manager
in 1.36. These metrics are also enabled by default, and are controlled using the same set of feature gates.&lt;/p&gt;
&lt;h3 id=&#34;metrics&#34;&gt;Metrics&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#metrics&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The following &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/reference/instrumentation/metrics/#list-of-alpha-kubernetes-metrics&#34;&gt;alpha metrics&lt;/a&gt; have been added to kube-controller-manager in 1.36:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;stale_sync_skips_total&lt;/code&gt;: The number of times the controller has skipped a sync due to stale cache. This metric is exposed
for each controller that uses the staleness mitigation feature with the subsystem of the controller.&lt;/p&gt;
&lt;p&gt;This metric is exposed by the kube-controller-manager metrics endpoint, and can be used to monitor the health of the controller.&lt;/p&gt;
&lt;p&gt;Along with this metric, client-go also emits metrics that expose the latest resource version of every shared informer
with the subsystem of the informer. This allows you to see the latest resource version of each informer, and use that to
determine if the controller&#39;s cache is stale, especially great for comparing against the resource version of the API server.&lt;/p&gt;
&lt;p&gt;This metric is named &lt;code&gt;store_resource_version&lt;/code&gt; and has the Group, Version, and Resource as labels.&lt;/p&gt;
&lt;h2 id=&#34;what-s-next&#34;&gt;What&#39;s next?&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#what-s-next&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Kubernetes SIG API Machinery is excited to continue working on this feature and hope to bring it to more controllers in the future.
We are also interested in hearing your feedback on this feature. Please let us know what you think in the comments
below or by opening an &lt;a href=&#34;https://github.com/kubernetes/kubernetes/issues&#34;&gt;issue&lt;/a&gt; on the Kubernetes GitHub repository.&lt;/p&gt;
&lt;p&gt;We are also working with &lt;a href=&#34;https://github.com/kubernetes-sigs/controller-runtime/pull/3473&#34;&gt;controller-runtime&lt;/a&gt; to enable this set of
semantics for all controllers built with controller-runtime. This will allow any controller built with controller-runtime to gain
the benefits of read your own writes, without having to implement the logic themselves.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes v1.36: Mutable Pod Resources for Suspended Jobs (beta)</title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/04/27/kubernetes-v1-36-mutable-pod-resources-for-suspended-jobs/</link>
      <pubDate>Mon, 27 Apr 2026 10:35:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/04/27/kubernetes-v1-36-mutable-pod-resources-for-suspended-jobs/</guid>
      <description>
        
        
        &lt;p&gt;Kubernetes v1.36 promotes the ability to modify container resource requests and limits
in the pod template of a suspended Job to beta. First introduced as alpha in v1.35, this
feature allows queue controllers and cluster administrators to adjust CPU, memory, GPU,
and extended resource specifications on a Job while it is suspended, before it starts
or resumes running.&lt;/p&gt;
&lt;h2 id=&#34;why-mutable-pod-resources-for-suspended-jobs&#34;&gt;Why mutable pod resources for suspended Jobs?&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#why-mutable-pod-resources-for-suspended-jobs&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Batch and machine learning workloads often have resource requirements that are not
precisely known at Job creation time. The optimal resource allocation depends on
current cluster capacity, queue priorities, and the availability of specialized hardware
like GPUs.&lt;/p&gt;
&lt;p&gt;Before this feature, resource requirements in a Job&#39;s pod template were immutable once set.
If a queue controller like &lt;a href=&#34;https://kueue.sigs.k8s.io/&#34;&gt;Kueue&lt;/a&gt; determined that a suspended
Job should run with different resources, the only option was to delete and recreate the Job,
losing any associated metadata, status, or history. This feature also provides a way
to let a specific Job instance for a CronJob progress slowly with reduced resources,
rather than outright failing to run if the cluster is heavily loaded.&lt;/p&gt;
&lt;p&gt;Consider a machine learning training Job initially requesting 4 GPUs:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;batch/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Job&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;training-job-example-abcd123&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;app.kubernetes.io/name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;trainer&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;suspend&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;template&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kubernetes.io/description&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;ML training, ID abcd123&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;containers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;trainer&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;example-registry.example.com/training:2026-04-23T150405.678&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;resources&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;requests&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;cpu&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;8&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;memory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;32Gi&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;example-hardware-vendor.com/gpu&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;4&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;limits&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;cpu&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;8&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;memory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;32Gi&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;example-hardware-vendor.com/gpu&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;4&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;restartPolicy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Never&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A queue controller managing cluster resources might determine that only 2 GPUs
are available. With this feature, the controller can update the Job&#39;s resource
requests before resuming it:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;batch/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Job&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;training-job-example-abcd123&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;app.kubernetes.io/name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;trainer&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;suspend&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;template&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kubernetes.io/description&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;ML training, ID abcd123&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;containers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;trainer&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;example-registry.example.com/training:2026-04-23T150405.678&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;resources&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;requests&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;cpu&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;4&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;memory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;16Gi&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;example-hardware-vendor.com/gpu&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;2&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;limits&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;cpu&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;4&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;memory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;16Gi&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;example-hardware-vendor.com/gpu&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;2&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;restartPolicy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Never&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Once the resources are updated, the controller resumes the Job by setting
&lt;code&gt;spec.suspend&lt;/code&gt; to &lt;code&gt;false&lt;/code&gt;, and the new Pods are created with the adjusted
resource specifications.&lt;/p&gt;
&lt;h2 id=&#34;how-it-works&#34;&gt;How it works&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#how-it-works&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The Kubernetes API server relaxes the immutability constraint on pod template
resource fields specifically for suspended Jobs. No new API types have been introduced;
the existing Job and pod template structures accommodate the change through
relaxed validation.&lt;/p&gt;
&lt;p&gt;The mutable fields are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;spec.template.spec.containers[*].resources.requests&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;spec.template.spec.containers[*].resources.limits&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;spec.template.spec.initContainers[*].resources.requests&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;spec.template.spec.initContainers[*].resources.limits&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Resource updates are permitted when the following conditions are met:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The Job has &lt;code&gt;spec.suspend&lt;/code&gt; set to &lt;code&gt;true&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;For a Job that was previously running and then suspended, all active
Pods must have terminated (&lt;code&gt;status.active&lt;/code&gt; equals 0) before resource
mutations are accepted.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Standard resource validation still applies. For example, resource limits
must be greater than or equal to requests, and extended resources must be
specified as whole numbers where required.&lt;/p&gt;
&lt;h2 id=&#34;what-s-new-in-beta&#34;&gt;What&#39;s new in beta&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#what-s-new-in-beta&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;With the promotion to beta in Kubernetes v1.36, the
&lt;code&gt;MutablePodResourcesForSuspendedJobs&lt;/code&gt; feature gate is enabled by default.
This means clusters running v1.36 can use this feature without any additional
configuration on the API server.&lt;/p&gt;
&lt;h2 id=&#34;try-it-out&#34;&gt;Try it out&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#try-it-out&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;If your cluster is running Kubernetes v1.36 or later, this feature is available
by default. For v1.35 clusters, enable the &lt;code&gt;MutablePodResourcesForSuspendedJobs&lt;/code&gt;
&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/reference/command-line-tools-reference/feature-gates/&#34;&gt;feature gate&lt;/a&gt; on
the &lt;code&gt;kube-apiserver&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You can test it by creating a suspended Job, updating its container resources
using &lt;code&gt;kubectl edit&lt;/code&gt; or a controller, and then resuming the Job:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Create a suspended Job&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl apply -f my-job.yaml --server-side
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Edit the resource requests&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl edit job training-job-example-abcd123
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Resume the Job&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl patch job training-job-example-abcd123 -p &lt;span class=&#34;s1&#34;&gt;&amp;#39;{&amp;#34;spec&amp;#34;:{&amp;#34;suspend&amp;#34;:false}}&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;considerations&#34;&gt;Considerations&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#considerations&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;h3 id=&#34;running-jobs-that-are-suspended&#34;&gt;Running Jobs that are suspended&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#running-jobs-that-are-suspended&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;If you suspend a Job that was already running, you must wait for &lt;strong&gt;all&lt;/strong&gt; of that Job&#39;s active
Pods to terminate before modifying resources. The API server rejects resource
mutations while &lt;code&gt;status.active&lt;/code&gt; is greater than zero. This prevents inconsistency
between running Pods and the updated pod template.&lt;/p&gt;
&lt;h3 id=&#34;pod-replacement-policy&#34;&gt;Pod replacement policy&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#pod-replacement-policy&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;When using this feature with Jobs that may have failed Pods, consider setting
&lt;code&gt;podReplacementPolicy: Failed&lt;/code&gt;. This ensures that replacement Pods are only
created after the previous Pods have fully terminated, preventing resource
contention from overlapping Pods.&lt;/p&gt;
&lt;h3 id=&#34;resourceclaims&#34;&gt;ResourceClaims&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#resourceclaims&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Dynamic Resource Allocation (DRA) &lt;code&gt;resourceClaimTemplates&lt;/code&gt; remain immutable.
If your workload uses DRA, you must recreate the claim templates separately
to match any resource changes.&lt;/p&gt;
&lt;h2 id=&#34;getting-involved&#34;&gt;Getting involved&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#getting-involved&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;This feature was developed by &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-apps&#34;&gt;SIG Apps&lt;/a&gt;
This feature was developed by &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/sigs/apps/&#34;&gt;SIG Apps&lt;/a&gt;
with input from &lt;a href=&#34;https://www.kubernetes.dev/community/community-groups/wg/batch/&#34;&gt;WG Batch&lt;/a&gt;. Both groups welcome feedback
as the feature progresses toward stable.&lt;/p&gt;
&lt;p&gt;You can reach out through:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Slack channel &lt;a href=&#34;https://kubernetes.slack.com/archives/C18NZM5K9&#34;&gt;#sig-apps&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Slack channel &lt;a href=&#34;https://kubernetes.slack.com/archives/C032ZE66A2X&#34;&gt;#wg-batch&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;The &lt;a href=&#34;https://kep.k8s.io/5440&#34;&gt;KEP-5440&lt;/a&gt; tracking issue.&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes v1.36: Fine-Grained Kubelet API Authorization Graduates to GA</title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/04/24/kubernetes-v1-36-fine-grained-kubelet-authorization-ga/</link>
      <pubDate>Fri, 24 Apr 2026 10:35:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/04/24/kubernetes-v1-36-fine-grained-kubelet-authorization-ga/</guid>
      <description>
        
        
        &lt;p&gt;On behalf of Kubernetes SIG Auth and SIG Node, we are pleased to announce the
graduation of fine-grained &lt;code&gt;kubelet&lt;/code&gt; API authorization to General Availability
(GA) in Kubernetes v1.36!&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;KubeletFineGrainedAuthz&lt;/code&gt; feature gate was introduced as an opt-in alpha
feature in Kubernetes v1.32, then graduated to beta (enabled by default) in
v1.33. Now, the feature is generally available and the feature gate is locked
to enabled. This feature enables more precise, least-privilege access control
over the &lt;code&gt;kubelet&lt;/code&gt;&#39;s HTTPS API, replacing the need to grant the overly broad
&lt;code&gt;nodes/proxy&lt;/code&gt; permission for common monitoring and observability use cases.&lt;/p&gt;
&lt;h2 id=&#34;motivation-the-nodes-proxy-problem&#34;&gt;Motivation: the &lt;code&gt;nodes/proxy&lt;/code&gt; problem&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#motivation-the-nodes-proxy-problem&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The &lt;code&gt;kubelet&lt;/code&gt; exposes an HTTPS endpoint with several APIs that give access to data
of varying sensitivity, including pod listings, node metrics, container logs,
and, critically, the ability to execute commands inside running containers.&lt;/p&gt;
&lt;p&gt;Prior to this feature, &lt;code&gt;kubelet&lt;/code&gt; authorization used a coarse-grained model. When
webhook authorization was enabled, almost all &lt;code&gt;kubelet&lt;/code&gt; API paths were mapped to a
single &lt;code&gt;nodes/proxy&lt;/code&gt; subresource. This meant that any workload needing to read
metrics or health status from the &lt;code&gt;kubelet&lt;/code&gt; required &lt;code&gt;nodes/proxy&lt;/code&gt; permission,
the same permission that also grants the ability to execute arbitrary commands
in any container running on the node.&lt;/p&gt;
&lt;h3 id=&#34;what-s-wrong-with-that&#34;&gt;What&#39;s wrong with that?&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#what-s-wrong-with-that&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Granting &lt;code&gt;nodes/proxy&lt;/code&gt; to monitoring agents, log collectors, or health-checking
tools violates the principle of least privilege. If any of those workloads were
compromised, an attacker would gain the ability to run commands in every
container on the node. The &lt;code&gt;nodes/proxy&lt;/code&gt; permission is effectively a node-level
superuser capability, and granting it broadly dramatically increases the blast
radius of a security incident.&lt;/p&gt;
&lt;p&gt;This problem has been well understood in the community for years (see
&lt;a href=&#34;https://github.com/kubernetes/kubernetes/issues/83465&#34;&gt;kubernetes/kubernetes#83465&lt;/a&gt;),
and was the driving motivation behind this enhancement &lt;a href=&#34;https://kep.k8s.io/2862&#34;&gt;KEP-2862&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;the-nodes-proxy-get-websocket-rce-risk&#34;&gt;The &lt;code&gt;nodes/proxy GET&lt;/code&gt; WebSocket RCE risk&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#the-nodes-proxy-get-websocket-rce-risk&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The situation is more severe than it might appear at first glance. Security
researchers &lt;a href=&#34;https://grahamhelton.com/blog/nodes-proxy-rce&#34;&gt;demonstrated in early 2026&lt;/a&gt;
that &lt;code&gt;nodes/proxy GET&lt;/code&gt; alone, which is the minimal read-only permission routinely
granted to monitoring tools, can be abused to execute commands in any pod on
reachable nodes.&lt;/p&gt;
&lt;p&gt;The root cause is a mismatch between how WebSocket connections work and how the
&lt;code&gt;kubelet&lt;/code&gt; maps HTTP methods to RBAC verbs. The
&lt;a href=&#34;https://datatracker.ietf.org/doc/html/rfc6455#section-1.2&#34;&gt;WebSocket protocol (RFC 6455)&lt;/a&gt;
requires an HTTP &lt;code&gt;GET&lt;/code&gt; request for the initial connection handshake. The &lt;code&gt;kubelet&lt;/code&gt;
maps this &lt;code&gt;GET&lt;/code&gt; to the RBAC &lt;code&gt;get&lt;/code&gt; verb and authorizes the request without
performing a secondary check to confirm that &lt;code&gt;CREATE&lt;/code&gt; permission is also present
for the write operation that follows. Using a WebSocket client like &lt;code&gt;websocat&lt;/code&gt;,
an attacker can reach the &lt;code&gt;kubelet&lt;/code&gt;&#39;s &lt;code&gt;/exec&lt;/code&gt; endpoint directly on port 10250 and
execute arbitrary commands:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;websocat --insecure &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;  --header &lt;span class=&#34;s2&#34;&gt;&amp;#34;Authorization: Bearer &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$TOKEN&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;  --protocol v4.channel.k8s.io &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;s2&#34;&gt;&amp;#34;wss://&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$NODE_IP&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;:10250/exec/default/nginx/nginx?output=1&amp;amp;error=1&amp;amp;command=id&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;uid&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;0&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;root&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;gid&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;0&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;root&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;groups&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;0&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;root&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;fine-grained-kubelet-authorization-how-it-works&#34;&gt;Fine-grained &lt;code&gt;kubelet&lt;/code&gt; authorization: how it works&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#fine-grained-kubelet-authorization-how-it-works&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;With &lt;code&gt;KubeletFineGrainedAuthz&lt;/code&gt;, the &lt;code&gt;kubelet&lt;/code&gt; now performs an additional, more
specific authorization check before falling back to the &lt;code&gt;nodes/proxy&lt;/code&gt;
subresource. Several commonly used &lt;code&gt;kubelet&lt;/code&gt; API paths are mapped to their own
dedicated subresources:&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;&lt;code&gt;kubelet&lt;/code&gt; API&lt;/th&gt;
          &lt;th&gt;Resource&lt;/th&gt;
          &lt;th&gt;Subresource&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;/stats/*&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;nodes&lt;/td&gt;
          &lt;td&gt;stats&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;/metrics/*&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;nodes&lt;/td&gt;
          &lt;td&gt;metrics&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;/logs/*&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;nodes&lt;/td&gt;
          &lt;td&gt;log&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;/pods&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;nodes&lt;/td&gt;
          &lt;td&gt;pods, proxy&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;/runningPods/&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;nodes&lt;/td&gt;
          &lt;td&gt;pods, proxy&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;/healthz&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;nodes&lt;/td&gt;
          &lt;td&gt;healthz, proxy&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;/configz&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;nodes&lt;/td&gt;
          &lt;td&gt;configz, proxy&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;/spec/*&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;nodes&lt;/td&gt;
          &lt;td&gt;spec&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;/checkpoint/*&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;nodes&lt;/td&gt;
          &lt;td&gt;checkpoint&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;all others&lt;/td&gt;
          &lt;td&gt;nodes&lt;/td&gt;
          &lt;td&gt;proxy&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;For the endpoints that now have fine-grained subresources (&lt;code&gt;/pods&lt;/code&gt;,
&lt;code&gt;/runningPods/&lt;/code&gt;, &lt;code&gt;/healthz&lt;/code&gt;, &lt;code&gt;/configz&lt;/code&gt;), the &lt;code&gt;kubelet&lt;/code&gt; first sends a
&lt;code&gt;SubjectAccessReview&lt;/code&gt; for the specific subresource. If that check succeeds, the
request is authorized. If it fails, the &lt;code&gt;kubelet&lt;/code&gt; retries with the coarse-grained
&lt;code&gt;nodes/proxy&lt;/code&gt; subresource for backward compatibility.&lt;/p&gt;
&lt;p&gt;This dual-check approach ensures a smooth migration path. Existing workloads
with &lt;code&gt;nodes/proxy&lt;/code&gt; permissions continue to work, while new deployments can adopt
least-privilege access from day one.&lt;/p&gt;
&lt;h2 id=&#34;what-this-means-in-practice&#34;&gt;What this means in practice&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#what-this-means-in-practice&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Consider a Prometheus node exporter or a monitoring &lt;code&gt;DaemonSet&lt;/code&gt; that needs to
scrape &lt;code&gt;/metrics&lt;/code&gt; from the &lt;code&gt;kubelet&lt;/code&gt;. Previously, you would need an RBAC
&lt;code&gt;ClusterRole&lt;/code&gt; like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;# Old approach: overly broad&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;rbac.authorization.k8s.io/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ClusterRole&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;monitoring-agent&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;rules&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;apiGroups&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;resources&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;nodes/proxy&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;verbs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;get&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This grants the monitoring agent far more access than it needs. With
fine-grained authorization, you can now scope the permissions precisely:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;# New approach: least privilege&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;rbac.authorization.k8s.io/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ClusterRole&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;monitoring-agent&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;rules&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;apiGroups&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;resources&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;nodes/metrics&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;nodes/stats&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;verbs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;get&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The monitoring agent can now read metrics and stats from the &lt;code&gt;kubelet&lt;/code&gt; without
ever being able to execute commands in containers.&lt;/p&gt;
&lt;h2 id=&#34;updated-system-kubelet-api-admin-clusterrole&#34;&gt;Updated &lt;code&gt;system:kubelet-api-admin&lt;/code&gt; &lt;code&gt;ClusterRole&lt;/code&gt;&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#updated-system-kubelet-api-admin-clusterrole&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;When RBAC authorization is enabled, the built-in &lt;code&gt;system:kubelet-api-admin&lt;/code&gt;
&lt;code&gt;ClusterRole&lt;/code&gt; is automatically updated to include permissions for all the new
fine-grained subresources. This ensures that cluster administrators who already
use this role, including the API server&#39;s &lt;code&gt;kubelet&lt;/code&gt; client, continue to have
full access without any manual configuration changes.&lt;/p&gt;
&lt;p&gt;The role now includes permissions for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;nodes/proxy&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;nodes/stats&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;nodes/metrics&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;nodes/log&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;nodes/spec&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;nodes/checkpoint&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;nodes/configz&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;nodes/healthz&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;nodes/pods&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;upgrade-considerations&#34;&gt;Upgrade considerations&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#upgrade-considerations&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Because the &lt;code&gt;kubelet&lt;/code&gt; performs a dual authorization check (fine-grained first,
then falling back to &lt;code&gt;nodes/proxy&lt;/code&gt;), upgrading to v1.36 should be seamless for
most clusters:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Existing workloads&lt;/strong&gt; with &lt;code&gt;nodes/proxy&lt;/code&gt; permissions continue to work without
changes. The fallback to &lt;code&gt;nodes/proxy&lt;/code&gt; ensures backward compatibility.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The API server&lt;/strong&gt; always has &lt;code&gt;nodes/proxy&lt;/code&gt; permissions via
&lt;code&gt;system:kubelet-api-admin&lt;/code&gt;, so &lt;code&gt;kube-apiserver&lt;/code&gt;-to-&lt;code&gt;kubelet&lt;/code&gt; communication is
unaffected regardless of feature gate state.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mixed-version clusters&lt;/strong&gt; are handled gracefully. If a &lt;code&gt;kubelet&lt;/code&gt; supports
fine-grained authorization but the API server does not (or vice versa),
&lt;code&gt;nodes/proxy&lt;/code&gt; permissions serve as the fallback.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;verifying-the-feature-is-enabled&#34;&gt;Verifying the feature is enabled&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#verifying-the-feature-is-enabled&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;You can confirm that the feature is active on a given node by checking the
&lt;code&gt;kubelet&lt;/code&gt; metrics endpoint. Since the metrics endpoint on port 10250 requires
authorization, you&#39;ll first need to create appropriate RBAC bindings for the pod
or &lt;code&gt;ServiceAccount&lt;/code&gt; making the request.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 1: Create a &lt;code&gt;ServiceAccount&lt;/code&gt; and &lt;code&gt;ClusterRole&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ServiceAccount&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;kubelet-metrics-checker&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;namespace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;default&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;rbac.authorization.k8s.io/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ClusterRole&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;kubelet-metrics-reader&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;rules&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;apiGroups&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;resources&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;nodes/metrics&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;verbs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;get&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Step 2: Bind the &lt;code&gt;ClusterRole&lt;/code&gt; to the &lt;code&gt;ServiceAccount&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;rbac.authorization.k8s.io/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ClusterRoleBinding&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;kubelet-metrics-checker&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;subjects&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ServiceAccount&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;kubelet-metrics-checker&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;namespace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;default&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;roleRef&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ClusterRole&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;kubelet-metrics-reader&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;apiGroup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;rbac.authorization.k8s.io&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Apply both manifests:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl apply -f serviceaccount.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl apply -f clusterrole.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl apply -f clusterrolebinding.yaml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Step 3: Run a pod with the &lt;code&gt;ServiceAccount&lt;/code&gt; and check the feature flag&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl run kubelet-check &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;  --image&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;curlimages/curl &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;  --serviceaccount&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;kubelet-metrics-checker &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;  --restart&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;Never &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;  --rm -it &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;  -- sh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then from within the pod, retrieve the node IP and query the metrics endpoint:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Get the token&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;TOKEN&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;cat /var/run/secrets/kubernetes.io/serviceaccount/token&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Query the kubelet metrics and filter for the feature gate&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;curl -sk &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;  --header &lt;span class=&#34;s2&#34;&gt;&amp;#34;Authorization: Bearer &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$TOKEN&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;  https://&lt;span class=&#34;nv&#34;&gt;$NODE_IP&lt;/span&gt;:10250/metrics &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; grep kubernetes_feature_enabled &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; grep KubeletFineGrainedAuthz
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If the feature is enabled, you should see output like:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;kubernetes_feature_enabled{name=&amp;#34;KubeletFineGrainedAuthz&amp;#34;,stage=&amp;#34;GA&amp;#34;} 1
&lt;/code&gt;&lt;/pre&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Replace &lt;code&gt;$NODE_IP&lt;/code&gt; with the IP address of the node you want to check.
You can retrieve node IPs with &lt;code&gt;kubectl get nodes -o wide&lt;/code&gt;.&lt;/p&gt;&lt;/blockquote&gt;
&lt;h2 id=&#34;the-journey-from-alpha-to-ga&#34;&gt;The journey from alpha to GA&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#the-journey-from-alpha-to-ga&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Release&lt;/th&gt;
          &lt;th&gt;Stage&lt;/th&gt;
          &lt;th&gt;Details&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;v1.32&lt;/td&gt;
          &lt;td&gt;Alpha&lt;/td&gt;
          &lt;td&gt;Feature gate &lt;code&gt;KubeletFineGrainedAuthz&lt;/code&gt; introduced, disabled by default&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;v1.33&lt;/td&gt;
          &lt;td&gt;Beta&lt;/td&gt;
          &lt;td&gt;Enabled by default; fine-grained checks for &lt;code&gt;/pods&lt;/code&gt;, &lt;code&gt;/runningPods/&lt;/code&gt;, &lt;code&gt;/healthz&lt;/code&gt;, &lt;code&gt;/configz&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;v1.36&lt;/td&gt;
          &lt;td&gt;GA&lt;/td&gt;
          &lt;td&gt;Feature gate locked to enabled; fine-grained &lt;code&gt;kubelet&lt;/code&gt; authorization is always active&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;what-s-next&#34;&gt;What&#39;s next?&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#what-s-next&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;With fine-grained &lt;code&gt;kubelet&lt;/code&gt; authorization now GA, the Kubernetes community can
begin recommending and eventually enforcing the use of specific subresources
instead of &lt;code&gt;nodes/proxy&lt;/code&gt; for monitoring and observability workloads. The urgency
of this migration is underscored by
&lt;a href=&#34;https://grahamhelton.com/blog/nodes-proxy-rce&#34;&gt;research showing that &lt;code&gt;nodes/proxy GET&lt;/code&gt; can be abused for unlogged remote code execution&lt;/a&gt; via the WebSocket protocol. This risk is present in the default RBAC
configurations of dozens of widely deployed Helm charts. Over time, we expect:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Ecosystem adoption:&lt;/strong&gt; Monitoring tools like Prometheus, Datadog agents, and
other &lt;code&gt;DaemonSets&lt;/code&gt; can update their default RBAC configurations to use
&lt;code&gt;nodes/metrics&lt;/code&gt;, &lt;code&gt;nodes/stats&lt;/code&gt;, and &lt;code&gt;nodes/pods&lt;/code&gt; instead of &lt;code&gt;nodes/proxy&lt;/code&gt;. This
directly eliminates the WebSocket RCE attack surface for those workloads.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Policy enforcement:&lt;/strong&gt; Admission controllers and policy engines can flag or
reject RBAC bindings that grant &lt;code&gt;nodes/proxy&lt;/code&gt; when fine-grained alternatives
exist, helping organizations adopt least-privilege access at scale.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Deprecation path:&lt;/strong&gt; As adoption grows, &lt;code&gt;nodes/proxy&lt;/code&gt; may eventually be
deprecated for monitoring use cases, further reducing the attack surface of
Kubernetes clusters.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;getting-involved&#34;&gt;Getting involved&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#getting-involved&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;This enhancement was driven by SIG Auth and SIG Node. If you are interested in
contributing to the security and authorization features of Kubernetes, please
join us:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-auth&#34;&gt;SIG Auth&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-node&#34;&gt;SIG Node&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Slack: &lt;code&gt;#sig-auth&lt;/code&gt; and &lt;code&gt;#sig-node&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/2862&#34;&gt;KEP-2862: Fine-Grained Kubelet API Authorization&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We look forward to hearing your feedback and experiences with this feature!&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes v1.36: User Namespaces in Kubernetes are finally GA</title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/04/23/kubernetes-v1-36-userns-ga/</link>
      <pubDate>Thu, 23 Apr 2026 10:35:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/04/23/kubernetes-v1-36-userns-ga/</guid>
      <description>
        
        
        &lt;p&gt;After several years of development, User Namespaces support in
Kubernetes reached General Availability (GA) with the v1.36 release.
This is a Linux-only feature.&lt;/p&gt;
&lt;p&gt;For those of us working on low level container runtimes and rootless
technologies, this has been a long awaited milestone. We finally
reached the point where &amp;quot;rootless&amp;quot; security isolation can be used for
Kubernetes workloads.&lt;/p&gt;
&lt;p&gt;This feature also enables a critical pattern: running workloads with
privileges and still being confined in the user namespace.  When
&lt;code&gt;hostUsers: false&lt;/code&gt; is set, capabilities like &lt;code&gt;CAP_NET_ADMIN&lt;/code&gt; become
&lt;strong&gt;namespaced&lt;/strong&gt;, meaning they grant administrative power over container
local resources without affecting the host.  This effectively enables
new use cases that were not possible before without running a fully
privileged container.&lt;/p&gt;
&lt;h2 id=&#34;the-problem-with-uid-0&#34;&gt;The Problem with UID 0&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#the-problem-with-uid-0&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;A process running as root inside a container is also seen from the
kernel as root on the host.  If an attacker manages to break out of
the container, whether through a kernel vulnerability or a
misconfigured mount, they are root on the host.&lt;/p&gt;
&lt;p&gt;While there are many security measures in place for running
containers, these measures don&#39;t change the underlying identity of the
process, it still has some &amp;quot;parts&amp;quot; of root.&lt;/p&gt;
&lt;h2 id=&#34;the-engine-id-mapped-mounts&#34;&gt;The engine: ID-mapped mounts&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#the-engine-id-mapped-mounts&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The road to GA wasn&#39;t just about the Kubernetes API; it was about
making the kernel work for us.  In the early stages, one of the
biggest blockers was volume ownership.  If you mapped a container to a
high UID range, the Kubelet had to recursively &lt;code&gt;chown&lt;/code&gt; every file in
the attached volume so the container could read/write them.  For large
volumes, this was such an expensive operation that destroyed startup
performance.&lt;/p&gt;
&lt;p&gt;The key enabler was &lt;em&gt;ID-mapped mounts&lt;/em&gt; (introduced in Linux
5.12 and refined in later versions). Instead of rewriting file
ownership on disk, the kernel remaps it at mount time.&lt;/p&gt;
&lt;p&gt;When a volume is mounted into a Pod with User Namespaces enabled, the
kernel performs a transparent translation of the UIDs (user ids) and
GIDs (group ids). To the container, the files appear owned by
UID 0. On disk, file ownership is unchanged — no &lt;code&gt;chown&lt;/code&gt; is needed.
This is an &lt;code&gt;O(1)&lt;/code&gt; operation, instant and efficient.&lt;/p&gt;
&lt;h2 id=&#34;using-it-in-kubernetes-v1-36&#34;&gt;Using it in Kubernetes v1.36&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#using-it-in-kubernetes-v1-36&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Using user namespaces is straightforward: all you need to do is set
&lt;code&gt;hostUsers: false&lt;/code&gt; in your Pod spec. No changes to your container
images, no complex configuration. The interface remains the same one
introduced during the Alpha phase. In the &lt;code&gt;spec&lt;/code&gt; for a Pod (or PodTemplate), you explicitly
opt-out of the host user namespace:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Pod&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;isolated-workload&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;hostUsers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;containers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;app&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;fedora:42&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;securityContext&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;runAsUser&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For more details on how user namespaces work in practice and demos of
CVEs rated HIGH mitigated, see the previous blog posts:
&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2022/10/03/userns-alpha/&#34;&gt;User Namespaces alpha&lt;/a&gt;,
&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2023/09/13/userns-alpha/&#34;&gt;User Namespaces stateful pods in alpha&lt;/a&gt;,
&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2024/04/22/userns-beta/&#34;&gt;User Namespaces beta&lt;/a&gt;, and
&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2025/04/25/userns-enabled-by-default/&#34;&gt;User Namespaces enabled by default&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;getting-involved&#34;&gt;Getting involved&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#getting-involved&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;If you&#39;re interested in user namespaces or want to contribute, here
are some useful links:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/workloads/pods/user-namespaces/&#34;&gt;User Namespaces documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/127&#34;&gt;KEP-127: Support User Namespaces&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-node&#34;&gt;SIG Node&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;acknowledgments&#34;&gt;Acknowledgments&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#acknowledgments&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;This feature has been years in the making: the first KEP was opened
10 years ago by other contributors, and we have been actively working
on it for the last 6 years. We&#39;d like to thank everyone who
contributed across SIG Node, the container runtimes, and the Linux
kernel. Special thanks to the reviewers and early adopters who helped
shape the design through multiple alpha and beta cycles.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>SELinux Volume Label Changes goes GA (and likely implications in v1.37)</title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/04/22/breaking-changes-in-selinux-volume-labeling/</link>
      <pubDate>Wed, 22 Apr 2026 10:35:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/04/22/breaking-changes-in-selinux-volume-labeling/</guid>
      <description>
        
        
        &lt;p&gt;If you run Kubernetes on Linux with SELinux in enforcing mode, plan ahead: a future release (anticipated to be v1.37) is
expected to turn the &lt;code&gt;SELinuxMount&lt;/code&gt; &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/reference/command-line-tools-reference/feature-gates/&#34;&gt;feature gate&lt;/a&gt; on by default. This makes volume setup faster
for most workloads, but &lt;strong&gt;it can break applications&lt;/strong&gt; that still depend on the older recursive relabeling
model in subtle ways (for example, sharing one volume between privileged and unprivileged Pods on the same node).
Kubernetes v1.36 is the right release to audit your cluster and fix or opt out of this change.&lt;/p&gt;
&lt;p&gt;If your nodes do not use SELinux, nothing changes for you: the kubelet skips the whole
SELinux logic when SELinux is unavailable or disabled in the Linux kernel. You can skip this article completely.&lt;/p&gt;
&lt;p&gt;This blog builds on the earlier work described in the
&lt;a href=&#34;https://kubernetes.io/blog/2023/04/18/kubernetes-1-27-efficient-selinux-relabeling-beta/&#34;&gt;Kubernetes 1.27: Efficient SELinux Relabeling (Beta)&lt;/a&gt;
post, where the &lt;code&gt;SELinuxMountReadWriteOncePod&lt;/code&gt; feature gate was described. The problem to be addressed remains
the same, however, this blog extends that same approach to all volumes.&lt;/p&gt;
&lt;h2 id=&#34;the-problem&#34;&gt;The problem&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#the-problem&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Linux systems with Security Enhanced Linux (SELinux) enabled use labels attached to objects
(for example, files and network sockets) to make access control decisions.
Historically, the container runtime applies SELinux labels to a Pod and all its volumes. Kubernetes only passes the SELinux label from a Pod&#39;s &lt;code&gt;securityContext&lt;/code&gt; fields
to the container runtime.&lt;/p&gt;
&lt;p&gt;The container runtime then recursively changes the SELinux label on all files that
are visible to the Pod&#39;s containers. This can be time-consuming if there are
many files on the volume, especially when the volume is on a remote filesystem.&lt;/p&gt;
&lt;div class=&#34;alert alert-caution&#34; role=&#34;note&#34;&gt;&lt;h4 class=&#34;alert-heading&#34;&gt;Caution:&lt;/h4&gt;If a container uses &lt;code&gt;subPath&lt;/code&gt; of a volume, only that &lt;code&gt;subPath&lt;/code&gt; of the whole
volume is relabeled. This allows two Pods that have two different SELinux labels
to use the same volume, as long as they use different subpaths of it.&lt;/div&gt;

&lt;p&gt;If a Pod does not have any SELinux label assigned in the Kubernetes API, the
container runtime assigns a unique random label, so a process that potentially
escapes the container boundary cannot access data of any other container on the
host. The container runtime still recursively relabels all Pod volumes with this
random SELinux label.&lt;/p&gt;
&lt;h2 id=&#34;what-kubernetes-is-improving&#34;&gt;What Kubernetes is improving&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#what-kubernetes-is-improving&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Where the stack supports it, the kubelet can mount the volume with &lt;code&gt;-o context=&amp;lt;label&amp;gt;&lt;/code&gt; so the kernel
applies the correct label for all inodes on that mount without a recursive inode traversal. That path is
gated by feature flags and requires, among other things, that the Pod expose enough of an SELinux
label (for example &lt;code&gt;spec.securityContext.seLinuxOptions.level&lt;/code&gt;) and that the volume driver opts in (for CSI,
CSIDriver field &lt;code&gt;spec.seLinuxMount: true&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;The project rolled this out in phases:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ReadWriteOncePod volumes were handled under the &lt;code&gt;SELinuxMountReadWriteOncePod&lt;/code&gt; feature gate, on by default since v1.28 and GA in v1.36.&lt;/li&gt;
&lt;li&gt;Broader coverage was handled under the &lt;code&gt;SELinuxMount&lt;/code&gt; flag, paired with the &lt;code&gt;spec.securityContext.seLinuxChangePolicy&lt;/code&gt; field on Pods.&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- a heavily edited copy from the previous blog + docs in https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ --&gt;
&lt;p&gt;If a Pod and its volume meet &lt;strong&gt;all&lt;/strong&gt; of the following conditions, Kubernetes will
mount the volume directly with the right SELinux label. Such a mount will happen
in a constant time and the container runtime will not need to recursively
relabel any files on it. For such a mount to happen:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;The operating system must support SELinux. Without SELinux support detected, the kubelet and the container runtime do not
do anything with regard to SELinux.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/reference/command-line-tools-reference/feature-gates/&#34;&gt;feature gate&lt;/a&gt;
&lt;code&gt;SELinuxMountReadWriteOncePod&lt;/code&gt; must be enabled.
If you&#39;re running Kubernetes v1.36, the feature is enabled unconditionally.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The Pod must use a PersistentVolumeClaim with applicable &lt;code&gt;accessModes&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Either the volume has &lt;code&gt;accessModes: [&amp;quot;ReadWriteOncePod&amp;quot;]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;or the volume can use any other access mode(s), provided that the feature gates
&lt;code&gt;SELinuxChangePolicy&lt;/code&gt; and &lt;code&gt;SELinuxMount&lt;/code&gt; are both enabled
&lt;strong&gt;and&lt;/strong&gt; the Pod has &lt;code&gt;spec.securityContext.seLinuxChangePolicy&lt;/code&gt; set to nil (default) or as &lt;code&gt;MountOption&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The feature gate &lt;code&gt;SELinuxMount&lt;/code&gt; is Beta and disabled by default in Kubernetes 1.36.
All other SELinux-related feature gates are now General Availability (GA).&lt;/p&gt;
&lt;p&gt;With any of these feature gates disabled, SELinux labels will always be
applied by the container runtime via recursively traversing through the volume
(or its subPaths).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The Pod must have at least &lt;code&gt;seLinuxOptions.level&lt;/code&gt; assigned in its
&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/reference/kubernetes-api/workload-resources/pod-v1/#security-context&#34;&gt;security context&lt;/a&gt;
or all containers in that Pod must have it set in their container-level &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/reference/kubernetes-api/workload-resources/pod-v1/#security-context-1&#34;&gt;security contexts&lt;/a&gt;.
Kubernetes will read the default &lt;code&gt;user&lt;/code&gt;, &lt;code&gt;role&lt;/code&gt; and &lt;code&gt;type&lt;/code&gt; from the operating
system defaults (typically &lt;code&gt;system_u&lt;/code&gt;, &lt;code&gt;system_r&lt;/code&gt; and &lt;code&gt;container_t&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;Without Kubernetes knowing at least the SELinux &lt;code&gt;level&lt;/code&gt;, the container
runtime will assign a random level after the volumes are mounted. The
container runtime will still relabel the volumes recursively in that case.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The volume plugin or the CSI driver responsible for the volume supports
mounting with SELinux mount options.&lt;/p&gt;
&lt;p&gt;These in-tree volume plugins support mounting with SELinux mount options:
&lt;code&gt;fc&lt;/code&gt; and &lt;code&gt;iscsi&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;CSI drivers that support mounting with SELinux mount options must declare this capability in their
&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/reference/kubernetes-api/config-and-storage-resources/csi-driver-v1/&#34;&gt;CSIDriver&lt;/a&gt;
instance by setting the &lt;code&gt;seLinuxMount&lt;/code&gt; field.&lt;/p&gt;
&lt;p&gt;Volumes managed by other volume plugins or CSI drivers that do not
set &lt;code&gt;seLinuxMount: true&lt;/code&gt; will be recursively relabeled by the container
runtime.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;the-breaking-change&#34;&gt;The breaking change&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#the-breaking-change&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The &lt;code&gt;SELinuxMount&lt;/code&gt; feature gate changes what volumes can be shared among multiple Pods in a subtle way.&lt;/p&gt;
&lt;p&gt;Both of these cases work with recursive relabeling:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Two Pods with different SELinux labels share the same volume, but each of them uses a different &lt;code&gt;subPath&lt;/code&gt; to the volume.&lt;/li&gt;
&lt;li&gt;A privileged Pod and an unprivileged Pod share the same volume.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The above scenarios will not work with modern, target behavior for Kubernetes mounting when SELinux is active. Instead, one of these Pods will be stuck in &lt;code&gt;ContainerCreating&lt;/code&gt; until the other Pod is terminated.&lt;/p&gt;
&lt;p&gt;The first case is very niche and hasn&#39;t been seen in practice.
Although the second case is still quite rare, this setup has been observed in applications.
Kubernetes v1.36 offers metrics and events to identify these Pods and allows cluster administrators to opt out of the
mount option through the Pod field &lt;code&gt;spec.securityContext.seLinuxChangePolicy&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&#34;selinuxchangepolicy&#34;&gt;&lt;code&gt;seLinuxChangePolicy&lt;/code&gt;&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#selinuxchangepolicy&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The new Pod field &lt;code&gt;spec.securityContext.seLinuxChangePolicy&lt;/code&gt; specifies how the SELinux label is applied to all Pod volumes.
In Kubernetes v1.36, this field is part of the stable Pod API.&lt;/p&gt;
&lt;p&gt;There are three choices available:&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;&lt;em&gt;field not set&lt;/em&gt; (default)&lt;/dt&gt;
&lt;dd&gt;In Kubernetes v1.36, the behavior depends on whether the &lt;code&gt;SELinuxMount&lt;/code&gt; feature gate is enabled. By default that feature gate is not enabled, and the SELinux label is applied recursively. If you enable that feature gate in your cluster, and &lt;a href=&#34;#what-kubernetes-is-improving&#34;&gt;all other conditions&lt;/a&gt; are met, labelling will be applied using the mount option.&lt;/dd&gt;
&lt;dt&gt;&lt;code&gt;Recursive&lt;/code&gt;&lt;/dt&gt;
&lt;dd&gt;the SELinux label is applied recursively. This opts out from using the mount option.&lt;/dd&gt;
&lt;dt&gt;&lt;code&gt;MountOption&lt;/code&gt;&lt;/dt&gt;
&lt;dd&gt;the SELinux label is applied using the mount option, if &lt;a href=&#34;#what-kubernetes-is-improving&#34;&gt;all other conditions&lt;/a&gt; are met.
This choice is available only when the &lt;code&gt;SELinuxMount&lt;/code&gt; feature gate is enabled.&lt;/dd&gt;
&lt;/dl&gt;
&lt;h2 id=&#34;selinux-warning-controller&#34;&gt;SELinux warning controller (optional)&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#selinux-warning-controller&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Kubernetes v1.36 provides a new controller within the control plane, &lt;code&gt;selinux-warning-controller&lt;/code&gt;.
This controller runs within the kube-controller-manager controller.
To use it, you pass &lt;code&gt;--controllers=*,selinux-warning-controller&lt;/code&gt; on the kube-controller-manager command line;
you also must not have explicitly overridden the &lt;code&gt;SELinuxChangePolicy&lt;/code&gt; feature gate to be disabled.&lt;/p&gt;
&lt;p&gt;The controller watches all Pods in the cluster and emits an Event when it finds two Pods that share the same
volume in a way that is not compatible with the &lt;code&gt;SELinuxMount&lt;/code&gt; feature gate.
All such conflicting Pods will receive an event, such as:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;go&#34;&gt;SELinuxLabel &amp;#34;system_u:system_r:container_t:s0:c98,c99&amp;#34; conflicts with pod my-other-pod that uses the same volume as this pod with SELinuxLabel &amp;#34;system_u:system_r:container_t:s0:c0,c1&amp;#34;. If both pods land on the same node, only one of them may access the volume.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The actual Pod name may be censored when the conflicting Pods run in different namespaces to prevent leaking information across namespace boundaries.&lt;/p&gt;
&lt;p&gt;The controller reports such an event even when these Pods don&#39;t run on the same node, to make sure all Pods work
regardless of the Kubernetes scheduler decision. They could run on the same node next time.&lt;/p&gt;
&lt;p&gt;In addition, the controller emits the metric &lt;code&gt;selinux_warning_controller_selinux_volume_conflict&lt;/code&gt; that lists all current conflicts among Pods.
The metric has labels that identify the conflicting Pods and their SELinux labels, such as:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;selinux_warning_controller_selinux_volume_conflict{pod1_name=&amp;#34;my-other-pod&amp;#34;,pod1_namespace=&amp;#34;default&amp;#34;,pod1_value=&amp;#34;system_u:object_r:container_file_t:s0:c0,c1&amp;#34;,pod2_name=&amp;#34;my-pod&amp;#34;,pod2_namespace=&amp;#34;default&amp;#34;,pod2_value=&amp;#34;system_u:object_r:container_file_t:s0:c0,c2&amp;#34;,property=&amp;#34;SELinuxLabel&amp;#34;} 1
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;There is a security consequence from enabling this opt-in controller: it may reveal namespace names, which are always present in the metric.
The Kubernetes project assumes only cluster administrators can access kube-controller-manager metrics.&lt;/p&gt;
&lt;h2 id=&#34;suggested-upgrade-path&#34;&gt;Suggested upgrade path&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#suggested-upgrade-path&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;To ensure a smooth upgrade path from v1.36 to a release with &lt;code&gt;SELinuxMount&lt;/code&gt; enabled (anticipated to be v1.37), we suggest you follow these steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Enable selinux-warning-controller in the kube-controller-manager.&lt;/li&gt;
&lt;li&gt;Check the &lt;code&gt;selinux_warning_controller_selinux_volume_conflict&lt;/code&gt; metric. It shows all &lt;em&gt;potential&lt;/em&gt; conflicts between Pods.
For each conflicting Pod (Deployment, StatefulSet, etc.), either apply the opt-out (set Pod&#39;s &lt;code&gt;spec.securityContext.seLinuxChangePolicy: Recursive&lt;/code&gt;)
or re-architect the application to remove such a conflict. For example, do your Pods really need to run as privileged?&lt;/li&gt;
&lt;li&gt;Check the &lt;code&gt;volume_manager_selinux_volume_context_mismatch_warnings_total&lt;/code&gt; metric. This metric is emitted by the kubelet when it actually
starts a Pod that runs when &lt;code&gt;SELinuxMount&lt;/code&gt; is disabled, but such a Pod won&#39;t start when &lt;code&gt;SELinuxMount&lt;/code&gt; is enabled.
This metric lists the number of Pods that will experience a true conflict. Unfortunately, this metric does not expose the exact Pod name as a label.
The full Pod name is available only in the &lt;code&gt;selinux_warning_controller_selinux_volume_conflict&lt;/code&gt; metric.&lt;/li&gt;
&lt;li&gt;Once both metrics have been accounted for, upgrade to a Kubernetes version that has &lt;code&gt;SELinuxMount&lt;/code&gt; enabled.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Consider using a &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/reference/access-authn-authz/mutating-admission-policy/&#34;&gt;MutatingAdmissionPolicy&lt;/a&gt;,
a &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/reference/access-authn-authz/extensible-admission-controllers/#what-are-admission-webhooks_&#34;&gt;mutating webhook&lt;/a&gt;,
or a policy engine like &lt;a href=&#34;https://github.com/kyverno/kyverno/&#34;&gt;Kyverno&lt;/a&gt; or &lt;a href=&#34;https://github.com/open-policy-agent/gatekeeper&#34;&gt;Gatekeeper&lt;/a&gt;
to apply the opt-out to all Pods in a namespace or across the entire cluster.&lt;/p&gt;
&lt;p&gt;When &lt;code&gt;SELinuxMount&lt;/code&gt; is enabled, the kubelet will emit the metric &lt;code&gt;volume_manager_selinux_volume_context_mismatch_errors_total&lt;/code&gt; with the number of
Pods that could not start because their SELinux label conflicts with an existing Pod that uses the same volume.
The exact Pod names should still be available in the &lt;code&gt;selinux_warning_controller_selinux_volume_conflict&lt;/code&gt; metric,
if the selinux-warning-controller is enabled.&lt;/p&gt;
&lt;h2 id=&#34;further-reading&#34;&gt;Further reading&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#further-reading&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;KEP: &lt;a href=&#34;https://kep.k8s.io/1710&#34;&gt;Speed up SELinux volume relabeling using mounts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#feature-gates&#34;&gt;SELinux Volume Relabeling Feature Gates&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/enhancements/tree/master/keps/sig-storage/1710-selinux-relabeling#story-3-cluster-upgrade&#34;&gt;Story 3: cluster upgrade&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/tasks/configure-pod-container/security-context/&#34;&gt;Configure a security context for a Pod&lt;/a&gt; — Efficient SELinux volume relabeling and selinux-warning-controller&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;acknowledgements&#34;&gt;Acknowledgements&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#acknowledgements&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;If you run into issues, have feedback, or want to contribute, find us
on the Kubernetes Slack in &lt;code&gt;#sig-node&lt;/code&gt; and &lt;code&gt;#sig-storage&lt;/code&gt; or join a
&lt;a href=&#34;https://github.com/kubernetes/community/tree/main/sig-node&#34;&gt;SIG Node&lt;/a&gt; or &lt;a href=&#34;https://github.com/kubernetes/community/tree/main/sig-storage&#34;&gt;SIG Storage&lt;/a&gt; meetings.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes v1.36: ハル (Haru)</title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/04/22/kubernetes-v1-36-release/</link>
      <pubDate>Wed, 22 Apr 2026 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/04/22/kubernetes-v1-36-release/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Editors:&lt;/strong&gt; Chad M. Crowell, Kirti Goyal, Sophia Ugochukwu, Swathi Rao, Utkarsh Umre&lt;/p&gt;
&lt;p&gt;Similar to previous releases, the release of Kubernetes v1.36 introduces new stable, beta, and alpha features. The consistent delivery of high-quality releases underscores the strength of our development cycle and the vibrant support from our community.&lt;/p&gt;
&lt;p&gt;This release consists of 70 enhancements. Of those enhancements, 18 have graduated to Stable, 25 are entering Beta, and 25 have graduated to Alpha.&lt;/p&gt;
&lt;p&gt;There are also some &lt;a href=&#34;#deprecations-removals-and-community-updates&#34;&gt;deprecations and removals&lt;/a&gt; in this release; make sure to read about those.&lt;/p&gt;
&lt;h2 id=&#34;release-theme-and-logo&#34;&gt;Release theme and logo&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#release-theme-and-logo&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;

&lt;figure class=&#34;release-logo &#34;&gt;
    &lt;img src=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/04/22/kubernetes-v1-36-release/k8s-v1.36.svg&#34;
         alt=&#34;Kubernetes v1.36 Haru logo: a hex badge with the title Haru in flowing script beneath v1.36; Mount Fuji rises on the right, its peak lit red with streaks of pale snow, the Japanese calligraphy 晴れに翔け brushed down its slope; a white Kubernetes helm floats in the blue sky to the left among stylised clouds in the ukiyo-e manner; in the foreground stand two cats as paired guardians, a grey-and-white cat on the left and a ginger tabby on the right, each wearing a collar with a small blue Kubernetes helm charm&#34;/&gt; 
&lt;/figure&gt;
&lt;p&gt;We open 2026 with Kubernetes v1.36, a release that arrives as the season turns and the light shifts on the mountain. ハル (&lt;em&gt;Haru&lt;/em&gt;) is a sound in Japanese that carries many meanings; among those we hold closest are 春 (spring), 晴れ (&lt;em&gt;hare&lt;/em&gt;, clear skies), and 遥か (&lt;em&gt;haruka&lt;/em&gt;, far-off, distant). A season, a sky, and a horizon. You will find all three in what follows.&lt;/p&gt;
&lt;p&gt;The logo, created by &lt;a href=&#34;https://x.com/avocadoneko&#34;&gt;avocadoneko / Natsuho Ide&lt;/a&gt;, draws inspiration from &lt;a href=&#34;https://en.wikipedia.org/wiki/Hokusai&#34;&gt;Katsushika Hokusai&lt;/a&gt;&#39;s &lt;a href=&#34;https://en.wikipedia.org/wiki/Thirty-six_Views_of_Mount_Fuji&#34;&gt;&lt;em&gt;Thirty-six Views of Mount Fuji&lt;/em&gt;&lt;/a&gt; (富嶽三十六景, &lt;em&gt;Fugaku Sanjūrokkei&lt;/em&gt;), the same series that gave the world &lt;a href=&#34;https://en.wikipedia.org/wiki/The_Great_Wave_off_Kanagawa&#34;&gt;&lt;em&gt;The Great Wave off Kanagawa&lt;/em&gt;&lt;/a&gt;. Our v1.36 logo reimagines one of the series&#39; most celebrated prints, &lt;a href=&#34;https://en.wikipedia.org/wiki/Fine_Wind,_Clear_Morning&#34;&gt;&lt;em&gt;Fine Wind, Clear Morning&lt;/em&gt;&lt;/a&gt; (凱風快晴, &lt;em&gt;Gaifū Kaisei&lt;/em&gt;), also known as Red Fuji (赤富士, &lt;em&gt;Aka Fuji&lt;/em&gt;): the mountain lit red in a summer dawn, bare of snow after the long thaw. Thirty-six views felt like a fitting number to sit with at v1.36, and a reminder that even Hokusai didn&#39;t stop there.&lt;sup&gt;1&lt;/sup&gt; Keeping watch over the scene is the Kubernetes helm, set into the sky alongside the mountain.&lt;/p&gt;
&lt;p&gt;At the foot of Fuji sit Stella (left) and Nacho (right), two cats with the Kubernetes helm on their collars, standing in for the role of &lt;a href=&#34;https://en.wikipedia.org/wiki/Komainu&#34;&gt;&lt;em&gt;komainu&lt;/em&gt;&lt;/a&gt;, the paired lion-dog guardians that watch over Japanese shrines. Paired, because nothing is guarded alone. Stella and Nacho stand in for a very much larger set of paws: the SIGs and working groups, the maintainers and reviewers, the people behind docs, blogs, and translations, the release team, first-time contributors taking their first steps, and lifelong contributors returning season after season. Kubernetes v1.36 is, as always, held up by many hands.&lt;/p&gt;
&lt;p&gt;Brushed across Red Fuji in the logo is the calligraphy 晴れに翔け (&lt;em&gt;hare ni kake&lt;/em&gt;), &amp;quot;soar into clear skies&amp;quot;. It is the first half of a couplet that was too long to fit on the mountain:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;晴れに翔け、未来よ明け&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;hare ni kake, asu yo ake&lt;/em&gt;&lt;br&gt;
&amp;quot;Soar into clear skies; toward tomorrow&#39;s sunrise.&amp;quot;&lt;sup&gt;2&lt;/sup&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;That is the wish we carry for this release: to soar into clear skies, for the release itself, for the project, and for everyone who ships it together. The dawn breaking over Red Fuji is not an ending but a passage: this release carries us to the next, and that one to the one after, on toward horizons far beyond what any single view can hold.&lt;/p&gt;
&lt;p&gt;&lt;sub&gt;1. The series was so popular that Hokusai added ten more prints, bringing the total to forty-six.&lt;/sub&gt;&lt;br&gt;
&lt;sub&gt;2. 未来 means &amp;quot;the future&amp;quot; in its widest sense, not just tomorrow but everything still to come. It is usually read &lt;em&gt;mirai&lt;/em&gt;; here it takes the informal reading &lt;em&gt;asu&lt;/em&gt;.&lt;/sub&gt;&lt;/p&gt;
&lt;h2 id=&#34;spotlight-on-key-updates&#34;&gt;Spotlight on key updates&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#spotlight-on-key-updates&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Kubernetes v1.36 is packed with new features and improvements. Here are a
few select updates the Release Team would like to highlight!&lt;/p&gt;
&lt;h3 id=&#34;stable-fine-grained-api-authorization&#34;&gt;Stable: Fine-grained API authorization&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#stable-fine-grained-api-authorization&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;On behalf of Kubernetes SIG Auth and SIG Node, we are pleased to announce the
graduation of fine-grained &lt;code&gt;kubelet&lt;/code&gt; API authorization to General Availability
(GA) in Kubernetes v1.36!&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;KubeletFineGrainedAuthz&lt;/code&gt; feature gate was introduced as an opt-in alpha feature
in Kubernetes v1.32, then graduated to beta (enabled by default) in v1.33.
Now, the feature is generally available.
This feature enables more precise, least-privilege access control over the kubelet&#39;s
HTTPS API replacing the need to grant the overly broad nodes/proxy permission for
common monitoring and observability use cases.&lt;/p&gt;
&lt;p&gt;​​This work was done as a part of &lt;a href=&#34;https://kep.k8s.io/2862&#34;&gt;KEP #2862&lt;/a&gt; led by SIG Auth and SIG Node.&lt;/p&gt;
&lt;h3 id=&#34;beta-resource-health-status&#34;&gt;Beta: Resource health status&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#beta-resource-health-status&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Before the v1.34 release, Kubernetes lacked a native way to report the health of allocated devices,
making it difficult to diagnose Pod crashes caused by hardware failures.
Building on the initial alpha release in v1.31 which focused on Device Plugins,
Kubernetes v1.36 expands this feature by promoting the &lt;code&gt;allocatedResourcesStatus&lt;/code&gt;
field within the &lt;code&gt;.status&lt;/code&gt; for each Pod (to beta). This field provides a unified health
reporting mechanism for all specialized hardware.&lt;/p&gt;
&lt;p&gt;Users can now run &lt;code&gt;kubectl describe pod&lt;/code&gt; to determine if a container&#39;s crash loop is
due to an &lt;code&gt;Unhealthy&lt;/code&gt; or &lt;code&gt;Unknown&lt;/code&gt; device status, regardless of whether the hardware was
provisioned via traditional plugins or the newer DRA framework.
This enhanced visibility allows administrators and automated controllers to
quickly identify faulty hardware and streamline the recovery of high-performance workloads.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://kep.k8s.io/4680&#34;&gt;KEP #4680&lt;/a&gt; led by SIG Node.&lt;/p&gt;
&lt;h3 id=&#34;alpha-workload-aware-scheduling-was-features&#34;&gt;Alpha: Workload Aware Scheduling (WAS) features&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#alpha-workload-aware-scheduling-was-features&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Previously, the Kubernetes scheduler and job controllers managed pods as independent units,
often leading to fragmented scheduling or resource waste for complex, distributed workloads.
Kubernetes v1.36 introduces a comprehensive suite of Workload Aware Scheduling (WAS) features in Alpha,
natively integrating the Job controller with a revised &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/workloads/workload-api/&#34;&gt;Workload&lt;/a&gt;
API and a new decoupled PodGroup API,
to treat related pods as a single logical entity.&lt;/p&gt;
&lt;p&gt;Kubernetes v1.35 already supported &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/scheduling-eviction/gang-scheduling/&#34;&gt;gang scheduling&lt;/a&gt; by requiring
a minimum number of pods to be schedulable before any were bound to nodes.
v1.36 goes further with a new PodGroup scheduling cycle that evaluates the entire group atomically,
either all pods in the group are bound together, or none are.&lt;/p&gt;
&lt;p&gt;This work was done across several KEPs (including &lt;a href=&#34;https://kep.k8s.io/4671&#34;&gt;#4671&lt;/a&gt;, &lt;a href=&#34;https://kep.k8s.io/5547&#34;&gt;#5547&lt;/a&gt;, &lt;a href=&#34;https://kep.k8s.io/5832&#34;&gt;#5832&lt;/a&gt;, &lt;a href=&#34;https://kep.k8s.io/5732&#34;&gt;#5732&lt;/a&gt;, and &lt;a href=&#34;https://kep.k8s.io/5710&#34;&gt;#5710&lt;/a&gt;) led by SIG Scheduling and SIG Apps.&lt;/p&gt;
&lt;h2 id=&#34;features-graduating-to-stable&#34;&gt;Features graduating to Stable&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#features-graduating-to-stable&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;&lt;em&gt;This is a selection of some of the improvements that are now stable following the v1.36 release.&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&#34;volume-group-snapshots&#34;&gt;Volume group snapshots&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#volume-group-snapshots&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;After several cycles in beta, VolumeGroupSnapshot support reaches General Availability (GA) in Kubernetes v1.36.
This feature allows you to take crash-consistent snapshots across multiple PersistentVolumeClaims simultaneously.
The support for volume group snapshots relies on a set of &lt;a href=&#34;https://kubernetes-csi.github.io/docs/group-snapshot-restore-feature.html#volume-group-snapshot-apis&#34;&gt;extension APIs for group snapshots&lt;/a&gt;.
These APIs allow users to take crash consistent snapshots for a set of volumes.
A key aim is to allow you to restore that set of snapshots to new volumes and recover your workload based on
a crash consistent recovery point.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://kep.k8s.io/3476&#34;&gt;KEP #3476&lt;/a&gt; led by SIG Storage.&lt;/p&gt;
&lt;h3 id=&#34;mutable-volume-attach-limits&#34;&gt;Mutable volume attach limits&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#mutable-volume-attach-limits&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;In Kubernetes v1.36, the &lt;em&gt;mutable &lt;code&gt;CSINode&lt;/code&gt; allocatable&lt;/em&gt; feature graduates to stable.
This enhancement allows &lt;a href=&#34;https://kubernetes-csi.github.io/docs/introduction.html&#34;&gt;Container Storage Interface (CSI)&lt;/a&gt; drivers to
dynamically update the reported maximum number of volumes that a node can handle.&lt;/p&gt;
&lt;p&gt;With this update, the &lt;code&gt;kubelet&lt;/code&gt; can dynamically update a node&#39;s volume limits and capacity information.
The &lt;code&gt;kubelet&lt;/code&gt; adjusts these limits based on periodic checks or in response to
resource exhaustion errors from the CSI driver, without requiring a component restart.
This ensures the Kubernetes scheduler maintains an accurate view of storage availability,
preventing pod scheduling failures caused by outdated volume limits.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://kep.k8s.io/4876&#34;&gt;KEP #4876&lt;/a&gt; led by SIG Storage.&lt;/p&gt;
&lt;h3 id=&#34;api-for-external-signing-of-service-account-tokens&#34;&gt;API for external signing of ServiceAccount tokens&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#api-for-external-signing-of-service-account-tokens&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;In Kubernetes v1.36, the &lt;em&gt;external ServiceAccount token signer&lt;/em&gt; feature for service accounts graduates to stable,
making it possible to offload token signing to an external system while still integrating cleanly with the Kubernetes API.
Clusters can now rely on an external JWT signer for issuing projected service account tokens that
follow the standard service account token format, including support for extended expiration when needed.
This is especially useful for clusters that already rely on external identity or key management systems,
allowing Kubernetes to integrate without duplicating key management inside the control plane.&lt;/p&gt;
&lt;p&gt;The kube-apiserver is wired to discover public keys from the external signer,
cache them, and validate tokens it did not sign itself,
so existing authentication and authorization flows continue to work as expected.
Over the alpha and beta phases, the API and configuration for the external signer plugin,
path validation, and OIDC discovery were hardened to handle real-world deployments and rotation patterns safely.&lt;/p&gt;
&lt;p&gt;With GA in v1.36, external ServiceAccount token signing is now a fully supported option for platforms that
centralize identity and signing, simplifying integration with external IAM systems and
reducing the need to manage signing keys directly inside the control plane.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://kep.k8s.io/740&#34;&gt;KEP #740&lt;/a&gt; led by SIG Auth.&lt;/p&gt;
&lt;h3 id=&#34;dra-features-graduating-to-stable&#34;&gt;DRA features graduating to Stable&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#dra-features-graduating-to-stable&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Part of the Dynamic Resource Allocation (DRA) ecosystem reaches full production maturity in
Kubernetes v1.36 as key governance and selection features graduate to Stable.
The transition of &lt;em&gt;DRA admin access&lt;/em&gt; to GA provides a permanent, secure framework for cluster administrators
to access and manage hardware resources globally, while the stabilization of &lt;em&gt;prioritized lists&lt;/em&gt; ensures that
resource selection logic remains consistent and predictable across all cluster environments.&lt;/p&gt;
&lt;p&gt;Now, organizations can confidently deploy mission-critical hardware automation with the guarantee
of long-term API stability and backward compatibility. These features empower users to implement
sophisticated resource-sharing policies and administrative overrides that are essential for
large-scale GPU clusters and multi-tenant AI platforms, marking the completion of the
core architectural foundation for next-generation resource management.&lt;/p&gt;
&lt;p&gt;This work was done as part of KEPs &lt;a href=&#34;https://kep.k8s.io/5018&#34;&gt;#5018&lt;/a&gt; and &lt;a href=&#34;https://kep.k8s.io/4816&#34;&gt;#4816&lt;/a&gt; led by SIG Auth and SIG Scheduling.&lt;/p&gt;
&lt;h3 id=&#34;mutating-admission-policies&#34;&gt;Mutating admission policies&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#mutating-admission-policies&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Declarative cluster management reaches a new level of sophistication in Kubernetes v1.36 with the
graduation of &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/reference/access-authn-authz/mutating-admission-policy/&#34;&gt;MutatingAdmissionPolicies&lt;/a&gt; to Stable. This milestone provides a native,
high-performance alternative to traditional webhooks by allowing administrators to
define resource mutations directly in the API server using the Common Expression Language (CEL),
fully replacing the need for external infrastructure for many common use cases.&lt;/p&gt;
&lt;p&gt;Now, cluster operators can modify incoming requests without the latency and operational
complexity associated with managing custom admission webhooks.
By moving mutation logic into a declarative, versioned policy, organizations can achieve
more predictable cluster behavior, reduced network overhead,
and a hardened security model with the full guarantee of long-term API stability.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://kep.k8s.io/3962&#34;&gt;KEP #3962&lt;/a&gt; led by SIG API Machinery.&lt;/p&gt;
&lt;h3 id=&#34;declarative-validation-of-kubernetes-native-types-with-validation-gen&#34;&gt;Declarative validation of Kubernetes native types with &lt;code&gt;validation-gen&lt;/code&gt;&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#declarative-validation-of-kubernetes-native-types-with-validation-gen&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The development of custom resources reaches a new level of efficiency in Kubernetes v1.36
as &lt;em&gt;declarative validation&lt;/em&gt; (with &lt;code&gt;validation-gen&lt;/code&gt;) graduates to Stable.
This milestone replaces the manual and often error-prone task of writing complex
OpenAPI schemas by allowing developers to define sophisticated validation logic directly
within Go struct tags using the Common Expression Language (CEL).&lt;/p&gt;
&lt;p&gt;Instead of writing custom validation functions, Kubernetes contributors can now define validation
rules using IDL marker comments (such as &lt;code&gt;+k8s:minimum&lt;/code&gt; or &lt;code&gt;+k8s:enum&lt;/code&gt;) directly
within the API type definitions (&lt;code&gt;types.go&lt;/code&gt;). The &lt;code&gt;validation-gen&lt;/code&gt; tool parses these
comments to automatically generate robust API validation code at compile-time.
This reduces maintenance overhead and ensures that API validation
remains consistent and synchronized with the source code.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://kep.k8s.io/5073&#34;&gt;KEP #5073&lt;/a&gt; led by SIG API Machinery.&lt;/p&gt;
&lt;h3 id=&#34;remove-gogo-protobuf-dependency-for-kubernetes-api-types&#34;&gt;Removal of gogo protobuf dependency for Kubernetes API types&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#remove-gogo-protobuf-dependency-for-kubernetes-api-types&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Security and long-term maintainability for the Kubernetes codebase take a major step forward
in Kubernetes v1.36 with the completion of the &lt;code&gt;gogoprotobuf&lt;/code&gt; removal.
This initiative has eliminated a significant dependency on the unmaintained &lt;code&gt;gogoprotobuf&lt;/code&gt; library,
which had become a source of potential security vulnerabilities and
a blocker for adopting modern Go language features.&lt;/p&gt;
&lt;p&gt;Instead of migrating to standard Protobuf generation, which presented compatibility risks
for Kubernetes API types, the project opted to fork and internalize the required
generation logic within &lt;code&gt;k8s.io/code-generator&lt;/code&gt;. This approach successfully eliminates
the unmaintained runtime dependencies from the Kubernetes dependency graph
while preserving existing API behavior and serialization compatibility.
For consumers of Kubernetes API Go types, this change reduces technical debt and
prevents accidental misuse with standard protobuf libraries.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://kep.k8s.io/5589&#34;&gt;KEP #5589&lt;/a&gt; led by SIG API Machinery.&lt;/p&gt;
&lt;h3 id=&#34;node-log-query&#34;&gt;Node log query&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#node-log-query&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Previously, Kubernetes required cluster administrators to log into nodes via SSH or implement a
client-side reader for debugging issues pertaining to control-plane or worker nodes.
While certain issues still require direct node access, issues with the kube-proxy or kubelet
can be diagnosed by inspecting their logs. Node logs offer cluster administrators
a method to view these logs using the kubelet API and kubectl plugin
to simplify troubleshooting without logging into nodes, similar to debugging issues
related to a pod or container. This method is operating system agnostic and
requires the services or nodes to log to &lt;code&gt;/var/log&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;As this feature reaches GA in Kubernetes 1.36 after thorough performance validation on production workloads,
it is enabled by default on the kubelet through the &lt;code&gt;NodeLogQuery&lt;/code&gt; feature gate.
In addition, the &lt;code&gt;enableSystemLogQuery&lt;/code&gt; kubelet configuration option must also be enabled.&lt;/p&gt;
&lt;p&gt;This work was done as a part of &lt;a href=&#34;https://kep.k8s.io/2258&#34;&gt;KEP #2258&lt;/a&gt; led by SIG Windows.&lt;/p&gt;
&lt;h3 id=&#34;support-user-namespaces-in-pods&#34;&gt;Support User Namespaces in pods&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#support-user-namespaces-in-pods&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Container isolation and node security reach a major maturity milestone in Kubernetes v1.36 as
support for User Namespaces graduates to Stable.
This long-awaited feature provides a critical layer of defense-in-depth by allowing the
mapping of a container&#39;s root user to a non-privileged user on the host,
ensuring that even if a process escapes the container,
it possesses no administrative power over the underlying node.&lt;/p&gt;
&lt;p&gt;Now, cluster operators can confidently enable this hardened isolation for production
workloads to mitigate the impact of container breakout vulnerabilities.
By decoupling the container&#39;s internal identity from the host&#39;s identity,
Kubernetes provides a robust, standardized mechanism to protect multi-tenant
environments and sensitive infrastructure from unauthorized access,
all with the full guarantee of long-term API stability.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://kep.k8s.io/127&#34;&gt;KEP #127&lt;/a&gt; led by SIG Node.&lt;/p&gt;
&lt;h3 id=&#34;support-psi-based-on-cgroupv2&#34;&gt;Support PSI based on cgroupv2&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#support-psi-based-on-cgroupv2&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Node resource management and observability become more precise in Kubernetes v1.36
as the export of Pressure Stall Information (PSI) metrics graduates to Stable.
This feature provides the kubelet with the ability to report &amp;quot;pressure&amp;quot; metrics for CPU,
memory, and I/O, offering a more granular view of resource contention than
traditional utilization metrics.&lt;/p&gt;
&lt;p&gt;Cluster operators and autoscalers can use these metrics to distinguish between a system that is
simply busy and one that is actively stalling due to resource exhaustion.
By leveraging these signals, users can more accurately tune pod resource requests,
improve the reliability of vertical autoscaling, and detect noisy neighbor
effects before they lead to application performance degradation or node instability.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://kep.k8s.io/4205&#34;&gt;KEP #4205&lt;/a&gt; led by SIG Node.&lt;/p&gt;
&lt;h3 id=&#34;volumesource-oci-artifact-and-or-image&#34;&gt;Volume source: OCI artifact and/or image&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#volumesource-oci-artifact-and-or-image&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The distribution of container data becomes more flexible in Kubernetes v1.36 as &lt;em&gt;OCI volume source&lt;/em&gt; support graduates to Stable.
This feature moves beyond the traditional requirement of mounting volumes from external storage providers
or config maps by allowing the kubelet to pull and mount content directly from any OCI-compliant registry,
such as a container image or an artifact repository.&lt;/p&gt;
&lt;p&gt;Now, developers and platform engineers can package application data, models, or static assets as OCI artifacts
and deliver them to pods using the same registries and versioning workflows they already use for container images.
This convergence of image and volume management simplifies CI/CD pipelines,
reduces dependency on specialized storage backends for read-only content,
and ensures that data remains portable and securely accessible across any environment.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://kep.k8s.io/4639&#34;&gt;KEP #4639&lt;/a&gt; led by SIG Node.&lt;/p&gt;
&lt;h2 id=&#34;new-features-in-beta&#34;&gt;New features in Beta&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#new-features-in-beta&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;&lt;em&gt;This is a selection of some of the improvements that are now beta following the v1.36 release.&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&#34;staleness-mitigation-for-controllers&#34;&gt;Staleness mitigation for controllers&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#staleness-mitigation-for-controllers&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Staleness in Kubernetes controllers is a problem that affects many controllers and can subtly affect controller behavior.
It is usually not until it is too late, when a controller in production has already taken incorrect action,
that staleness is found to be an issue due to some underlying assumption made by the controller author.
This could lead to conflicting updates or data corruption upon controller reconciliation during times of cache staleness.&lt;/p&gt;
&lt;p&gt;We are excited to announce that Kubernetes v1.36 includes new features that help mitigate controller staleness and
provide better observability of controller behavior.
This prevents reconciliation based on an outdated view of cluster state that can often lead to harmful behavior.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://kep.k8s.io/5647&#34;&gt;KEP #5647&lt;/a&gt; led by SIG API Machinery.&lt;/p&gt;
&lt;h3 id=&#34;ip-cidr-validation-improvements&#34;&gt;IP/CIDR validation improvements&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#ip-cidr-validation-improvements&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;In Kubernetes v1.36, the &lt;code&gt;StrictIPCIDRValidation&lt;/code&gt; feature for API IP and CIDR fields graduates to beta,
tightening validation to catch malformed addresses and prefixes that previously slipped through.
This helps prevent subtle configuration bugs where Services, Pods, NetworkPolicies,
or other resources reference invalid IPs, which could otherwise lead to
confusing runtime behavior or security surprises.&lt;/p&gt;
&lt;p&gt;Controllers are updated to canonicalize IPs they write back into objects and to warn when they
encounter bad values that were already stored, so clusters can gradually converge on clean,
consistent data. With beta, &lt;code&gt;StrictIPCIDRValidation&lt;/code&gt; is ready for wider use,
giving operators more reliable guardrails around IP-related configuration
as they evolve networks and policies over time.&lt;/p&gt;
&lt;p&gt;This work was done as a part of &lt;a href=&#34;https://kep.k8s.io/4858&#34;&gt;KEP #4858&lt;/a&gt; led by SIG Network.&lt;/p&gt;
&lt;h3 id=&#34;separate-kubectl-user-preferences-from-cluster-configs&#34;&gt;Separate kubectl user preferences from cluster configs&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#separate-kubectl-user-preferences-from-cluster-configs&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The &lt;code&gt;.kuberc&lt;/code&gt; feature for customizing &lt;code&gt;kubectl&lt;/code&gt; user preferences continues to be beta
and is enabled by default. The &lt;code&gt;~/.kube/kuberc&lt;/code&gt; file allows users to store aliases, default flags,
and other personal settings separately from &lt;code&gt;kubeconfig&lt;/code&gt; files, which hold cluster endpoints and credentials.
This separation prevents personal preferences from interfering with CI pipelines or shared &lt;code&gt;kubeconfig&lt;/code&gt; files,
while maintaining a consistent &lt;code&gt;kubectl&lt;/code&gt; experience across different clusters and contexts.&lt;/p&gt;
&lt;p&gt;In Kubernetes v1.36, &lt;code&gt;.kuberc&lt;/code&gt; was expanded with the ability to define policies for credential plugins
(allowlists or denylists) to enforce safer authentication practicies.
Users can disable this functionality if needed by setting the &lt;code&gt;KUBECTL_KUBERC=false&lt;/code&gt; or &lt;code&gt;KUBERC=off&lt;/code&gt; environment variables.&lt;/p&gt;
&lt;p&gt;This work was done as a part of &lt;a href=&#34;https://kep.k8s.io/3104&#34;&gt;KEP #3104&lt;/a&gt; led by SIG CLI, with the help from SIG Auth.&lt;/p&gt;
&lt;h3 id=&#34;mutable-container-resources-when-job-is-suspended&#34;&gt;Mutable container resources when Job is suspended&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#mutable-container-resources-when-job-is-suspended&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;In Kubernetes v1.36, the &lt;code&gt;MutablePodResourcesForSuspendedJobs&lt;/code&gt; feature graduates to beta and is enabled by default.
This update relaxes Job validation to allow updates to container CPU, memory,
GPU, and extended resource requests and limits while a Job is suspended.&lt;/p&gt;
&lt;p&gt;This capability allows queue controllers and operators to adjust batch workload requirements based on
real‑time cluster conditions. For example, a queueing system can suspend incoming Jobs,
adjust their resource requirements to match available capacity or quota, and then unsuspend them.
The feature strictly limits mutability to suspended Jobs (or Jobs whose pods have been terminated upon suspension)
to prevent disruptive changes to actively running pods.&lt;/p&gt;
&lt;p&gt;This work was done as a part of &lt;a href=&#34;https://kep.k8s.io/5440&#34;&gt;KEP #5440&lt;/a&gt; led by SIG Apps.&lt;/p&gt;
&lt;h3 id=&#34;constrained-impersonation&#34;&gt;Constrained impersonation&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#constrained-impersonation&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;In Kubernetes v1.36, the &lt;code&gt;ConstrainedImpersonation&lt;/code&gt; feature for user impersonation graduates to beta,
tightening a historically all‑or‑nothing mechanism into something that can actually follow least‑privilege principles.
When this feature is enabled, an impersonator must have two distinct sets of permissions:
one to impersonate a given identity, and another to perform specific actions on that identity’s behalf.
This prevents support tools, controllers, or node agents from using impersonation to gain broader access
than they themselves are allowed, even if their impersonation RBAC is misconfigured.
Existing impersonate rules keep working, but the API server prefers the new constrained checks first,
making the transition incremental instead of a flag day. With beta in v1.36, &lt;code&gt;ConstrainedImpersonation&lt;/code&gt; is tested,
documented, and ready for wider adoption by platform teams that rely on impersonation for debugging, proxying,
or node‑level controllers.&lt;/p&gt;
&lt;p&gt;This work was done as a part of &lt;a href=&#34;https://kep.k8s.io/5284&#34;&gt;KEP #5284&lt;/a&gt; led by SIG Auth.&lt;/p&gt;
&lt;h3 id=&#34;dra-features-in-beta&#34;&gt;DRA features in beta&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#dra-features-in-beta&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/scheduling-eviction/dynamic-resource-allocation/&#34;&gt;Dynamic Resource Allocation (DRA)&lt;/a&gt; framework reaches another maturity milestone in Kubernetes v1.36 as several core features graduate to beta and are enabled by default.
This transition moves DRA beyond basic allocation by graduating &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/scheduling-eviction/dynamic-resource-allocation/#partitionable-devices&#34;&gt;partitionable devices&lt;/a&gt; and &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/scheduling-eviction/dynamic-resource-allocation/#consumable-capacity&#34;&gt;consumable capacity&lt;/a&gt;, allowing for more granular sharing of hardware like GPUs,
while &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/scheduling-eviction/dynamic-resource-allocation/#device-taints-and-tolerations&#34;&gt;device taints and tolerations&lt;/a&gt; ensure that specialized resources are only utilized by the appropriate workloads.&lt;/p&gt;
&lt;p&gt;Now, users benefit from a much more reliable and observable resource lifecycle through &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/scheduling-eviction/dynamic-resource-allocation/#resourceclaim-device-status&#34;&gt;ResourceClaim device status&lt;/a&gt;
and the ability to ensure device attachment before Pod scheduling.
By integrating these features with &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/scheduling-eviction/dynamic-resource-allocation/#extended-resource&#34;&gt;extended resource&lt;/a&gt; support,
Kubernetes provides a robust production-ready alternative to the legacy device plugin system,
enabling complex AI and HPC workloads to manage hardware with unprecedented precision and operational safety.&lt;/p&gt;
&lt;p&gt;This work was done across several KEPs (including &lt;a href=&#34;https://kep.k8s.io/5004&#34;&gt;#5004&lt;/a&gt;, &lt;a href=&#34;https://kep.k8s.io/4817&#34;&gt;#4817&lt;/a&gt;, &lt;a href=&#34;https://kep.k8s.io/5055&#34;&gt;#5055&lt;/a&gt;, &lt;a href=&#34;https://kep.k8s.io/5075&#34;&gt;#5075&lt;/a&gt;, &lt;a href=&#34;https://kep.k8s.io/4815&#34;&gt;#4815&lt;/a&gt;, and &lt;a href=&#34;https://kep.k8s.io/issues/5007&#34;&gt;#5007&lt;/a&gt;) led by SIG Scheduling and SIG Node.&lt;/p&gt;
&lt;h3 id=&#34;statusz-for-kubernetes-components&#34;&gt;Statusz for Kubernetes components&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#statusz-for-kubernetes-components&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;In Kubernetes v1.36, the &lt;code&gt;ComponentStatusz&lt;/code&gt; feature gate for core Kubernetes components graduates to beta,
providing a &lt;code&gt;/statusz&lt;/code&gt; endpoint (enabled by default) that surfaces real‑time build and version details for each component.
This low‑overhead &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/reference/instrumentation/zpages/&#34;&gt;z-page&lt;/a&gt; exposes information like start time, uptime, Go version, binary version,
emulation version, and minimum compatibility version, so operators and developers can quickly see exactly
what is running without digging through logs or configs.&lt;/p&gt;
&lt;p&gt;The endpoint offers a human‑readable text view by default, plus a versioned structured API (&lt;code&gt;config.k8s.io/v1beta1&lt;/code&gt;)
for programmatic access in JSON, YAML, or CBOR via explicit content negotiation.
Access is granted to the &lt;code&gt;system:monitoring&lt;/code&gt; group, keeping it aligned with existing protections on
health and metrics endpoints and avoiding exposure of sensitive data.&lt;/p&gt;
&lt;p&gt;With beta, &lt;code&gt;ComponentStatusz&lt;/code&gt; is enabled by default across all core control‑plane components and node agents,
backed by unit, integration, and end‑to‑end tests so it can be safely used in production for
observability and debugging workflows.&lt;/p&gt;
&lt;p&gt;This work was done as a part of &lt;a href=&#34;https://kep.k8s.io/4827&#34;&gt;KEP #4827&lt;/a&gt; led by SIG Instrumentation.&lt;/p&gt;
&lt;h3 id=&#34;flagz-for-kubernetes-components&#34;&gt;Flagz for Kubernetes components&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#flagz-for-kubernetes-components&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;In Kubernetes v1.36, the &lt;code&gt;ComponentFlagz&lt;/code&gt; feature gate for core Kubernetes components graduates to beta,
standardizing a &lt;code&gt;/flagz&lt;/code&gt; endpoint that exposes the effective command‑line flags each component was started with.
This gives cluster operators and developers real‑time, in‑cluster visibility into component configuration,
making it much easier to debug unexpected behavior or verify that a flag rollout actually took effect after a restart.&lt;/p&gt;
&lt;p&gt;The endpoint supports both a human‑readable text view and a versioned structured API (initially &lt;code&gt;config.k8s.io/v1beta1&lt;/code&gt;),
so you can either &lt;code&gt;curl&lt;/code&gt; it during an incident or wire it into automated tooling once you are ready.
Access is granted to the &lt;code&gt;system:monitoring&lt;/code&gt; group and sensitive values can be redacted,
keeping configuration insight aligned with existing security practices around health and status endpoints.&lt;/p&gt;
&lt;p&gt;With beta, &lt;code&gt;ComponentFlagz&lt;/code&gt; is now enabled by default and implemented across all core control‑plane components
and node agents, backed by unit, integration, and end‑to‑end tests to ensure the endpoint is reliable in production clusters.&lt;/p&gt;
&lt;p&gt;This work was done as a part of &lt;a href=&#34;https://kep.k8s.io/4828&#34;&gt;KEP #4828&lt;/a&gt; led by SIG Instrumentation.&lt;/p&gt;
&lt;h3 id=&#34;mixed-version-proxy&#34;&gt;Mixed version proxy (aka &lt;em&gt;unknown version interoperability proxy&lt;/em&gt;)&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#mixed-version-proxy&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;In Kubernetes v1.36, the &lt;em&gt;mixed version proxy&lt;/em&gt; feature graduates to beta, building on its alpha introduction in v1.28
to provide safer control-plane upgrades for mixed-version clusters. Each API request can now be routed to the apiserver
instance that serves the requested group, version, and resource, reducing 404s and failures due to version skew.&lt;/p&gt;
&lt;p&gt;The feature relies on peer-aggregated discovery, so apiservers share information about which resources and versions they expose,
then use that data to transparently reroute requests when needed. New metrics on rerouted traffic and proxy behavior
help operators understand how often requests are forwarded and to which peers.
Together, these changes make it easier to run highly available, mixed-version API control planes in production
while performing multi-step or partial control-plane upgrades.&lt;/p&gt;
&lt;p&gt;This work was done as a part of &lt;a href=&#34;https://kep.k8s.io/4020&#34;&gt;KEP #4020&lt;/a&gt; led by SIG API Machinery&lt;/p&gt;
&lt;h3 id=&#34;memory-qos-with-cgroups-v2&#34;&gt;Memory QoS with cgroups v2&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#memory-qos-with-cgroups-v2&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Kubernetes now enhances memory QoS on Linux cgroup v2 nodes with smarter, tiered memory protection that better aligns kernel
controls with pod requests and limits, reducing interference and thrashing for workloads sharing the same node.
This iteration also refines how kubelet programs memory.high and memory.min, adds metrics and safeguards to avoid livelocks,
and introduces configuration options so cluster operators can tune memory protection behavior for their environments.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://kep.k8s.io/2570&#34;&gt;KEP #2570&lt;/a&gt; led by SIG Node.&lt;/p&gt;
&lt;h2 id=&#34;new-features-in-alpha&#34;&gt;New features in Alpha&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#new-features-in-alpha&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;This is a selection of some of the improvements that are now alpha following the v1.36 release.&lt;/p&gt;
&lt;h3 id=&#34;hpa-scale-to-zero-for-custom-metrics&#34;&gt;HPA scale to zero for custom metrics&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#hpa-scale-to-zero-for-custom-metrics&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Until now, the HorizontalPodAutoscaler (HPA) required a minimum of at least one replica to remain active,
as it could only calculate scaling needs based on metrics (like CPU or Memory) from running pods.
Kubernetes v1.36 continues the development of the &lt;em&gt;HPA scale to zero&lt;/em&gt; feature (disabled by default) in Alpha,
allowing workloads to scale down to zero replicas specifically when using Object or External metrics.&lt;/p&gt;
&lt;p&gt;Now, users can experiment with significantly reducing infrastructure costs by completely idling heavy workloads when
no work is pending. While the feature remains behind the &lt;code&gt;HPAScaleToZero&lt;/code&gt; feature gate,
it enables the HPA to stay active even with zero running pods,
automatically scaling the deployment back up as soon as the external metric (e.g., queue length)
indicates that new tasks have arrived.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://kep.k8s.io/2021&#34;&gt;KEP #2021&lt;/a&gt; led by SIG Autoscaling.&lt;/p&gt;
&lt;h3 id=&#34;dra-features-in-alpha&#34;&gt;DRA features in Alpha&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#dra-features-in-alpha&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Historically, the Dynamic Resource Allocation (DRA) framework lacked seamless integration with high-level controllers and
provided limited visibility into device-specific metadata or availability.
Kubernetes v1.36 introduces a wave of DRA enhancements in Alpha, including native ResourceClaim support for workloads,
and DRA native resources to provide the flexibility of DRA to cpu management.&lt;/p&gt;
&lt;p&gt;Now, users can leverage the &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/workloads/pods/downward-api/&#34;&gt;downward API&lt;/a&gt; to expose complex resource attributes directly to containers and
benefit from improved resource availability visibility for more predictable scheduling. these updates,
combined with support for list types in device attributes, transform DRA from a low-level primitive into a robust system
capable of handling the sophisticated networking and compute requirements of modern AI and
high-performance computing (HPC) stacks.&lt;/p&gt;
&lt;p&gt;This work was done across several KEPs (including &lt;a href=&#34;https://kep.k8s.io/5729&#34;&gt;#5729&lt;/a&gt;, &lt;a href=&#34;https://kep.k8s.io/5304&#34;&gt;#5304&lt;/a&gt;, &lt;a href=&#34;https://kep.k8s.io/5517&#34;&gt;#5517&lt;/a&gt;, &lt;a href=&#34;https://kep.k8s.io/5677&#34;&gt;#5677&lt;/a&gt;, and &lt;a href=&#34;https://kep.k8s.io/5491&#34;&gt;#5491&lt;/a&gt;) led by SIG Scheduling and SIG Node.&lt;/p&gt;
&lt;h3 id=&#34;native-histogram-support-for-kubernetes-metrics&#34;&gt;Native histogram support for Kubernetes metrics&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#native-histogram-support-for-kubernetes-metrics&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;High-resolution monitoring reaches a new milestone in Kubernetes v1.36 with the introduction of native histogram support
in Alpha. While classical Prometheus histograms relied on static, pre-defined buckets that often forced a compromise
between data accuracy and memory usage, this update allows the control plane to export sparse histograms that
dynamically adjust their resolution based on real-time data.&lt;/p&gt;
&lt;p&gt;Now, cluster operators can capture precise latency distributions for the kube-apiserver and other core components without
the overhead of manual bucket management. This architectural shift ensures more reliable SLIs and SLOs,
providing high-fidelity heatmaps that remain accurate even during the most unpredictable workload spikes.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://kep.k8s.io/5808&#34;&gt;KEP #5808&lt;/a&gt; led by SIG Instrumentation.&lt;/p&gt;
&lt;h3 id=&#34;manifest-based-admission-control-config&#34;&gt;Manifest based admission control config&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#manifest-based-admission-control-config&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Managing admission controllers moves toward a more declarative and consistent model in Kubernetes v1.36 with the
introduction of &lt;em&gt;manifest-based admission control&lt;/em&gt; configuration in Alpha.
This change addresses the long-standing challenge of configuring admission plugins through disparate command-line
flags or separate, complex config files by allowing administrators to define the desired state of admission control
directly through a structured manifest.&lt;/p&gt;
&lt;p&gt;Now, cluster operators can manage admission plugin settings with the same versioned, declarative workflows used for
other Kubernetes objects, significantly reducing the risk of configuration drift and manual errors during cluster upgrades.
By centralizing these configurations into a unified manifest, the kube-apiserver becomes easier to audit and automate,
paving the way for more secure and reproducible cluster deployments.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://kep.k8s.io/5793&#34;&gt;KEP #5793&lt;/a&gt; led by SIG API Machinery.&lt;/p&gt;
&lt;h3 id=&#34;cri-list-streaming&#34;&gt;CRI list streaming&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#cri-list-streaming&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;With the introduction of &lt;em&gt;CRI list streaming&lt;/em&gt; in Alpha, Kubernetes v1.36 uses new internal streaming operations.
This enhancement addresses the memory pressure and latency spikes often seen on large-scale nodes by replacing traditional,
monolithic &lt;code&gt;List&lt;/code&gt; requests between the kubelet and the container runtime with a more efficient server-side streaming RPC.&lt;/p&gt;
&lt;p&gt;Now, instead of waiting for a single, massive response containing all container or image data, the kubelet can process results
incrementally as they are streamed. This shift significantly reduces the peak memory footprint of the kubelet and improves
responsiveness on high-density nodes, ensuring that cluster management remains fluid even as the number of
containers per node continues to grow.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://kep.k8s.io/5825&#34;&gt;KEP #5825&lt;/a&gt; led by SIG Node.&lt;/p&gt;
&lt;h2 id=&#34;other-notable-changes&#34;&gt;Other notable changes&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#other-notable-changes&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;h3 id=&#34;ingress-nginx-retirement&#34;&gt;Ingress NGINX retirement&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#ingress-nginx-retirement&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;To prioritize the safety and security of the ecosystem, Kubernetes SIG Network and the Security Response Committee have
retired Ingress NGINX on March 24, 2026.
Since that date, there have been no further releases, no bugfixes, and no updates to resolve any security vulnerabilities discovered. Existing deployments of
Ingress NGINX will continue to function, and installation artifacts like Helm charts and container images will remain available.&lt;/p&gt;
&lt;p&gt;For full details, see the &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2025/11/11/ingress-nginx-retirement/&#34;&gt;official retirement announcement&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;volume-selinux-labelling&#34;&gt;Faster SELinux labelling for volumes (GA)&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#volume-selinux-labelling&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Kubernetes v1.36 makes the SELinux volume mounting improvement generally available. This change replaced recursive file
relabeling with &lt;code&gt;mount -o context=XYZ&lt;/code&gt; option, applying the correct SELinux label to the entire volume at mount time.
It brings more consistent performance and reduces Pod startup delays on SELinux-enforcing systems.&lt;/p&gt;
&lt;p&gt;This feature was introduced as beta in v1.28 for &lt;code&gt;ReadWriteOncePod&lt;/code&gt; volumes. In v1.32, it gained metrics and an opt-out
option (&lt;code&gt;securityContext.seLinuxChangePolicy: Recursive&lt;/code&gt;) to help catch conflicts. Now in v1.36,
it reaches Stable and defaults to all volumes, with Pods or CSIDrivers opting in via &lt;code&gt;spec.seLinuxMount&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;However, we expect this feature to create the risk of breaking changes in the future Kubernetes releases, potentially due to sharing one volume between privileged and unprivileged Pods on the same node.&lt;/p&gt;
&lt;p&gt;Developers have the responsibility of setting the &lt;code&gt;seLinuxChangePolicy&lt;/code&gt; field and SELinux volume labels on Pods. Regardless of whether they are writing a Deployment, StatefulSet, DaemonSet or even a custom resource that includes a Pod template, being careless with these settings can lead to a range of problems such as Pods not starting up correctly when Pods share a volume.&lt;/p&gt;
&lt;p&gt;Kubernetes v1.36 is the ideal release to audit your clusters. To learn more, check out &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/04/22/breaking-changes-in-selinux-volume-labeling/&#34;&gt;SELinux Volume Label Changes goes GA (and likely implications in v1.37)&lt;/a&gt; blog.&lt;/p&gt;
&lt;p&gt;For more details on this enhancement, refer to &lt;a href=&#34;https://kep.k8s.io/1710&#34;&gt;KEP-1710: Speed up recursive SELinux label change&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;graduations-deprecations-and-removals-in-v1-36&#34;&gt;Graduations, deprecations, and removals in v1.36&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#graduations-deprecations-and-removals-in-v1-36&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;h3 id=&#34;graduations-to-stable&#34;&gt;Graduations to stable&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#graduations-to-stable&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;This lists all the features that graduated to stable (also known as general availability).
For a full list of updates including new features and graduations from alpha to beta, see the release notes.&lt;/p&gt;
&lt;p&gt;This release includes a total of 18 enhancements promoted to stable:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/127&#34;&gt;Support User Namespaces in pods&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/740&#34;&gt;API for external signing of Service Account tokens&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/1710&#34;&gt;Speed up recursive SELinux label change&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/2589&#34;&gt;Portworx file in-tree to CSI driver migration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/2862&#34;&gt;Fine grained Kubelet API authorization&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/3962&#34;&gt;Mutating Admission Policies&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/2258&#34;&gt;Node log query&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/3476&#34;&gt;VolumeGroupSnapshot&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/4876&#34;&gt;Mutable CSINode Allocatable Property&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/4816&#34;&gt;DRA: Prioritized Alternatives in Device Requests&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/4205&#34;&gt;Support PSI based on cgroupv2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/4265&#34;&gt;add ProcMount option&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/3695&#34;&gt;DRA: Extend PodResources to include resources from Dynamic Resource Allocation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/4639&#34;&gt;VolumeSource: OCI Artifact and/or Image&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/5109&#34;&gt;Split L3 Cache Topology Awareness in CPU Manager&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/5018&#34;&gt;DRA: AdminAccess for ResourceClaims and ResourceClaimTemplates&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/5589&#34;&gt;Remove gogo protobuf dependency for Kubernetes API types&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/5538&#34;&gt;CSI driver opt-in for service account tokens via secrets field&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;deprecations-removals-and-community-updates&#34;&gt;Deprecations removals, and community updates&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#deprecations-removals-and-community-updates&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;As Kubernetes develops and matures, features may be deprecated, removed, or replaced with better ones to improve the
project&#39;s overall health. See the Kubernetes deprecation and removal policy for more details on this process.
Kubernetes v1.36 includes a couple of deprecations.&lt;/p&gt;
&lt;h3 id=&#34;deprecate-service-spec-externalips&#34;&gt;Deprecation of Service .spec.externalIPs&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#deprecate-service-spec-externalips&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;With this release, the &lt;code&gt;externalIPs&lt;/code&gt; field in Service &lt;code&gt;spec&lt;/code&gt; is deprecated. This means the functionality exists, but will no longer function in a &lt;strong&gt;future&lt;/strong&gt; version of Kubernetes. You should plan to migrate if you currently rely on that field.
This field has been a known security headache for years,
enabling man-in-the-middle attacks on your cluster traffic, as documented in &lt;a href=&#34;https://github.com/kubernetes/kubernetes/issues/97076&#34;&gt;CVE-2020-8554&lt;/a&gt;.
From Kubernetes v1.36 and onwards, you will see deprecation warnings when using it, with full removal planned for v1.43.&lt;/p&gt;
&lt;p&gt;If your Services still lean on &lt;code&gt;externalIPs&lt;/code&gt;, consider using LoadBalancer services for cloud-managed ingress,
NodePort for simple port exposure, or &lt;a href=&#34;https://gateway-api.sigs.k8s.io/&#34;&gt;Gateway API&lt;/a&gt; for a more flexible and secure way to handle external traffic.&lt;/p&gt;
&lt;p&gt;For more details on this field and its deprecation, refer to &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/services-networking/service/#external-ips&#34;&gt;External IPs&lt;/a&gt; or read
&lt;a href=&#34;https://kep.k8s.io/5707&#34;&gt;KEP-5707: Deprecate service.spec.externalIPs&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;remove-gitrepo-volume-driver&#34;&gt;Removal of the &lt;code&gt;gitRepo&lt;/code&gt; volume driver&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#remove-gitrepo-volume-driver&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The &lt;code&gt;gitRepo&lt;/code&gt; volume type has been deprecated since v1.11. For Kubernetes v1.36, the &lt;code&gt;gitRepo&lt;/code&gt; volume plugin is
permanently disabled and cannot be turned back on. This change protects clusters from a critical security issue where
using &lt;code&gt;gitRepo&lt;/code&gt; could let an attacker run code as root on the node.&lt;/p&gt;
&lt;p&gt;Although &lt;code&gt;gitRepo&lt;/code&gt; has been deprecated for years and better alternatives have been recommended,
it was still technically possible to use it in previous releases.
From v1.36 onward, that path is closed for good, so any existing workloads depending on &lt;code&gt;gitRepo&lt;/code&gt; will need to migrate to
supported approaches such as init containers or external &lt;code&gt;git-sync&lt;/code&gt; style tools.&lt;/p&gt;
&lt;p&gt;For more details on this removal, refer to &lt;a href=&#34;https://kep.k8s.io/5040&#34;&gt;KEP-5040: Remove gitRepo volume driver&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;release-notes&#34;&gt;Release notes&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#release-notes&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Check out the full details of the Kubernetes v1.36 release in our &lt;a href=&#34;https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.36.md&#34;&gt;release notes&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;availability&#34;&gt;Availability&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#availability&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Kubernetes v1.36 is available for download on &lt;a href=&#34;https://github.com/kubernetes/kubernetes/releases/tag/v1.36.0&#34;&gt;GitHub&lt;/a&gt; or on the &lt;a href=&#34;https://kubernetes.io/releases/download/&#34;&gt;Kubernetes download page&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To get started with Kubernetes, check out &lt;a href=&#34;https://kubernetes.io/docs/tutorials/&#34;&gt;these tutorials&lt;/a&gt; or run local Kubernetes clusters using &lt;a href=&#34;https://minikube.sigs.k8s.io/&#34;&gt;minikube&lt;/a&gt;.
You can also easily &lt;a href=&#34;https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/&#34;&gt;install v1.36 using kubeadm&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;release-team&#34;&gt;Release Team&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#release-team&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Kubernetes is only possible with the support, commitment, and hard work of its community. Each release team is
made up of dedicated community volunteers who work together to build the many pieces that make up the
Kubernetes releases you rely on. This requires the specialized skills of people from all corners of our community,
from the code itself to its documentation and project management.&lt;/p&gt;
&lt;p&gt;We would like to thank the entire &lt;a href=&#34;https://github.com/kubernetes/sig-release/blob/master/releases/release-1.36/release-team.md&#34;&gt;Release Team&lt;/a&gt; for the hours spent hard at work to deliver the Kubernetes v1.36 release to our community.
The Release Team&#39;s membership ranges from first-time shadows to returning team leads with experience forged over
several release cycles. A very special thanks goes out to our release lead, Ryota Sawada,
for guiding us through a successful release cycle, for his hands-on approach to solving challenges,
and for bringing the energy and care that drives our community forward.&lt;/p&gt;
&lt;h2 id=&#34;project-velocity&#34;&gt;Project Velocity&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#project-velocity&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The CNCF K8s &lt;a href=&#34;https://k8s.devstats.cncf.io/d/11/companies-contributing-in-repository-groups?orgId=1&amp;var-period=m&amp;var-repogroup_name=All&#34;&gt;DevStats&lt;/a&gt; project aggregates a number of interesting data points related to the velocity of
Kubernetes and various sub-projects. This includes everything from individual contributions to the number of
companies that are contributing, and is an illustration of the depth and breadth of effort that goes into evolving this ecosystem.&lt;/p&gt;
&lt;p&gt;During the v1.36 release cycle, which spanned 15 weeks from 12th January 2026 to 22nd April 2026,
Kubernetes received contributions from as many as 106 different companies and 491 individuals.
In the wider cloud native ecosystem, the figure goes up to 370 companies, counting 2235 total contributors.&lt;/p&gt;
&lt;p&gt;Note that “contribution” counts when someone makes a commit, code review, comment, creates an issue or PR,
reviews a PR (including blogs and documentation) or comments on issues and PRs.
If you are interested in contributing, visit &lt;a href=&#34;https://www.kubernetes.dev/docs/guide/#getting-started&#34;&gt;Getting Started&lt;/a&gt; on our contributor website.&lt;/p&gt;
&lt;p&gt;Source for this data:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://k8s.devstats.cncf.io/d/11/companies-contributing-in-repository-groups?orgId=1&amp;from=1747609200000&amp;to=1756335599000&amp;var-period=d28&amp;var-repogroup_name=Kubernetes&amp;var-repo_name=kubernetes%2Fkubernetes&#34;&gt;Companies contributing to Kubernetes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://k8s.devstats.cncf.io/d/11/companies-contributing-in-repository-groups?orgId=1&amp;from=1747609200000&amp;to=1756335599000&amp;var-period=d28&amp;var-repogroup_name=All&amp;var-repo_name=kubernetes%2Fkubernetes&#34;&gt;Overall ecosystem contributions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;events-update&#34;&gt;Events Update&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#events-update&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Explore upcoming Kubernetes and cloud native events, including KubeCon + CloudNativeCon, KCD,
and other notable conferences worldwide. Stay informed and get involved with the Kubernetes community!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;April 2026&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;KCD - &lt;a href=&#34;https://community.cncf.io/events/details/cncf-kcd-guadalajara-presents-kcd-guadalajara-2026/cohost-kcd-guadalajara/&#34;&gt;Kubernetes Community Days: Guadalajara&lt;/a&gt;: April 18, 2026 | Guadalajara, Mexico&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;May 2026&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;KCD - &lt;a href=&#34;https://community.cncf.io/events/details/cncf-kcd-toronto-presents-kcd-toronto-2026/&#34;&gt;Kubernetes Community Days: Toronto&lt;/a&gt;: May 13, 2026 | Toronto, Canada&lt;/li&gt;
&lt;li&gt;KCD - &lt;a href=&#34;https://community.cncf.io/events/details/cncf-kcd-texas-presents-kcd-texas-2026/cohost-kcd-texas/&#34;&gt;Kubernetes Community Days: Texas&lt;/a&gt;: May 15, 2026 | Austin, USA&lt;/li&gt;
&lt;li&gt;KCD - &lt;a href=&#34;https://community.cncf.io/events/details/cncf-kcd-istanbul-presents-kcd-istanbul-2026/&#34;&gt;Kubernetes Community Days: Istanbul&lt;/a&gt;: May 15, 2026 | Istanbul, Turkey&lt;/li&gt;
&lt;li&gt;KCD - &lt;a href=&#34;https://community.cncf.io/events/details/cncf-kcd-helsinki-presents-kubernetes-community-days-helsinki-2026/&#34;&gt;Kubernetes Community Days: Helsinki&lt;/a&gt;: May 20, 2026 | Helsinki, Finland&lt;/li&gt;
&lt;li&gt;KCD - &lt;a href=&#34;https://community.cncf.io/events/details/cncf-kcd-czech-slovak-presents-kcd-czech-amp-slovak-prague-2026/&#34;&gt;Kubernetes Community Days: Czech &amp;amp; Slovak&lt;/a&gt;: May 21, 2026 | Prague, Czechia&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;June 2026&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;KCD - &lt;a href=&#34;https://community.cncf.io/events/details/cncf-kcd-new-york-presents-kcd-new-york-2026/&#34;&gt;Kubernetes Community Days: New York&lt;/a&gt;: June 10, 2026 | New York, USA&lt;/li&gt;
&lt;li&gt;KCD - &lt;a href=&#34;https://community2.cncf.io/events/details/cncf-kcd-kuala-lumpur-2026-presents-kcd-kuala-lumpur-2026/&#34;&gt;Kubernetes Community Days: Kuala Lumpur&lt;/a&gt;: June 27, 2026 | Kuala Lumpur, Malaysia&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://events.linuxfoundation.org/kubecon-cloudnativecon-india/&#34;&gt;KubeCon + CloudNativeCon India 2026: June 18-19, 2026&lt;/a&gt; | Mumbai, India&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;July 2026&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://events.linuxfoundation.org/kubecon-cloudnativecon-japan/&#34;&gt;KubeCon + CloudNativeCon Japan 2026: July 29-30, 2026&lt;/a&gt; | Yokohama, Japan&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;September 2026&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;KCD - &lt;a href=&#34;https://community2.cncf.io/events/details/cncf-kcd-sf-bay-area-presents-kcd-san-francisco-bay-area-2026/&#34;&gt;Kubernetes Community Days: San Francisco Bay Area&lt;/a&gt;: September 1, 2026 | Mountain View, USA&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.lfopensource.cn/kubecon-cloudnativecon-openinfra-summit-pytorch-conference-china/&#34;&gt;KubeCon + CloudNativeCon China 2026: September 8-9, 2026&lt;/a&gt; | Shanghai, China&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;October 2026&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;KCD - &lt;a href=&#34;https://community.cncf.io/events/details/cncf-kcd-uk-presents-kubernetes-community-days-uk-edinburgh-2026/&#34;&gt;Kubernetes Community Days: UK: Oct 19, 2026&lt;/a&gt; | Edinburgh, UK&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;November 2026&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;KCD - &lt;a href=&#34;https://community.cncf.io/events/details/cncf-kcd-porto-presents-kcd-porto-2026-collab-with-devops-days-portugal/&#34;&gt;Kubernetes Community Days: Porto&lt;/a&gt;: Nov 19, 2026 | Porto, Portugal&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://events.linuxfoundation.org/kubecon-cloudnativecon-north-america/&#34;&gt;KubeCon + CloudNativeCon North America 2026&lt;/a&gt;: Nov 9-12, 2026 | Salt Lake City, USA&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can find the latest event details &lt;a href=&#34;https://community.cncf.io/events/#/list&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;upcoming-release-webinar&#34;&gt;Upcoming Release Webinar&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#upcoming-release-webinar&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Join members of the Kubernetes v1.36 Release Team on &lt;strong&gt;Wednesday, May 20th 2026 at 4:00 PM (UTC)&lt;/strong&gt; to learn about the release highlights
of this release. For more information and registration, visit the &lt;a href=&#34;https://community.cncf.io/events/details/cncf-cncf-online-programs-presents-cloud-native-live-kubernetes-v136-release/&#34;&gt;event page&lt;/a&gt; on the CNCF Online Programs site.&lt;/p&gt;
&lt;h2 id=&#34;get-involved&#34;&gt;Get Involved&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#get-involved&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The simplest way to get involved with Kubernetes is by joining one of the many &lt;a href=&#34;https://github.com/kubernetes/community/blob/master/sig-list.md&#34;&gt;Special Interest Groups&lt;/a&gt; (SIGs) that align with your interests.
Have something you’d like to broadcast to the Kubernetes community? Share your voice at our weekly &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/communication&#34;&gt;community meeting&lt;/a&gt;,
and through the channels below. Thank you for your continued feedback and support.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Follow us on Bluesky &lt;a href=&#34;https://bsky.app/profile/kubernetes.io&#34;&gt;@kubernetes.io&lt;/a&gt; for the latest updates&lt;/li&gt;
&lt;li&gt;Join the community discussion on &lt;a href=&#34;https://discuss.kubernetes.io/&#34;&gt;Discuss&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Join the community on &lt;a href=&#34;https://slack.k8s.io/&#34;&gt;Slack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Post questions (or answer questions) on &lt;a href=&#34;https://stackoverflow.com/questions/tagged/kubernetes&#34;&gt;Stack Overflow&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Share your Kubernetes &lt;a href=&#34;https://docs.google.com/a/linuxfoundation.org/forms/d/e/1FAIpQLScuI7Ye3VQHQTwBASrgkjQDSS5TP0g3AXfFhwSM9YpHgxRKFA/viewform&#34;&gt;story&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Read more about what’s happening with Kubernetes on the &lt;a href=&#34;https://kubernetes.io/blog/&#34;&gt;blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Learn more about the &lt;a href=&#34;https://github.com/kubernetes/sig-release/tree/master/release-team&#34;&gt;Kubernetes Release Team&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Gateway API v1.5: Moving features to Stable</title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/04/21/gateway-api-v1-5/</link>
      <pubDate>Tue, 21 Apr 2026 08:30:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/04/21/gateway-api-v1-5/</guid>
      <description>
        
        
        &lt;p&gt;&lt;img src=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/04/21/gateway-api-v1-5/gateway-api-logo.svg&#34; alt=&#34;Gateway API logo&#34;&gt;&lt;/p&gt;
&lt;p&gt;The Kubernetes SIG Network community presents the release of Gateway API (v1.5)!
Released on February 27, 2026, version 1.5 is our biggest release yet, and concentrates on moving existing Experimental features to Standard (Stable).&lt;/p&gt;
&lt;p&gt;The Gateway API &lt;a href=&#34;https://github.com/kubernetes-sigs/gateway-api/releases/tag/v1.5.1&#34;&gt;v1.5.1&lt;/a&gt; patch release is already available.&lt;/p&gt;
&lt;p&gt;The Gateway API v1.5 brings six widely-requested feature promotions to the Standard channel (Gateway API&#39;s GA release channel):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ListenerSet&lt;/li&gt;
&lt;li&gt;TLSRoute&lt;/li&gt;
&lt;li&gt;HTTPRoute CORS Filter&lt;/li&gt;
&lt;li&gt;Client Certificate Validation&lt;/li&gt;
&lt;li&gt;Certificate Selection for Gateway TLS Origination&lt;/li&gt;
&lt;li&gt;ReferenceGrant&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Special thanks for &lt;a href=&#34;https://github.com/kubernetes-sigs/gateway-api/blob/a811d174a406553006bbb9a3594b49380cb9069e/CHANGELOG/1.5-TEAM.md&#34;&gt;Gateway API Contributors&lt;/a&gt; for their efforts on this release.&lt;/p&gt;
&lt;h2 id=&#34;new-release-process&#34;&gt;New release process&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#new-release-process&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;As of Gateway API v1.5, the project has moved to a release train model, where on a feature freeze date, any features that are ready are shipped in the release.&lt;/p&gt;
&lt;p&gt;This applies to both Experimental and Standard, and also applies to documentation -- if the documentation isn&#39;t ready to ship, the feature isn&#39;t ready to ship.&lt;/p&gt;
&lt;p&gt;We are aiming for this to produce a more reliable release cadence (since we are basing our work off the excellent work done by SIG Release on Kubernetes itself).
As part of this change, we&#39;ve also introduced Release Manager and Release Shadow roles to our release team. Many thanks to Flynn (Buoyant) and Beka Modebadze (Google) for all the great work coordinating and filing the rough edges of our release process. They are both going to continue in this role for the next release as well.&lt;/p&gt;
&lt;h2 id=&#34;new-standard-features&#34;&gt;New standard features&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#new-standard-features&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;h3 id=&#34;listenerset&#34;&gt;ListenerSet&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#listenerset&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Leads: &lt;a href=&#34;https://github.com/dprotaso&#34;&gt;Dave Protasowski&lt;/a&gt;, &lt;a href=&#34;https://github.com/davidjumani&#34;&gt;David Jumani&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://gateway-api.sigs.k8s.io/geps/gep-1713/&#34;&gt;GEP-1713&lt;/a&gt;&lt;/p&gt;
&lt;h4 id=&#34;why-listenerset&#34;&gt;Why ListenerSet?&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#why-listenerset&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;Prior to ListenerSet, all listeners had to be specified directly on the Gateway object.
While this worked well for simple use cases, it created challenges for more complex
or multi-tenant environments:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Platform teams and application teams often needed to coordinate changes to the same Gateway&lt;/li&gt;
&lt;li&gt;Safely delegating ownership of individual listeners was difficult&lt;/li&gt;
&lt;li&gt;Extending existing Gateways required direct modification of the original resource&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&#34;https://gateway-api.sigs.k8s.io/guides/listener-set/&#34;&gt;ListenerSet&lt;/a&gt; addresses these limitations by allowing listeners to be defined independently and then merged onto a target Gateway.&lt;/p&gt;
&lt;p&gt;ListenerSets also enable attaching more than 64 listeners to a single, shared Gateway. This is critical for large scale deployments and scenarios with multiple hostnames per listener.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Even though the ListenerSet feature significantly enhances scalability, the &lt;strong&gt;listener&lt;/strong&gt; field in Gateway &lt;strong&gt;remains a mandatory requirement&lt;/strong&gt; and the Gateway must have at least one valid listener.&lt;/p&gt;&lt;/blockquote&gt;
&lt;h4 id=&#34;how-it-works&#34;&gt;How it works&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#how-it-works&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;A ListenerSet attaches to a Gateway and contributes one or more listeners.
The Gateway controller is responsible for merging listeners from the Gateway resource itself and any attached ListenerSet resources.&lt;/p&gt;
&lt;p&gt;In this example, a central infrastructure team defines a Gateway with a default HTTP listener,
while two different application teams define their own ListenerSet resources in separate namespaces.
Both ListenerSets attach to the same Gateway and contribute additional HTTPS listeners.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;gateway.networking.k8s.io/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Gateway&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;example-gateway&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;namespace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;infra&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;gatewayClassName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;example-gateway-class&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;allowedListeners&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;namespaces&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;from&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;All&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# A selector lets you fine tune this&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;listeners&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;http&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;protocol&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;HTTP&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;port&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;80&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;gateway.networking.k8s.io/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ListenerSet&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;team-a-listeners&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;namespace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;team-a&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;parentRef&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;example-gateway&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;namespace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;infra&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;listeners&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;https-a&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;protocol&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;HTTPS&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;port&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;443&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;hostname&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;a.example.com&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;tls&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;certificateRefs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;a-cert&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;gateway.networking.k8s.io/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ListenerSet&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;team-b-listeners&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;namespace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;team-b&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;parentRef&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;example-gateway&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;namespace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;infra&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;listeners&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;https-b&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;protocol&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;HTTPS&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;port&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;443&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;hostname&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;b.example.com&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;tls&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;certificateRefs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;b-cert&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;tlsroute&#34;&gt;TLSRoute&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#tlsroute&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Leads: &lt;a href=&#34;https://github.com/rostislavbobo&#34;&gt;Rostislav Bobrovsky&lt;/a&gt;, &lt;a href=&#34;https://github.com/rikatz&#34;&gt;Ricardo Pchevuzinske Katz&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://gateway-api.sigs.k8s.io/geps/gep-2643/&#34;&gt;GEP-2643&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The &lt;a href=&#34;https://gateway-api.sigs.k8s.io/api-types/tlsroute/&#34;&gt;TLSRoute resource&lt;/a&gt; allows you to route requests by matching the Server Name Indication (SNI) presented by the client during the TLS handshake and directing the stream to the appropriate Kubernetes backends.&lt;/p&gt;
&lt;p&gt;When working with TLSRoute, a Gateway&#39;s TLS listener can be configured in one of two modes: &lt;code&gt;Passthrough&lt;/code&gt; or &lt;code&gt;Terminate&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;If you install Gateway API v1.5 Standard over v1.4 or earlier Experimental, your existing
Experimental TLSRoutes will not be usable&lt;/strong&gt;. This is because they will be stored in the &lt;code&gt;v1alpha2&lt;/code&gt; or &lt;code&gt;v1alpha3&lt;/code&gt; version, which is &lt;strong&gt;&lt;em&gt;not&lt;/em&gt;&lt;/strong&gt; included in the v1.5 Standard YAMLs.
If this applies to you, either continue using Experimental for v1.5.1 and onward, or you&#39;ll need to download and migrate your TLSRoutes to &lt;code&gt;v1&lt;/code&gt;, which &lt;em&gt;is&lt;/em&gt; present in the Standard YAMLs.&lt;/p&gt;
&lt;h4 id=&#34;passthrough-mode&#34;&gt;Passthrough mode&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#passthrough-mode&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;The Passthrough mode is designed for strict security requirements. It is ideal for scenarios where traffic must remain encrypted end-to-end until it reaches the destination backend, when the external client and backend need to authenticate directly with each other, or when you can’t store certificates on the Gateway. This configuration is also applicable when an encrypted TCP stream is required instead of standard HTTP traffic.&lt;/p&gt;
&lt;p&gt;In this mode, the encrypted byte stream is proxied directly to the destination backend. The Gateway has zero access to private keys or unencrypted data.&lt;/p&gt;
&lt;p&gt;The following TLSRoute is attached to a listener that is configured in &lt;code&gt;Passthrough&lt;/code&gt; mode. It will match only TLS handshakes with the &lt;code&gt;foo.example.com&lt;/code&gt; SNI hostname and apply its routing rules to pass the encrypted TCP stream to the configured backend:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;gateway.networking.k8s.io/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Gateway&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;example-gateway&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;gatewayClassName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;example-gateway-class&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;listeners&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;tls-passthrough&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;protocol&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;TLS&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;port&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;8443&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;tls&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;mode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Passthrough&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;gateway.networking.k8s.io/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;TLSRoute&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;foo-route&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;parentRefs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;example-gateway&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;sectionName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;tls-passthrough&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;hostnames&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;s2&#34;&gt;&amp;#34;foo.example.com&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;rules&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;backendRefs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;foo-svc&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;port&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;8443&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;terminate-mode&#34;&gt;Terminate mode&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#terminate-mode&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;The Terminate mode provides the convenience of centralized TLS certificate management directly at the Gateway.&lt;/p&gt;
&lt;p&gt;In this mode, the TLS session is fully terminated at the Gateway, which then
routes the decrypted payload to the destination backend as a plain text TCP stream.&lt;/p&gt;
&lt;p&gt;The following TLSRoute is attached to a listener that is configured in Terminate mode.
It will match only TLS handshakes with the &lt;code&gt;bar.example.com&lt;/code&gt; SNI hostname and apply its routing rules to pass the decrypted TCP stream to the configured backend:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;gateway.networking.k8s.io/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Gateway&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;example-gateway&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;gatewayClassName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;example-gateway-class&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;listeners&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;tls-terminate&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;protocol&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;TLS&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;port&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;443&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;tls&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;mode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Terminate&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;certificateRefs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;tls-terminate-certificate&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;gateway.networking.k8s.io/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;TLSRoute&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;bar-route&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;parentRefs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;example-gateway&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;sectionName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;tls-terminate&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;hostnames&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;s2&#34;&gt;&amp;#34;bar.example.com&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;rules&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;backendRefs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;bar-svc&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;port&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;8080&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;httproute-cors-filter&#34;&gt;HTTPRoute CORS filter&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#httproute-cors-filter&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Leads: &lt;a href=&#34;https://github.com/DamianSawicki&#34;&gt;Damian Sawicki&lt;/a&gt;, &lt;a href=&#34;https://github.com/rikatz&#34;&gt;Ricardo Pchevuzinske Katz&lt;/a&gt;, &lt;a href=&#34;https://github.com/snorwin&#34;&gt;Norwin Schnyder&lt;/a&gt;, &lt;a href=&#34;https://github.com/zhaohuabing&#34;&gt;Huabing (Robin) Zhao&lt;/a&gt;, &lt;a href=&#34;https://github.com/LiangLliu&#34;&gt;LiangLliu&lt;/a&gt;,&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://gateway-api.sigs.k8s.io/geps/gep-1767/&#34;&gt;GEP-1767&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Cross-origin resource sharing (CORS) is an HTTP-header based security mechanism that allows (or denies) a web page to access resources from a server on an origin different from the domain that served the web page. See our &lt;a href=&#34;https://gateway-api.sigs.k8s.io/guides/http-cors/&#34;&gt;documentation page&lt;/a&gt; for more information.
The &lt;a href=&#34;https://gateway-api.sigs.k8s.io/api-types/httproute/&#34;&gt;HTTPRoute resource&lt;/a&gt; can be used to configure Cross-Origin Resource Sharing (CORS). The following HTTPRoute allows requests from &lt;a href=&#34;https://app.example&#34;&gt;https://app.example&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;gateway.networking.k8s.io/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;HTTPRoute&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;cors&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;parentRefs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;same-namespace&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;rules&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;matches&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;PathPrefix&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;/cors-behavior-creds-false&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;backendRefs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;infra-backend-v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;port&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;8080&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;filters&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;cors&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;allowOrigins&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;https://app.example&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;CORS&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Instead of specifying a list of specific origins, you can also specify a single wildcard (&amp;quot;*&amp;quot;), which will allow any origin. It is also allowed to use semi-specified origins in the list, where the wildcard appears after the scheme and at the beginning of the hostname, e.g. https://*.bar.com:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;gateway.networking.k8s.io/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;HTTPRoute&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;cors&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;parentRefs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;same-namespace&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;rules&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;matches&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;PathPrefix&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;/cors-behavior-creds-false&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;backendRefs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;infra-backend-v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;port&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;8080&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;filters&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;cors&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;allowOrigins&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;https://www.baz.com&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;https://*.bar.com&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;https://*.foo.com&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;CORS&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;HTTPRoute filters allow for the configuration of CORS settings. See a list of supported options below:&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;&lt;code&gt;allowCredentials&lt;/code&gt;&lt;/dt&gt;
&lt;dd&gt;Specifies whether the browser is allowed to include credentials (such as cookies and HTTP authentication) in the CORS request.&lt;/dd&gt;
&lt;dt&gt;&lt;code&gt;allowMethods&lt;/code&gt;&lt;/dt&gt;
&lt;dd&gt;The HTTP methods that are allowed for CORS requests.&lt;/dd&gt;
&lt;dt&gt;&lt;code&gt;allowHeaders&lt;/code&gt;&lt;/dt&gt;
&lt;dd&gt;The HTTP headers that are allowed for CORS requests.&lt;/dd&gt;
&lt;dt&gt;&lt;code&gt;exposeHeaders&lt;/code&gt;&lt;/dt&gt;
&lt;dd&gt;The HTTP headers that are exposed to the client.&lt;/dd&gt;
&lt;dt&gt;&lt;code&gt;maxAge&lt;/code&gt;&lt;/dt&gt;
&lt;dd&gt;The maximum time in seconds that the browser should cache the preflight response.&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;A comprehensive example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;gateway.networking.k8s.io/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;HTTPRoute&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;cors-allow-credentials&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;parentRefs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;same-namespace&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;rules&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;matches&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;PathPrefix&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;/cors-behavior-creds-true&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;backendRefs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;infra-backend-v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;port&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;8080&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;filters&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;cors&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;allowOrigins&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;- &lt;span class=&#34;s2&#34;&gt;&amp;#34;https://www.foo.example.com&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;- &lt;span class=&#34;s2&#34;&gt;&amp;#34;https://*.bar.example.com&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;allowMethods&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;GET&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;OPTIONS&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;allowHeaders&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;- &lt;span class=&#34;s2&#34;&gt;&amp;#34;*&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;exposeHeaders&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;- &lt;span class=&#34;s2&#34;&gt;&amp;#34;x-header-3&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;- &lt;span class=&#34;s2&#34;&gt;&amp;#34;x-header-4&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;allowCredentials&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;maxAge&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;3600&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;CORS&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;gateway-client-certificate-validation&#34;&gt;Gateway client certificate validation&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#gateway-client-certificate-validation&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Leads: &lt;a href=&#34;https://github.com/arkodg&#34;&gt;Arko Dasgupta&lt;/a&gt;, &lt;a href=&#34;https://github.com/kl52752&#34;&gt;Katarzyna Łach&lt;/a&gt;, &lt;a href=&#34;https://github.com/snorwin&#34;&gt;Norwin Schnyder&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://gateway-api.sigs.k8s.io/geps/gep-91/&#34;&gt;GEP-91&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Client certificate validation, also known as mutual TLS (mTLS), is a security mechanism where the client provides a certificate to the server to prove its identity. This is in contrast to standard TLS, where only the server presents a certificate to the client.
In the context of the Gateway API, frontend mTLS means that the Gateway validates the client&#39;s certificate before allowing the connection to proceed to a backend service. This validation is done by checking the client certificate against a set of trusted Certificate Authorities (CAs) configured on the Gateway. The API was shaped this way to address a critical security vulnerability related to connection reuse and still provide some level of flexibility.&lt;/p&gt;
&lt;h4 id=&#34;configuration-overview&#34;&gt;Configuration overview&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#configuration-overview&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;Client validation is defined using the frontendValidation struct, which specifies how the Gateway should verify the client&#39;s identity.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;caCertificateRefs&lt;/strong&gt;: A list of references to Kubernetes objects (typically ConfigMap&#39;s) containing PEM-encoded CA certificate bundles used as trust anchors to validate the client&#39;s certificate.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;mode&lt;/strong&gt;: Defines the validation behavior.
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;AllowValidOnly&lt;/strong&gt; (Default): The Gateway accepts connections only if the client presents a valid certificate that passes validation against the specified CA bundle.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AllowInsecureFallback&lt;/strong&gt;: The Gateway accepts connections even if the client certificate is missing or fails verification. This mode typically delegates authorization to the backend and should be used with caution.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Validation can be applied globally to the Gateway or overridden for specific ports:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Default Configuration&lt;/strong&gt;: This configuration applies to all HTTPS listeners on the Gateway, unless a per-port override is defined.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Per-Port Configuration&lt;/strong&gt;: This allows for fine-grained control, overriding the default configuration for all listeners handling traffic on a specific port.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;gateway.networking.k8s.io/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Gateway&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;client-validation-basic&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;gatewayClassName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;acme-lb&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;tls&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;frontend&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;default&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;validation&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;caCertificateRefs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ConfigMap&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;group&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;foo-example-com-ca-cert&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;perPort&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;port&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;8443&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;tls&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;validation&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;caCertificateRefs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ConfigMap&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;              &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;group&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;              &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;foo-example-com-ca-cert&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;mode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;AllowInsecureFallback&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;listeners&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;foo-https&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;protocol&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;HTTPS&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;port&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;443&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;hostname&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;foo.example.com&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;tls&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;certificateRefs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Secret&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;group&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;foo-example-com-cert&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;bar-https&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;protocol&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;HTTPS&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;port&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;8443&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;hostname&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;bar.example.com&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;tls&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;certificateRefs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Secret&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;group&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;bar-example-com-cert&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;certificate-selection-for-gateway-tls-origination&#34;&gt;Certificate selection for Gateway TLS origination&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#certificate-selection-for-gateway-tls-origination&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Leads: &lt;a href=&#34;https://github.com/mkosieradzki&#34;&gt;Marcin Kosieradzki&lt;/a&gt;, &lt;a href=&#34;https://github.com/robscott&#34;&gt;Rob Scott&lt;/a&gt;, &lt;a href=&#34;https://github.com/snorwin&#34;&gt;Norwin Schnyder&lt;/a&gt;, &lt;a href=&#34;https://github.com/LiorLieberman&#34;&gt;Lior Lieberman&lt;/a&gt;, &lt;a href=&#34;https://github.com/kl52752&#34;&gt;Katarzyna Lach&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://gateway-api.sigs.k8s.io/geps/gep-3155/&#34;&gt;GEP-3155&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Mutual TLS (mTLS) for upstream connections requires the Gateway to present a client certificate to the backend, in addition to verifying the backend&#39;s certificate. This ensures that the backend only accepts connections from authorized Gateways.&lt;/p&gt;
&lt;h4 id=&#34;gateway-s-client-certificate-configuration&#34;&gt;Gateway’s client certificate configuration&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#gateway-s-client-certificate-configuration&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;To configure the client certificate that the Gateway uses when connecting to backends,
use the &lt;strong&gt;tls.backend.clientCertificateRef&lt;/strong&gt; field in the Gateway resource.
This configuration applies to the Gateway as a client for &lt;strong&gt;all&lt;/strong&gt; upstream connections managed by that Gateway.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;gateway.networking.k8s.io/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Gateway&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;backend-tls&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;gatewayClassName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;acme-lb&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;tls&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;backend&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;clientCertificateRef&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Secret&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;group&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# empty string means core API group&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;foo-example-cert&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;listeners&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;foo-http&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;protocol&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;HTTP&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;port&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;80&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;hostname&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;foo.example.com&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;referencegrant-promoted-to-v1&#34;&gt;ReferenceGrant promoted to v1&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#referencegrant-promoted-to-v1&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The ReferenceGrant resource has not changed in more than a year, and we do not expect it to change further, so its version has been bumped to v1, and it is now officially in the Standard channel, and abides by the GA API contract (that is, no breaking changes).&lt;/p&gt;
&lt;h2 id=&#34;try-it-out&#34;&gt;Try it out&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#try-it-out&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Unlike other Kubernetes APIs, you don&#39;t need to upgrade to the latest version of
Kubernetes to get the latest version of Gateway API. As long as you&#39;re running
Kubernetes 1.30 or later, you&#39;ll be able to get up and running with this version
of Gateway API.&lt;/p&gt;
&lt;p&gt;To try out the API, follow the &lt;a href=&#34;https://gateway-api.sigs.k8s.io/guides/&#34;&gt;Getting Started Guide&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;As of this writing, seven implementations are already fully conformant with Gateway API v1.5. In alphabetical order:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/agentgateway/agentgateway/releases/tag/v1.0.0&#34;&gt;Agentgateway&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/airlock/microgateway/releases/tag/5.0.0&#34;&gt;Airlock Microgateway&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.cloud.google.com/kubernetes-engine/docs/concepts/gateway-api&#34;&gt;GKE Gateway&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/jcmoraisjr/haproxy-ingress/releases/tag/v0.17.0-alpha.1&#34;&gt;HAProxy Ingress&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kgateway-dev/kgateway/releases/tag/v2.3.0-beta.3&#34;&gt;kgateway&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/nginx/nginx-gateway-fabric/releases/tag/v2.5.0&#34;&gt;NGINX Gateway Fabric&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/traefik/traefik/releases/tag/v3.7.0-rc.1&#34;&gt;Traefik Proxy&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;get-involved&#34;&gt;Get involved&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#get-involved&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Wondering when a feature will be added?  There are lots of opportunities to get
involved and help define the future of Kubernetes routing APIs for both ingress
and service mesh.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Check out the &lt;a href=&#34;https://gateway-api.sigs.k8s.io/guides&#34;&gt;user guides&lt;/a&gt; to see what use-cases can be addressed.&lt;/li&gt;
&lt;li&gt;Try out one of the &lt;a href=&#34;https://gateway-api.sigs.k8s.io/implementations/&#34;&gt;existing Gateway controllers&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Or &lt;a href=&#34;https://gateway-api.sigs.k8s.io/contributing/&#34;&gt;join us in the community&lt;/a&gt; and help us build the future of Gateway API together!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The maintainers would like to thank &lt;strong&gt;everyone&lt;/strong&gt; who&#39;s contributed to Gateway
API, whether in the form of commits to the repo, discussion, ideas, or general
support. We could never have made this kind of progress without the support of
this dedicated and active community.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This article was edited in April 2026 to correct the release date for Gateway API 1.5.0.&lt;/em&gt;&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes v1.36 Sneak Peek</title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/03/30/kubernetes-v1-36-sneak-peek/</link>
      <pubDate>Mon, 30 Mar 2026 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/03/30/kubernetes-v1-36-sneak-peek/</guid>
      <description>
        
        
        &lt;p&gt;Kubernetes v1.36 is coming at the end of April 2026. This release will include removals and deprecations, and it is packed with an impressive number of
enhancements. Here are some of the features we are most excited about in this cycle!&lt;/p&gt;
&lt;p&gt;Please note that this information reflects the current state of v1.36 development and may change before release.&lt;/p&gt;
&lt;h2 id=&#34;the-kubernetes-api-removal-and-deprecation-process&#34;&gt;The Kubernetes API removal and deprecation process&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#the-kubernetes-api-removal-and-deprecation-process&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The Kubernetes project has a well-documented &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/reference/using-api/deprecation-policy/&#34;&gt;deprecation policy&lt;/a&gt; for features. This policy states that stable APIs
may only be deprecated when a newer, stable version of that same API is available and that APIs have a minimum lifetime for each stability level. A deprecated API
has been marked for removal in a future Kubernetes release. It will continue to function until removal (at least one year from the deprecation), but usage will
result in a warning being displayed. Removed APIs are no longer available in the current version, at which point you must migrate to using the replacement.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Generally available (GA) or stable API versions may be marked as deprecated but must not be removed within a major version of Kubernetes.&lt;/li&gt;
&lt;li&gt;Beta or pre-release API versions must be supported for 3 releases after the deprecation.&lt;/li&gt;
&lt;li&gt;Alpha or experimental API versions may be removed in any release without prior deprecation notice; this process can become a withdrawal in cases where a different implementation for the same feature is already in place.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Whether an API is removed as a result of a feature graduating from beta to stable, or because that API simply did not succeed, all removals comply with this
deprecation policy. Whenever an API is removed, migration options are communicated in the &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/reference/using-api/deprecation-guide/&#34;&gt;deprecation guide&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;A recent example of this principle in action is the retirement of the ingress-nginx project, announced
by SIG-Security on March 24, 2026. As stewardship shifts away from the project, the community has been
encouraged to evaluate alternative ingress controllers that align with current security and maintenance
best practices. This transition reflects the same lifecycle discipline that underpins Kubernetes itself,
ensuring continued evolution without abrupt disruption.&lt;/p&gt;
&lt;h2 id=&#34;ingress-nginx-retirement&#34;&gt;Ingress NGINX retirement&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#ingress-nginx-retirement&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;To prioritize the safety and security of the ecosystem, Kubernetes SIG Network and the Security Response Committee have retired Ingress NGINX on March 24, 2026.
Since that date, there have been no further releases, no bugfixes, and no updates to resolve any security vulnerabilities discovered. Existing deployments of
Ingress NGINX will continue to function, and installation artifacts like Helm charts and container images will remain available.&lt;/p&gt;
&lt;p&gt;For full details, see the &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2025/11/11/ingress-nginx-retirement/&#34;&gt;official retirement announcement&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;deprecations-and-removals-for-kubernetes-v1-36&#34;&gt;Deprecations and removals for Kubernetes v1.36&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#deprecations-and-removals-for-kubernetes-v1-36&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;h3 id=&#34;deprecation-of-spec-externalips-in-service&#34;&gt;Deprecation of &lt;code&gt;.spec.externalIPs&lt;/code&gt; in Service&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#deprecation-of-spec-externalips-in-service&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The &lt;code&gt;externalIPs&lt;/code&gt; field in Service &lt;code&gt;spec&lt;/code&gt; is being deprecated, which means you’ll soon lose a quick way to route arbitrary externalIPs to your Services. This
field has been a known security headache for years, enabling man-in-the-middle attacks on your cluster traffic, as documented in &lt;a href=&#34;https://github.com/kubernetes/kubernetes/issues/970760&#34;&gt;CVE-2020-8554&lt;/a&gt;. From Kubernetes v1.36 and onwards, you will see deprecation warnings when using it, with full removal
planned for v1.43.&lt;/p&gt;
&lt;p&gt;If your Services still lean on &lt;code&gt;externalIPs&lt;/code&gt;, consider using LoadBalancer services for cloud-managed ingress, NodePort for simple port exposure, or Gateway API
for a more flexible and secure way to handle external traffic.&lt;/p&gt;
&lt;p&gt;For more details on this enhancement, refer to &lt;a href=&#34;https://kep.k8s.io/5707&#34;&gt;KEP-5707: Deprecate service.spec.externalIPs&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;removal-of-gitrepo-volume-driver&#34;&gt;Removal of &lt;code&gt;gitRepo&lt;/code&gt; volume driver&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#removal-of-gitrepo-volume-driver&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The gitRepo volume type has been deprecated since v1.11. Starting Kubernetes v1.36, the &lt;code&gt;gitRepo&lt;/code&gt; volume plugin is permanently disabled and cannot be turned back
on. This change protects clusters from a critical security issue where using &lt;code&gt;gitRepo&lt;/code&gt; could let an attacker run code as root on the node.&lt;/p&gt;
&lt;p&gt;Although &lt;code&gt;gitRepo&lt;/code&gt; has been deprecated for years and better alternatives have been recommended, it was still technically possible to use it in previous releases.
From v1.36 onward, that path is closed for good, so any existing workloads depending on &lt;code&gt;gitRepo&lt;/code&gt; will need to migrate to supported approaches such as init
containers or external git-sync style tools.&lt;/p&gt;
&lt;p&gt;For more details on this enhancement, refer to &lt;a href=&#34;https://kep.k8s.io/5040&#34;&gt;KEP-5040: Remove gitRepo volume driver&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;featured-enhancements-of-kubernetes-v1-36&#34;&gt;Featured enhancements of Kubernetes v1.36&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#featured-enhancements-of-kubernetes-v1-36&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The following list of enhancements is likely to be included in the upcoming v1.36 release. This is not a commitment and the release content is subject to change.&lt;/p&gt;
&lt;h3 id=&#34;volume-selinux-labelling&#34;&gt;Faster SELinux labelling for volumes (GA)&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#volume-selinux-labelling&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Kubernetes v1.36 makes the SELinux volume mounting improvement generally available. This change replaced recursive file relabeling with &lt;code&gt;mount -o context=XYZ&lt;/code&gt; option, applying the correct SELinux label to the entire volume at mount time. It brings more consistent performance and reduces Pod startup delays on SELinux-enforcing systems.&lt;/p&gt;
&lt;p&gt;This feature was introduced as beta in v1.28 for &lt;code&gt;ReadWriteOncePod&lt;/code&gt; volumes. In v1.32, it gained metrics and an opt-out option
(&lt;code&gt;securityContext.seLinuxChangePolicy: Recursive&lt;/code&gt;) to help catch conflicts. Now in v1.36, it reaches stable and defaults to all volumes, with Pods or
CSIDrivers opting in via &lt;code&gt;spec.SELinuxMount&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;However, we expect this feature to create the risk of breaking changes in the future Kubernetes releases, due to the potential for mixing of privileged and unprivileged pods.
Setting the &lt;code&gt;seLinuxChangePolicy&lt;/code&gt; field and
SELinux volume labels on Pods, correctly, is the responsibility of the Pod author
Developers have that responsibility whether they are writing a Deployment, StatefulSet, DaemonSet or even a custom resource that includes a Pod template.
Being careless
with these settings can lead to a range of problems when Pods share volumes.&lt;/p&gt;
&lt;p&gt;For more details on this enhancement, refer to  &lt;a href=&#34;https://kep.k8s.io/1710&#34;&gt;KEP-1710: Speed up recursive SELinux label change&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;external-signing-of-serviceaccount-tokens&#34;&gt;External signing of ServiceAccount tokens&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#external-signing-of-serviceaccount-tokens&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;As a beta feature, Kubernetes already supports external signing of ServiceAccount tokens. This allows clusters to integrate with external key management systems
or signing services instead of relying only on internally managed keys.&lt;/p&gt;
&lt;p&gt;With this enhancement, the &lt;code&gt;kube-apiserver&lt;/code&gt; can delegate token signing to external systems such as cloud key management services or hardware security modules. This
improves security and simplifies key management services for clusters that rely on centralized signing infrastructure.
We expect that this will graduate to stable (GA) in Kubernetes v1.36.&lt;/p&gt;
&lt;p&gt;For more details on this enhancement, refer to &lt;a href=&#34;https://kep.k8s.io/740&#34;&gt;KEP-740: Support external signing of service account tokens&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;dra-driver-support-for-device-taints-and-tolerations&#34;&gt;DRA Driver support for Device taints and tolerations&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#dra-driver-support-for-device-taints-and-tolerations&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Kubernetes v1.33 introduced support for taints and tolerations for physical devices managed through &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/scheduling-eviction/dynamic-resource-allocation/&#34;&gt;Dynamic Resource Allocation (DRA)&lt;/a&gt;. Normally, any device can be
used for scheduling. However, this enhancement allows DRA drivers to mark devices as tainted, which ensures that they will not be used for scheduling purposes.
Alternatively, cluster administrators can create a &lt;code&gt;DeviceTaintRule&lt;/code&gt; to mark devices that match a certain selection criteria(such as all devices of a certain
driver) as tainted. This improves scheduling control and helps ensure that specialized hardware resources are only used by workloads that explicitly request them.&lt;/p&gt;
&lt;p&gt;In Kubernetes v1.36, this feature graduates to beta with more comprehensive testing complete, making it accessible by default without the need for a feature
flag and open to user feedback.&lt;/p&gt;
&lt;p&gt;To learn about taints and tolerations, see &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/scheduling-eviction/taint-and-toleration/&#34;&gt;taints and tolerations&lt;/a&gt;.&lt;br&gt;
For more details on this enhancement, refer to &lt;a href=&#34;https://kep.k8s.io/5055&#34;&gt;KEP-5055: DRA: device taints and tolerations&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;dra-support-for-partitionable-devices&#34;&gt;DRA support for partitionable devices&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#dra-support-for-partitionable-devices&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Kubernetes v1.36 expands Dynamic Resource Allocation (DRA) by introducing support for partitionable devices, allowing a single hardware accelerator to be split
into multiple logical units that can be shared across workloads.  This is especially useful for high-cost resources like GPUs, where dedicating an entire device
to a single workload can lead to underutilization.&lt;/p&gt;
&lt;p&gt;With this enhancement, platform teams can improve overall cluster efficiency by allocating only the required portion of a device to each workload, rather than
reserving it entirely. This makes it easier to run multiple workloads on the same hardware while maintaining isolation and control, helping organizations get more
value out of their infrastructure.&lt;/p&gt;
&lt;p&gt;To learn more about this enhancement, refer to &lt;a href=&#34;https://kep.k8s.io/4815&#34;&gt;KEP-4815: DRA Partitionable Devices&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;want-to-know-more&#34;&gt;Want to know more?&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#want-to-know-more&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;New features and deprecations are also announced in the Kubernetes release notes. We will formally announce what&#39;s new in &lt;a href=&#34;https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.36.md&#34;&gt;Kubernetes v1.36&lt;/a&gt; as part of the CHANGELOG for that release.&lt;/p&gt;
&lt;p&gt;Kubernetes v1.36 release is planned for Wednesday, April 22, 2026. Stay tuned for updates!&lt;/p&gt;
&lt;p&gt;You can also see the announcements of changes in the release notes for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.35.md&#34;&gt;Kubernetes v1.35&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.34.md&#34;&gt;Kubernetes v1.34&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.33.md&#34;&gt;Kubernetes v1.33&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.32.md&#34;&gt;Kubernetes v1.32&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.31.md&#34;&gt;Kubernetes v1.31&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.30.md&#34;&gt;Kubernetes v1.30&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;get-involved&#34;&gt;Get involved&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#get-involved&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The simplest way to get involved with Kubernetes is by joining one of the many &lt;a href=&#34;https://github.com/kubernetes/community/blob/master/siglist.md&#34;&gt;Special Interest Groups&lt;/a&gt; (SIGs) that align with your interests. Have something you’d like to broadcast to the Kubernetes community? Share your voice at our weekly
&lt;a href=&#34;https://github.com/kubernetes/community/tree/master/communication&#34;&gt;community meeting&lt;/a&gt;, and through the channels below. Thank you for your continued feedback and support.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Follow us on Bluesky &lt;a href=&#34;https://bsky.app/profile/kubernetes.io&#34;&gt;@kubernetes.io&lt;/a&gt; for the latest updates&lt;/li&gt;
&lt;li&gt;Join the community discussion on &lt;a href=&#34;https://discuss.kubernetes.io/&#34;&gt;Discuss&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Join the community on &lt;a href=&#34;http://slack.k8s.io/&#34;&gt;Slack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Post questions (or answer questions) on &lt;a href=&#34;https://serverfault.com/questions/tagged/kubernetes&#34;&gt;Server Fault&lt;/a&gt; or &lt;a href=&#34;http://stackoverflow.com/questions/tagged/kubernetes&#34;&gt;Stack Overflow&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Share your Kubernetes &lt;a href=&#34;https://docs.google.com/a/linuxfoundation.org/forms/d/e/1FAIpQLScuI7Ye3VQHQTwBASrgkjQDSS5TP0g3AXfFhwSM9YpHgxRKFA/viewform&#34;&gt;story&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Read more about what’s happening with Kubernetes on the &lt;a href=&#34;https://kubernetes.io/blog/&#34;&gt;blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Learn more about the &lt;a href=&#34;https://github.com/kubernetes/sig-release/tree/master/release-team&#34;&gt;Kubernetes Release Team&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Announcing Ingress2Gateway 1.0: Your Path to Gateway API</title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/03/20/ingress2gateway-1-0-release/</link>
      <pubDate>Fri, 20 Mar 2026 11:00:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/03/20/ingress2gateway-1-0-release/</guid>
      <description>
        
        
        &lt;p&gt;With the Ingress-NGINX &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2025/11/11/ingress-nginx-retirement/&#34;&gt;retirement&lt;/a&gt; scheduled for March 2026, the Kubernetes networking landscape is at a turning point.
For most organizations, the question isn&#39;t whether to migrate to &lt;a href=&#34;https://gateway-api.sigs.k8s.io/&#34;&gt;Gateway API&lt;/a&gt;, but how to do so safely.&lt;/p&gt;
&lt;p&gt;Migrating from Ingress to Gateway API is a fundamental shift in API design.
Gateway API provides a modular, extensible API with strong support for Kubernetes-native RBAC.
Conversely, the Ingress API is simple, and implementations such as Ingress-NGINX extend the API through esoteric annotations, ConfigMaps, and CRDs.
Migrating away from Ingress controllers such as Ingress-NGINX presents the daunting task of capturing all the nuances of the Ingress controller,
and mapping that behavior to Gateway API.&lt;/p&gt;
&lt;p&gt;Ingress2Gateway is an assistant that helps teams confidently move from Ingress to Gateway API.
It translates Ingress resources/manifests along with implementation-specific annotations to Gateway API while warning you about untranslatable configuration and offering suggestions.&lt;/p&gt;
&lt;p&gt;Today, SIG Network is proud to announce the &lt;strong&gt;1.0 release of Ingress2Gateway&lt;/strong&gt;.
This milestone represents a stable, tested migration assistant for teams ready to modernize their networking stack.&lt;/p&gt;
&lt;h2 id=&#34;ingress2gateway-1-0&#34;&gt;Ingress2Gateway 1.0&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#ingress2gateway-1-0&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;h3 id=&#34;ingress-nginx-annotation-support&#34;&gt;Ingress-NGINX annotation support&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#ingress-nginx-annotation-support&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The main improvement for the 1.0 release is more comprehensive Ingress-NGINX support.
Before the 1.0 release, Ingress2Gateway only supported three Ingress-NGINX annotations.
For the 1.0 release, Ingress2Gateway supports over 30 common annotations (CORS, backend TLS, regex matching, path rewrite, etc.).&lt;/p&gt;
&lt;h3 id=&#34;comprehensive-integration-testing&#34;&gt;Comprehensive integration testing&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#comprehensive-integration-testing&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Each supported Ingress-NGINX annotation, and representative combinations of common annotations, is backed by controller-level integration tests that verify the behavioral equivalence of the Ingress-NGINX configuration and the generated Gateway API.
These tests exercise real controllers in live clusters and compare runtime behavior (routing, redirects, rewrites, etc.), not just YAML structure.&lt;/p&gt;
&lt;p&gt;The tests:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;spin up an Ingress-NGINX controller&lt;/li&gt;
&lt;li&gt;spin up multiple Gateway API controllers&lt;/li&gt;
&lt;li&gt;apply Ingress resources that have implementation-specific configuration&lt;/li&gt;
&lt;li&gt;translate Ingress resources to Gateway API with &lt;code&gt;ingress2gateway&lt;/code&gt; and apply generated manifests&lt;/li&gt;
&lt;li&gt;verify that the Gateway API controllers and the Ingress controller exhibit equivalent behavior.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A comprehensive test suite not only catches bugs in development, but also ensures the correctness of the translation, especially given &lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/02/27/ingress-nginx-before-you-migrate&#34;&gt;surprising edge cases and unexpected defaults&lt;/a&gt;,
so that you don&#39;t find out about them in production.&lt;/p&gt;
&lt;h3 id=&#34;notification-error-handling&#34;&gt;Notification &amp;amp; error handling&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#notification-error-handling&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Migration is not a &amp;quot;one-click&amp;quot; affair.
Surfacing subtleties and untranslatable behavior is as important as translating supported configuration.
The 1.0 release cleans up the formatting and content of notifications, so it is clear what is missing and how you can fix it.&lt;/p&gt;
&lt;h2 id=&#34;using-ingress2gateway&#34;&gt;Using Ingress2Gateway&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#using-ingress2gateway&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Ingress2Gateway is a migration assistant, not a one-shot replacement.
Its goal is to&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;migrate supported Ingress configuration and behavior&lt;/li&gt;
&lt;li&gt;identify unsupported configuration and suggest alternatives&lt;/li&gt;
&lt;li&gt;reevaluate and potentially discard undesirable configuration&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The rest of the section shows you how to safely migrate the following Ingress-NGINX configuration&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;networking.k8s.io/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Ingress&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;nginx.ingress.kubernetes.io/proxy-body-size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;1G&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;nginx.ingress.kubernetes.io/use-regex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;true&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;nginx.ingress.kubernetes.io/proxy-send-timeout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;1&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;nginx.ingress.kubernetes.io/proxy-read-timeout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;1&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;nginx.ingress.kubernetes.io/enable-cors&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;true&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;nginx.ingress.kubernetes.io/configuration-snippet&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sd&#34;&gt;      more_set_headers &amp;#34;Request-Id: $req_id&amp;#34;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;my-ingress&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;namespace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;my-ns&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ingressClassName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;nginx&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;rules&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;host&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;my-host.example.com&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;http&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;paths&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;backend&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;              &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;service&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;website-service&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;port&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;                  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;number&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;80&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;/users/(\d+)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;pathType&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ImplementationSpecific&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;tls&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;hosts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;my-host.example.com&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;secretName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;my-secret&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;1-install-ingress2gateway&#34;&gt;1. Install Ingress2Gateway&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#1-install-ingress2gateway&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;If you have a Go environment set up, you can install Ingress2Gateway with&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;go install github.com/kubernetes-sigs/ingress2gateway@v1.0.0
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Otherwise,&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;brew install ingress2gateway
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You can also download the binary from &lt;a href=&#34;https://github.com/kubernetes-sigs/ingress2gateway/releases/tag/v1.0.0&#34;&gt;GitHub&lt;/a&gt; or &lt;a href=&#34;https://github.com/kubernetes-sigs/ingress2gateway/&#34;&gt;build from source&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;2-run-ingress2gateway&#34;&gt;2. Run Ingress2Gateway&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#2-run-ingress2gateway&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;You can pass Ingress2Gateway Ingress manifests, or have the tool read directly from your cluster.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Pass it files&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ingress2gateway print --input-file my-manifest.yaml,my-other-manifest.yaml --providers&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;ingress-nginx &amp;gt; gwapi.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Use a namespace in your cluster&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ingress2gateway print --namespace my-api --providers&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;ingress-nginx &amp;gt; gwapi.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Or your whole cluster&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ingress2gateway print --providers&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;ingress-nginx --all-namespaces &amp;gt; gwapi.yaml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&#34;alert alert-info&#34; role=&#34;note&#34;&gt;&lt;h4 class=&#34;alert-heading&#34;&gt;Note:&lt;/h4&gt;You can also pass &lt;code&gt;--emitter &amp;lt;agentgateway|envoy-gateway|kgateway&amp;gt;&lt;/code&gt; to output implementation-specific extensions.&lt;/div&gt;

&lt;h3 id=&#34;3-review-the-output&#34;&gt;3. Review the output&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#3-review-the-output&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;This is the most critical step.
The commands from the previous section output a Gateway API manifest to &lt;code&gt;gwapi.yaml&lt;/code&gt;, and they also emit warnings that explain what did not translate exactly and what to review manually.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;gateway.networking.k8s.io/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Gateway&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;gateway.networking.k8s.io/generator&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ingress2gateway-dev&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;nginx&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;namespace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;my-ns&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;gatewayClassName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;nginx&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;listeners&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;hostname&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;my-host.example.com&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;my-host-example-com-http&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;port&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;80&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;protocol&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;HTTP&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;hostname&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;my-host.example.com&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;my-host-example-com-https&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;port&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;443&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;protocol&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;HTTPS&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;tls&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;certificateRefs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;group&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Secret&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;my-secret&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;gateway.networking.k8s.io/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;HTTPRoute&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;gateway.networking.k8s.io/generator&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ingress2gateway-dev&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;my-ingress-my-host-example-com&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;namespace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;my-ns&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;hostnames&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;my-host.example.com&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;parentRefs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;nginx&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;port&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;443&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;rules&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;backendRefs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;website-service&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;port&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;80&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;filters&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;cors&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;allowCredentials&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;allowHeaders&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;DNT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;Keep-Alive&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;User-Agent&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;X-Requested-With&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;If-Modified-Since&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;Cache-Control&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;Content-Type&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;Range&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;Authorization&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;allowMethods&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;GET&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;PUT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;POST&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;DELETE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;PATCH&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;OPTIONS&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;allowOrigins&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;- &lt;span class=&#34;s1&#34;&gt;&amp;#39;*&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;maxAge&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1728000&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;CORS&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;matches&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;RegularExpression&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;(?i)/users/(\d+).*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;rule-0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;timeouts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;request&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;10s&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;gateway.networking.k8s.io/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;HTTPRoute&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;gateway.networking.k8s.io/generator&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ingress2gateway-dev&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;my-ingress-my-host-example-com-ssl-redirect&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;namespace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;my-ns&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;hostnames&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;my-host.example.com&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;parentRefs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;nginx&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;port&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;80&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;rules&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;filters&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;requestRedirect&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;scheme&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;https&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;statusCode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;308&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;RequestRedirect&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Ingress2Gateway successfully translated some annotations into their Gateway API equivalents.
For example, the &lt;code&gt;nginx.ingress.kubernetes.io/enable-cors&lt;/code&gt; annotation was translated into a CORS filter.
But upon closer inspection, the &lt;code&gt;nginx.ingress.kubernetes.io/proxy-{read,send}-timeout&lt;/code&gt; and &lt;code&gt;nginx.ingress.kubernetes.io/proxy-body-size&lt;/code&gt; annotations do not map perfectly.
The logs show the reason for these omissions as well as reasoning behind the translation.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;┌─ WARN  ────────────────────────────────────────
│  Unsupported annotation nginx.ingress.kubernetes.io/configuration-snippet
│  source: INGRESS-NGINX
│  object: Ingress: my-ns/my-ingress
└─
┌─ INFO  ────────────────────────────────────────
│  Using case-insensitive regex path matches. You may want to change this.
│  source: INGRESS-NGINX
│  object: HTTPRoute: my-ns/my-ingress-my-host-example-com
└─
┌─ WARN  ────────────────────────────────────────
│  ingress-nginx only supports TCP-level timeouts; i2gw has made a best-effort translation to Gateway API timeouts.request. Please verify that this meets your needs. See documentation: https://gateway-api.sigs.k8s.io/guides/http-timeouts/
│  source: INGRESS-NGINX
│  object: HTTPRoute: my-ns/my-ingress-my-host-example-com
└─
┌─ WARN  ────────────────────────────────────────
│  Failed to apply my-ns.my-ingress.metadata.annotations.&amp;#34;nginx.ingress.kubernetes.io/proxy-body-size&amp;#34; from my-ns/my-ingress: Most Gateway API implementations have reasonable body size and buffering defaults
│  source: STANDARD_EMITTER
│  object: HTTPRoute: my-ns/my-ingress-my-host-example-com
└─
┌─ WARN  ────────────────────────────────────────
│  Gateway API does not support configuring URL normalization (RFC 3986, Section 6). Please check if this matters for your use case and consult implementation-specific details.
│  source: STANDARD_EMITTER
└─
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;There is a warning that Ingress2Gateway does not support the &lt;code&gt;nginx.ingress.kubernetes.io/configuration-snippet&lt;/code&gt; annotation.
You will have to check your Gateway API implementation documentation to see if there is a way to achieve equivalent behavior.&lt;/p&gt;
&lt;p&gt;The tool also notified us that Ingress-NGINX regex matches are case-insensitive prefix matches, which is why there is a match pattern of &lt;code&gt;(?i)/users/(\d+).*&lt;/code&gt;.
Most organizations will want to change this behavior to be an exact case-sensitive match by removing the leading &lt;code&gt;(?i)&lt;/code&gt; and the trailing &lt;code&gt;.*&lt;/code&gt; from the path pattern.&lt;/p&gt;
&lt;p&gt;Ingress2Gateway made a best-effort translation from the &lt;code&gt;nginx.ingress.kubernetes.io/proxy-{send,read}-timeout&lt;/code&gt; annotations to a 10 second &lt;a href=&#34;https://gateway-api.sigs.k8s.io/guides/http-timeouts/&#34;&gt;request timeout&lt;/a&gt; in our HTTP route.
If requests for this service should be much shorter, say 3 seconds, you can make the corresponding changes to your Gateway API manifests.&lt;/p&gt;
&lt;p&gt;Also, &lt;code&gt;nginx.ingress.kubernetes.io/proxy-body-size&lt;/code&gt; does not have a Gateway API equivalent, and was thus not translated.
However, most Gateway API implementations have reasonable defaults for maximum body size and buffering, so this might not be a problem in practice.
Further, some emitters might offer support for this annotation through implementation-specific extensions.
For example, adding the &lt;code&gt;--emitter agentgateway&lt;/code&gt;, &lt;code&gt;--emitter envoy-gateway&lt;/code&gt;, or &lt;code&gt;--emitter kgateway&lt;/code&gt; flag to the previous &lt;code&gt;ingress2gateway print&lt;/code&gt; command would have resulted in additional implementation-specific configuration in the generated Gateway API manifests that attempted to capture the body size configuration.&lt;/p&gt;
&lt;p&gt;We also see a warning about URL normalization.
Gateway API implementations such as Agentgateway, Envoy Gateway, Kgateway, and Istio have some level of URL normalization, but the behavior varies across implementations and is not configurable through standard Gateway API.
You should check and test the URL normalization behavior of your Gateway API implementation to ensure it is compatible with your use case.&lt;/p&gt;
&lt;p&gt;To match Ingress-NGINX default behavior, Ingress2Gateway also added a listener on port 80 and a &lt;a href=&#34;https://gateway-api.sigs.k8s.io/reference/spec/#httprequestredirectfilter&#34;&gt;HTTP Request redirect filter&lt;/a&gt; to redirect HTTP traffic to HTTPS.
You may not want to serve HTTP traffic at all and remove the listener on port 80 and the corresponding HTTPRoute.&lt;/p&gt;
&lt;div class=&#34;alert alert-caution&#34; role=&#34;note&#34;&gt;&lt;h4 class=&#34;alert-heading&#34;&gt;Caution:&lt;/h4&gt;Always thoroughly review the generated output and logs.&lt;/div&gt;

&lt;p&gt;After manually applying these changes, the Gateway API manifests might look as follows.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;gateway.networking.k8s.io/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Gateway&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;gateway.networking.k8s.io/generator&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ingress2gateway-dev&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;nginx&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;namespace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;my-ns&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;gatewayClassName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;nginx&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;listeners&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;hostname&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;my-host.example.com&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;my-host-example-com-https&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;port&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;443&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;protocol&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;HTTPS&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;tls&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;certificateRefs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;group&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Secret&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;my-secret&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;gateway.networking.k8s.io/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;HTTPRoute&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;gateway.networking.k8s.io/generator&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ingress2gateway-dev&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;my-ingress-my-host-example-com&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;namespace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;my-ns&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;hostnames&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;my-host.example.com&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;parentRefs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;nginx&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;port&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;443&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;rules&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;backendRefs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;website-service&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;port&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;80&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;filters&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;cors&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;allowCredentials&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;allowHeaders&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;DNT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;...&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;allowMethods&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;GET&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;...&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;allowOrigins&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;- &lt;span class=&#34;s1&#34;&gt;&amp;#39;*&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;maxAge&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1728000&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;CORS&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;matches&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;RegularExpression&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;/users/(\d+)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;rule-0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;timeouts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;request&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;3s&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;4-verify&#34;&gt;4. Verify&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#4-verify&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Now that you have Gateway API manifests, you should thoroughly test them in a development cluster.
In this case, you should at least double-check that your Gateway API implementation&#39;s maximum body size defaults are appropriate for you and verify that a three-second timeout is enough.&lt;/p&gt;
&lt;p&gt;After validating behavior in a development cluster, deploy your Gateway API configuration alongside your existing Ingress.
We strongly suggest that you then gradually shift traffic using weighted DNS, your cloud load balancer, or traffic-splitting features of your platform.
This way, you can quickly recover from any misconfiguration that made it through your tests.&lt;/p&gt;
&lt;p&gt;Finally, when you have shifted all your traffic to your Gateway API controller, delete your Ingress resources and uninstall your Ingress controller.&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#conclusion&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The Ingress2Gateway 1.0 release is just the beginning, and we hope that you use Ingress2Gateway to safely migrate to Gateway API.
As we approach the March 2026 Ingress-NGINX retirement, we invite the community to help us increase our configuration coverage, expand testing, and improve UX.&lt;/p&gt;
&lt;h2 id=&#34;resources-about-gateway-api&#34;&gt;Resources about Gateway API&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#resources-about-gateway-api&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The scope of Gateway API can be daunting.
Here are some resources to help you work with Gateway API:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://gateway-api.sigs.k8s.io/geps/gep-1713/?h=listenersets&#34;&gt;Listener sets&lt;/a&gt; allow application developers to manage gateway listeners.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes-sigs/gwctl&#34;&gt;&lt;code&gt;gwctl&lt;/code&gt;&lt;/a&gt; gives you a comprehensive view of your Gateway resources, such as attachments and linter errors.&lt;/li&gt;
&lt;li&gt;Gateway API Slack: &lt;code&gt;#sig-network-gateway-api&lt;/code&gt; on &lt;a href=&#34;https://kubernetes.slack.com&#34;&gt;Kubernetes Slack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Ingress2Gateway Slack: &lt;code&gt;#sig-network-ingress2gateway&lt;/code&gt; on &lt;a href=&#34;https://kubernetes.slack.com&#34;&gt;Kubernetes Slack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;GitHub: &lt;a href=&#34;https://github.com/kubernetes-sigs/ingress2gateway&#34;&gt;kubernetes-sigs/ingress2gateway&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Running Agents on Kubernetes with Agent Sandbox</title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/03/20/running-agents-on-kubernetes-with-agent-sandbox/</link>
      <pubDate>Fri, 20 Mar 2026 10:00:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/03/20/running-agents-on-kubernetes-with-agent-sandbox/</guid>
      <description>
        
        
        &lt;p&gt;The landscape of artificial intelligence is undergoing a massive architectural shift. In the early days of generative AI, interacting with a model was often treated as a transient, stateless function call: a request that spun up, executed for perhaps 50 milliseconds, and terminated.&lt;/p&gt;
&lt;p&gt;Today, the world is witnessing AI v2 eating AI v1. The ecosystem is moving from short-lived, isolated tasks to deploying multiple, coordinated AI agents that run constantly. These autonomous agents need to maintain context, use external tools, write and execute code, and communicate with one another over extended periods.&lt;/p&gt;
&lt;p&gt;As platform engineering teams look for the right infrastructure to host these new AI workloads, one platform stands out as the natural choice: Kubernetes. However, mapping these unique agentic workloads to traditional Kubernetes primitives requires a new abstraction.&lt;/p&gt;
&lt;p&gt;This is where the new &lt;a href=&#34;https://github.com/kubernetes-sigs/agent-sandbox&#34;&gt;Agent Sandbox&lt;/a&gt; project (currently in development under SIG Apps) comes into play.&lt;/p&gt;
&lt;h2 id=&#34;the-kubernetes-advantage-and-the-abstraction-gap&#34;&gt;The Kubernetes advantage (and the abstraction gap)&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#the-kubernetes-advantage-and-the-abstraction-gap&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Kubernetes is the de facto standard for orchestrating cloud-native applications precisely because it solves the challenges of extensibility, robust networking, and ecosystem maturity. However, as AI evolves from short-lived inference requests to long-running, autonomous agents, we are seeing the emergence of a new operational pattern.&lt;/p&gt;
&lt;p&gt;AI agents, by contrast, are typically isolated, stateful, singleton workloads. They act as a digital workspace or execution environment for an LLM. An agent needs a persistent identity and a secure scratchpad for writing and executing (often untrusted) code. Crucially, because these long-lived agents are expected to be mostly idle except for brief bursts of activity, they require a lifecycle that supports mechanisms like suspension and rapid resumption.&lt;/p&gt;
&lt;p&gt;While you could theoretically approximate this by stringing together a StatefulSet of size 1, a headless Service, and a PersistentVolumeClaim for every single agent, managing this at scale becomes an operational nightmare.&lt;/p&gt;
&lt;p&gt;Because of these unique properties, traditional Kubernetes primitives don&#39;t perfectly align.&lt;/p&gt;
&lt;h2 id=&#34;introducing-kubernetes-agent-sandbox&#34;&gt;Introducing Kubernetes Agent Sandbox&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#introducing-kubernetes-agent-sandbox&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;To bridge this gap, SIG Apps is developing &lt;a href=&#34;https://github.com/kubernetes-sigs/agent-sandbox&#34;&gt;agent-sandbox&lt;/a&gt;. The project introduces a declarative, standardized API specifically tailored for singleton, stateful workloads like AI agent runtimes.&lt;/p&gt;
&lt;p&gt;At its core, the project introduces the Sandbox CRD. It acts as a lightweight, single-container environment built entirely on Kubernetes primitives, offering:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Strong isolation for untrusted code&lt;/strong&gt;: When an AI agent generates and executes code autonomously, security is paramount. The Sandbox custom resource natively supports different runtimes, like gVisor or Kata Containers. This provides the necessary kernel and network isolation required for multi-tenant, untrusted execution.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Lifecycle management&lt;/strong&gt;: Unlike traditional web servers optimized for steady, stateless traffic, an AI agent operates as a stateful workspace that may be idle for hours between tasks. Agent Sandbox supports scaling these idle environments to zero to save resources, while ensuring they can resume exactly where they left off.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Stable identity&lt;/strong&gt;: Coordinated multi-agent systems require stable networking. Every Sandbox is given a stable hostname and network identity, allowing distinct agents to discover and communicate with each other seamlessly.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;scaling-agents-with-extensions&#34;&gt;Scaling agents with extensions&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#scaling-agents-with-extensions&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Because the AI space is moving incredibly quickly, we built an Extensions API layer that enables even faster iteration and development.&lt;/p&gt;
&lt;p&gt;Starting a new pod adds about a second of overhead. That&#39;s perfectly fine when deploying a new version of a microservice, but when an agent is invoked after being idle, a one-second cold start breaks the continuity of the interaction. It forces the user or the orchestrating service to wait for the environment to provision before the model can even begin to think or act. SandboxWarmPool solves this by maintaining a pool of pre-provisioned Sandbox pods, effectively eliminating cold starts. Users or orchestration services can simply issue a SandboxClaim against a SandboxTemplate, and the controller immediately hands over a pre-warmed, fully isolated environment to the agent.&lt;/p&gt;
&lt;h2 id=&#34;quick-start&#34;&gt;Quick start&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#quick-start&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Ready to try it yourself? You can install the Agent Sandbox core components and extensions directly into your learning or sandbox cluster, using your chosen release.&lt;/p&gt;
&lt;p&gt;We recommend you use the latest release as the project is moving fast.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Replace &amp;#34;vX.Y.Z&amp;#34; with a specific version tag (e.g., &amp;#34;v0.1.0&amp;#34;) from&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# https://github.com/kubernetes-sigs/agent-sandbox/releases&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;VERSION&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;vX.Y.Z&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Install the core components:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl apply -f https://github.com/kubernetes-sigs/agent-sandbox/releases/download/&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;VERSION&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;/manifest.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Install the extensions components (optional):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl apply -f https://github.com/kubernetes-sigs/agent-sandbox/releases/download/&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;VERSION&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;/extensions.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Install the Python SDK (optional):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Create a virtual Python environment&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;python3 -m venv .venv
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;source&lt;/span&gt; .venv/bin/activate
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Install from PyPI&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pip install k8s-agent-sandbox
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Once installed, you can try out the &lt;a href=&#34;https://github.com/kubernetes-sigs/agent-sandbox/tree/main/clients/python/agentic-sandbox-client&#34;&gt;Python SDK&lt;/a&gt; for AI agents or deploy one of the ready-to-use &lt;a href=&#34;https://github.com/kubernetes-sigs/agent-sandbox/tree/main/examples&#34;&gt;examples&lt;/a&gt; to see how easy it is to spin up an isolated agent environment.&lt;/p&gt;
&lt;h2 id=&#34;the-future-of-agents-is-cloud-native&#34;&gt;The future of agents is cloud native&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#the-future-of-agents-is-cloud-native&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Whether it’s a 50-millisecond stateless task, or a multi-week, mostly-idle collaborative process, extending Kubernetes with primitives designed specifically for isolated stateful singletons allows us to leverage all the robust benefits of the cloud-native ecosystem.&lt;/p&gt;
&lt;p&gt;The Agent Sandbox project is open source and community-driven. If you are building AI platforms, developing agentic frameworks, or are interested in Kubernetes extensibility, we invite you to get involved:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Check out the project on GitHub: &lt;a href=&#34;https://github.com/kubernetes-sigs/agent-sandbox&#34;&gt;kubernetes-sigs/agent-sandbox&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Join the discussion in the &lt;a href=&#34;https://kubernetes.slack.com/messages/sig-apps&#34;&gt;#sig-apps&lt;/a&gt; and &lt;a href=&#34;https://kubernetes.slack.com/messages/agent-sandbox&#34;&gt;#agent-sandbox&lt;/a&gt; channels on the Kubernetes Slack.&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Securing Production Debugging in Kubernetes</title>
      <link>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/03/18/securing-production-debugging-in-kubernetes/</link>
      <pubDate>Wed, 18 Mar 2026 10:00:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/blog/2026/03/18/securing-production-debugging-in-kubernetes/</guid>
      <description>
        
        
        &lt;p&gt;During production debugging, the fastest route is often broad access such as &lt;code&gt;cluster-admin&lt;/code&gt; (a ClusterRole that grants administrator-level access), shared bastions/jump boxes, or long-lived SSH keys. It works in the moment, but it comes with two common problems: auditing becomes difficult, and temporary exceptions have a way of becoming routine.&lt;/p&gt;
&lt;p&gt;This post offers my recommendations for good practices applicable to existing Kubernetes environments with minimal tooling changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Least privilege with RBAC&lt;/li&gt;
&lt;li&gt;Short-lived, identity-bound credentials&lt;/li&gt;
&lt;li&gt;An SSH-style handshake model for cloud native debugging&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A good architecture for securing production debugging workflows is to use a just-in-time secure shell gateway
(often deployed as an on demand pod in the cluster).
It acts as an SSH-style “front door” that makes temporary access actually temporary. You can
authenticate with short-lived, identity-bound credentials, establish a session to the gateway,
and the gateway uses the Kubernetes API and RBAC to control what they can do, such as &lt;code&gt;pods/log&lt;/code&gt;, &lt;code&gt;pods/exec&lt;/code&gt;, and &lt;code&gt;pods/portforward&lt;/code&gt;.
Sessions expire automatically, and both the gateway logs and Kubernetes audit logs capture who accessed what and when without shared bastion accounts or long-lived keys.&lt;/p&gt;
&lt;h2 id=&#34;1-using-an-access-broker-on-top-of-kubernetes-rbac&#34;&gt;1) Using an access broker on top of Kubernetes RBAC&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#1-using-an-access-broker-on-top-of-kubernetes-rbac&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;RBAC controls who can do what in Kubernetes. Many Kubernetes environments rely primarily on RBAC for authorization, although Kubernetes also supports other authorization modes such as Webhook authorization. You can enforce access directly with Kubernetes RBAC, or put an access broker in front of the cluster that still relies on Kubernetes permissions under the hood. In either model, Kubernetes RBAC remains the source of truth for what the Kubernetes API allows and at what scope.&lt;/p&gt;
&lt;p&gt;An access broker adds controls that RBAC does not cover well. For example, it can decide whether a request is auto-approved or requires manual approval, whether a user can run a command, and which commands are allowed in a session. It can also manage group membership so that you grant permissions to groups instead of individual users. Kubernetes RBAC can allow actions such as pods/exec, but it cannot restrict which commands run inside an exec session.&lt;/p&gt;
&lt;p&gt;With that model, Kubernetes RBAC defines the allowed actions for a user or group (for example, an on-call team in a single namespace).
I recommend you only define access rules that grant rights to groups or to ServiceAccounts - never to individual users. The broker or identity provider then adds or removes users from that group as needed.&lt;/p&gt;
&lt;p&gt;The broker can also enforce extra policy on top, like which commands are permitted in an interactive session and
which requests can be auto-approved versus require manual approval.
That policy can live in a JSON or XML file and be maintained through code review, so updates go through a formal pull request and are reviewed like any other production change.&lt;/p&gt;
&lt;h3 id=&#34;example-a-namespaced-on-call-debug-role&#34;&gt;Example: a namespaced on-call debug Role&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#example-a-namespaced-on-call-debug-role&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;rbac.authorization.k8s.io/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Role&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;oncall-debug&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;namespace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;&amp;lt;namespace&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;rules&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# Discover what’s running&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;apiGroups&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;resources&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;pods&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;events&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;verbs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;get&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;list&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;watch&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# Read logs&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;apiGroups&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;resources&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;pods/log&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;verbs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;get&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# Interactive debugging actions&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;apiGroups&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;resources&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;pods/exec&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;pods/portforward&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;verbs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;create&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# Understand rollout/controller state&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;apiGroups&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;apps&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;resources&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;deployments&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;replicasets&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;verbs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;get&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;list&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;watch&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# Optional: allow kubectl debug ephemeral containers&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;apiGroups&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;resources&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;pods/ephemeralcontainers&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;verbs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;update&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Bind the Role to a group (rather than individual users) so membership can be managed through your identity provider:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;rbac.authorization.k8s.io/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;RoleBinding&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;oncall-debug&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;namespace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;&amp;lt;namespace&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;subjects&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Group&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;oncall-&amp;lt;team-name&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;apiGroup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;rbac.authorization.k8s.io&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;roleRef&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Role&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;oncall-debug&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;apiGroup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;rbac.authorization.k8s.io&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;2-short-lived-identity-bound-credentials&#34;&gt;2) Short-lived, identity-bound credentials&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#2-short-lived-identity-bound-credentials&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The goal is to use short-lived, identity-bound credentials that clearly tie a session to a real person and expire quickly. These credentials can include the user’s identity and the scope of what they’re allowed to do. They’re typically signed using a private key that stays with the engineer, such as a hardware-backed key (for example, a YubiKey), so they can not be forged without access to that key.&lt;/p&gt;
&lt;p&gt;You can implement this with Kubernetes-native authentication (for example, client certificates or an OIDC-based flow),
or have the access broker from the previous section issue short-lived credentials on the user’s behalf.
In many setups, Kubernetes still uses RBAC to enforce permissions based on the authenticated identity and groups/claims.
If you use an access broker, it can also encode additional scope constraints in the credential and enforce them during the session, such as which cluster or namespace the session applies to and which actions
(or approved commands) are allowed against pods or nodes.
In either case, the credentials should be signed by a certificate authority (CA), and that CA should be rotated on a regular schedule (for example, quarterly) to limit long-term risk.&lt;/p&gt;
&lt;h3 id=&#34;option-a-short-lived-oidc-tokens&#34;&gt;Option A: short-lived OIDC tokens&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#option-a-short-lived-oidc-tokens&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;A lot of managed Kubernetes clusters already give you short-lived tokens. The main thing is to make sure your kubeconfig refreshes them automatically instead of copying a long-lived token into the file.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;users&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;oncall&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;user&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;exec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;client.authentication.k8s.io/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;command&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;cred-helper&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;--cluster=prod&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;--ttl=30m&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;option-b-short-lived-client-certificates-x-509&#34;&gt;Option B: Short-lived client certificates (X.509)&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#option-b-short-lived-client-certificates-x-509&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;If your API server (or your access broker from the previous section) is set up to trust a client CA, you can use short-lived client certificates for debugging access. The idea is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The private key is created and kept under the engineer’s machine (ideally hardware-backed, like a non-exportable key in a YubiKey/PIV token)&lt;/li&gt;
&lt;li&gt;A short-lived certificate is issued (often via the
&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/reference/access-authn-authz/certificate-signing-requests/#certificate-signing-requests&#34;&gt;CertificateSigningRequest&lt;/a&gt; API, or your access broker from the previous section, with a TTL).&lt;/li&gt;
&lt;li&gt;RBAC maps the authenticated identity to a minimal Role&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is straightforward to operationalize with the Kubernetes CertificateSigningRequest API.&lt;/p&gt;
&lt;p&gt;Generate a key and CSR locally:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Generate a private key.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# This could instead be generated within a hardware token;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# OpenSSL and several similar tools include support for that.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;openssl genpkey -algorithm Ed25519 -out oncall.key
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;openssl req -new -key oncall.key -out oncall.csr &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;  -subj &lt;span class=&#34;s2&#34;&gt;&amp;#34;/CN=user/O=oncall-payments&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Create a CertificateSigningRequest with a short expiration:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;certificates.k8s.io/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;CertificateSigningRequest&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;oncall-&amp;lt;user&amp;gt;-20260218&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;request&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;&amp;lt;base64-encoded oncall.csr&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;signerName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;kubernetes.io/kube-apiserver-client&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expirationSeconds&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1800&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# 30 minutes&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;usages&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;client auth&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;After the CSR is approved and signed, you extract the issued certificate and use it together with the private key to authenticate, for example via kubectl.&lt;/p&gt;
&lt;h2 id=&#34;3-use-a-just-in-time-access-gateway-to-run-debugging-commands&#34;&gt;3) Use a just-in-time access gateway to run debugging commands&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#3-use-a-just-in-time-access-gateway-to-run-debugging-commands&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Once you have short-lived credentials, you can use them to open a secure shell session to a just-in-time access gateway, often exposed over SSH and created on demand. If the gateway is exposed over SSH, a common pattern is to issue the engineer a short-lived OpenSSH user certificate for the session. The gateway trusts your SSH user CA, authenticates the engineer at connection time, and then applies the approved session policy before making Kubernetes API calls on the user’s behalf. OpenSSH certificates are separate from Kubernetes X.509 client certificates, so these are usually treated as distinct layers.&lt;/p&gt;
&lt;p&gt;The resulting session should also be scoped so it cannot be reused outside of what was approved. For example, the gateway or broker can limit it to a specific cluster and namespace, and optionally to a narrower target such as a pod or node. That way, even if someone tries to reuse the access, it will not work outside the intended scope. After the session is established, the gateway executes only the allowed actions and records what happened for auditing.&lt;/p&gt;
&lt;h3 id=&#34;example-namespace-scoped-role-bindings&#34;&gt;Example: Namespace-scoped role bindings&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#example-namespace-scoped-role-bindings&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;rbac.authorization.k8s.io/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Role&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;jit-debug&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;namespace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;&amp;lt;namespace&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kubernetes.io/description&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sd&#34;&gt;      Colleagues performing semi-privileged debugging, with access provided
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sd&#34;&gt;      just in time and on demand.&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;rules&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;apiGroups&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;resources&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;pods&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;pods/log&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;verbs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;get&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;list&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;watch&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;apiGroups&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;resources&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;pods/exec&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;verbs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;create&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;rbac.authorization.k8s.io/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;RoleBinding&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;jit-debug&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;namespace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;&amp;lt;namespace&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;subjects&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Group&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;jit:oncall:&amp;lt;namespace&amp;gt;  &lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# mapped from the short-lived credential (cert/OIDC)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;apiGroup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;rbac.authorization.k8s.io&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;roleRef&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Role&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;jit-debug&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;apiGroup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;rbac.authorization.k8s.io&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;These RBAC objects, and the rules they define, allow debugging only within the specified namespace; attempts to access other namespaces are not allowed.&lt;/p&gt;
&lt;h3 id=&#34;example-cluster-scoped-role-binding&#34;&gt;Example: Cluster-scoped role binding&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#example-cluster-scoped-role-binding&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;rbac.authorization.k8s.io/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ClusterRole&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;jit-cluster-read&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;rules&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;apiGroups&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;resources&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;nodes&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;namespaces&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;verbs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;get&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;list&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;watch&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;rbac.authorization.k8s.io/v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ClusterRoleBinding&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metadata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;jit-cluster-read&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;subjects&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Group&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;jit:oncall:cluster&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;apiGroup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;rbac.authorization.k8s.io&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;roleRef&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ClusterRole&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;jit-cluster-read&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;apiGroup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;rbac.authorization.k8s.io&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;These RBAC rules grant cluster-wide read access (for example, to nodes and namespaces) and should be used only for workflows that truly require cluster-scoped resources.&lt;/p&gt;
&lt;p&gt;Finer-grained restrictions like “only this pod/node” or “only these commands” are typically enforced by the access gateway/broker during the session, but Kubernetes also offers other options, such as ValidatingAdmissionPolicy for restricting writes and webhook authorization for custom authorization across verbs.&lt;/p&gt;
&lt;p&gt;In environments with stricter access controls, you can add an extra, short-lived session mediation layer
to separate session establishment from privileged actions. Both layers are ephemeral, use identity-bound expiring credentials,
and produce independent audit trails. The mediation layer handles session setup/forwarding,
while the execution layer performs only RBAC-authorized Kubernetes actions.
This separation can reduce exposure by narrowing responsibilities, scoping credentials per step, and enforcing end-to-end session expiry.&lt;/p&gt;
&lt;h2 id=&#34;references&#34;&gt;References&lt;a class=&#34;td-heading-self-link&#34; href=&#34;#references&#34; aria-label=&#34;Heading self-link&#34;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/reference/access-authn-authz/authorization/&#34;&gt;Authorization&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/reference/access-authn-authz/rbac/&#34;&gt;Using RBAC Authorization&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/reference/access-authn-authz/authentication/&#34;&gt;Authenticating&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/reference/access-authn-authz/certificate-signing-requests/&#34;&gt;Certificates and Certificate Signing Requests&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/tasks/tls/certificate-issue-client-csr/&#34;&gt;Issue a Certificate for a Kubernetes API Client Using a CertificateSigningRequest&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://deploy-preview-57268--kubernetes-io-main-staging.netlify.app/docs/concepts/security/rbac-good-practices/&#34;&gt;Role Based Access Control Good Practices&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;Disclaimer: The views expressed in this post are solely those of the author and do not reflect the views of the author’s employer or any other organization.&lt;/em&gt;&lt;/p&gt;

      </description>
    </item>
    
  </channel>
</rss>
