<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Kubernetes Blog</title>
    <link>https://deploy-preview-50011--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-50011--kubernetes-io-main-staging.netlify.app/</link>
    </image>
    
    <atom:link href="https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/feed.xml" rel="self" type="application/rss+xml" />
    
    
    <item>
      <title>Spotlight on SIG etcd</title>
      <link>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2025/03/04/sig-etcd-spotlight/</link>
      <pubDate>Tue, 04 Mar 2025 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2025/03/04/sig-etcd-spotlight/</guid>
      <description>
        
        
        &lt;p&gt;In this SIG etcd spotlight we talked with &lt;a href=&#34;https://github.com/jmhbnz&#34;&gt;James Blair&lt;/a&gt;, &lt;a href=&#34;https://github.com/serathius&#34;&gt;Marek
Siarkowicz&lt;/a&gt;, &lt;a href=&#34;https://github.com/wenjiaswe&#34;&gt;Wenjia Zhang&lt;/a&gt;, and
&lt;a href=&#34;https://github.com/ahrtr&#34;&gt;Benjamin Wang&lt;/a&gt; to learn a bit more about this Kubernetes Special Interest
Group.&lt;/p&gt;
&lt;h2 id=&#34;introducing-sig-etcd&#34;&gt;Introducing SIG etcd&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Frederico: Hello, thank you for the time! Let’s start with some introductions, could you tell us a
bit about yourself, your role and how you got involved in Kubernetes.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Benjamin:&lt;/strong&gt; Hello, I am Benjamin. I am a SIG etcd Tech Lead and one of the etcd maintainers. I
work for VMware, which is part of the Broadcom group. I got involved in Kubernetes &amp;amp; etcd &amp;amp; CSI
(&lt;a href=&#34;https://github.com/container-storage-interface/spec/blob/master/spec.md&#34;&gt;Container Storage Interface&lt;/a&gt;)
because of work and also a big passion for open source. I have been working on Kubernetes &amp;amp; etcd
(and also CSI) since 2020.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;James:&lt;/strong&gt; Hey team, I’m James, a co-chair for SIG etcd and etcd maintainer. I work at Red Hat as a
Specialist Architect helping people adopt cloud native technology. I got involved with the
Kubernetes ecosystem in 2019. Around the end of 2022 I noticed how the etcd community and project
needed help so started contributing as often as I could. There is a saying in our community that
&amp;quot;you come for the technology, and stay for the people&amp;quot;: for me this is absolutely real, it’s been a
wonderful journey so far and I’m excited to support our community moving forward.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Marek:&lt;/strong&gt; Hey everyone, I&#39;m Marek, the SIG etcd lead. At Google, I lead the GKE etcd team, ensuring
a stable and reliable experience for all GKE users. My Kubernetes journey began with &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-instrumentation&#34;&gt;SIG
Instrumentation&lt;/a&gt;, where I
created and led the &lt;a href=&#34;https://kubernetes.io/blog/2020/09/04/kubernetes-1-19-introducing-structured-logs/&#34;&gt;Kubernetes Structured Logging effort&lt;/a&gt;.&lt;br&gt;
I&#39;m still the main project lead for &lt;a href=&#34;https://kubernetes-sigs.github.io/metrics-server/&#34;&gt;Kubernetes Metrics Server&lt;/a&gt;,
providing crucial signals for autoscaling in Kubernetes. I started working on etcd 3 years ago,
right around the 3.5 release. We faced some challenges, but I&#39;m thrilled to see etcd now the most
scalable and reliable it&#39;s ever been, with the highest contribution numbers in the project&#39;s
history. I&#39;m passionate about distributed systems, extreme programming, and testing.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Wenjia:&lt;/strong&gt; Hi there, my name is Wenjia, I am the co-chair of SIG etcd and one of the etcd
maintainers. I work at Google as an Engineering Manager, working on GKE (Google Kubernetes Engine)
and GDC (Google Distributed Cloud).  I have been working in the area of open source Kubernetes and
etcd since the Kubernetes v1.10 and etcd v3.1 releases. I got involved in Kubernetes because of my
job, but what keeps me in the space is the charm of the container orchestration technology, and more
importantly, the awesome open source community.&lt;/p&gt;
&lt;h2 id=&#34;becoming-a-kubernetes-special-interest-group-sig&#34;&gt;Becoming a Kubernetes Special Interest Group (SIG)&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Frederico: Excellent, thank you. I&#39;d like to start with the origin of the SIG itself: SIG etcd is
a very recent SIG, could you quickly go through the history and reasons behind its creation?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Marek&lt;/strong&gt;: Absolutely! SIG etcd was formed because etcd is a critical component of Kubernetes,
serving as its data store. However, etcd was facing challenges like maintainer turnover and
reliability issues. &lt;a href=&#34;https://etcd.io/blog/2023/introducing-sig-etcd/&#34;&gt;Creating a dedicated SIG&lt;/a&gt;
allowed us to focus on addressing these problems, improving development and maintenance processes,
and ensuring etcd evolves in sync with the cloud-native landscape.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Frederico: And has becoming a SIG worked out as expected? Better yet, are the motivations you just
described being addressed, and to what extent?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Marek&lt;/strong&gt;: It&#39;s been a positive change overall. Becoming a SIG has brought more structure and
transparency to etcd&#39;s development. We&#39;ve adopted Kubernetes processes like KEPs
(&lt;a href=&#34;https://github.com/kubernetes/enhancements/blob/master/keps/README.md&#34;&gt;Kubernetes Enhancement Proposals&lt;/a&gt;
and PRRs (&lt;a href=&#34;https://github.com/kubernetes/community/blob/master/sig-architecture/production-readiness.md&#34;&gt;Production Readiness Reviews&lt;/a&gt;,
which has improved our feature development and release cycle.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Frederico: On top of those, what would you single out as the major benefit that has resulted from
becoming a SIG?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Marek&lt;/strong&gt;: The biggest benefits for me was adopting Kubernetes testing infrastructure, tools like
&lt;a href=&#34;https://docs.prow.k8s.io/&#34;&gt;Prow&lt;/a&gt; and &lt;a href=&#34;https://testgrid.k8s.io/&#34;&gt;TestGrid&lt;/a&gt;. For large projects like
etcd there is just no comparison to the default GitHub tooling. Having known, easy to use, clear
tools is a major boost to the etcd as it makes it much easier for Kubernetes contributors to also
help etcd.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Wenjia&lt;/strong&gt;: Totally agree, while challenges remain, the SIG structure provides a solid foundation
for addressing them and ensuring etcd&#39;s continued success as a critical component of the Kubernetes
ecosystem.&lt;/p&gt;
&lt;p&gt;The positive impact on the community is another crucial aspect of SIG etcd&#39;s success that I’d like
to highlight. The Kubernetes SIG structure has created a welcoming environment for etcd
contributors, leading to increased participation from the broader Kubernetes community.  We have had
greater collaboration with other SIGs like &lt;a href=&#34;https://github.com/kubernetes/community/blob/master/sig-api-machinery/README.md&#34;&gt;SIG API
Machinery&lt;/a&gt;,
&lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-scalability&#34;&gt;SIG Scalability&lt;/a&gt;,
&lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-scalability&#34;&gt;SIG Testing&lt;/a&gt;,
&lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-cluster-lifecycle&#34;&gt;SIG Cluster Lifecycle&lt;/a&gt;, etc.&lt;/p&gt;
&lt;p&gt;This collaboration helps ensure etcd&#39;s development aligns with the needs of the wider Kubernetes
ecosystem. The formation of the &lt;a href=&#34;https://github.com/kubernetes/community/blob/master/wg-etcd-operator/README.md&#34;&gt;etcd Operator Working Group&lt;/a&gt;
under the joint effort between SIG etcd and SIG Cluster Lifecycle exemplifies this successful
collaboration, demonstrating a shared commitment to improving etcd&#39;s operational aspects within
Kubernetes.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Frederico: Since you mentioned collaboration, have you seen changes in terms of contributors and
community involvement in recent months?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;James&lt;/strong&gt;: Yes -- as showing in our
&lt;a href=&#34;https://etcd.devstats.cncf.io/d/23/prs-authors-repository-groups?orgId=1&amp;var-period=m&amp;var-repogroup_name=All&amp;from=1422748800000&amp;to=1738454399000&#34;&gt;unique PR author data&lt;/a&gt;
we recently hit an all time high in March and are trending in a positive direction:&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2025/03/04/sig-etcd-spotlight/stats.png&#34;
         alt=&#34;Unique PR author data stats&#34;/&gt; 
&lt;/figure&gt;
&lt;p&gt;Additionally, looking at our
&lt;a href=&#34;https://etcd.devstats.cncf.io/d/74/contributions-chart?orgId=1&amp;from=1422748800000&amp;to=1738454399000&amp;var-period=m&amp;var-metric=contributions&amp;var-repogroup_name=All&amp;var-country_name=All&amp;var-company_name=All&amp;var-company=all&#34;&gt;overall contributions across all etcd project repositories&lt;/a&gt;
we are also observing a positive trend showing a resurgence in etcd project activity:&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2025/03/04/sig-etcd-spotlight/stats2.png&#34;
         alt=&#34;Overall contributions stats&#34;/&gt; 
&lt;/figure&gt;
&lt;h2 id=&#34;the-road-ahead&#34;&gt;The road ahead&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Frederico: That&#39;s quite telling, thank you. In terms of the near future, what are the current
priorities for SIG etcd?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Marek&lt;/strong&gt;: Reliability is always top of mind -– we need to make sure etcd is rock-solid. We&#39;re also
working on making etcd easier to use and manage for operators. And we have our sights set on making
etcd a viable standalone solution for infrastructure management, not just for Kubernetes. Oh, and of
course, scaling -– we need to ensure etcd can handle the growing demands of the cloud-native world.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Benjamin&lt;/strong&gt;: I agree that reliability should always be our top guiding principle. We need to ensure
not only correctness but also compatibility. Additionally, we should continuously strive to improve
the understandability and maintainability of etcd. Our focus should be on addressing the pain points
that the community cares about the most.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Frederico: Are there any specific SIGs that you work closely with?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Marek&lt;/strong&gt;: SIG API Machinery, for sure – they own the structure of the data etcd stores, so we&#39;re
constantly working together. And SIG Cluster Lifecycle – etcd is a key part of Kubernetes clusters,
so we collaborate on the newly created etcd operator Working group.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Wenjia&lt;/strong&gt;: Other than SIG API Machinery and SIG Cluster Lifecycle that Marek mentioned above, SIG
Scalability and SIG Testing is another group that we work closely with.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Frederico: In a more general sense, how would you list the key challenges for SIG etcd in the
evolving cloud native landscape?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Marek&lt;/strong&gt;: Well, reliability is always a challenge when you&#39;re dealing with critical data. The
cloud-native world is evolving so fast that scaling to meet those demands is a constant effort.&lt;/p&gt;
&lt;h2 id=&#34;getting-involved&#34;&gt;Getting involved&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Frederico: We&#39;re almost at the end of our conversation, but for those interested in in etcd, how
can they get involved?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Marek&lt;/strong&gt;: We&#39;d love to have them! The best way to start is to join our
&lt;a href=&#34;https://github.com/kubernetes/community/blob/master/sig-etcd/README.md#meetings&#34;&gt;SIG etcd meetings&lt;/a&gt;,
follow discussions on the &lt;a href=&#34;https://groups.google.com/g/etcd-dev&#34;&gt;etcd-dev mailing list&lt;/a&gt;, and check
out our &lt;a href=&#34;https://github.com/etcd-io/etcd/issues&#34;&gt;GitHub issues&lt;/a&gt;. We&#39;re always looking for people to
review proposals, test code, and contribute to documentation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Wenjia&lt;/strong&gt;: I love this question 😀 . There are numerous ways for people interested in contributing
to SIG etcd to get involved and make a difference. Here are some key areas where you can help:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Code Contributions&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Bug Fixes&lt;/em&gt;: Tackle existing issues in the etcd codebase. Start with issues labeled &amp;quot;good first
issue&amp;quot; or &amp;quot;help wanted&amp;quot; to find tasks that are suitable for newcomers.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Feature Development&lt;/em&gt;: Contribute to the development of new features and enhancements. Check the
etcd roadmap and discussions to see what&#39;s being planned and where your skills might fit in.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Testing and Code Reviews&lt;/em&gt;: Help ensure the quality of etcd by writing tests, reviewing code
changes, and providing feedback.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Documentation&lt;/em&gt;: Improve &lt;a href=&#34;https://etcd.io/docs/&#34;&gt;etcd&#39;s documentation&lt;/a&gt; by adding new content,
clarifying existing information, or fixing errors. Clear and comprehensive documentation is
essential for users and contributors.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Community Support&lt;/em&gt;: Answer questions on forums, mailing lists, or &lt;a href=&#34;https://kubernetes.slack.com/archives/C3HD8ARJ5&#34;&gt;Slack  channels&lt;/a&gt;.
Helping others understand and use etcd is a valuable contribution.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Getting Started&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Join the community&lt;/em&gt;: Start by joining the etcd community on Slack,
attending SIG meetings, and following the mailing lists. This will
help you get familiar with the project, its processes, and the
people involved.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Find a mentor&lt;/em&gt;: If you&#39;re new to open source or etcd, consider
finding a mentor who can guide you and provide support. Stay tuned!
Our first cohort of mentorship program was very successful. We will
have a new round of mentorship program coming up.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Start small&lt;/em&gt;: Don&#39;t be afraid to start with small contributions. Even
fixing a typo in the documentation or submitting a simple bug fix
can be a great way to get involved.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;By contributing to etcd, you&#39;ll not only be helping to improve a
critical piece of the cloud-native ecosystem but also gaining valuable
experience and skills. So, jump in and start contributing!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Frederico: Excellent, thank you. Lastly, one piece of advice that
you&#39;d like to give to other newly formed SIGs?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Marek&lt;/strong&gt;: Absolutely! My advice would be to embrace the established
processes of the larger community, prioritize collaboration with other
SIGs, and focus on building a strong community.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Wenjia&lt;/strong&gt;: Here are some tips I myself found very helpful in my OSS
journey:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Be patient&lt;/em&gt;: Open source development can take time. Don&#39;t get
discouraged if your contributions aren&#39;t accepted immediately or if
you encounter challenges.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Be respectful&lt;/em&gt;: The etcd community values collaboration and
respect. Be mindful of others&#39; opinions and work together to achieve
common goals.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Have fun&lt;/em&gt;: Contributing to open source should be
enjoyable. Find areas that interest you and contribute in ways that
you find fulfilling.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Frederico: A great way to end this spotlight, thank you all!&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;For more information and resources, please take a look at :&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;etcd website: &lt;a href=&#34;https://etcd.io/&#34;&gt;https://etcd.io/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;etcd GitHub repository: &lt;a href=&#34;https://github.com/etcd-io/etcd&#34;&gt;https://github.com/etcd-io/etcd&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;etcd community: &lt;a href=&#34;https://etcd.io/community/&#34;&gt;https://etcd.io/community/&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

      </description>
    </item>
    
    <item>
      <title>NFTables mode for kube-proxy</title>
      <link>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2025/02/28/nftables-kube-proxy/</link>
      <pubDate>Fri, 28 Feb 2025 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2025/02/28/nftables-kube-proxy/</guid>
      <description>
        
        
        &lt;p&gt;A new nftables mode for kube-proxy was introduced as an alpha feature
in Kubernetes 1.29. Currently in beta, it is expected to be GA as of
1.33. The new mode fixes long-standing performance problems with the
iptables mode and all users running on systems with reasonably-recent
kernels are encouraged to try it out. (For compatibility reasons, even
once nftables becomes GA, iptables will still be the &lt;em&gt;default&lt;/em&gt;.)&lt;/p&gt;
&lt;h2 id=&#34;why-nftables-part-1-data-plane-latency&#34;&gt;Why nftables? Part 1: data plane latency&lt;/h2&gt;
&lt;p&gt;The iptables API was designed for implementing simple firewalls, and
has problems scaling up to support Service proxying in a large
Kubernetes cluster with tens of thousands of Services.&lt;/p&gt;
&lt;p&gt;In general, the ruleset generated by kube-proxy in iptables mode has a
number of iptables rules proportional to the sum of the number of
Services and the total number of endpoints. In particular, at the top
level of the ruleset, there is one rule to test each possible Service
IP (and port) that a packet might be addressed to:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# If the packet is addressed to 172.30.0.41:80, then jump to the chain
# KUBE-SVC-XPGD46QRK7WJZT7O for further processing
-A KUBE-SERVICES -m comment --comment &amp;#34;namespace1/service1:p80 cluster IP&amp;#34; -m tcp -p tcp -d 172.30.0.41 --dport 80 -j KUBE-SVC-XPGD46QRK7WJZT7O

# If the packet is addressed to 172.30.0.42:443, then...
-A KUBE-SERVICES -m comment --comment &amp;#34;namespace2/service2:p443 cluster IP&amp;#34; -m tcp -p tcp -d 172.30.0.42 --dport 443 -j KUBE-SVC-GNZBNJ2PO5MGZ6GT

# etc...
-A KUBE-SERVICES -m comment --comment &amp;#34;namespace3/service3:p80 cluster IP&amp;#34; -m tcp -p tcp -d 172.30.0.43 --dport 80 -j KUBE-SVC-X27LE4BHSL4DOUIK
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This means that when a packet comes in, the time it takes the kernel
to check it against all of the Service rules is &lt;strong&gt;O(n)&lt;/strong&gt; in the number
of Services. As the number of Services increases, both the average and
the worst-case latency for the first packet of a new connection
increases (with the difference between best-case, average, and
worst-case being mostly determined by whether a given Service IP
address appears earlier or later in the &lt;code&gt;KUBE-SERVICES&lt;/code&gt; chain).&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2025/02/28/nftables-kube-proxy/iptables-only.svg&#34;
         alt=&#34;kube-proxy iptables first packet latency, at various percentiles, in clusters of various sizes&#34;/&gt; 
&lt;/figure&gt;
&lt;p&gt;By contrast, with nftables, the normal way to write a ruleset like
this is to have a &lt;em&gt;single&lt;/em&gt; rule, using a &amp;quot;verdict map&amp;quot; to do the
dispatch:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;table ip kube-proxy {

        # The service-ips verdict map indicates the action to take for each matching packet.
	map service-ips {
		type ipv4_addr . inet_proto . inet_service : verdict
		comment &amp;#34;ClusterIP, ExternalIP and LoadBalancer IP traffic&amp;#34;
		elements = { 172.30.0.41 . tcp . 80 : goto service-ULMVA6XW-namespace1/service1/tcp/p80,
                             172.30.0.42 . tcp . 443 : goto service-42NFTM6N-namespace2/service2/tcp/p443,
                             172.30.0.43 . tcp . 80 : goto service-4AT6LBPK-namespace3/service3/tcp/p80,
                             ... }
        }

        # Now we just need a single rule to process all packets matching an
        # element in the map. (This rule says, &amp;#34;construct a tuple from the
        # destination IP address, layer 4 protocol, and destination port; look
        # that tuple up in &amp;#34;service-ips&amp;#34;; and if there&amp;#39;s a match, execute the
        # associated verdict.)
	chain services {
		ip daddr . meta l4proto . th dport vmap @service-ips
	}

        ...
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Since there&#39;s only a single rule, with a roughly &lt;strong&gt;O(1)&lt;/strong&gt; map lookup,
packet processing time is more or less constant regardless of cluster
size, and the best/average/worst cases are very similar:&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2025/02/28/nftables-kube-proxy/nftables-only.svg&#34;
         alt=&#34;kube-proxy nftables first packet latency, at various percentiles, in clusters of various sizes&#34;/&gt; 
&lt;/figure&gt;
&lt;p&gt;But note the huge difference in the vertical scale between the
iptables and nftables graphs! In the clusters with 5000 and 10,000
Services, the p50 (average) latency for nftables is about the same as
the p01 (approximately best-case) latency for iptables. In the 30,000
Service cluster, the p99 (approximately worst-case) latency for
nftables manages to beat out the p01 latency for iptables by a few
microseconds! Here&#39;s both sets of data together, but you may have to
squint to see the nftables results!:&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2025/02/28/nftables-kube-proxy/iptables-vs-nftables.svg&#34;
         alt=&#34;kube-proxy iptables-vs-nftables first packet latency, at various percentiles, in clusters of various sizes&#34;/&gt; 
&lt;/figure&gt;
&lt;h2 id=&#34;why-nftables-part-2-control-plane-latency&#34;&gt;Why nftables? Part 2: control plane latency&lt;/h2&gt;
&lt;p&gt;While the improvements to data plane latency in large clusters are
great, there&#39;s another problem with iptables kube-proxy that often
keeps users from even being able to grow their clusters to that size:
the time it takes kube-proxy to program new iptables rules when
Services and their endpoints change.&lt;/p&gt;
&lt;p&gt;With both iptables and nftables, the total size of the ruleset as a
whole (actual rules, plus associated data) is &lt;strong&gt;O(n)&lt;/strong&gt; in the combined
number of Services and their endpoints. Originally, the iptables
backend would rewrite every rule on every update, and with tens of
thousands of Services, this could grow to be hundreds of thousands of
iptables rules. Starting in Kubernetes 1.26, we began improving
kube-proxy so that it could skip updating &lt;em&gt;most&lt;/em&gt; of the unchanged
rules in each update, but the limitations of &lt;code&gt;iptables-restore&lt;/code&gt; as an
API meant that it was still always necessary to send an update that&#39;s
&lt;strong&gt;O(n)&lt;/strong&gt; in the number of Services (though with a noticeably smaller
constant than it used to be). Even with those optimizations, it can
still be necessary to make use of kube-proxy&#39;s &lt;code&gt;minSyncPeriod&lt;/code&gt; config
option to ensure that it doesn&#39;t spend every waking second trying to
push iptables updates.&lt;/p&gt;
&lt;p&gt;The nftables APIs allow for doing much more incremental updates, and
when kube-proxy in nftables mode does an update, the size of the
update is only &lt;strong&gt;O(n)&lt;/strong&gt; in the number of Services and endpoints that
have changed since the last sync, regardless of the total number of
Services and endpoints. The fact that the nftables API allows each
nftables-using component to have its own private table also means that
there is no global lock contention between components like with
iptables. As a result, kube-proxy&#39;s nftables updates can be done much
more efficiently than with iptables.&lt;/p&gt;
&lt;p&gt;(Unfortunately I don&#39;t have cool graphs for this part.)&lt;/p&gt;
&lt;h2 id=&#34;why-not-nftables&#34;&gt;Why &lt;em&gt;not&lt;/em&gt; nftables?&lt;/h2&gt;
&lt;p&gt;All that said, there are a few reasons why you might not want to jump
right into using the nftables backend for now.&lt;/p&gt;
&lt;p&gt;First, the code is still fairly new. While it has plenty of unit
tests, performs correctly in our CI system, and has now been used in
the real world by multiple users, it has not seen anything close to as
much real-world usage as the iptables backend has, so we can&#39;t promise
that it is as stable and bug-free.&lt;/p&gt;
&lt;p&gt;Second, the nftables mode will not work on older Linux distributions;
currently it requires a 5.13 or newer kernel. Additionally, because of
bugs in early versions of the &lt;code&gt;nft&lt;/code&gt; command line tool, you should not
run kube-proxy in nftables mode on nodes that have an old (earlier
than 1.0.0) version of &lt;code&gt;nft&lt;/code&gt; in the host filesystem (or else
kube-proxy&#39;s use of nftables may interfere with other uses of nftables
on the system).&lt;/p&gt;
&lt;p&gt;Third, you may have other networking components in your cluster, such
as the pod network or NetworkPolicy implementation, that do not yet
support kube-proxy in nftables mode. You should consult the
documentation (or forums, bug tracker, etc.) for any such components
to see if they have problems with nftables mode. (In many cases they
will not; as long as they don&#39;t try to directly interact with or
override kube-proxy&#39;s iptables rules, they shouldn&#39;t care whether
kube-proxy is using iptables or nftables.) Additionally, observability
and monitoring tools that have not been updated may report less data
for kube-proxy in nftables mode than they do for kube-proxy in
iptables mode.&lt;/p&gt;
&lt;p&gt;Finally, kube-proxy in nftables mode is intentionally not 100%
compatible with kube-proxy in iptables mode. There are a few old
kube-proxy features whose default behaviors are less secure, less
performant, or less intuitive than we&#39;d like, but where we felt that
changing the default would be a compatibility break. Since the
nftables mode is opt-in, this gave us a chance to fix those bad
defaults without breaking users who weren&#39;t expecting changes. (In
particular, with nftables mode, NodePort Services are now only
reachable on their nodes&#39; default IPs, as opposed to being reachable
on all IPs, including &lt;code&gt;127.0.0.1&lt;/code&gt;, with iptables mode.) The
&lt;a href=&#34;https://kubernetes.io/docs/reference/networking/virtual-ips/#migrating-from-iptables-mode-to-nftables&#34;&gt;kube-proxy documentation&lt;/a&gt; has more information about this, including
information about metrics you can look at to determine if you are
relying on any of the changed functionality, and what configuration
options are available to get more backward-compatible behavior.&lt;/p&gt;
&lt;h2 id=&#34;trying-out-nftables-mode&#34;&gt;Trying out nftables mode&lt;/h2&gt;
&lt;p&gt;Ready to try it out? In Kubernetes 1.31 and later, you just need to
pass &lt;code&gt;--proxy-mode nftables&lt;/code&gt; to kube-proxy (or set &lt;code&gt;mode: nftables&lt;/code&gt; in
your kube-proxy config file).&lt;/p&gt;
&lt;p&gt;If you are using kubeadm to set up your cluster, the kubeadm
documentation explains &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/setup/production-environment/tools/kubeadm/control-plane-flags/#customizing-kube-proxy&#34;&gt;how to pass a &lt;code&gt;KubeProxyConfiguration&lt;/code&gt; to
&lt;code&gt;kubeadm init&lt;/code&gt;&lt;/a&gt;. You can also &lt;a href=&#34;https://kind.sigs.k8s.io/docs/user/configuration/#kube-proxy-mode&#34;&gt;deploy nftables-based clusters with
&lt;code&gt;kind&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You can also convert existing clusters from iptables (or ipvs) mode to
nftables by updating the kube-proxy configuration and restarting the
kube-proxy pods. (You do not need to reboot the nodes: when restarting
in nftables mode, kube-proxy will delete any existing iptables or ipvs
rules, and likewise, if you later revert back to iptables or ipvs
mode, it will delete any existing nftables rules.)&lt;/p&gt;
&lt;h2 id=&#34;future-plans&#34;&gt;Future plans&lt;/h2&gt;
&lt;p&gt;As mentioned above, while nftables is now the &lt;em&gt;best&lt;/em&gt; kube-proxy mode,
it is not the &lt;em&gt;default&lt;/em&gt;, and we do not yet have a plan for changing
that. We will continue to support the iptables mode for a long time.&lt;/p&gt;
&lt;p&gt;The future of the IPVS mode of kube-proxy is less certain: its main
advantage over iptables was that it was faster, but certain aspects of
the IPVS architecture and APIs were awkward for kube-proxy&#39;s purposes
(for example, the fact that the &lt;code&gt;kube-ipvs0&lt;/code&gt; device needs to have
&lt;em&gt;every&lt;/em&gt; Service IP address assigned to it), and some parts of
Kubernetes Service proxying semantics were difficult to implement
using IPVS (particularly the fact that some Services had to have
different endpoints depending on whether you connected to them from a
local or remote client). And now, the nftables mode has the same
performance as IPVS mode (actually, slightly better), without any of
the downsides:&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2025/02/28/nftables-kube-proxy/ipvs-vs-nftables.svg&#34;
         alt=&#34;kube-proxy ipvs-vs-nftables first packet latency, at various percentiles, in clusters of various sizes&#34;/&gt; 
&lt;/figure&gt;
&lt;p&gt;(In theory the IPVS mode also has the advantage of being able to use
various other IPVS functionality, like alternative &amp;quot;schedulers&amp;quot; for
balancing endpoints. In practice, this ended up not being very useful,
because kube-proxy runs independently on every node, and the IPVS
schedulers on each node had no way of sharing their state with the
proxies on other nodes, thus thwarting the effort to balance traffic
more cleverly.)&lt;/p&gt;
&lt;p&gt;While the Kubernetes project does not have an immediate plan to drop
the IPVS backend, it is probably doomed in the long run, and people
who are currently using IPVS mode should try out the nftables mode
instead (and file bugs if you think there is missing functionality in
nftables mode that you can&#39;t work around).&lt;/p&gt;
&lt;h2 id=&#34;learn-more&#34;&gt;Learn more&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&amp;quot;&lt;a href=&#34;https://github.com/kubernetes/enhancements/blob/master/keps/sig-network/3866-nftables-proxy/README.md&#34;&gt;KEP-3866: Add an nftables-based kube-proxy backend&lt;/a&gt;&amp;quot; has the
history of the new feature.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&amp;quot;&lt;a href=&#34;https://youtu.be/yOGHb2HjslY?si=6O4PVJu7fGpReo1U&#34;&gt;How the Tables Have Turned: Kubernetes Says Goodbye to IPTables&lt;/a&gt;&amp;quot;,
from KubeCon/CloudNativeCon North America 2024, talks about porting
kube-proxy and Calico from iptables to nftables.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&amp;quot;&lt;a href=&#34;https://youtu.be/uYo2O3jbJLk?si=py2AXzMJZ4PuhxNg&#34;&gt;From Observability to Performance&lt;/a&gt;&amp;quot;, from KubeCon/CloudNativeCon
North America 2024. (This is where the kube-proxy latency data came
from; the &lt;a href=&#34;https://docs.google.com/spreadsheets/d/1-ryDNc6gZocnMHEXC7mNtqknKSOv5uhXFKDx8Hu3AYA/edit&#34;&gt;raw data for the charts&lt;/a&gt; is also available.)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>The Cloud Controller Manager Chicken and Egg Problem</title>
      <link>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2025/02/14/cloud-controller-manager-chicken-egg-problem/</link>
      <pubDate>Fri, 14 Feb 2025 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2025/02/14/cloud-controller-manager-chicken-egg-problem/</guid>
      <description>
        
        
        &lt;p&gt;Kubernetes 1.31
&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/05/20/completing-cloud-provider-migration/&#34;&gt;completed the largest migration in Kubernetes history&lt;/a&gt;, removing the in-tree
cloud provider.  While the component migration is now done, this leaves some additional
complexity for users and installer projects (for example, kOps or Cluster API) .  We will go
over those additional steps and failure points and make recommendations for cluster owners.
This migration was complex and some logic had to be extracted from the core components,
building four new subsystems.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Cloud controller manager&lt;/strong&gt; (&lt;a href=&#34;https://github.com/kubernetes/enhancements/blob/master/keps/sig-cloud-provider/2392-cloud-controller-manager/README.md&#34;&gt;KEP-2392&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;API server network proxy&lt;/strong&gt; (&lt;a href=&#34;https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/1281-network-proxy&#34;&gt;KEP-1281&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;kubelet credential provider plugins&lt;/strong&gt; (&lt;a href=&#34;https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/2133-kubelet-credential-providers&#34;&gt;KEP-2133&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Storage migration to use &lt;a href=&#34;https://github.com/container-storage-interface/spec?tab=readme-ov-file#container-storage-interface-csi-specification-&#34;&gt;CSI&lt;/a&gt;&lt;/strong&gt; (&lt;a href=&#34;https://github.com/kubernetes/enhancements/blob/master/keps/sig-storage/625-csi-migration/README.md&#34;&gt;KEP-625&lt;/a&gt;)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/architecture/cloud-controller/&#34;&gt;cloud controller manager is part of the control plane&lt;/a&gt;. It is a critical component
that replaces some functionality that existed previously in the kube-controller-manager and the
kubelet.&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/images/docs/components-of-kubernetes.svg&#34;
         alt=&#34;Components of Kubernetes&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;Components of Kubernetes&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;One of the most critical functionalities of the cloud controller manager is the node controller,
which is responsible for the initialization of the nodes.&lt;/p&gt;
&lt;p&gt;As you can see in the following diagram, when the &lt;strong&gt;kubelet&lt;/strong&gt; starts, it registers the Node
object with the apiserver, Tainting the node so it can be processed first by the
cloud-controller-manager. The initial Node is missing the cloud-provider specific information,
like the Node Addresses and the Labels with the cloud provider specific information like the
Node, Region and Instance type information.&lt;/p&gt;


&lt;figure class=&#34;diagram-medium &#34;&gt;
    &lt;img src=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2025/02/14/cloud-controller-manager-chicken-egg-problem/ccm-chicken-egg-problem-sequence-diagram.svg&#34;
         alt=&#34;Chicken and egg problem sequence diagram&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;Chicken and egg problem sequence diagram&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;This new initialization process adds some latency to the node readiness. Previously, the kubelet
was able to initialize the node at the same time it created the node. Since the logic has moved
to the cloud-controller-manager, this can cause a &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/tasks/administer-cluster/running-cloud-controller/#chicken-and-egg&#34;&gt;chicken and egg problem&lt;/a&gt;
during the cluster bootstrapping for those Kubernetes architectures that do not deploy the
controller manager as the other components of the control plane, commonly as static pods,
standalone binaries or daemonsets/deployments with tolerations to the taints and using
&lt;code&gt;hostNetwork&lt;/code&gt; (more on this below)&lt;/p&gt;
&lt;h2 id=&#34;examples-of-the-dependency-problem&#34;&gt;Examples of the dependency problem&lt;/h2&gt;
&lt;p&gt;As noted above, it is possible during bootstrapping for the cloud-controller-manager to be
unschedulable and as such the cluster will not initialize properly. The following are a few
concrete examples of how this problem can be expressed and the root causes for why they might
occur.&lt;/p&gt;
&lt;p&gt;These examples assume you are running your cloud-controller-manager using a Kubernetes resource
(e.g. Deployment, DaemonSet, or similar) to control its lifecycle. Because these methods
rely on Kubernetes to schedule the cloud-controller-manager, care must be taken to ensure it
will schedule properly.&lt;/p&gt;
&lt;h3 id=&#34;example-cloud-controller-manager-not-scheduling-due-to-uninitialized-taint&#34;&gt;Example: Cloud controller manager not scheduling due to uninitialized taint&lt;/h3&gt;
&lt;p&gt;As &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/tasks/administer-cluster/running-cloud-controller/#running-cloud-controller-manager&#34;&gt;noted in the Kubernetes documentation&lt;/a&gt;, when the kubelet is started with the command line
flag &lt;code&gt;--cloud-provider=external&lt;/code&gt;, its corresponding &lt;code&gt;Node&lt;/code&gt; object will have a no schedule taint
named &lt;code&gt;node.cloudprovider.kubernetes.io/uninitialized&lt;/code&gt; added. Because the cloud-controller-manager
is responsible for removing the no schedule taint, this can create a situation where a
cloud-controller-manager that is being managed by a Kubernetes resource, such as a &lt;code&gt;Deployment&lt;/code&gt;
or &lt;code&gt;DaemonSet&lt;/code&gt;, may not be able to schedule.&lt;/p&gt;
&lt;p&gt;If the cloud-controller-manager is not able to be scheduled during the initialization of the
control plane, then the resulting &lt;code&gt;Node&lt;/code&gt; objects will all have the
&lt;code&gt;node.cloudprovider.kubernetes.io/uninitialized&lt;/code&gt; no schedule taint. It also means that this taint
will not be removed as the cloud-controller-manager is responsible for its removal. If the no
schedule taint is not removed, then critical workloads, such as the container network interface
controllers, will not be able to schedule, and the cluster will be left in an unhealthy state.&lt;/p&gt;
&lt;h3 id=&#34;example-cloud-controller-manager-not-scheduling-due-to-not-ready-taint&#34;&gt;Example: Cloud controller manager not scheduling due to not-ready taint&lt;/h3&gt;
&lt;p&gt;The next example would be possible in situations where the container network interface (CNI) is
waiting for IP address information from the cloud-controller-manager (CCM), and the CCM has not
tolerated the taint which would be removed by the CNI.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/reference/labels-annotations-taints/#node-kubernetes-io-not-ready&#34;&gt;Kubernetes documentation describes&lt;/a&gt; the &lt;code&gt;node.kubernetes.io/not-ready&lt;/code&gt; taint as follows:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;The Node controller detects whether a Node is ready by monitoring its health and adds or removes this taint accordingly.&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;One of the conditions that can lead to a Node resource having this taint is when the container
network has not yet been initialized on that node. As the cloud-controller-manager is responsible
for adding the IP addresses to a Node resource, and the IP addresses are needed by the container
network controllers to properly configure the container network, it is possible in some
circumstances for a node to become stuck as not ready and uninitialized permanently.&lt;/p&gt;
&lt;p&gt;This situation occurs for a similar reason as the first example, although in this case, the
&lt;code&gt;node.kubernetes.io/not-ready&lt;/code&gt; taint is used with the no execute effect and thus will cause the
cloud-controller-manager not to run on the node with the taint. If the cloud-controller-manager is
not able to execute, then it will not initialize the node. It will cascade into the container
network controllers not being able to run properly, and the node will end up carrying both the
&lt;code&gt;node.cloudprovider.kubernetes.io/uninitialized&lt;/code&gt; and &lt;code&gt;node.kubernetes.io/not-ready&lt;/code&gt; taints,
leaving the cluster in an unhealthy state.&lt;/p&gt;
&lt;h2 id=&#34;our-recommendations&#34;&gt;Our Recommendations&lt;/h2&gt;
&lt;p&gt;There is no one “correct way” to run a cloud-controller-manager. The details will depend on the
specific needs of the cluster administrators and users. When planning your clusters and the
lifecycle of the cloud-controller-managers please consider the following guidance:&lt;/p&gt;
&lt;p&gt;For cloud-controller-managers running in the same cluster, they are managing.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Use host network mode, rather than the pod network: in most cases, a cloud controller manager
will need to communicate with an API service endpoint associated with the infrastructure.
Setting “hostNetwork” to true will ensure that the cloud controller is using the host
networking instead of the container network and, as such, will have the same network access as
the host operating system. It will also remove the dependency on the networking plugin. This
will ensure that the cloud controller has access to the infrastructure endpoint (always check
your networking configuration against your infrastructure provider’s instructions).&lt;/li&gt;
&lt;li&gt;Use a scalable resource type. &lt;code&gt;Deployments&lt;/code&gt; and &lt;code&gt;DaemonSets&lt;/code&gt; are useful for controlling the
lifecycle of a cloud controller. They allow easy access to running multiple copies for redundancy
as well as using the Kubernetes scheduling to ensure proper placement in the cluster. When using
these primitives to control the lifecycle of your cloud controllers and running multiple
replicas, you must remember to enable leader election, or else your controllers will collide
with each other which could lead to nodes not being initialized in the cluster.&lt;/li&gt;
&lt;li&gt;Target the controller manager containers to the control plane. There might exist other
controllers which need to run outside the control plane (for example, Azure’s node manager
controller). Still, the controller managers themselves should be deployed to the control plane.
Use a node selector or affinity stanza to direct the scheduling of cloud controllers to the
control plane to ensure that they are running in a protected space. Cloud controllers are vital
to adding and removing nodes to a cluster as they form a link between Kubernetes and the
physical infrastructure. Running them on the control plane will help to ensure that they run
with a similar priority as other core cluster controllers and that they have some separation
from non-privileged user workloads.
&lt;ol&gt;
&lt;li&gt;It is worth noting that an anti-affinity stanza to prevent cloud controllers from running
on the same host is also very useful to ensure that a single node failure will not degrade
the cloud controller performance.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Ensure that the tolerations allow operation. Use tolerations on the manifest for the cloud
controller container to ensure that it will schedule to the correct nodes and that it can run
in situations where a node is initializing. This means that cloud controllers should tolerate
the &lt;code&gt;node.cloudprovider.kubernetes.io/uninitialized&lt;/code&gt; taint, and it should also tolerate any
taints associated with the control plane (for example, &lt;code&gt;node-role.kubernetes.io/control-plane&lt;/code&gt;
or &lt;code&gt;node-role.kubernetes.io/master&lt;/code&gt;). It can also be useful to tolerate the
&lt;code&gt;node.kubernetes.io/not-ready&lt;/code&gt; taint to ensure that the cloud controller can run even when the
node is not yet available for health monitoring.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For cloud-controller-managers that will not be running on the cluster they manage (for example,
in a hosted control plane on a separate cluster), then the rules are much more constrained by the
dependencies of the environment of the cluster running the cloud-controller-manager. The advice
for running on a self-managed cluster may not be appropriate as the types of conflicts and network
constraints will be different. Please consult the architecture and requirements of your topology
for these scenarios.&lt;/p&gt;
&lt;h3 id=&#34;example&#34;&gt;Example&lt;/h3&gt;
&lt;p&gt;This is an example of a Kubernetes Deployment highlighting the guidance shown above. It is
important to note that this is for demonstration purposes only, for production uses please
consult your cloud provider’s documentation.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app.kubernetes.io/name: cloud-controller-manager
  name: cloud-controller-manager
  namespace: kube-system
spec:
  replicas: 2
  selector:
    matchLabels:
      app.kubernetes.io/name: cloud-controller-manager
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app.kubernetes.io/name: cloud-controller-manager
      annotations:
        kubernetes.io/description: Cloud controller manager for my infrastructure
    spec:
      containers: # the container details will depend on your specific cloud controller manager
      - name: cloud-controller-manager
        command:
        - /bin/my-infrastructure-cloud-controller-manager
        - --leader-elect=true
        - -v=1
        image: registry/my-infrastructure-cloud-controller-manager@latest
        resources:
          requests:
            cpu: 200m
            memory: 50Mi
      hostNetwork: true # these Pods are part of the control plane
      nodeSelector:
        node-role.kubernetes.io/control-plane: &amp;#34;&amp;#34;
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - topologyKey: &amp;#34;kubernetes.io/hostname&amp;#34;
            labelSelector:
              matchLabels:
                app.kubernetes.io/name: cloud-controller-manager
      tolerations:
      - effect: NoSchedule
        key: node-role.kubernetes.io/master
        operator: Exists
      - effect: NoExecute
        key: node.kubernetes.io/unreachable
        operator: Exists
        tolerationSeconds: 120
      - effect: NoExecute
        key: node.kubernetes.io/not-ready
        operator: Exists
        tolerationSeconds: 120
      - effect: NoSchedule
        key: node.cloudprovider.kubernetes.io/uninitialized
        operator: Exists
      - effect: NoSchedule
        key: node.kubernetes.io/not-ready
        operator: Exists
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;When deciding how to deploy your cloud controller manager it is worth noting that
cluster-proportional, or resource-based, pod autoscaling is not recommended. Running multiple
replicas of a cloud controller manager is good practice for ensuring high-availability and
redundancy, but does not contribute to better performance. In general, only a single instance
of a cloud controller manager will be reconciling a cluster at any given time.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Spotlight on SIG Architecture: Enhancements</title>
      <link>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2025/01/21/sig-architecture-enhancements/</link>
      <pubDate>Tue, 21 Jan 2025 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2025/01/21/sig-architecture-enhancements/</guid>
      <description>
        
        
        &lt;p&gt;&lt;em&gt;This is the fourth interview of a SIG Architecture Spotlight series that will cover the different
subprojects, and we will be covering &lt;a href=&#34;https://github.com/kubernetes/community/blob/master/sig-architecture/README.md#enhancements&#34;&gt;SIG Architecture:
Enhancements&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;In this SIG Architecture spotlight we talked with &lt;a href=&#34;https://github.com/kikisdeliveryservice&#34;&gt;Kirsten
Garrison&lt;/a&gt;, lead of the Enhancements subproject.&lt;/p&gt;
&lt;h2 id=&#34;the-enhancements-subproject&#34;&gt;The Enhancements subproject&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Frederico (FSM): Hi Kirsten, very happy to have the opportunity to talk about the Enhancements
subproject. Let&#39;s start with some quick information about yourself and your role.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Kirsten Garrison (KG)&lt;/strong&gt;: I’m a lead of the Enhancements subproject of SIG-Architecture and
currently work at Google. I first got involved by contributing to the service-catalog project with
the help of &lt;a href=&#34;https://github.com/carolynvs&#34;&gt;Carolyn Van Slyck&lt;/a&gt;. With time, &lt;a href=&#34;https://github.com/kubernetes/sig-release/blob/master/releases/release-1.17/release_team.md&#34;&gt;I joined the Release
team&lt;/a&gt;,
eventually becoming the Enhancements Lead and a Release Lead shadow. While on the release team, I
worked on some ideas to make the process better for the SIGs and Enhancements team (the opt-in
process) based on my team’s experiences. Eventually, I started attending Subproject meetings and
contributing to the Subproject’s work.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;FSM: You mentioned the Enhancements subproject: how would you describe its main goals and areas of
intervention?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;KG&lt;/strong&gt;: The &lt;a href=&#34;https://github.com/kubernetes/community/blob/master/sig-architecture/README.md#enhancements&#34;&gt;Enhancements
Subproject&lt;/a&gt;
primarily concerns itself with the &lt;a href=&#34;https://github.com/kubernetes/enhancements/blob/master/keps/sig-architecture/0000-kep-process/README.md&#34;&gt;Kubernetes Enhancement
Proposal&lt;/a&gt;
(&lt;em&gt;KEP&lt;/em&gt; for short)—the &amp;quot;design&amp;quot; documents required for all features and significant changes
to the Kubernetes project.&lt;/p&gt;
&lt;h2 id=&#34;the-kep-and-its-impact&#34;&gt;The KEP and its impact&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;FSM: The improvement of the KEP process was (and is) one in which SIG Architecture was heavily
involved. Could you explain the process to those that aren’t aware of it?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;KG&lt;/strong&gt;: &lt;a href=&#34;https://kubernetes.io/releases/release/#the-release-cycle&#34;&gt;Every release&lt;/a&gt;, the SIGs let the
Release Team know which features they intend to work on to be put into the release. As mentioned
above, the prerequisite for these changes is a KEP - a standardized design document that all authors
must fill out and approve in the first weeks of the release cycle. Most features &lt;a href=&#34;https://kubernetes.io/docs/reference/command-line-tools-reference/feature-gates/#feature-stages&#34;&gt;will move
through 3
phases&lt;/a&gt;:
alpha, beta and finally GA so approving a feature represents a significant commitment for the SIG.&lt;/p&gt;
&lt;p&gt;The KEP serves as the full source of truth of a feature. The &lt;a href=&#34;https://github.com/kubernetes/enhancements/blob/master/keps/NNNN-kep-template/README.md&#34;&gt;KEP
template&lt;/a&gt;
has different requirements based on what stage a feature is in, but it generally requires a detailed
discussion of the design and the impact as well as providing artifacts of stability and
performance. The KEP takes quite a bit of iterative work between authors, SIG reviewers, api review
team and the Production Readiness Review team&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; before it is approved. Each set of reviewers is
looking to make sure that the proposal meets their standards in order to have a stable and
performant Kubernetes release. Only after all approvals are secured, can an author go forth and
merge their feature in the Kubernetes code base.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;FSM: I see, quite a bit of additional structure was added. Looking back, what were the most
significant improvements of that approach?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;KG&lt;/strong&gt;: In general, I think that the improvements with the most impact had to do with focusing on
the core intent of the KEP. KEPs exist not just to memorialize designs, but provide a structured way
to discuss and come to an agreement about different facets of the change. At the core of the KEP
process is communication and consideration.&lt;/p&gt;
&lt;p&gt;To that end, some of the significant changes revolve around a more detailed and accessible KEP
template. A significant amount of work was put in over time to get the
&lt;a href=&#34;https://github.com/kubernetes/enhancements&#34;&gt;k/enhancements&lt;/a&gt; repo into its current form -- a
directory structure organized by SIG with the contours of the modern KEP template (with
Proposal/Motivation/Design Details subsections). We might take that basic structure for granted
today, but it really represents the work of many people trying to get the foundation of this process
in place over time.&lt;/p&gt;
&lt;p&gt;As Kubernetes matures, we’ve needed to think about more than just the end goal of getting a single
feature merged. We need to think about things like: stability, performance, setting and meeting user
expectations. And as we’ve thought about those things the template has grown more detailed. The
addition of the Production Readiness Review was major as well as the enhanced testing requirements
(varying at different stages of a KEP’s lifecycle).&lt;/p&gt;
&lt;h2 id=&#34;current-areas-of-focus&#34;&gt;Current areas of focus&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;FSM: Speaking of maturing, we’ve &lt;a href=&#34;https://kubernetes.io/blog/2024/08/13/kubernetes-v1-31-release/&#34;&gt;recently released Kubernetes
v1.31&lt;/a&gt;, and work on v1.32 &lt;a href=&#34;https://github.com/fsmunoz/sig-release/tree/release-1.32/releases/release-1.32&#34;&gt;has
started&lt;/a&gt;. Are there
any areas that the Enhancements sub-project is currently addressing that might change the way things
are done?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;KG&lt;/strong&gt;: We’re currently working on two things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;em&gt;Creating a Process KEP template.&lt;/em&gt; Sometimes people want to harness the KEP process for
significant changes that are more process oriented rather than feature oriented. We want to
support this because memorializing changes is important and giving people a better tool to do so
will only encourage more discussion and transparency.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;KEP versioning.&lt;/em&gt; While our template changes aim to be as non-disruptive as possible, we
believe that it will be easier to track and communicate those changes to the community better with
a versioned KEP template and the policies that go alongside such versioning.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Both features will take some time to get right and fully roll out (just like a KEP feature) but we
believe that they will both provide improvements that will benefit the community at large.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;FSM: You mentioned improvements: I remember when project boards for Enhancement tracking were
introduced in recent releases, to great effect and unanimous applause from release team members. Was
this a particular area of focus for the subproject?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;KG&lt;/strong&gt;: The Subproject provided support to the Release Team’s Enhancement team in the migration away
from using the spreadsheet to a project board. The collection and tracking of enhancements has
always been a logistical challenge. During my time on the Release Team, I helped with the transition
to an opt-in system of enhancements, whereby the SIG leads &amp;quot;opt-in&amp;quot; KEPs for release tracking. This
helped to enhance communication between authors and SIGs before any significant work was undertaken
on a KEP and removed toil from the Enhancements team. This change used the existing tools to avoid
introducing too many changes at once to the community. Later, the Release Team approached the
Subproject with an idea of leveraging GitHub Project Boards to further improve the collection
process. This was to be a move away from the use of complicated spreadsheets to using repo-native
labels on &lt;a href=&#34;https://github.com/kubernetes/enhancements&#34;&gt;k/enhancement&lt;/a&gt; issues and project boards.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;FSM: That surely adds an impact on simplifying the workflow...&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;KG&lt;/strong&gt;: Removing sources of friction and promoting clear communication is very important to the
Enhancements Subproject.  At the same time, it’s important to give careful consideration to
decisions that impact the community as a whole. We want to make sure that changes are balanced to
give an upside and while not causing any regressions and pain in the rollout. We supported the
Release Team in ideation as well as through the actual migration to the project boards. It was a
great success and exciting to see the team make high impact changes that helped everyone involved in
the KEP process!&lt;/p&gt;
&lt;h2 id=&#34;getting-involved&#34;&gt;Getting involved&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;FSM: For those reading that might be curious and interested in helping, how would you describe the
required skills for participating in the sub-project?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;KG&lt;/strong&gt;: Familiarity with KEPs either via experience or taking time to look through the
kubernetes/enhancements repo is helpful. All are welcome to participate if interested - we can take
it from there.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;FSM: Excellent! Many thanks for your time and insight -- any final comments you would like to
share with our readers?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;KG&lt;/strong&gt;: The Enhancements process is one of the most important parts of Kubernetes and requires
enormous amounts of coordination and collaboration of people and teams across the project to make it
successful. I’m thankful and inspired by everyone’s continued hard work and dedication to making the
project great. This is truly a wonderful community.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;For more information, check the &lt;a href=&#34;https://kubernetes.io/blog/2023/11/02/sig-architecture-production-readiness-spotlight-2023/&#34;&gt;Production Readiness Review spotlight
interview&lt;/a&gt;
in this series.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes 1.32: Moving Volume Group Snapshots to Beta</title>
      <link>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/12/18/kubernetes-1-32-volume-group-snapshot-beta/</link>
      <pubDate>Wed, 18 Dec 2024 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/12/18/kubernetes-1-32-volume-group-snapshot-beta/</guid>
      <description>
        
        
        &lt;p&gt;Volume group snapshots were &lt;a href=&#34;https://deploy-preview-50011--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 1.27 release.
The recent release of Kubernetes v1.32 moved that support to &lt;strong&gt;beta&lt;/strong&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 PersistentVolumeClaims
for snapshotting.
A key aim is to allow you 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 new 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;/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;h2 id=&#34;why-add-volume-group-snapshots-to-kubernetes&#34;&gt;Why add volume group snapshots to Kubernetes?&lt;/h2&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.&lt;/p&gt;
&lt;p&gt;Underpinning all these features is the Kubernetes goal of workload portability:
Kubernetes aims to create an abstraction layer between distributed applications and
underlying clusters so that applications can be agnostic to the specifics of the
cluster they run on and application deployment requires no cluster specific knowledge.&lt;/p&gt;
&lt;p&gt;There was already a &lt;a href=&#34;https://deploy-preview-50011--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, there are other snapshotting functionalities
not covered by the VolumeSnapshot API.&lt;/p&gt;
&lt;p&gt;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 can be useful for applications that contain multiple volumes. For example,
an application may have data stored in one volume and logs stored in another volume.
If snapshots for the data volume and the logs volume are taken at different times,
the application will not be consistent and will not function properly if it is restored
from those snapshots when a disaster strikes.&lt;/p&gt;
&lt;p&gt;It is true that you can quiesce the application first, take an individual snapshot from
each volume that is part of the application one after the other, and then unquiesce the
application after all the individual snapshots are taken. This way, you would get
application consistent snapshots.&lt;/p&gt;
&lt;p&gt;However, sometimes the application quiesce can be so time consuming that you want to do it less frequently,
or it may not be possible to quiesce an application at all.
For example, a user may want to run weekly backups with application quiesce
and nightly backups without application quiesce but with consistent group support which
provides crash consistency across all volumes in the group.&lt;/p&gt;
&lt;h2 id=&#34;kubernetes-apis-for-volume-group-snapshots&#34;&gt;Kubernetes APIs for volume group snapshots&lt;/h2&gt;
&lt;p&gt;Kubernetes&#39; support for &lt;em&gt;volume group snapshots&lt;/em&gt; 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 perhaps by your own automation) to request
creation of a volume group snapshot for multiple persistent volume claims.
It contains information about the volume group snapshot operation such as the
timestamp when the volume group snapshot was taken and whether it is ready to use.
The creation and deletion of this object represents a desire to create or delete a
cluster resource (a group snapshot).&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 volume group snapshot including the volume group
snapshot ID.
This object represents a provisioned resource on the cluster (a group snapshot).
The VolumeGroupSnapshotContent 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
&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/extend-kubernetes/api-extension/custom-resources/&#34;&gt;CustomResourceDefinitions&lt;/a&gt;
(CRDs).
These CRDs must be installed in a Kubernetes cluster for a CSI Driver to support
volume group snapshots.&lt;/p&gt;
&lt;h2 id=&#34;what-components-are-needed-to-support-volume-group-snapshots&#34;&gt;What components are needed to support volume group snapshots&lt;/h2&gt;
&lt;p&gt;Volume group snapshots are implemented in the
&lt;a href=&#34;https://github.com/kubernetes-csi/external-snapshotter&#34;&gt;external-snapshotter&lt;/a&gt; repository.
Implementing volume group snapshots meant adding or changing several components:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Added new CustomResourceDefinitions for VolumeGroupSnapshot and two supporting APIs.&lt;/li&gt;
&lt;li&gt;Volume group snapshot controller logic is added to the common snapshot controller.&lt;/li&gt;
&lt;li&gt;Adding logic to make CSI calls into the snapshotter sidecar controller.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The volume snapshot controller and CRDs are deployed once per
cluster, while the sidecar is bundled with each CSI driver.&lt;/p&gt;
&lt;p&gt;Therefore, it makes sense to deploy the volume snapshot controller and CRDs as a cluster addon.&lt;/p&gt;
&lt;p&gt;The Kubernetes project recommends that Kubernetes distributors
bundle and deploy the volume snapshot controller and CRDs as part
of their Kubernetes cluster management process (independent of any CSI Driver).&lt;/p&gt;
&lt;h2 id=&#34;what-s-new-in-beta&#34;&gt;What&#39;s new in Beta?&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The VolumeGroupSnapshot feature in CSI spec moved to GA in the &lt;a href=&#34;https://github.com/container-storage-interface/spec/releases/tag/v1.11.0&#34;&gt;v1.11.0 release&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The snapshot validation webhook was deprecated in external-snapshotter v8.0.0 and it is now removed.
Most of the validation webhook logic was added as validation rules into the CRDs.
Minimum required Kubernetes version is 1.25 for these validation rules.
One thing in the validation webhook not moved to CRDs is the prevention of creating
multiple default volume snapshot classes and multiple default volume group snapshot classes
for the same CSI driver.
With the removal of the validation webhook, an error will still be raised when dynamically
provisioning a VolumeSnapshot or VolumeGroupSnapshot when multiple default volume snapshot
classes or multiple default volume group snapshot classes for the same CSI driver exist.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;enable-volumegroup-snapshot&lt;/code&gt; flag in the snapshot-controller and the CSI snapshotter
sidecar has been replaced by a feature gate.
Since VolumeGroupSnapshot is a new API, the feature moves to Beta but the feature gate is
disabled by default.
To use this feature, enable the feature gate by adding the flag &lt;code&gt;--feature-gates=CSIVolumeGroupSnapshot=true&lt;/code&gt;
when starting the snapshot-controller and the CSI snapshotter sidecar.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The logic to dynamically create the VolumeGroupSnapshot and its corresponding individual
VolumeSnapshot and VolumeSnapshotContent objects are moved from the CSI snapshotter to the common
snapshot-controller.
New RBAC rules are added to the common snapshot-controller and some RBAC rules are removed from
the CSI snapshotter sidecar accordingly.&lt;/p&gt;
&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;/h2&gt;
&lt;h3 id=&#34;creating-a-new-group-snapshot-with-kubernetes&#34;&gt;Creating a new group snapshot with Kubernetes&lt;/h3&gt;
&lt;p&gt;Once a VolumeGroupSnapshotClass object is defined and you have volumes you want to
snapshot together, you may request a new group snapshot by creating a VolumeGroupSnapshot
object.&lt;/p&gt;
&lt;p&gt;The source of the group snapshot specifies whether the underlying group snapshot
should be dynamically created or if a pre-existing VolumeGroupSnapshotContent
should be used.&lt;/p&gt;
&lt;p&gt;A pre-existing VolumeGroupSnapshotContent is created by a cluster administrator.
It contains the details of the real volume group snapshot on the storage system which
is available for use by cluster users.&lt;/p&gt;
&lt;p&gt;One of the following members in the source of the group snapshot must be set.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;selector&lt;/code&gt; - a label query over PersistentVolumeClaims that are to be grouped
together for snapshotting. This selector will be used to match the label
added to a PVC.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;volumeGroupSnapshotContentName&lt;/code&gt; - specifies the name of a pre-existing
VolumeGroupSnapshotContent object representing an existing volume group snapshot.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;dynamically-provision-a-group-snapshot&#34;&gt;Dynamically provision a group snapshot&lt;/h4&gt;
&lt;p&gt;In the following example, there are two PVCs.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;NAME    STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS      VOLUMEATTRIBUTESCLASS   AGE
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;pvc-0   Bound    pvc-6e1f7d34-a5c5-4548-b104-01e72c72b9f2   100Mi      RWO            csi-hostpath-sc   &amp;lt;unset&amp;gt;                 2m15s
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;pvc-1   Bound    pvc-abc640b3-2cc1-4c56-ad0c-4f0f0e636efa   100Mi      RWO            csi-hostpath-sc   &amp;lt;unset&amp;gt;                 2m7s
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Label the PVCs.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;%&lt;/span&gt; kubectl label pvc pvc-0 &lt;span style=&#34;color:#b8860b&#34;&gt;group&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;myGroup
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;persistentvolumeclaim/pvc-0 labeled
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;&lt;/span&gt;&lt;span style=&#34;&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;%&lt;/span&gt; kubectl label pvc pvc-1 &lt;span style=&#34;color:#b8860b&#34;&gt;group&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;myGroup
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#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; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;groupsnapshot.storage.k8s.io/v1beta1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;VolumeGroupSnapshot&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;snapshot-daily-20241217&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;namespace&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;demo-namespace&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;spec&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;volumeGroupSnapshotClassName&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;csi-groupSnapclass&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;source&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;selector&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;matchLabels&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;group&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;myGroup&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In the VolumeGroupSnapshot spec, a user can specify the VolumeGroupSnapshotClass which
has the information about which CSI driver should be used for creating the group snapshot.
A VolumGroupSnapshotClass is required for dynamic provisioning.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;groupsnapshot.storage.k8s.io/v1beta1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;VolumeGroupSnapshotClass&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;csi-groupSnapclass&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;annotations&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kubernetes.io/description&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;Example group snapshot class&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;driver&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;example.csi.k8s.io&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;deletionPolicy&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Delete&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;As a result of the volume group snapshot creation, a corresponding VolumeGroupSnapshotContent
object will be created with a volumeGroupSnapshotHandle pointing to a resource on the storage
system.&lt;/p&gt;
&lt;p&gt;Two individual volume snapshots will be created as part of the volume group snapshot creation.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;NAME                                                                        READYTOUSE   SOURCEPVC   RESTORESIZE   SNAPSHOTCONTENT                                                                AGE
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;snapshot-0962a745b2bf930bb385b7b50c9b08af471f1a16780726de19429dd9c94eaca0   true         pvc-0       100Mi         snapcontent-0962a745b2bf930bb385b7b50c9b08af471f1a16780726de19429dd9c94eaca0   16m
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;snapshot-da577d76bd2106c410616b346b2e72440f6ec7b12a75156263b989192b78caff   true         pvc-1       100Mi         snapcontent-da577d76bd2106c410616b346b2e72440f6ec7b12a75156263b989192b78caff   16m
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;importing-an-existing-group-snapshot-with-kubernetes&#34;&gt;Importing an existing group snapshot with Kubernetes&lt;/h4&gt;
&lt;p&gt;To import a pre-existing volume group snapshot into Kubernetes, you must also import
the corresponding individual volume snapshots.&lt;/p&gt;
&lt;p&gt;Identify the individual volume snapshot handles, manually construct a
VolumeSnapshotContent object first, then create a VolumeSnapshot object pointing to
the VolumeSnapshotContent object. Repeat this for every individual volume snapshot.&lt;/p&gt;
&lt;p&gt;Then manually create a VolumeGroupSnapshotContent object, specifying the
volumeGroupSnapshotHandle and individual volumeSnapshotHandles already existing
on the storage system.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;groupsnapshot.storage.k8s.io/v1beta1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;VolumeGroupSnapshotContent&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;static-group-content&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;spec&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;deletionPolicy&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Delete&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;driver&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;hostpath.csi.k8s.io&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;source&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;groupSnapshotHandles&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;volumeGroupSnapshotHandle&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;e8779136-a93e-11ef-9549-66940726f2fd&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;volumeSnapshotHandles&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;- e8779147-a93e-11ef-9549-66940726f2fd&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;- e8783cd0-a93e-11ef-9549-66940726f2fd&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;volumeGroupSnapshotRef&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;static-group-snapshot&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;namespace&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;demo-namespace&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;After that create a VolumeGroupSnapshot object pointing to the VolumeGroupSnapshotContent
object.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;groupsnapshot.storage.k8s.io/v1beta1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;VolumeGroupSnapshot&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;static-group-snapshot&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;namespace&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;demo-namespace&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;spec&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;source&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;volumeGroupSnapshotContentName&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;static-group-content&lt;span style=&#34;color:#bbb&#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-in-kubernetes&#34;&gt;How to use group snapshot for restore in Kubernetes&lt;/h3&gt;
&lt;p&gt;At restore time, the user can request a new PersistentVolumeClaim to be created from
a VolumeSnapshot object that is part of a VolumeGroupSnapshot. This will trigger
provisioning of a new volume that is pre-populated with data from the specified
snapshot. The user should repeat this until all volumes are created from all the
snapshots that are part of a group snapshot.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;v1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;PersistentVolumeClaim&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;examplepvc-restored-2024-12-17&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;namespace&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;demo-namespace&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;spec&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;storageClassName&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;example-foo-nearline&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;dataSource&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;snapshot-0962a745b2bf930bb385b7b50c9b08af471f1a16780726de19429dd9c94eaca0&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;VolumeSnapshot&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;apiGroup&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;snapshot.storage.k8s.io&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;accessModes&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- ReadWriteOncePod&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;resources&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;requests&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;storage&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;100Mi&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# must be enough storage to fit the existing snapshot&lt;/span&gt;&lt;span style=&#34;color:#bbb&#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-to-my-csi-driver&#34;&gt;As a storage vendor, how do I add support for group snapshots to my CSI driver?&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;p&gt;As mentioned earlier, it is strongly recommended that Kubernetes distributors
bundle and deploy the volume snapshot controller and CRDs as part
of their Kubernetes cluster management process (independent of any CSI Driver).&lt;/p&gt;
&lt;p&gt;As part of this recommended deployment process, the Kubernetes team provides a number of
sidecar (helper) containers, including the
&lt;a href=&#34;https://kubernetes-csi.github.io/docs/external-snapshotter.html&#34;&gt;external-snapshotter sidecar container&lt;/a&gt;
which has been updated to support volume group snapshot.&lt;/p&gt;
&lt;p&gt;The external-snapshotter watches the Kubernetes API server for
VolumeGroupSnapshotContent objects, and triggers &lt;code&gt;CreateVolumeGroupSnapshot&lt;/code&gt; and
&lt;code&gt;DeleteVolumeGroupSnapshot&lt;/code&gt; operations against a CSI endpoint.&lt;/p&gt;
&lt;h2 id=&#34;what-are-the-limitations&#34;&gt;What are the limitations?&lt;/h2&gt;
&lt;p&gt;The beta implementation of volume group snapshots for Kubernetes has the following limitations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Does not support reverting an existing PVC to an earlier state represented by
a snapshot (only supports provisioning a new volume from a snapshot).&lt;/li&gt;
&lt;li&gt;No application consistency guarantees beyond any guarantees provided by the storage system
(e.g. crash consistency). See this &lt;a href=&#34;https://github.com/kubernetes/community/blob/30d06f49fba22273f31b3c616b74cf8745c19b3d/wg-data-protection/data-protection-workflows-white-paper.md#quiesce-and-unquiesce-hooks&#34;&gt;doc&lt;/a&gt;
for more discussions on application consistency.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;what-s-next&#34;&gt;What’s next?&lt;/h2&gt;
&lt;p&gt;Depending on feedback and adoption, the Kubernetes project plans to push the volume
group snapshot implementation to general availability (GA) in a future release.&lt;/p&gt;
&lt;h2 id=&#34;how-can-i-learn-more&#34;&gt;How can I learn more?&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;/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 the contributors who stepped up these last few quarters
to help the project reach 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;Cici Huang (&lt;a href=&#34;https://github.com/cici37&#34;&gt;cici37&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;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>Enhancing Kubernetes API Server Efficiency with API Streaming</title>
      <link>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/12/17/kube-apiserver-api-streaming/</link>
      <pubDate>Tue, 17 Dec 2024 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/12/17/kube-apiserver-api-streaming/</guid>
      <description>
        
        
        &lt;p&gt;Managing Kubernetes clusters efficiently is critical, especially as their size is growing.
A significant challenge with large clusters is the memory overhead caused by &lt;strong&gt;list&lt;/strong&gt; requests.&lt;/p&gt;
&lt;p&gt;In the existing implementation, the kube-apiserver processes &lt;strong&gt;list&lt;/strong&gt; requests by assembling the entire response in-memory before transmitting any data to the client.
But what if the response body is substantial, say hundreds of megabytes? Additionally, imagine a scenario where multiple &lt;strong&gt;list&lt;/strong&gt; requests flood in simultaneously, perhaps after a brief network outage.
While &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/cluster-administration/flow-control/&#34;&gt;API Priority and Fairness&lt;/a&gt; has proven to reasonably protect kube-apiserver from CPU overload, its impact is visibly smaller for memory protection.
This can be explained by the differing nature of resource consumption by a single API request - the CPU usage at any given time is capped by a constant, whereas memory, being uncompressible, can grow proportionally with the number of processed objects and is unbounded.
This situation poses a genuine risk, potentially overwhelming and crashing any kube-apiserver within seconds due to out-of-memory (OOM) conditions. To better visualize the issue, let&#39;s consider the below graph.&lt;/p&gt;


&lt;figure class=&#34;diagram-large clickable-zoom&#34;&gt;
    &lt;img src=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/12/17/kube-apiserver-api-streaming/kube-apiserver-memory_usage.png&#34;
         alt=&#34;Monitoring graph showing kube-apiserver memory usage&#34;/&gt; 
&lt;/figure&gt;
&lt;p&gt;The graph shows the memory usage of a kube-apiserver during a synthetic test.
(see the &lt;a href=&#34;#the-synthetic-test&#34;&gt;synthetic test&lt;/a&gt; section for more details).
The results clearly show that increasing the number of informers significantly boosts the server&#39;s memory consumption.
Notably, at approximately 16:40, the server crashed when serving only 16 informers.&lt;/p&gt;
&lt;h2 id=&#34;why-does-kube-apiserver-allocate-so-much-memory-for-list-requests&#34;&gt;Why does kube-apiserver allocate so much memory for list requests?&lt;/h2&gt;
&lt;p&gt;Our investigation revealed that this substantial memory allocation occurs because the server before sending the first byte to the client must:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;fetch data from the database,&lt;/li&gt;
&lt;li&gt;deserialize the data from its stored format,&lt;/li&gt;
&lt;li&gt;and finally construct the final response by converting and serializing the data into a client requested format&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This sequence results in significant temporary memory consumption.
The actual usage depends on many factors like the page size, applied filters (e.g. label selectors), query parameters, and sizes of individual objects.&lt;/p&gt;
&lt;p&gt;Unfortunately, neither &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/cluster-administration/flow-control/&#34;&gt;API Priority and Fairness&lt;/a&gt; nor Golang&#39;s garbage collection or Golang memory limits can prevent the system from exhausting memory under these conditions.
The memory is allocated suddenly and rapidly, and just a few requests can quickly deplete the available memory, leading to resource exhaustion.&lt;/p&gt;
&lt;p&gt;Depending on how the API server is run on the node, it might either be killed through OOM by the kernel when exceeding the configured memory limits during these uncontrolled spikes, or if limits are not configured it might have even worse impact on the control plane node.
And worst, after the first API server failure, the same requests will likely hit another control plane node in an HA setup with probably the same impact.
Potentially a situation that is hard to diagnose and hard to recover from.&lt;/p&gt;
&lt;h2 id=&#34;streaming-list-requests&#34;&gt;Streaming list requests&lt;/h2&gt;
&lt;p&gt;Today, we&#39;re excited to announce a major improvement.
With the graduation of the &lt;em&gt;watch list&lt;/em&gt; feature to beta in Kubernetes 1.32, client-go users can opt-in (after explicitly enabling &lt;code&gt;WatchListClient&lt;/code&gt; feature gate)
to streaming lists by switching from &lt;strong&gt;list&lt;/strong&gt; to (a special kind of) &lt;strong&gt;watch&lt;/strong&gt; requests.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Watch&lt;/strong&gt; requests are served from the &lt;em&gt;watch cache&lt;/em&gt;, an in-memory cache designed to improve scalability of read operations.
By streaming each item individually instead of returning the entire collection, the new method maintains constant memory overhead.
The API server is bound by the maximum allowed size of an object in etcd plus a few additional allocations.
This approach drastically reduces the temporary memory usage compared to traditional &lt;strong&gt;list&lt;/strong&gt; requests, ensuring a more efficient and stable system,
especially in clusters with a large number of objects of a given type or large average object sizes where despite paging memory consumption used to be high.&lt;/p&gt;
&lt;p&gt;Building on the insight gained from the synthetic test (see the &lt;a href=&#34;#the-synthetic-test&#34;&gt;synthetic test&lt;/a&gt;, we developed an automated performance test to systematically evaluate the impact of the &lt;em&gt;watch list&lt;/em&gt; feature.
This test replicates the same scenario, generating a large number of Secrets with a large payload, and scaling the number of informers to simulate heavy &lt;strong&gt;list&lt;/strong&gt; request patterns.
The automated test is executed periodically to monitor memory usage of the server with the feature enabled and disabled.&lt;/p&gt;
&lt;p&gt;The results showed significant improvements with the &lt;em&gt;watch list&lt;/em&gt; feature enabled.
With the feature turned on, the kube-apiserver’s memory consumption stabilized at approximately &lt;strong&gt;2 GB&lt;/strong&gt;.
By contrast, with the feature disabled, memory usage increased to approximately &lt;strong&gt;20GB&lt;/strong&gt;, a &lt;strong&gt;10x&lt;/strong&gt; increase!
These results confirm the effectiveness of the new streaming API, which reduces the temporary memory footprint.&lt;/p&gt;
&lt;h2 id=&#34;enabling-api-streaming-for-your-component&#34;&gt;Enabling API Streaming for your component&lt;/h2&gt;
&lt;p&gt;Upgrade to Kubernetes 1.32. Make sure your cluster uses etcd in version 3.4.31+ or 3.5.13+.
Change your client software to use watch lists. If your client code is written in Golang, you&#39;ll want to enable &lt;code&gt;WatchListClient&lt;/code&gt; for client-go.
For details on enabling that feature, read &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/08/12/feature-gates-in-client-go&#34;&gt;Introducing Feature Gates to Client-Go: Enhancing Flexibility and Control&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;what-s-next&#34;&gt;What&#39;s next?&lt;/h2&gt;
&lt;p&gt;In Kubernetes 1.32, the feature is enabled in kube-controller-manager by default despite its beta state.
This will eventually be expanded to other core components like kube-scheduler or kubelet; once the feature becomes generally available, if not earlier.
Other 3rd-party components are encouraged to opt-in to the feature during the beta phase, especially when they are at risk of accessing a large number of resources or kinds with potentially large object sizes.&lt;/p&gt;
&lt;p&gt;For the time being, &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/cluster-administration/flow-control/&#34;&gt;API Priority and Fairness&lt;/a&gt; assigns a reasonable small cost to &lt;strong&gt;list&lt;/strong&gt; requests.
This is necessary to allow enough parallelism for the average case where &lt;strong&gt;list&lt;/strong&gt; requests are cheap enough.
But it does not match the spiky exceptional situation of many and large objects.
Once the majority of the Kubernetes ecosystem has switched to &lt;em&gt;watch list&lt;/em&gt;, the &lt;strong&gt;list&lt;/strong&gt; cost estimation can be changed to larger values without risking degraded performance in the average case,
and with that increasing the protection against this kind of requests that can still hit the API server in the future.&lt;/p&gt;
&lt;h2 id=&#34;the-synthetic-test&#34;&gt;The synthetic test&lt;/h2&gt;
&lt;p&gt;In order to reproduce the issue, we conducted a manual test to understand the impact of &lt;strong&gt;list&lt;/strong&gt; requests on kube-apiserver memory usage.
In the test, we created 400 Secrets, each containing 1 MB of data, and used informers to retrieve all Secrets.&lt;/p&gt;
&lt;p&gt;The results were alarming, only 16 informers were needed to cause the test server to run out of memory and crash, demonstrating how quickly memory consumption can grow under such conditions.&lt;/p&gt;
&lt;p&gt;Special shout out to &lt;a href=&#34;https://github.com/deads2k&#34;&gt;@deads2k&lt;/a&gt; for his help in shaping this feature.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes v1.32 Adds A New CPU Manager Static Policy Option For Strict CPU Reservation</title>
      <link>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/12/16/cpumanager-strict-cpu-reservation/</link>
      <pubDate>Mon, 16 Dec 2024 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/12/16/cpumanager-strict-cpu-reservation/</guid>
      <description>
        
        
        &lt;p&gt;In Kubernetes v1.32, after years of community discussion, we are excited to introduce a
&lt;code&gt;strict-cpu-reservation&lt;/code&gt; option for the &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/tasks/administer-cluster/cpu-management-policies/#static-policy-options&#34;&gt;CPU Manager static policy&lt;/a&gt;.
This feature is currently in alpha, with the associated policy hidden by default. You can only use the
policy if you explicitly enable the alpha behavior in your cluster.&lt;/p&gt;
&lt;h2 id=&#34;understanding-the-feature&#34;&gt;Understanding the feature&lt;/h2&gt;
&lt;p&gt;The CPU Manager static policy is used to reduce latency or improve performance. The &lt;code&gt;reservedSystemCPUs&lt;/code&gt; defines an explicit CPU set for OS system daemons and kubernetes system daemons. This option is designed for Telco/NFV type use cases where uncontrolled interrupts/timers may impact the workload performance. you can use this option to define the explicit cpuset for the system/kubernetes daemons as well as the interrupts/timers, so the rest CPUs on the system can be used exclusively for workloads, with less impact from uncontrolled interrupts/timers. More details of this parameter can be found on the &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/tasks/administer-cluster/reserve-compute-resources/#explicitly-reserved-cpu-list&#34;&gt;Explicitly Reserved CPU List&lt;/a&gt; page.&lt;/p&gt;
&lt;p&gt;If you want to protect your system daemons and interrupt processing, the obvious way is to use the &lt;code&gt;reservedSystemCPUs&lt;/code&gt; option.&lt;/p&gt;
&lt;p&gt;However, until the Kubernetes v1.32 release, this isolation was only implemented for guaranteed
pods that made requests for a whole number of CPUs. At pod admission time, the kubelet only
compares the CPU &lt;em&gt;requests&lt;/em&gt; against the allocatable CPUs. In Kubernetes, limits can be higher than
the requests; the previous implementation allowed burstable and best-effort pods to use up
the capacity of &lt;code&gt;reservedSystemCPUs&lt;/code&gt;, which could then starve host OS services of CPU - and we
know that people saw this in real life deployments.
The existing behavior also made benchmarking (for both infrastructure and workloads) results inaccurate.&lt;/p&gt;
&lt;p&gt;When this new &lt;code&gt;strict-cpu-reservation&lt;/code&gt; policy option is enabled, the CPU Manager static policy will not allow any workload to use the reserved system CPU cores.&lt;/p&gt;
&lt;h2 id=&#34;enabling-the-feature&#34;&gt;Enabling the feature&lt;/h2&gt;
&lt;p&gt;To enable this feature, you need to turn on both the &lt;code&gt;CPUManagerPolicyAlphaOptions&lt;/code&gt; feature gate and the &lt;code&gt;strict-cpu-reservation&lt;/code&gt; policy option. And you need to remove the &lt;code&gt;/var/lib/kubelet/cpu_manager_state&lt;/code&gt; file if it exists and restart kubelet.&lt;/p&gt;
&lt;p&gt;With the following kubelet configuration:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;KubeletConfiguration&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;kubelet.config.k8s.io/v1beta1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;featureGates&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;...&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;CPUManagerPolicyOptions&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;true&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;CPUManagerPolicyAlphaOptions&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;true&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;cpuManagerPolicy&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;static&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;cpuManagerPolicyOptions&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;strict-cpu-reservation&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;true&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;reservedSystemCPUs&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;0,32,1,33,16,48&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#00f;font-weight:bold&#34;&gt;...&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;When &lt;code&gt;strict-cpu-reservation&lt;/code&gt; is not set or set to false:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;#&lt;/span&gt; cat /var/lib/kubelet/cpu_manager_state
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;{&amp;#34;policyName&amp;#34;:&amp;#34;static&amp;#34;,&amp;#34;defaultCpuSet&amp;#34;:&amp;#34;0-63&amp;#34;,&amp;#34;checksum&amp;#34;:1058907510}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;When &lt;code&gt;strict-cpu-reservation&lt;/code&gt; is set to true:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;#&lt;/span&gt; cat /var/lib/kubelet/cpu_manager_state
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;{&amp;#34;policyName&amp;#34;:&amp;#34;static&amp;#34;,&amp;#34;defaultCpuSet&amp;#34;:&amp;#34;2-15,17-31,34-47,49-63&amp;#34;,&amp;#34;checksum&amp;#34;:4141502832}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;monitoring-the-feature&#34;&gt;Monitoring the feature&lt;/h2&gt;
&lt;p&gt;You can monitor the feature impact by checking the following CPU Manager counters:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;cpu_manager_shared_pool_size_millicores&lt;/code&gt;: report shared pool size, in millicores (e.g. 13500m)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cpu_manager_exclusive_cpu_allocation_count&lt;/code&gt;: report exclusively allocated cores, counting full cores (e.g. 16)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Your best-effort workloads may starve if the &lt;code&gt;cpu_manager_shared_pool_size_millicores&lt;/code&gt; count is zero for prolonged time.&lt;/p&gt;
&lt;p&gt;We believe any pod that is required for operational purpose like a log forwarder should not run as best-effort, but you can review and adjust the amount of CPU cores reserved as needed.&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Strict CPU reservation is critical for Telco/NFV use cases. It is also a prerequisite for enabling the all-in-one type of deployments where workloads are placed on nodes serving combined control+worker+storage roles.&lt;/p&gt;
&lt;p&gt;We want you to start using the feature and looking forward to your feedback.&lt;/p&gt;
&lt;h2 id=&#34;further-reading&#34;&gt;Further reading&lt;/h2&gt;
&lt;p&gt;Please check out the &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/tasks/administer-cluster/cpu-management-policies/&#34;&gt;Control CPU Management Policies on the Node&lt;/a&gt;
task page to learn more about the CPU Manager, and how it fits in relation to the other node-level resource managers.&lt;/p&gt;
&lt;h2 id=&#34;getting-involved&#34;&gt;Getting involved&lt;/h2&gt;
&lt;p&gt;This feature is driven by the &lt;a href=&#34;https://github.com/Kubernetes/community/blob/master/sig-node/README.md&#34;&gt;SIG Node&lt;/a&gt;. If you are interested in helping develop this feature, sharing feedback, or participating in any other ongoing SIG Node projects, please attend the SIG Node meeting for more details.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes v1.32: Memory Manager Goes GA</title>
      <link>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/12/13/memory-manager-goes-ga/</link>
      <pubDate>Fri, 13 Dec 2024 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/12/13/memory-manager-goes-ga/</guid>
      <description>
        
        
        &lt;p&gt;With Kubernetes 1.32, the memory manager has officially graduated to General Availability (GA),
marking a significant milestone in the journey toward efficient and predictable memory allocation for containerized applications.
Since Kubernetes v1.22, where it graduated to beta, the memory manager has proved itself reliable, stable and a good complementary feature for the
&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/tasks/administer-cluster/cpu-management-policies/&#34;&gt;CPU Manager&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;As part of kubelet&#39;s workload admission process,
the memory manager provides topology hints
to optimize memory allocation and alignment.
This enables users to allocate exclusive
memory for Pods in the &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/workloads/pods/pod-qos/#guaranteed&#34;&gt;Guaranteed&lt;/a&gt; QoS class.
More details about the process can be found in the memory manager goes to beta &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2021/08/11/kubernetes-1-22-feature-memory-manager-moves-to-beta/&#34;&gt;blog&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Most of the changes introduced since the Beta are bug fixes, internal refactoring and
observability improvements, such as metrics and better logging.&lt;/p&gt;
&lt;h2 id=&#34;observability-improvements&#34;&gt;Observability improvements&lt;/h2&gt;
&lt;p&gt;As part of the effort
to increase the observability of memory manager, new metrics have been added
to provide some statistics on memory allocation patterns.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;memory_manager_pinning_requests_total&lt;/strong&gt; -
tracks the number of times the pod spec required the memory manager to pin memory pages.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;memory_manager_pinning_errors_total&lt;/strong&gt; -
tracks the number of times the pod spec required the memory manager
to pin memory pages, but the allocation failed.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;improving-memory-manager-reliability-and-consistency&#34;&gt;Improving memory manager reliability and consistency&lt;/h2&gt;
&lt;p&gt;The kubelet does not guarantee pod ordering
when admitting pods after a restart or reboot.&lt;/p&gt;
&lt;p&gt;In certain edge cases, this behavior could cause
the memory manager to reject some pods,
and in more extreme cases, it may cause kubelet to fail upon restart.&lt;/p&gt;
&lt;p&gt;Previously, the beta implementation lacked certain checks and logic to prevent
these issues.&lt;/p&gt;
&lt;p&gt;To stabilize the memory manager for general availability (GA) readiness,
small but critical refinements have been
made to the algorithm, improving its robustness and handling of edge cases.&lt;/p&gt;
&lt;h2 id=&#34;future-development&#34;&gt;Future development&lt;/h2&gt;
&lt;p&gt;There is more to come for the future of Topology Manager in general,
and memory manager in particular.
Notably, ongoing efforts are underway
to extend &lt;a href=&#34;https://github.com/kubernetes/kubernetes/pull/128560&#34;&gt;memory manager support to Windows&lt;/a&gt;,
enabling CPU and memory affinity on a Windows operating system.&lt;/p&gt;
&lt;h2 id=&#34;getting-involved&#34;&gt;Getting involved&lt;/h2&gt;
&lt;p&gt;This feature is driven by the &lt;a href=&#34;https://github.com/Kubernetes/community/blob/master/sig-node/README.md&#34;&gt;SIG Node&lt;/a&gt; community.
Please join us to connect with the community
and share your ideas and feedback around the above feature and
beyond.
We look forward to hearing from you!&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes v1.32: QueueingHint Brings a New Possibility to Optimize Pod Scheduling</title>
      <link>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/12/12/scheduler-queueinghint/</link>
      <pubDate>Thu, 12 Dec 2024 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/12/12/scheduler-queueinghint/</guid>
      <description>
        
        
        &lt;p&gt;The Kubernetes &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/scheduling-eviction/kube-scheduler/&#34;&gt;scheduler&lt;/a&gt; is the core
component that selects the nodes on which new Pods run. The scheduler processes
these new Pods &lt;strong&gt;one by one&lt;/strong&gt;. Therefore, the larger your clusters, the more important
the throughput of the scheduler becomes.&lt;/p&gt;
&lt;p&gt;Over the years, Kubernetes SIG Scheduling has improved the throughput
of the scheduler in multiple enhancements. This blog post describes a major improvement to the
scheduler in Kubernetes v1.32: a
&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/scheduling-eviction/scheduling-framework/#extension-points&#34;&gt;scheduling context element&lt;/a&gt;
named &lt;em&gt;QueueingHint&lt;/em&gt;. This page provides background knowledge of the scheduler and explains how
QueueingHint improves scheduling throughput.&lt;/p&gt;
&lt;h2 id=&#34;scheduling-queue&#34;&gt;Scheduling queue&lt;/h2&gt;
&lt;p&gt;The scheduler stores all unscheduled Pods in an internal component called the &lt;em&gt;scheduling queue&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The scheduling queue consists of the following data structures:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ActiveQ&lt;/strong&gt;: holds newly created Pods or Pods that are ready to be retried for scheduling.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;BackoffQ&lt;/strong&gt;: holds Pods that are ready to be retried but are waiting for a backoff period to end. The
backoff period depends on the number of unsuccessful scheduling attempts performed by the scheduler on that Pod.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Unschedulable Pod Pool&lt;/strong&gt;: holds Pods that the scheduler won&#39;t attempt to schedule for one of the
following reasons:
&lt;ul&gt;
&lt;li&gt;The scheduler previously attempted and was unable to schedule the Pods. Since that attempt, the cluster
hasn&#39;t changed in a way that could make those Pods schedulable.&lt;/li&gt;
&lt;li&gt;The Pods are blocked from entering the scheduling cycles by PreEnqueue Plugins,
for example, they have a &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/scheduling-eviction/pod-scheduling-readiness/#configuring-pod-schedulinggates&#34;&gt;scheduling gate&lt;/a&gt;,
and get blocked by the scheduling gate plugin.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;scheduling-framework-and-plugins&#34;&gt;Scheduling framework and plugins&lt;/h2&gt;
&lt;p&gt;The Kubernetes scheduler is implemented following the Kubernetes
&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/scheduling-eviction/scheduling-framework/&#34;&gt;scheduling framework&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;And, all scheduling features are implemented as plugins
(e.g., &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity&#34;&gt;Pod affinity&lt;/a&gt;
is implemented in the &lt;code&gt;InterPodAffinity&lt;/code&gt; plugin.)&lt;/p&gt;
&lt;p&gt;The scheduler processes pending Pods in phases called &lt;em&gt;cycles&lt;/em&gt; as follows:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Scheduling cycle&lt;/strong&gt;: the scheduler takes pending Pods from the activeQ component of the scheduling
queue  &lt;em&gt;one by one&lt;/em&gt;. For each Pod, the scheduler runs the filtering/scoring logic from every scheduling plugin. The
scheduler then decides on the best node for the Pod, or decides that the Pod can&#39;t be scheduled at that time.&lt;/p&gt;
&lt;p&gt;If the scheduler decides that a Pod can&#39;t be scheduled, that Pod enters the Unschedulable Pod Pool
component of the scheduling queue. However, if the scheduler decides to place the Pod on a node,
the Pod goes to the binding cycle.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Binding cycle&lt;/strong&gt;: the scheduler communicates the node placement decision to the Kubernetes API
server. This operation bounds the Pod to the selected node.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Aside from some exceptions, most unscheduled Pods enter the unschedulable pod pool after each scheduling
cycle. The Unschedulable Pod Pool component is crucial because of how the scheduling cycle processes Pods one by one. If the scheduler had to constantly retry placing unschedulable Pods, instead of offloading those
Pods to the Unschedulable Pod Pool, multiple scheduling cycles would be wasted on those Pods.&lt;/p&gt;
&lt;h2 id=&#34;improvements-to-retrying-pod-scheduling-with-queuinghint&#34;&gt;Improvements to retrying Pod scheduling with QueuingHint&lt;/h2&gt;
&lt;p&gt;Unschedulable Pods only move back into the ActiveQ or BackoffQ components of the scheduling
queue if changes in the cluster might allow the scheduler to place those Pods on nodes.&lt;/p&gt;
&lt;p&gt;Prior to v1.32, each plugin registered which cluster changes could solve their failures, an object creation, update, or deletion in the cluster (called &lt;em&gt;cluster events&lt;/em&gt;),
with &lt;code&gt;EnqueueExtensions&lt;/code&gt; (&lt;code&gt;EventsToRegister&lt;/code&gt;),
and the scheduling queue retries a pod with an event that is registered by a plugin that rejected the pod in a previous scheduling cycle.&lt;/p&gt;
&lt;p&gt;Additionally, we had an internal feature called &lt;code&gt;preCheck&lt;/code&gt;, which helped further filtering of events for efficiency, based on Kubernetes core scheduling constraints;
For example, &lt;code&gt;preCheck&lt;/code&gt; could filter out node-related events when the node status is &lt;code&gt;NotReady&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;However, we had two issues for those approaches:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Requeueing with events was too broad, could lead to scheduling retries for no reason.
&lt;ul&gt;
&lt;li&gt;A new scheduled Pod &lt;em&gt;might&lt;/em&gt; solve the &lt;code&gt;InterPodAffinity&lt;/code&gt;&#39;s failure, but not all of them do.
For example, if a new Pod is created, but without a label matching &lt;code&gt;InterPodAffinity&lt;/code&gt; of the unschedulable pod, the pod wouldn&#39;t be schedulable.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;preCheck&lt;/code&gt; relied on the logic of in-tree plugins and was not extensible to custom plugins,
like in issue &lt;a href=&#34;https://github.com/kubernetes/kubernetes/issues/110175&#34;&gt;#110175&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here QueueingHints come into play;
a QueueingHint subscribes to a particular kind of cluster event, and make a decision about whether each incoming event could make the Pod schedulable.&lt;/p&gt;
&lt;p&gt;For example, consider a Pod named &lt;code&gt;pod-a&lt;/code&gt; that has a required Pod affinity. &lt;code&gt;pod-a&lt;/code&gt; was rejected in
the scheduling cycle by the &lt;code&gt;InterPodAffinity&lt;/code&gt; plugin because no node had an existing Pod that matched
the Pod affinity specification for &lt;code&gt;pod-a&lt;/code&gt;.&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/12/12/scheduler-queueinghint/queueinghint1.svg&#34;
         alt=&#34;A diagram showing the scheduling queue and pod-a rejected by InterPodAffinity plugin&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;A diagram showing the scheduling queue and pod-a rejected by InterPodAffinity plugin&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;code&gt;pod-a&lt;/code&gt; moves into the Unschedulable Pod Pool. The scheduling queue records which plugin caused
the scheduling failure for the Pod. For &lt;code&gt;pod-a&lt;/code&gt;, the scheduling queue records that the &lt;code&gt;InterPodAffinity&lt;/code&gt;
plugin rejected the Pod.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;pod-a&lt;/code&gt; will never be schedulable until the InterPodAffinity failure is resolved.
There&#39;re some scenarios that the failure could be resolved, one example is an existing running pod gets a label update and becomes matching a Pod affinity.
For this scenario, the &lt;code&gt;InterPodAffinity&lt;/code&gt; plugin&#39;s &lt;code&gt;QueuingHint&lt;/code&gt; callback function checks every Pod label update that occurs in the cluster.
Then, if a Pod gets a label update that matches the Pod affinity requirement of &lt;code&gt;pod-a&lt;/code&gt;, the &lt;code&gt;InterPodAffinity&lt;/code&gt;,
plugin&#39;s &lt;code&gt;QueuingHint&lt;/code&gt; prompts the scheduling queue to move &lt;code&gt;pod-a&lt;/code&gt; back into the ActiveQ or
the BackoffQ component.&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/12/12/scheduler-queueinghint/queueinghint2.svg&#34;
         alt=&#34;A diagram showing the scheduling queue and pod-a being moved by InterPodAffinity QueueingHint&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;A diagram showing the scheduling queue and pod-a being moved by InterPodAffinity QueueingHint&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&#34;queueinghint-s-history-and-what-s-new-in-v1-32&#34;&gt;QueueingHint&#39;s history and what&#39;s new in v1.32&lt;/h2&gt;
&lt;p&gt;At SIG Scheduling, we have been working on the development of QueueingHint since
Kubernetes v1.28.&lt;/p&gt;
&lt;p&gt;While QueuingHint isn&#39;t user-facing, we implemented the &lt;code&gt;SchedulerQueueingHints&lt;/code&gt; feature gate as a
safety measure when we originally added this feature. In v1.28, we implemented QueueingHints with a
few in-tree plugins experimentally, and made the feature gate enabled by default.&lt;/p&gt;
&lt;p&gt;However, users reported a memory leak, and consequently we disabled the feature gate in a
patch release of v1.28.  From v1.28 until v1.31, we kept working on the QueueingHint implementation
within the rest of the in-tree plugins and fixing bugs.&lt;/p&gt;
&lt;p&gt;In v1.32, we made this feature enabled by default again. We finished implementing QueueingHints
in all plugins and also identified the cause of the memory leak!&lt;/p&gt;
&lt;p&gt;We thank all the contributors who participated in the development of this feature and those who reported and investigated the earlier issues.&lt;/p&gt;
&lt;h2 id=&#34;getting-involved&#34;&gt;Getting involved&lt;/h2&gt;
&lt;p&gt;These features are managed by Kubernetes &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-scheduling&#34;&gt;SIG Scheduling&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Please join us and share your feedback.&lt;/p&gt;
&lt;h2 id=&#34;how-can-i-learn-more&#34;&gt;How can I learn more?&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/enhancements/blob/master/keps/sig-scheduling/4247-queueinghint/README.md&#34;&gt;KEP-4247: Per-plugin callback functions for efficient requeueing in the scheduling queue&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes v1.32: Penelope</title>
      <link>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/12/11/kubernetes-v1-32-release/</link>
      <pubDate>Wed, 11 Dec 2024 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/12/11/kubernetes-v1-32-release/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Editors:&lt;/strong&gt; Matteo Bianchi, Edith Puclla, William Rizzo, Ryota Sawada, Rashan Smith&lt;/p&gt;
&lt;p&gt;Announcing the release of Kubernetes v1.32: Penelope!&lt;/p&gt;
&lt;p&gt;In line with previous releases, the release of Kubernetes v1.32 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.
This release consists of 44 enhancements in total.
Of those enhancements, 13 have graduated to Stable, 12 are entering Beta, and 19 have entered in Alpha.&lt;/p&gt;
&lt;h2 id=&#34;release-theme-and-logo&#34;&gt;Release theme and logo&lt;/h2&gt;


&lt;figure class=&#34;release-logo &#34;&gt;
    &lt;img src=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/12/11/kubernetes-v1-32-release/k8s-1.32.png&#34;
         alt=&#34;Kubernetes v1.32 logo: Penelope from the Odyssey, a helm and a purple geometric background&#34;/&gt; 
&lt;/figure&gt;
&lt;p&gt;The Kubernetes v1.32 Release Theme is &amp;quot;Penelope&amp;quot;.&lt;/p&gt;
&lt;p&gt;If Kubernetes is Ancient Greek for &amp;quot;pilot&amp;quot;, in this release we start from that origin
and reflect on the last 10 years of Kubernetes and our accomplishments:
each release cycle is a journey, and just like Penelope, in &amp;quot;The Odyssey&amp;quot;,&lt;br&gt;
weaved for 10 years -- each night removing parts of what she had done during the day --
so does each release add new features and removes others, albeit here with a much
clearer purpose of constantly improving Kubernetes.
With v1.32 being the last release in the year Kubernetes marks its first decade anniversary,
we wanted to honour all of those that have been part of the global Kubernetes crew
that roams the cloud-native seas through perils and challanges:
may we continue to weave the future of Kubernetes together.&lt;/p&gt;
&lt;h2 id=&#34;updates-to-recent-key-features&#34;&gt;Updates to recent key features&lt;/h2&gt;
&lt;h3 id=&#34;a-note-on-dra-enhancements&#34;&gt;A note on DRA enhancements&lt;/h3&gt;
&lt;p&gt;In this release, like the previous one, the Kubernetes project continues proposing a number of enhancements to the
Dynamic Resource Allocation (DRA), a key component of the Kubernetes resource management system. These enhancements aim
to improve the flexibility and efficiency of resource allocation for workloads that require specialized hardware, such
as GPUs, FPGAs and network adapters.
These features are particularly useful for use-cases such as machine learning or high-performance computing
applications. The core part enabling DRA Structured parameter support &lt;a href=&#34;#structured-parameter-support&#34;&gt;got promoted to beta&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;quality-of-life-improvements-on-nodes-and-sidecar-containers-update&#34;&gt;Quality of life improvements on nodes and sidecar containers update&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-node&#34;&gt;SIG Node&lt;/a&gt; has the following highlights that go beyond
KEPs:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;The systemd watchdog capability is now used to restart the kubelet when its health check fails, while also limiting
the maximum number of restarts within a given time period. This enhances the reliability of the kubelet. For more
details, see pull request &lt;a href=&#34;https://github.com/kubernetes/kubernetes/pull/127566&#34;&gt;#127566&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In cases when an image pull back-off error is encountered, the message displayed in the Pod status has been improved
to be more human-friendly and to indicate details about why the Pod is in this condition.
When an image pull back-off occurs, the error is appended to the &lt;code&gt;status.containerStatuses[*].state.waiting.message&lt;/code&gt;
field in the Pod specification with an &lt;code&gt;ImagePullBackOff&lt;/code&gt; value in the &lt;code&gt;reason&lt;/code&gt; field. This change provides you with
more context and helps you to identify the root cause of the issue. For more details, see pull request
&lt;a href=&#34;https://github.com/kubernetes/kubernetes/pull/127918&#34;&gt;#127918&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The sidecar containers feature is targeting graduation to Stable in v1.33. To view the remaining work items and
feedback from users, see comments in the issue
&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/753#issuecomment-2350136594&#34;&gt;#753&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;highlights-of-features-graduating-to-stable&#34;&gt;Highlights of features graduating to Stable&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.32 release.&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&#34;custom-resource-field-selectors&#34;&gt;Custom Resource field selectors&lt;/h3&gt;
&lt;p&gt;Custom resource field selector allows developers to add field selectors to custom resources, mirroring the functionality
available for built-in Kubernetes objects. This allows for more efficient and precise filtering of custom resources,
promoting better API design practices.&lt;/p&gt;
&lt;p&gt;This work was done as a part of &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/4358&#34;&gt;KEP #4358&lt;/a&gt;, by &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-api-machinery&#34;&gt;SIG API
Machinery&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;support-to-size-memory-backed-volumes&#34;&gt;Support to size memory backed volumes&lt;/h3&gt;
&lt;p&gt;This feature makes it possible to dynamically size memory-backed volumes based on Pod resource limits, improving the
workload&#39;s portability and overall node resource utilization.&lt;/p&gt;
&lt;p&gt;This work was done as a part of &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/1967&#34;&gt;KEP #1967&lt;/a&gt;, by &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-node&#34;&gt;SIG
Node&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;bound-service-account-token-improvement&#34;&gt;Bound service account token improvement&lt;/h3&gt;
&lt;p&gt;The inclusion of the node name in the service account token claims allows users to use such information during
authorization and admission (ValidatingAdmissionPolicy).
Furthermore this improvement keeps service account credentials from being a privilege escalation path for nodes.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/4193&#34;&gt;KEP #4193&lt;/a&gt; by &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-auth&#34;&gt;SIG
Auth&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;structured-authorization-configuration&#34;&gt;Structured authorization configuration&lt;/h3&gt;
&lt;p&gt;Multiple authorizers can be configured in the API server to allow for structured authorization decisions,
with support for CEL match conditions in webhooks.
This work was done as part of &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/3221&#34;&gt;KEP #3221&lt;/a&gt; by &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-auth&#34;&gt;SIG
Auth&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;auto-remove-pvcs-created-by-statefulset&#34;&gt;Auto remove PVCs created by StatefulSet&lt;/h3&gt;
&lt;p&gt;PersistentVolumeClaims (PVCs) created by StatefulSets get automatically deleted when no longer needed,
while ensuring data persistence during StatefulSet updates and node maintenance.
This feature simplifies storage management for StatefulSets and reduces the risk of orphaned PVCs.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/1847&#34;&gt;KEP #1847&lt;/a&gt; by &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-apps&#34;&gt;SIG
Apps&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;highlights-of-features-graduating-to-beta&#34;&gt;Highlights of features graduating to Beta&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.32 release.&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&#34;job-api-managed-by-mechanism&#34;&gt;Job API managed-by mechanism&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;managedBy&lt;/code&gt; field for Jobs was promoted to beta in the v1.32 release. This feature enables external controllers
(like &lt;a href=&#34;https://kueue.sigs.k8s.io/&#34;&gt;Kueue&lt;/a&gt;) to manage Job synchronization, offering greater flexibility and integration
with advanced workload management systems.&lt;/p&gt;
&lt;p&gt;This work was done as a part of &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/4368&#34;&gt;KEP #4368&lt;/a&gt;, by &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-apps&#34;&gt;SIG
Apps&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;only-allow-anonymous-auth-for-configured-endpoints&#34;&gt;Only allow anonymous auth for configured endpoints&lt;/h3&gt;
&lt;p&gt;This feature lets admins specify which endpoints are allowed for anonymous requests. For example, the admin
can choose to only allow anonymous access to health endpoints like &lt;code&gt;/healthz&lt;/code&gt;, &lt;code&gt;/livez&lt;/code&gt;, and &lt;code&gt;/readyz&lt;/code&gt; while
making sure preventing anonymous access to other cluster endpoints or resources even if a user
misconfigures RBAC.&lt;/p&gt;
&lt;p&gt;This work was done as a part of &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/4633&#34;&gt;KEP #4633&lt;/a&gt;, by &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-auth&#34;&gt;SIG
Auth&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;per-plugin-callback-functions-for-accurate-requeueing-in-kube-scheduler-enhancements&#34;&gt;Per-plugin callback functions for accurate requeueing in kube-scheduler enhancements&lt;/h3&gt;
&lt;p&gt;This feature enhances scheduling throughput with more efficient scheduling retry decisions by
per-plugin callback functions (QueueingHint). All plugins now have QueueingHints.&lt;/p&gt;
&lt;p&gt;This work was done as a part of &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/4247&#34;&gt;KEP #4247&lt;/a&gt;, by &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-scheduling&#34;&gt;SIG
Scheduling&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;recover-from-volume-expansion-failure&#34;&gt;Recover from volume expansion failure&lt;/h3&gt;
&lt;p&gt;This feature lets users recover from volume expansion failure by retrying with a smaller size. This enhancement ensures
that volume expansion is more resilient and reliable, reducing the risk of data loss or corruption during the process.&lt;/p&gt;
&lt;p&gt;This work was done as a part of &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/1790&#34;&gt;KEP #1790&lt;/a&gt;, by &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-storage&#34;&gt;SIG
Storage&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;volume-group-snapshot&#34;&gt;Volume group snapshot&lt;/h3&gt;
&lt;p&gt;This feature introduces a VolumeGroupSnapshot API, which lets users take a snapshot of multiple volumes together, ensuring data consistency across the volumes.&lt;/p&gt;
&lt;p&gt;This work was done as a part of &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/3476&#34;&gt;KEP #3476&lt;/a&gt;, by &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-storage&#34;&gt;SIG
Storage&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;structured-parameter-support&#34;&gt;Structured parameter support&lt;/h3&gt;
&lt;p&gt;The core part of Dynamic Resource Allocation (DRA), the structured parameter support, got promoted to beta.
This allows the kube-scheduler and Cluster Autoscaler to simulate claim allocation directly, without needing a
third-party driver.
These components can now predict whether resource requests can be fulfilled based on the cluster&#39;s current state without actually
committing to the allocation. By eliminating the need for a third-party driver to validate or test allocations, this
feature improves planning and decision-making for resource distribution, making the scheduling and scaling processes
more efficient.&lt;/p&gt;
&lt;p&gt;This work was done as a part of &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/4381&#34;&gt;KEP #4381&lt;/a&gt;, by WG Device
Management (a cross functional team containing &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-node&#34;&gt;SIG Node&lt;/a&gt;,
&lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-scheduling&#34;&gt;SIG Scheduling&lt;/a&gt; and &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-autoscaling&#34;&gt;SIG
Autoscaling&lt;/a&gt;).&lt;/p&gt;
&lt;h3 id=&#34;label-and-field-selector-authorization&#34;&gt;Label and field selector authorization&lt;/h3&gt;
&lt;p&gt;Label and field selectors can be used in authorization decisions. The node authorizer
automatically takes advantage of this to limit nodes to list or watch their pods only.
Webhook authorizers can be updated to limit requests based on the label or field selector used.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/4601&#34;&gt;KEP #4601&lt;/a&gt;
by &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-auth&#34;&gt;SIG Auth&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;highlights-of-new-features-in-alpha&#34;&gt;Highlights of new features in Alpha&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;This is a selection of key improvements introduced as alpha features in the v1.32 release.&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&#34;asynchronous-preemption-in-the-kubernetes-scheduler&#34;&gt;Asynchronous preemption in the Kubernetes Scheduler&lt;/h3&gt;
&lt;p&gt;The Kubernetes scheduler has been enhanced with Asynchronous Preemption, a feature that improves scheduling throughput
by handling preemption operations asynchronously. Preemption ensures higher-priority pods get the resources they need by
evicting lower-priority ones, but this process previously involved heavy operations like API calls to delete pods,
slowing down the scheduler. With this enhancement, such tasks are now processed in parallel, allowing the scheduler to
continue scheduling other pods without delays.
This improvement is particularly beneficial in clusters with high Pod churn or frequent scheduling failures, ensuring a
more efficient and resilient scheduling process.&lt;/p&gt;
&lt;p&gt;This work was done as a part of KEP &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/4832&#34;&gt;#4832&lt;/a&gt;
by &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-scheduling&#34;&gt;SIG Scheduling&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;mutating-admission-policies-using-cel-expressions&#34;&gt;Mutating admission policies using CEL expressions&lt;/h3&gt;
&lt;p&gt;This feature leverages CEL&#39;s object instantiation and JSON Patch strategies, combined with Server Side Apply’s merge
algorithms. It simplifies policy definition, reduces mutation conflicts, and enhances admission control performance
while laying a foundation for more robust, extensible policy frameworks in Kubernetes.&lt;/p&gt;
&lt;p&gt;The Kubernetes API server now supports Common Expression Language (CEL)-based Mutating Admission Policies, providing a
lightweight, efficient alternative to mutating admission webhooks. With this enhancement, administrators can use CEL to
declare mutations like setting labels, defaulting fields, or injecting sidecars with simple, declarative expressions.
This approach reduces operational complexity, eliminates the need for webhooks, and integrates directly with the
kube-apiserver, offering faster and more reliable in-process mutation handling.&lt;/p&gt;
&lt;p&gt;This work was done as a part of &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/3962&#34;&gt;KEP #3962&lt;/a&gt; by &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-api-machinery&#34;&gt;SIG API
Machinery&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;pod-level-resource-specifications&#34;&gt;Pod-level resource specifications&lt;/h3&gt;
&lt;p&gt;This enhancement simplifies resource management in Kubernetes by introducing the ability to set resource requests and
limits at the Pod level, creating a shared pool that all containers in the Pod can dynamically use. This is particularly
valuable for workloads with containers that have fluctuating or bursty resource needs, as it minimizes over-provisioning
and improves overall resource efficiency.&lt;/p&gt;
&lt;p&gt;By leveraging Linux cgroup settings at the Pod level, Kubernetes ensures that these resource limits are enforced while
enabling tightly coupled containers to collaborate more effectively without hitting artificial constraints. Importantly,
this feature maintains backward compatibility with existing container-level resource settings, allowing users to adopt
it incrementally without disrupting current workflows or existing configurations.&lt;/p&gt;
&lt;p&gt;This marks a significant improvement for multi-container pods, as it reduces the operational complexity of managing
resource allocations across containers. It also provides a performance boost for tightly integrated applications, such
as sidecar architectures, where containers share workloads or depend on each other’s availability to perform optimally.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/2837&#34;&gt;KEP #2837&lt;/a&gt; by &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-node&#34;&gt;SIG
Node&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;allow-zero-value-for-sleep-action-of-prestop-hook&#34;&gt;Allow zero value for sleep action of PreStop hook&lt;/h3&gt;
&lt;p&gt;This enhancement introduces the ability to set a zero-second sleep duration for the PreStop lifecycle hook in
Kubernetes, offering a more flexible and no-op option for resource validation and customization. Previously, attempting
to define a zero value for the sleep action resulted in validation errors, restricting its use. With this update, users
can configure a zero-second duration as a valid sleep setting, enabling immediate execution and termination behaviors
where needed.&lt;/p&gt;
&lt;p&gt;The enhancement is backward-compatible, introduced as an opt-in feature controlled by the
&lt;code&gt;PodLifecycleSleepActionAllowZero&lt;/code&gt; feature gate. This change is particularly beneficial for scenarios requiring PreStop
hooks for validation or admission webhook processing without requiring an actual sleep duration. By aligning with the
capabilities of the &lt;code&gt;time.After&lt;/code&gt; Go function, this update simplifies configuration and expands usability for Kubernetes
workloads.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/4818&#34;&gt;KEP #4818&lt;/a&gt; by &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-node&#34;&gt;SIG
Node&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;dra-standardized-network-interface-data-for-resource-claim-status&#34;&gt;DRA: Standardized network interface data for resource claim status&lt;/h3&gt;
&lt;p&gt;This enhancement adds a new field that allows drivers to report specific device status data for each allocated object
in a ResourceClaim. It also establishes a standardized way to represent networking devices information.&lt;/p&gt;
&lt;p&gt;This work was done as a part of
&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/4817&#34;&gt;KEP #4817&lt;/a&gt;, by
&lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-network&#34;&gt;SIG Network&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;new-statusz-and-flagz-endpoints-for-core-components&#34;&gt;New statusz and flagz endpoints for core components&lt;/h3&gt;
&lt;p&gt;You can enable two new  HTTP endpoints, &lt;code&gt;/statusz&lt;/code&gt; and &lt;code&gt;/flagz&lt;/code&gt;, for core components.
These enhance cluster debuggability by gaining insight into what versions (e.g. Golang version) that component is
running as, along with details about its uptime, and which command line flags that component was executed with;
making it easier to diagnose both runtime and configuration issues.&lt;/p&gt;
&lt;p&gt;This work was done as part of
&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/4827&#34;&gt;KEP #4827&lt;/a&gt;
and &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/4828&#34;&gt;KEP #4828&lt;/a&gt; by
&lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-instrumentation&#34;&gt;SIG Instrumentation&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;windows-strikes-back&#34;&gt;Windows strikes back!&lt;/h3&gt;
&lt;p&gt;Support for graceful shutdowns of Windows nodes in Kubernetes clusters has been added.
Before this release, Kubernetes provided graceful node shutdown functionality for Linux nodes
but lacked equivalent support for Windows. This enhancement enables the kubelet on Windows nodes to handle system
shutdown events properly. Doing so, it ensures that Pods running on Windows nodes are gracefully terminated,
allowing workloads to be rescheduled without disruption. This improvement enhances the reliability and stability
of clusters that include Windows nodes, especially during a planned maintenance or any system updates.&lt;/p&gt;
&lt;p&gt;Moreover CPU and memory affinity support has been added for Windows nodes with nodes, with improvements
to the CPU manager, memory manager and topology manager.&lt;/p&gt;
&lt;p&gt;This work was done respectively as part of &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/4802&#34;&gt;KEP #4802&lt;/a&gt;
and &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/4885&#34;&gt;KEP #4885&lt;/a&gt; by &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-windows&#34;&gt;SIG
Windows&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;graduations-deprecations-and-removals-in-1-32&#34;&gt;Graduations, deprecations, and removals in 1.32&lt;/h2&gt;
&lt;h3 id=&#34;graduations-to-stable&#34;&gt;Graduations to Stable&lt;/h3&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 13 enhancements promoted to Stable:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/3221&#34;&gt;Structured Authorization Configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/4193&#34;&gt;Bound service account token improvements&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/4358&#34;&gt;Custom Resource Field Selectors&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/4420&#34;&gt;Retry Generate Name&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/1860&#34;&gt;Make Kubernetes aware of the LoadBalancer behaviour&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/2681&#34;&gt;Field &lt;code&gt;status.hostIPs&lt;/code&gt; added for Pod&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/4292&#34;&gt;Custom profile in kubectl debug&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/1769&#34;&gt;Memory Manager&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/1967&#34;&gt;Support to size memory backed volumes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/3545&#34;&gt;Improved multi-numa alignment in Topology Manager&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/4026&#34;&gt;Add job creation timestamp to job annotations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/4017&#34;&gt;Add Pod Index Label for StatefulSets and Indexed Jobs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/1847&#34;&gt;Auto remove PVCs created by StatefulSet&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;deprecations-and-removals&#34;&gt;Deprecations and removals&lt;/h3&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-50011--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.&lt;/p&gt;
&lt;h4 id=&#34;withdrawal-of-the-old-dra-implementation&#34;&gt;Withdrawal of the old DRA implementation&lt;/h4&gt;
&lt;p&gt;The enhancement &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/3063&#34;&gt;#3063&lt;/a&gt; introduced Dynamic Resource Allocation
(DRA) in Kubernetes 1.26.&lt;/p&gt;
&lt;p&gt;However, in Kubernetes v1.32, this approach to DRA will be significantly changed. Code related to the original
implementation will be removed, leaving KEP &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/4381&#34;&gt;#4381&lt;/a&gt; as the &amp;quot;new&amp;quot;
base functionality.&lt;/p&gt;
&lt;p&gt;The decision to change the existing approach originated from its incompatibility with cluster autoscaling as resource
availability was non-transparent, complicating decision-making for both Cluster Autoscaler and controllers.
The newly added Structured Parameter model substitutes the functionality.&lt;/p&gt;
&lt;p&gt;This removal will allow Kubernetes to handle new hardware requirements and resource claims more predictably, bypassing
the complexities of back and forth API calls to the kube-apiserver.&lt;/p&gt;
&lt;p&gt;See the enhancement issue &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/3063&#34;&gt;#3063&lt;/a&gt; to find out more.&lt;/p&gt;
&lt;h4 id=&#34;api-removals&#34;&gt;API removals&lt;/h4&gt;
&lt;p&gt;There is one API removal in &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/reference/using-api/deprecation-guide/#v1-32&#34;&gt;Kubernetes v1.32&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;flowcontrol.apiserver.k8s.io/v1beta3&lt;/code&gt; API version of FlowSchema and PriorityLevelConfiguration has been removed.
To prepare for this, you can edit your existing manifests and rewrite client software to use the
&lt;code&gt;flowcontrol.apiserver.k8s.io/v1 API&lt;/code&gt; version, available since v1.29.
All existing persisted objects are accessible via the new API. Notable changes in flowcontrol.apiserver.k8s.io/v1beta3
include that the PriorityLevelConfiguration &lt;code&gt;spec.limited.nominalConcurrencyShares&lt;/code&gt; field only defaults to 30 when
unspecified, and an explicit value of 0 is not changed to 30.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For more information, refer to the &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/reference/using-api/deprecation-guide/#v1-32&#34;&gt;API deprecation guide&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;release-notes-and-upgrade-actions-required&#34;&gt;Release notes and upgrade actions required&lt;/h3&gt;
&lt;p&gt;Check out the full details of the Kubernetes v1.32 release in our &lt;a href=&#34;https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.32.md&#34;&gt;release
notes&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;availability&#34;&gt;Availability&lt;/h2&gt;
&lt;p&gt;Kubernetes v1.32 is available for download on &lt;a href=&#34;https://github.com/kubernetes/kubernetes/releases/tag/v1.32.0&#34;&gt;GitHub&lt;/a&gt; or
on the &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/releases/download/&#34;&gt;Kubernetes download page&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To get started with Kubernetes, check out these &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/tutorials/&#34;&gt;interactive 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.32 using
&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/setup/independent/create-cluster-kubeadm/&#34;&gt;kubeadm&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;release-team&#34;&gt;Release team&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.32/release-team.md&#34;&gt;release
team&lt;/a&gt; for the hours spent
hard at work to deliver the Kubernetes v1.32 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 our release lead, Frederico Muñoz, for leading the release team so gracefully and handle
any matter with the uttermost care, making sure this release was executed smoothly and efficiently.
Last but not least a big thanks goes to all the release members - leads and shadows alike - and to the following SIGs
for the terrific work and outcome achieved during these 14 weeks of release work:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-docs&#34;&gt;SIG Docs&lt;/a&gt; - for the fundamental support in docs and
blog reviews and continous collaboration with release Comms and Docs;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-k8s-infra&#34;&gt;SIG k8s Infra&lt;/a&gt; and &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-testing&#34;&gt;SIG
Testing&lt;/a&gt; - for the outstanding work in keeping the
testing framework in check, along with all the infra components necessary;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-release&#34;&gt;SIG Release&lt;/a&gt; and
all the release managers - for the incredible support provided throughout the orchestration of the entire release,
addressing even the most challenging issues in a graceful and timely manner.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;project-velocity&#34;&gt;Project velocity&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
project&lt;/a&gt;
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;In the v1.32 release cycle, which ran for 14 weeks (September 9th to December 11th), we saw contributions to Kubernetes
from as many as 125 different companies and 559 individuals as of writing.&lt;/p&gt;
&lt;p&gt;In the whole Cloud Native ecosystem, the figure goes up to 433 companies counting 2441 total contributors. This sees an
increase of 7% more overall contributions compared to the &lt;a href=&#34;https://kubernetes.io/blog/2024/08/13/kubernetes-v1-31-release/#project-velocity&#34;&gt;previous
release&lt;/a&gt; cycle, along with 14%
increase in the number of companies involved, showcasing strong interest and community behind the Cloud Native projects.&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=1725832800000&amp;to=1733961599000&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=1725832800000&amp;to=1733961599000&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 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;&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;Check out
DevStats&lt;/a&gt;
to learn more about the overall velocity of the Kubernetes project and community.&lt;/p&gt;
&lt;h2 id=&#34;event-updates&#34;&gt;Event updates&lt;/h2&gt;
&lt;p&gt;Explore the upcoming Kubernetes and cloud-native events from March to June 2025, featuring KubeCon and KCD Stay informed
and engage with the Kubernetes community.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;March 2025&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.cncf.io/kcds/&#34;&gt;&lt;strong&gt;KCD - Kubernetes Community Days: Beijing, China&lt;/strong&gt;&lt;/a&gt;: In March | Beijing, China&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.cncf.io/kcds/&#34;&gt;&lt;strong&gt;KCD - Kubernetes Community Days: Guadalajara, Mexico&lt;/strong&gt;&lt;/a&gt;: March 16, 2025 | Guadalajara,
Mexico&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.cncf.io/kcds/&#34;&gt;&lt;strong&gt;KCD - Kubernetes Community Days: Rio de Janeiro, Brazil&lt;/strong&gt;&lt;/a&gt;: March 22, 2025 | Rio de
Janeiro, Brazil&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;April 2025&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://events.linuxfoundation.org/kubecon-cloudnativecon-europe&#34;&gt;&lt;strong&gt;KubeCon + CloudNativeCon Europe 2025&lt;/strong&gt;&lt;/a&gt;: April
1-4, 2025 | London, United Kingdom&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.cncf.io/kcds/&#34;&gt;&lt;strong&gt;KCD - Kubernetes Community Days: Budapest, Hungary&lt;/strong&gt;&lt;/a&gt;: April 23, 2025 | Budapest,
Hungary&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.cncf.io/kcds/&#34;&gt;&lt;strong&gt;KCD - Kubernetes Community Days: Chennai, India&lt;/strong&gt;&lt;/a&gt;: April 26, 2025 | Chennai, India&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.cncf.io/kcds/&#34;&gt;&lt;strong&gt;KCD - Kubernetes Community Days: Auckland, New Zealand&lt;/strong&gt;&lt;/a&gt;: April 28, 2025 | Auckland,
New Zealand&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;May 2025&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.cncf.io/kcds/&#34;&gt;&lt;strong&gt;KCD - Kubernetes Community Days: Helsinki, Finland&lt;/strong&gt;&lt;/a&gt;: May 6, 2025 | Helsinki, Finland&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.cncf.io/kcds/&#34;&gt;&lt;strong&gt;KCD - Kubernetes Community Days: San Francisco, USA&lt;/strong&gt;&lt;/a&gt;: May 8, 2025 | San Francisco, USA&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://community.cncf.io/events/details/cncf-kcd-texas-presents-kcd-texas-austin-2025/&#34;&gt;&lt;strong&gt;KCD - Kubernetes Community Days: Austin,
USA&lt;/strong&gt;&lt;/a&gt;: May 15, 2025 | Austin,
USA&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.cncf.io/kcds/&#34;&gt;&lt;strong&gt;KCD - Kubernetes Community Days: Seoul, South Korea&lt;/strong&gt;&lt;/a&gt;: May 22, 2025 | Seoul, South
Korea&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.cncf.io/kcds/&#34;&gt;&lt;strong&gt;KCD - Kubernetes Community Days: Istanbul, Turkey&lt;/strong&gt;&lt;/a&gt;: May 23, 2025 | Istanbul, Turkey&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.cncf.io/kcds/&#34;&gt;&lt;strong&gt;KCD - Kubernetes Community Days: Heredia, Costa Rica&lt;/strong&gt;&lt;/a&gt;: May 31, 2025 | Heredia, Costa
Rica&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.cncf.io/kcds/&#34;&gt;&lt;strong&gt;KCD - Kubernetes Community Days: New York, USA&lt;/strong&gt;&lt;/a&gt;: In May | New York, USA&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;June 2025&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.cncf.io/kcds/&#34;&gt;&lt;strong&gt;KCD - Kubernetes Community Days: Bratislava, Slovakia&lt;/strong&gt;&lt;/a&gt;: June 5, 2025 | Bratislava,
Slovakia&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.cncf.io/kcds/&#34;&gt;&lt;strong&gt;KCD - Kubernetes Community Days: Bangalore, India&lt;/strong&gt;&lt;/a&gt;: June 6, 2025 | Bangalore, India&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://events.linuxfoundation.org/kubecon-cloudnativecon-china/&#34;&gt;&lt;strong&gt;KubeCon + CloudNativeCon China 2025&lt;/strong&gt;&lt;/a&gt;: June
10-11, 2025 | Hong Kong&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.cncf.io/kcds/&#34;&gt;&lt;strong&gt;KCD - Kubernetes Community Days: Antigua Guatemala, Guatemala&lt;/strong&gt;&lt;/a&gt;: June 14, 2025 |
Antigua Guatemala, Guatemala&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://events.linuxfoundation.org/kubecon-cloudnativecon-japan&#34;&gt;&lt;strong&gt;KubeCon + CloudNativeCon Japan 2025&lt;/strong&gt;&lt;/a&gt;: June
16-17, 2025 | Tokyo, Japan&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.cncf.io/kcds/&#34;&gt;&lt;strong&gt;KCD - Kubernetes Community Days: Nigeria, Africa&lt;/strong&gt;&lt;/a&gt;: June 19, 2025 | Nigeria, Africa&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;upcoming-release-webinar&#34;&gt;Upcoming release webinar&lt;/h2&gt;
&lt;p&gt;Join members of the Kubernetes v1.32 release team on &lt;strong&gt;Thursday, January 9th 2025 at 5:00 PM (UTC)&lt;/strong&gt;, to learn about the
release highlights of this release, as well as deprecations and removals to help plan for upgrades.
For more information and registration, visit the &lt;a href=&#34;https://community.cncf.io/events/details/cncf-cncf-online-programs-presents-cncf-live-webinar-kubernetes-132-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;/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://www.kubernetes.dev/community/community-groups/#special-interest-groups&#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/did:plc:kyg4uikmq7lzpb76ugvxa6ul&#34;&gt;@Kubernetes.io&lt;/a&gt; for 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;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>Gateway API v1.2: WebSockets, Timeouts, Retries, and More</title>
      <link>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/11/21/gateway-api-v1-2/</link>
      <pubDate>Thu, 21 Nov 2024 09:00:00 -0800</pubDate>
      
      <guid>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/11/21/gateway-api-v1-2/</guid>
      <description>
        
        
        &lt;p&gt;&lt;img alt=&#34;Gateway API logo&#34; src=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/11/21/gateway-api-v1-2/gateway-api-logo.svg&#34;&gt;&lt;/p&gt;
&lt;p&gt;Kubernetes SIG Network is delighted to announce the general availability of
&lt;a href=&#34;https://gateway-api.sigs.k8s.io/&#34;&gt;Gateway API&lt;/a&gt; v1.2! This version of the API
was released on October 3, and we&#39;re delighted to report that we now have a
number of conformant implementations of it for you to try out.&lt;/p&gt;
&lt;p&gt;Gateway API v1.2 brings a number of new features to the &lt;em&gt;Standard channel&lt;/em&gt;
(Gateway API&#39;s GA release channel), introduces some new experimental features,
and inaugurates our new release process — but it also brings two breaking
changes that you&#39;ll want to be careful of.&lt;/p&gt;
&lt;h2 id=&#34;breaking-changes&#34;&gt;Breaking changes&lt;/h2&gt;
&lt;h3 id=&#34;grpcroute-and-referencegrant-v1alpha2-removal&#34;&gt;GRPCRoute and ReferenceGrant &lt;code&gt;v1alpha2&lt;/code&gt; removal&lt;/h3&gt;
&lt;p&gt;Now that the &lt;code&gt;v1&lt;/code&gt; versions of GRPCRoute and ReferenceGrant have graduated to
Standard, the old &lt;code&gt;v1alpha2&lt;/code&gt; versions have been removed from both the Standard
and Experimental channels, in order to ease the maintenance burden that
perpetually supporting the old versions would place on the Gateway API
community.&lt;/p&gt;
&lt;p&gt;Before upgrading to Gateway API v1.2, you&#39;ll want to confirm that any
implementations of Gateway API have been upgraded to support the v1 API
version of these resources instead of the v1alpha2 API version. Note that even
if you&#39;ve been using v1 in your YAML manifests, a controller may still be
using v1alpha2 which would cause it to fail during this upgrade. Additionally,
Kubernetes itself goes to some effort to stop you from removing a CRD version
that it thinks you&#39;re using: check out the &lt;a href=&#34;https://github.com/kubernetes-sigs/gateway-api/releases/tag/v1.2.0&#34;&gt;release notes&lt;/a&gt; for more
information about what you need to do to safely upgrade.&lt;/p&gt;
&lt;h3 id=&#34;status-supported-features&#34;&gt;Change to &lt;code&gt;.status.supportedFeatures&lt;/code&gt; (experimental)&lt;/h3&gt;
&lt;p&gt;A much smaller breaking change: &lt;code&gt;.status.supportedFeatures&lt;/code&gt; in a Gateway is
now a list of objects instead of a list of strings. The objects have a single
&lt;code&gt;name&lt;/code&gt; field, so the translation from the strings is straightforward, but
moving to objects permits a lot more flexibility for the future. This stanza
is not yet present in the Standard channel.&lt;/p&gt;
&lt;h2 id=&#34;graduations-to-the-standard-channel&#34;&gt;Graduations to the standard channel&lt;/h2&gt;
&lt;p&gt;Gateway API 1.2.0 graduates four features to the Standard channel, meaning
that they can now be considered generally available. Inclusion in the Standard
release channel denotes a high level of confidence in the API surface and
provides guarantees of backward compatibility. Of course, as with any other
Kubernetes API, Standard channel features can continue to evolve with
backward-compatible additions over time, and we certainly expect further
refinements and improvements to these new features in the future. For more
information on how all of this works, refer to the &lt;a href=&#34;https://gateway-api.sigs.k8s.io/concepts/versioning/&#34;&gt;Gateway API Versioning
Policy&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;httproute-timeouts&#34;&gt;HTTPRoute timeouts&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://gateway-api.sigs.k8s.io/geps/gep-1742/&#34;&gt;GEP-1742&lt;/a&gt; introduced the
&lt;code&gt;timeouts&lt;/code&gt; stanza into HTTPRoute, permitting configuring basic timeouts for
HTTP traffic. This is a simple but important feature for proper resilience
when handling HTTP traffic, and it is now Standard.&lt;/p&gt;
&lt;p&gt;For example, this HTTPRoute configuration sets a timeout of 300ms for traffic
to the &lt;code&gt;/face&lt;/code&gt; path:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;gateway.networking.k8s.io/v1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;HTTPRoute&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;face-with-timeouts&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;namespace&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;faces&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;spec&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;parentRefs&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;my-gateway&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Gateway&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;rules&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;matches&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;path&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;type&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;PathPrefix&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;value&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;/face&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;backendRefs&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;face&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;port&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;80&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;timeouts&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;request&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;300ms&lt;span style=&#34;color:#bbb&#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 information, check out the &lt;a href=&#34;https://gateway-api.sigs.k8s.io/guides/http-routing/&#34;&gt;HTTP routing&lt;/a&gt; documentation. (Note that
this applies only to HTTPRoute timeouts. GRPCRoute timeouts are not yet part
of Gateway API.)&lt;/p&gt;
&lt;h3 id=&#34;gateway-infrastructure-labels-and-annotations&#34;&gt;Gateway infrastructure labels and annotations&lt;/h3&gt;
&lt;p&gt;Gateway API implementations are responsible for creating the backing
infrastructure needed to make each Gateway work. For example, implementations
running in a Kubernetes cluster often create Services and Deployments, while
cloud-based implementations may be creating cloud load balancer resources. In
many cases, it can be helpful to be able to propagate labels or annotations to
these generated resources.&lt;/p&gt;
&lt;p&gt;In v1.2.0, the Gateway &lt;code&gt;infrastructure&lt;/code&gt; stanza moves to the Standard channel,
allowing you to specify labels and annotations for the infrastructure created
by the Gateway API controller. For example, if your Gateway infrastructure is
running in-cluster, you can specify both Linkerd and Istio injection using the
following Gateway configuration, making it simpler for the infrastructure to
be incorporated into whichever service mesh you&#39;ve installed:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: meshed-gateway
  namespace: incoming
spec:
  gatewayClassName: meshed-gateway-class
  listeners:
  - name: http-listener
    protocol: HTTP
    port: 80
  infrastructure:
    labels:
      istio-injection: enabled
    annotations:
      linkerd.io/inject: enabled
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For more information, check out the
&lt;a href=&#34;https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.GatewayInfrastructure&#34;&gt;&lt;code&gt;infrastructure&lt;/code&gt; API reference&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;backend-protocol-support&#34;&gt;Backend protocol support&lt;/h3&gt;
&lt;p&gt;Since Kubernetes v1.20, the Service and EndpointSlice resources have supported
a stable &lt;code&gt;appProtocol&lt;/code&gt;  field to allow users to specify the L7 protocol that
Service supports. With the adoption of
&lt;a href=&#34;https://github.com/kubernetes/enhancements/tree/master/keps/sig-network/3726-standard-application-protocols&#34;&gt;KEP 3726&lt;/a&gt;,
Kubernetes now supports three new &lt;code&gt;appProtocol&lt;/code&gt; values:&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;&lt;code&gt;kubernetes.io/h2c&lt;/code&gt;&lt;/dt&gt;
&lt;dd&gt;HTTP/2 over cleartext as described in &lt;a href=&#34;https://www.rfc-editor.org/rfc/rfc7540&#34;&gt;RFC7540&lt;/a&gt;&lt;/dd&gt;
&lt;dt&gt;&lt;code&gt;kubernetes.io/ws&lt;/code&gt;&lt;/dt&gt;
&lt;dd&gt;WebSocket over cleartext as described in &lt;a href=&#34;https://www.rfc-editor.org/rfc/rfc6445&#34;&gt;RFC6445&lt;/a&gt;&lt;/dd&gt;
&lt;dt&gt;&lt;code&gt;kubernetes.io/wss&lt;/code&gt;&lt;/dt&gt;
&lt;dd&gt;WebSocket over TLS as described in &lt;a href=&#34;https://www.rfc-editor.org/rfc/rfc6445&#34;&gt;RFC6445&lt;/a&gt;&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;With Gateway API 1.2.0, support for honoring &lt;code&gt;appProtocol&lt;/code&gt; is now Standard.
For example, given the following Service:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;v1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Service&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;websocket-service&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;namespace&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;my-namespace&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;spec&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;selector&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;app.kubernetes.io/name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;websocket-app&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;ports&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;http&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;port&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;80&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;targetPort&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;9376&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;protocol&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;TCP&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;appProtocol&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;kubernetes.io/ws&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;then an HTTPRoute that includes this Service as a &lt;code&gt;backendRef&lt;/code&gt; will
automatically upgrade the connection to use WebSockets rather than assuming
that the connection is pure HTTP.&lt;/p&gt;
&lt;p&gt;For more information, check out
&lt;a href=&#34;https://gateway-api.sigs.k8s.io/geps/gep-1911/&#34;&gt;GEP-1911&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;new-additions-to-experimental-channel&#34;&gt;New additions to experimental channel&lt;/h2&gt;
&lt;h3 id=&#34;named-rules-for-route-resources&#34;&gt;Named rules for *Route resources&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;rules&lt;/code&gt; field in HTTPRoute and GRPCRoute resources can now be named, in
order to make it easier to reference the specific rule, for example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;gateway.networking.k8s.io/v1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;HTTPRoute&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;multi-color-route&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;namespace&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;faces&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;spec&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;parentRefs&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;my-gateway&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Gateway&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;port&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;80&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;rules&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;center-rule&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;matches&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;path&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;type&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;PathPrefix&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;value&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;/color/center&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;backendRefs&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;color-center&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;port&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;80&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;edge-rule&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;matches&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;path&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;type&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;PathPrefix&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;value&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;/color/edge&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;backendRefs&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;color-edge&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;port&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;80&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Logging or status messages can now refer to these two rules as &lt;code&gt;center-rule&lt;/code&gt;
or &lt;code&gt;edge-rule&lt;/code&gt; instead of being forced to refer to them by index. For more
information, see &lt;a href=&#34;https://gateway-api.sigs.k8s.io/geps/gep-995/&#34;&gt;GEP-995&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;httproute-retry-support&#34;&gt;HTTPRoute retry support&lt;/h3&gt;
&lt;p&gt;Gateway API 1.2.0 introduces experimental support for counted HTTPRoute
retries. For example, the following HTTPRoute configuration retries requests
to the &lt;code&gt;/face&lt;/code&gt; path up to 3 times with a 500ms delay between retries:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;gateway.networking.k8s.io/v1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;HTTPRoute&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;face-with-retries&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;namespace&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;faces&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;spec&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;parentRefs&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;my-gateway&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Gateway&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;port&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;80&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;rules&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;matches&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;path&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;type&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;PathPrefix&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;value&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;/face&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;backendRefs&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;face&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;port&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;80&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;retry&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;codes&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;[&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;500&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;502&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;503&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;504&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;attempts&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;3&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;backoff&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;500ms&lt;span style=&#34;color:#bbb&#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 information, check out &lt;a href=&#34;https://gateway-api.sigs.k8s.io/geps/gep-1731&#34;&gt;GEP
1731&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;httproute-percentage-based-mirroring&#34;&gt;HTTPRoute percentage-based mirroring&lt;/h3&gt;
&lt;p&gt;Gateway API has long supported the
&lt;a href=&#34;https://gateway-api.sigs.k8s.io/guides/http-request-mirroring/&#34;&gt;Request Mirroring&lt;/a&gt;
feature, which allows sending the same request to multiple backends. In
Gateway API 1.2.0, we&#39;re introducing percentage-based mirroring, which allows
you to specify a percentage of requests to mirror to a different backend. For
example, the following HTTPRoute configuration mirrors 42% of requests to the
&lt;code&gt;color-mirror&lt;/code&gt; backend:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;gateway.networking.k8s.io/v1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;HTTPRoute&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;color-mirror-route&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;namespace&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;faces&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;spec&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;parentRefs&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;mirror-gateway&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;hostnames&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- mirror.example&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;rules&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;backendRefs&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;color&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;port&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;80&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;filters&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;type&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;RequestMirror&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;requestMirror&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;backendRef&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;color-mirror&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;port&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;80&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;percent&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;42&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;   &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# This value must be an integer.&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;There&#39;s also a &lt;code&gt;fraction&lt;/code&gt; stanza which can be used in place of &lt;code&gt;percent&lt;/code&gt;, to
allow for more precise control over exactly what amount of traffic is
mirrored, for example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;...&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;filters&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;type&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;RequestMirror&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;requestMirror&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;backendRef&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;color-mirror&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;port&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;80&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;fraction&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;numerator&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;denominator&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;10000&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This configuration mirrors 1 in 10,000 requests to the &lt;code&gt;color-mirror&lt;/code&gt; backend,
which may be relevant with very high request rates. For more details, see
&lt;a href=&#34;https://gateway-api.sigs.k8s.io/geps/gep-3171&#34;&gt;GEP-1731&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;additional-backend-tls-configuration&#34;&gt;Additional backend TLS configuration&lt;/h3&gt;
&lt;p&gt;This release includes three additions related to TLS configuration for
communications between a Gateway and a workload (a &lt;em&gt;backend&lt;/em&gt;):&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;A new &lt;code&gt;backendTLS&lt;/code&gt; field on Gateway&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This new field allows you to specify the client certificate that a Gateway
should use when connecting to backends.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;A new &lt;code&gt;subjectAltNames&lt;/code&gt; field on BackendTLSPolicy&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Previously, the &lt;code&gt;hostname&lt;/code&gt; field was used to configure both the SNI that a
Gateway should send to a backend &lt;em&gt;and&lt;/em&gt; the identity that should be provided
by a certificate. When the new &lt;code&gt;subjectAltNames&lt;/code&gt; field is specified, any
certificate matching at least one of the specified SANs will be considered
valid. This is particularly critical for SPIFFE where URI-based SANs may
not be valid SNIs.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;A new &lt;code&gt;options&lt;/code&gt; field on BackendTLSPolicy&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Similar to the TLS options field on Gateway Listeners, we believe the same
concept will be broadly useful for TLS-specific configuration for Backend
TLS.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For more information, check out
&lt;a href=&#34;https://gateway-api.sigs.k8s.io/geps/gep-3155&#34;&gt;GEP-3135&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;more-changes&#34;&gt;More changes&lt;/h2&gt;
&lt;p&gt;For a full list of the changes included in this release, please refer to the
&lt;a href=&#34;https://github.com/kubernetes-sigs/gateway-api/releases/tag/v1.2.0&#34;&gt;v1.2.0 release notes&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;project-updates&#34;&gt;Project updates&lt;/h2&gt;
&lt;p&gt;Beyond the technical, the v1.2 release also marks a few milestones in the life
of the Gateway API project itself.&lt;/p&gt;
&lt;h3 id=&#34;release-process-improvements&#34;&gt;Release process improvements&lt;/h3&gt;
&lt;p&gt;Gateway API has never been intended to be a static API, and as more projects
use it as a component to build on, it&#39;s become clear that we need to bring
some more predictability to Gateway API releases. To that end, we&#39;re pleased -
and a little nervous! - to announce that we&#39;ve formalized a new release
process:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Scoping&lt;/strong&gt; (4-6 weeks): maintainers and community determine the set of
features we want to include in the release. A particular emphasis here is
getting features &lt;em&gt;out&lt;/em&gt; of the Experimental channel — ideally this involves
moving them to Standard, but it can also mean removing them.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;GEP Iteration and Review&lt;/strong&gt; (5-7 weeks): contributors write or update
Gateway Enhancement Proposals (GEPs) for features accepted into the release,
with emphasis on getting consensus around the design and graduation criteria
of the feature.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;API Refinement and Documentation&lt;/strong&gt; (3-5 weeks): contributors implement the
features in the Gateway API controllers and write the necessary
documentation.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;SIG Network Review and Release Candidates&lt;/strong&gt; (2-4 weeks): maintainers get
the required upstream review, build release candidates, and release the new
version.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Gateway API 1.2.0 was the first release to use the new process, and although
there are the usual rough edges of anything new, we believe that it went well.
We&#39;ve already completed the Scoping phase for Gateway API 1.3, with the
release expected around the end of January 2025.&lt;/p&gt;
&lt;h3 id=&#34;gwctl-moves-out&#34;&gt;&lt;code&gt;gwctl&lt;/code&gt; moves out&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;gwctl&lt;/code&gt; CLI tool has moved into its very own repository,
&lt;a href=&#34;https://github.com/kubernetes-sigs/gwctl&#34;&gt;https://github.com/kubernetes-sigs/gwctl&lt;/a&gt;. &lt;code&gt;gwctl&lt;/code&gt; has proven a valuable tool
for the Gateway API community; moving it into its own repository will, we
believe, make it easier to maintain and develop. As always, we welcome
contributions; while still experimental, &lt;code&gt;gwctl&lt;/code&gt; already helps make working
with Gateway API a bit easier — especially for newcomers to the project!&lt;/p&gt;
&lt;h3 id=&#34;maintainer-changes&#34;&gt;Maintainer changes&lt;/h3&gt;
&lt;p&gt;Rounding out our changes to the project itself, we&#39;re pleased to announce that
&lt;a href=&#34;https://github.com/mlavacca&#34;&gt;Mattia Lavacca&lt;/a&gt; has joined the ranks of Gateway API Maintainers! We&#39;re also
sad to announce that &lt;a href=&#34;https://github.com/keithmattix&#34;&gt;Keith Mattix&lt;/a&gt; has stepped down as a GAMMA lead —
happily, &lt;a href=&#34;https://github.com/mikemorris&#34;&gt;Mike Morris&lt;/a&gt; has returned to the role. We&#39;re grateful for everything
Keith has done, and excited to have Mattia and Mike on board.&lt;/p&gt;
&lt;h2 id=&#34;try-it-out&#34;&gt;Try it out&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.26 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 our &lt;a href=&#34;https://gateway-api.sigs.k8s.io/guides/&#34;&gt;Getting Started
Guide&lt;/a&gt;. As of this writing, five
implementations are already conformant with Gateway API v1.2. In alphabetical
order:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/cilium/cilium&#34;&gt;Cilium v1.17.0-pre.1&lt;/a&gt;, Experimental channel&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/envoyproxy/gateway&#34;&gt;Envoy Gateway v1.2.0-rc.1&lt;/a&gt;, Experimental channel&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://istio.io&#34;&gt;Istio v1.24.0-alpha.0&lt;/a&gt;, Experimental channel&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kong/kubernetes-ingress-controller&#34;&gt;Kong v3.2.0-244-gea4944bb0&lt;/a&gt;, Experimental channel&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://traefik.io&#34;&gt;Traefik v3.2&lt;/a&gt;, Experimental channel&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;get-involved&#34;&gt;Get involved&lt;/h2&gt;
&lt;p&gt;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;em&gt;everyone&lt;/em&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 gotten this far without the support of this
dedicated and active community.&lt;/p&gt;
&lt;h2 id=&#34;related-kubernetes-blog-articles&#34;&gt;Related Kubernetes blog articles&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://kubernetes.io/blog/2024/05/09/gateway-api-v1-1/&#34;&gt;Gateway API v1.1: Service mesh, GRPCRoute, and a whole lot more&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2023/11/28/gateway-api-ga/&#34;&gt;New Experimental Features in Gateway API v1.0&lt;/a&gt;
11/2023&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2023/10/31/gateway-api-ga/&#34;&gt;Gateway API v1.0: GA Release&lt;/a&gt;
10/2023&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2023/10/25/introducing-ingress2gateway/&#34;&gt;Introducing ingress2gateway; Simplifying Upgrades to Gateway API&lt;/a&gt;
10/2023&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2023/08/29/gateway-api-v0-8/&#34;&gt;Gateway API v0.8.0: Introducing Service Mesh Support&lt;/a&gt;
08/2023&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>How we built a dynamic Kubernetes API Server for the API Aggregation Layer in Cozystack</title>
      <link>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/11/21/dynamic-kubernetes-api-server-for-cozystack/</link>
      <pubDate>Thu, 21 Nov 2024 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/11/21/dynamic-kubernetes-api-server-for-cozystack/</guid>
      <description>
        
        
        &lt;p&gt;Hi there! I&#39;m Andrei Kvapil, but you might know me as &lt;a href=&#34;https://github.com/kvaps&#34;&gt;@kvaps&lt;/a&gt; in communities dedicated to Kubernetes
and cloud-native tools. In this article, I want to share how we implemented our own extension api-server
in the open-source PaaS platform, Cozystack.&lt;/p&gt;
&lt;p&gt;Kubernetes truly amazes me with its powerful extensibility features. You&#39;re probably already
familiar with the &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/architecture/controller/&#34;&gt;controller&lt;/a&gt; concept
and frameworks like &lt;a href=&#34;https://book.kubebuilder.io/&#34;&gt;kubebuilder&lt;/a&gt; and
&lt;a href=&#34;https://sdk.operatorframework.io/&#34;&gt;operator-sdk&lt;/a&gt; that help you implement it. In a nutshell, they
allow you to extend your Kubernetes cluster by defining custom resources (CRDs) and writing additional
controllers that handle your business logic for reconciling and managing these kinds of resources.
This approach is well-documented, with a wealth of information available online on how to develop your
own operators.&lt;/p&gt;
&lt;p&gt;However, this is not the only way to
&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/extend-kubernetes/#api-extensions&#34;&gt;extend the Kubernetes API&lt;/a&gt;.
For more complex scenarios such as implementing imperative logic,
managing subresources, and dynamically generating responses—the Kubernetes API &lt;em&gt;aggregation layer&lt;/em&gt;
provides an effective alternative. Through the aggregation layer, you can develop a custom
extension API server and seamlessly integrate it within the broader Kubernetes API framework.&lt;/p&gt;
&lt;p&gt;In this article, I will explore the API aggregation layer, the types of challenges it is well-suited
to address, cases where it may be less appropriate, and how we utilized this model to implement
our own extension API server in Cozystack.&lt;/p&gt;
&lt;h2 id=&#34;what-is-the-api-aggregation-layer&#34;&gt;What Is the API Aggregation Layer?&lt;/h2&gt;
&lt;p&gt;First, let&#39;s get definitions straight to avoid any confusion down the road.
The &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/extend-kubernetes/api-extension/apiserver-aggregation/&#34;&gt;API aggregation layer&lt;/a&gt;
is a feature in Kubernetes, while an extension api-server is a specific implementation of an
API server for the aggregation layer. An extension API server is just like the standard Kubernetes API server, except it runs separately and handles requests for your specific resource types.&lt;/p&gt;
&lt;p&gt;So, the aggregation layer lets you write your own extension API server, integrate it easily into Kubernetes,
and directly process requests for resources in a certain group. Unlike the CRD mechanism, the extension API
is registered in Kubernetes as an APIService, telling Kubernetes to consider this new API server and acknowledge
that it serves certain APIs.&lt;/p&gt;
&lt;p&gt;You can execute this command to list all registered apiservices:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kubectl get apiservices.apiregistration.k8s.io
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Example APIService:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;NAME                          	SERVICE                   	AVAILABLE   AGE
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;v1alpha1.apps.cozystack.io    	cozy-system/cozystack-api 	True    	7h29m
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;As soon as the Kubernetes api-server receives requests for resources in the group
&lt;code&gt;v1alpha1.apps.cozystack.io&lt;/code&gt;, it redirects all those requests to our extension api-server,
which can handle them based on the business logic we&#39;ve built into it.&lt;/p&gt;
&lt;h2 id=&#34;when-to-use-the-api-aggregation-layer&#34;&gt;When to use the API Aggregation Layer&lt;/h2&gt;
&lt;p&gt;The API Aggregation Layer helps solve several issues where the usual CRD mechanism might
not enough. Let&#39;s break them down.&lt;/p&gt;
&lt;h3 id=&#34;imperative-logic-and-subresources&#34;&gt;Imperative Logic and Subresources&lt;/h3&gt;
&lt;p&gt;Besides regular resources, Kubernetes also has something called subresources.&lt;/p&gt;
&lt;p&gt;In Kubernetes, subresources are additional actions or operations you can perform on primary resources
(like Pods, Deployments, Services) via the Kubernetes API. They provide interfaces to manage
specific aspects of resources without affecting the entire object.&lt;/p&gt;
&lt;p&gt;A simple example is &lt;code&gt;status&lt;/code&gt;, which is traditionally exposed as a separate subresource that you can
access independently from the parent object. The &lt;code&gt;status&lt;/code&gt; field isn&#39;t meant to be changed&lt;/p&gt;
&lt;p&gt;But beyond &lt;code&gt;/status&lt;/code&gt;, Pods in Kubernetes also have subresources like &lt;code&gt;/exec&lt;/code&gt;, &lt;code&gt;/portforward&lt;/code&gt;, and
&lt;code&gt;/log&lt;/code&gt;. Interestingly, instead of the usual declarative resources in Kubernetes, these represent
endpoints for imperative operations like viewing logs, proxying connections, executing commands in
a running container, and so on.&lt;/p&gt;
&lt;p&gt;To support such imperative commands on your own API, you need implement an extension API and an
extension API server. Here are some well-known examples:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;KubeVirt&lt;/strong&gt;: An add-on for Kubernetes that extends its API capabilities to run traditional virtual machines.
The extension api-server created as part of KubeVirt handles subresources
like &lt;code&gt;/restart&lt;/code&gt;, &lt;code&gt;/console&lt;/code&gt;, and &lt;code&gt;/vnc&lt;/code&gt; for virtual machines.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Knative&lt;/strong&gt;: A Kubernetes add-on that extends its capabilities for serverless computing,
implementing the &lt;code&gt;/scale&lt;/code&gt; subresource to set up autoscaling for its resource types.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;By the way, even though subresource logic in Kubernetes can be &lt;em&gt;imperative&lt;/em&gt;, you can manage access
to them &lt;em&gt;declaratively&lt;/em&gt; using Kubernetes standard RBAC model.&lt;/p&gt;
&lt;p&gt;For example this way you can control access to the &lt;code&gt;/log&lt;/code&gt; and &lt;code&gt;/exec&lt;/code&gt; subresources of the Pod kind:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Role&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;rbac.authorization.k8s.io/v1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;namespace&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;default&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;pod-and-pod-logs-reader&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;rules&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;apiGroups&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;[&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;resources&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;[&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;pods&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;pods/log&amp;#34;&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;verbs&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;[&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;get&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;list&amp;#34;&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;apiGroups&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;[&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;resources&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;[&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;pods/exec&amp;#34;&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;verbs&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;[&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;create&amp;#34;&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;you-re-not-tied-to-use-etcd&#34;&gt;You&#39;re not tied to use etcd&lt;/h3&gt;
&lt;p&gt;Usually, the Kubernetes API server uses &lt;a href=&#34;https://etcd.io/&#34;&gt;etcd&lt;/a&gt; for its backend.
However, implementing your own API server doesn&#39;t lock you into using only etcd.
If it doesn&#39;t make sense to store your server&#39;s state in etcd, you can store information in any
other system and generate responses on the fly. Here are a few cases to illustrate:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/kubernetes-sigs/metrics-server&#34;&gt;metrics-server&lt;/a&gt; is a standard extension for Kubernetes
which allows you to view real-time metrics of your nodes and pods. It defines alternative Pod and Node
kinds in its own metrics.k8s.io API. Requests to these resources are translated into metrics
directly from Kubelet. So when you run &lt;code&gt;kubectl top node&lt;/code&gt; or &lt;code&gt;kubectl top pod&lt;/code&gt;, metrics-server fetches
metrics from cAdvisor in real-time. It then returns these metrics to you. Since the information
is generated in real-time and is only relevant at the moment of the request, there is no need
to store it in etcd. This approach saves resources.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If needed, you can use a backend other than etcd. You can even implement a Kubernetes-compatible API
for it. For example, if you use Postgres, you can create a transparent representation of its entities
in the Kubernetes API. Eg. databases, users, and grants within Postgres would appear as regular
Kubernetes resources, thanks to your extension API server. You could manage them using &lt;code&gt;kubectl&lt;/code&gt; or any
other Kubernetes-compatible tool. Unlike controllers, which implement business logic using custom resources
and reconciliation methods, an extension API server eliminates the need for separate controllers for every kind.
This means you don&#39;t have to sync state between the Kubernetes API and your backend.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;one-time-resources&#34;&gt;One-Time resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Kubernetes has a special API used to provide users with information about their permissions.
This is implemented using the SelfSubjectAccessReview API. One unusual detail of these
resources is that you can&#39;t view them using &lt;strong&gt;get&lt;/strong&gt; or &lt;strong&gt;list&lt;/strong&gt; verbs. You can only create them (using
the &lt;strong&gt;create&lt;/strong&gt; verb) and receive output with information about what you have access to at that
moment.&lt;/p&gt;
&lt;p&gt;If you try to run &lt;code&gt;kubectl get selfsubjectaccessreviews&lt;/code&gt; directly, you&#39;ll just get an error
like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;Error from server (MethodNotAllowed): the server does not allow this method on the requested resource
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The reason is that the Kubernetes API server doesn&#39;t support any other interaction with this
type of resource (you can only CREATE them).&lt;/p&gt;
&lt;p&gt;The SelfSubjectAccessReview API supports commands such as:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kubectl auth can-i create deployments --namespace dev
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;When you run the command above, &lt;code&gt;kubectl&lt;/code&gt; creates a SelfSubjectAccessReview using the
Kubernetes API. This allows Kubernetes to fetch a list of possible permissions for your user.
Kubernetes then generates a personalized response to your request in real-time. This logic is
different from a scenario where this resource is simply stored in etcd.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Similarly, in KubeVirt&#39;s &lt;a href=&#34;https://github.com/kubevirt/containerized-data-importer&#34;&gt;CDI (Containerized Data Importer)&lt;/a&gt;
extension, which allows file uploads into a PVC from a local machine using the &lt;code&gt;virtctl&lt;/code&gt; tool,
a special token is required before the upload process begins.
This token is generated by creating an UploadTokenRequest resource via the Kubernetes API. Kubernetes
routes (proxies) all UploadTokenRequest resource creation requests to the CDI extension API server,
which generates and returns the token in response.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;full-control-over-conversion-validation-and-output-formatting&#34;&gt;Full control over conversion, validation, and output formatting&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Your own API server can have all the capabilities of the vanilla Kubernetes API server. The resources you create
in your API server can be validated immediately on the server side without additional webhooks.
While CRDs also support server-side validation using &lt;a href=&#34;https://kubernetes.io/docs/reference/using-api/cel/&#34;&gt;Common Expression Language (CEL)&lt;/a&gt;
for declarative validation and &lt;a href=&#34;https://kubernetes.io/docs/reference/access-authn-authz/validating-admission-policy/&#34;&gt;ValidatingAdmissionPolicies&lt;/a&gt;
without the need for webhooks, a custom API server allows for more complex and tailored validation logic if needed.&lt;/p&gt;
&lt;p&gt;Kubernetes allows you to serve multiple API versions for each resource type, traditionally
&lt;code&gt;v1alpha1&lt;/code&gt;, &lt;code&gt;v1beta1&lt;/code&gt; and &lt;code&gt;v1&lt;/code&gt;. Only one version can be specified as the storage version.
All requests to other versions must be automatically converted to the version specified as storage version.
With CRDs, this mechanism is implemented using conversion webhooks. Whereas in an extension API server,
you can implement your own conversion mechanism, choose to mix up different storage versions (one
object might be serialized as &lt;code&gt;v1&lt;/code&gt;, another as &lt;code&gt;v2&lt;/code&gt;), or rely on an external backing API.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Directly implementing the Kubernetes API lets you format table output however you like and doesn&#39;t force you to follow
the &lt;code&gt;additionalPrinterColumns&lt;/code&gt; logic in CRDs. Instead, you can write your own formatter that
formats the table output and custom fields in it. For example, when using &lt;code&gt;additionalPrinterColumns&lt;/code&gt;,
you can display field values only following the JSONPath logic. In your own API server, you can generate
and insert values on the fly, formatting the table output as you wish.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;dynamic-resource-registration&#34;&gt;Dynamic resource registration&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The resources served by an extension api-server don&#39;t need to be pre-registered as CRDs.
Once your extension API server is registered using an APIService, Kubernetes starts polling it to discover
APIs and resources it can serve. After receiving a discovery response, the Kubernetes API server automatically
registers all available types for this API group.
Although this isn&#39;t considered common practice, you can implement logic that dynamically registers
the resource types you need in your Kubernetes cluster.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;when-not-to-use-the-api-aggregation-layer&#34;&gt;When not to use the API Aggregation Layer&lt;/h2&gt;
&lt;p&gt;There are some anti-patterns where using the API Aggregation Layer isn&#39;t recommended.
Let&#39;s go through them.&lt;/p&gt;
&lt;h3 id=&#34;unstable-backend&#34;&gt;Unstable backend&lt;/h3&gt;
&lt;p&gt;If your API server stops responding for some reason due to an unavailable backend or other issues it
may block some Kubernetes functionality. For example, when deleting namespaces, Kubernetes will wait
for a response from your API server to see if there are any remaining resources.
If the response doesn&#39;t come, the namespace deletion will be blocked.&lt;/p&gt;
&lt;p&gt;Also, you might have encountered a &lt;a href=&#34;https://github.com/kedacore/keda/issues/4224&#34;&gt;situation&lt;/a&gt; where,
when the metrics-server is unavailable, an extra message appears in stderr after every API request
(even unrelated to metrics) stating that &lt;code&gt;metrics.k8s.io&lt;/code&gt; is unavailable. This is another example
of how using the API Aggregation Layer can lead to problems when the api-server handling requests
is unavailable.&lt;/p&gt;
&lt;h3 id=&#34;slow-requests&#34;&gt;Slow requests&lt;/h3&gt;
&lt;p&gt;If you can&#39;t guarantee an instant response for user requests, it&#39;s better to consider using a
CustomResourceDefinition and controller.
Otherwise, you might make your cluster less stable. Many projects implement an extension
API server only for a limited set of resources, particularly for imperative logic and subresources.
This recommendation is also
&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/extend-kubernetes/api-extension/apiserver-aggregation/#response-latency&#34;&gt;mentioned&lt;/a&gt;
in the official Kubernetes
documentation.&lt;/p&gt;
&lt;h2 id=&#34;why-we-needed-it-in-cozystack&#34;&gt;Why we needed it in Cozystack&lt;/h2&gt;
&lt;p&gt;As a reminder, we&#39;re developing the open-source PaaS platform &lt;a href=&#34;https://cozystack.io/&#34;&gt;Cozystack&lt;/a&gt;,
which can also be used as a framework for building your own private cloud. Therefore, the ability
to easily extend the platform is crucial for us.&lt;/p&gt;
&lt;p&gt;Cozystack is built on top of &lt;a href=&#34;https://fluxcd.io/&#34;&gt;FluxCD&lt;/a&gt;. Any application is packaged into its
own Helm chart, ready for deployment in a tenant namespace. Deploying any application on the platform
is done by creating a HelmRelease resource, specifying the chart name and parameters for the application.
All the rest logic is handled by FluxCD. This pattern allows us to easily extend the platform with new
applications and provide the ability to create new applications that just need to be packaged
into the appropriate Helm chart.&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/11/21/dynamic-kubernetes-api-server-for-cozystack/cozystack.png&#34;
         alt=&#34;Interface of the Cozystack platform&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;Interface of the Cozystack platform&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;So, in our platform, everything is configured as HelmRelease resources. However, we ran into
two problems: limitations of the RBAC model and the need for a public API. Let&#39;s delve into these&lt;/p&gt;
&lt;h3 id=&#34;limitations-of-the-rbac-model&#34;&gt;Limitations of the RBAC model&lt;/h3&gt;
&lt;p&gt;The widely-deployed RBAC system in Kubernetes doesn&#39;t allow you to restrict access to a list of resources
of the same kind based on labels or specific fields in the spec. When creating a role, you can limit
access across the resources in the same kind only by specifying specific resource names in &lt;code&gt;resourceNames&lt;/code&gt;.
For verbs like &lt;strong&gt;get&lt;/strong&gt; or &lt;strong&gt;update&lt;/strong&gt; it will work. However, filtering by &lt;code&gt;resourceNames&lt;/code&gt; using &lt;strong&gt;list&lt;/strong&gt;
verb doesn&#39;t work like that. Thus you can limit listing certain resources by kind but not by name.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Kubernetes has a special API used to provide users with information about their permissions.
This is implemented using the SelfSubjectAccessReview API. One unusual detail of these
resources is that you can&#39;t view them using &lt;strong&gt;get&lt;/strong&gt; or &lt;strong&gt;list&lt;/strong&gt; verbs. You can only create them (using
the &lt;strong&gt;create&lt;/strong&gt; verb) and receive output with information about what you have access to at that
moment.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So, we decided to introduce new resource types based on the names of the Helm charts they use and
generate the list of available kinds dynamically at runtime in our extension api-server.
This way, we can reuse Kubernetes standard RBAC model to manage access to specific resource types.&lt;/p&gt;
&lt;h3 id=&#34;need-for-a-public-api&#34;&gt;Need for a public API&lt;/h3&gt;
&lt;p&gt;Since our platform provides capabilities for deploying various managed services, we want to organize
public access to the platform&#39;s API. However, we can&#39;t allow users to interact directly with resources
like HelmRelease because that would let them specify arbitrary names and parameters for Helm charts to
deploy, potentially compromising our system.&lt;/p&gt;
&lt;p&gt;We wanted to give users the ability to deploy a specific service simply by creating the resource with corresponding
kind in Kubernetes. The type of this resource should be named the same as the chart from
which it&#39;s deployed. Here are some examples:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;kind: Kubernetes&lt;/code&gt; → &lt;code&gt;chart: kubernetes&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;kind: Postgres&lt;/code&gt; → &lt;code&gt;chart: postgres&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;kind: Redis&lt;/code&gt; → &lt;code&gt;chart: redis&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;kind: VirtualMachine&lt;/code&gt; → &lt;code&gt;chart: virtual-machine&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Moreover, we don&#39;t want to have to add a new type to codegen and recompile our extension API server
every time we add a new chart for it to start being served.
The schema update should be done dynamically or provided via a ConfigMap by the administrator.&lt;/p&gt;
&lt;h3 id=&#34;two-way-conversion&#34;&gt;Two-Way conversion&lt;/h3&gt;
&lt;p&gt;Currently, we already have integrations and a dashboard that continue to use HelmRelease resources.
At this stage, we didn&#39;t want to lose the ability to support this API. Considering that we&#39;re simply
translating one resource into another, support is maintained and it works both ways.
If you create a HelmRelease, you&#39;ll get a custom resource in Kubernetes, and if you create a
custom resource in Kubernetes, it will also be available as a HelmRelease.&lt;/p&gt;
&lt;p&gt;We don&#39;t have any additional controllers that synchronize state between these resources.
All requests to resources in our extension API server are transparently proxied to HelmRelease and vice versa.
This eliminates intermediate states and the need to write controllers and synchronization logic.&lt;/p&gt;
&lt;h2 id=&#34;implementation&#34;&gt;Implementation&lt;/h2&gt;
&lt;p&gt;To implement the Aggregation API, you might consider starting with the following projects:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes-sigs/apiserver-builder-alpha&#34;&gt;apiserver-builder&lt;/a&gt;:
Currently in alpha and hasn&#39;t been updated for two years. It works like kubebuilder,
providing a framework for creating an extension API server, allowing you to sequentially create
a project structure and generate code for your resources.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/sample-apiserver&#34;&gt;sample-apiserver&lt;/a&gt;:
A ready-made example of an implemented API server, based on official Kubernetes libraries,
which you can use as a foundation for your project.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For practical reasons, we chose the second project. Here&#39;s what we needed to do:&lt;/p&gt;
&lt;h3 id=&#34;disable-etcd-support&#34;&gt;Disable etcd support&lt;/h3&gt;
&lt;p&gt;In our case, we don&#39;t need it since all resources are stored directly in the Kubernetes API.&lt;/p&gt;
&lt;p&gt;You can disable etcd options by passing nil to &lt;code&gt;RecommendedOptions.Etcd&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/aenix-io/cozystack/blob/003edf8cf0a419bd67cd822d61ff806db49e7026/pkg/cmd/server/start.go#L70&#34;&gt;Disabling etcd options&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;generate-a-common-resource-kind&#34;&gt;Generate a common resource kind&lt;/h3&gt;
&lt;p&gt;We called it Application, and it looks like this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/aenix-io/cozystack/blob/003edf8cf0a419bd67cd822d61ff806db49e7026/pkg/apis/apps/v1alpha1/types.go&#34;&gt;Application type definition&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is a generic type used for any application type, and its handling logic is the same for all charts.&lt;/p&gt;
&lt;h3 id=&#34;configure-configuration-loading&#34;&gt;Configure configuration loading&lt;/h3&gt;
&lt;p&gt;Since we want to configure our extension api-server via a config file, we formed the config structure in Go:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/aenix-io/cozystack/blob/003edf8cf0a419bd67cd822d61ff806db49e7026/pkg/config/config.go&#34;&gt;Config type definition&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We also modified the resource registration logic so that the resources we create are registered in scheme with different &lt;code&gt;Kind&lt;/code&gt; values:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/aenix-io/cozystack/blob/003edf8cf0a419bd67cd822d61ff806db49e7026/pkg/apis/apps/v1alpha1/register.go#L63-L77&#34;&gt;Dynamic resource registration&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As a result, we got a config where you can pass all possible types and specify what they should map to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/aenix-io/cozystack/blob/003edf8cf0a419bd67cd822d61ff806db49e7026/packages/system/cozystack-api/templates/configmap.yaml&#34;&gt;ConfigMap example&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;implement-our-own-registry&#34;&gt;Implement our own registry&lt;/h3&gt;
&lt;p&gt;To store state not in etcd but translate it directly into Kubernetes HelmRelease resources (and vice versa),
we wrote conversion functions from Application to HelmRelease and from HelmRelease to Application:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/aenix-io/cozystack/blob/003edf8cf0a419bd67cd822d61ff806db49e7026/pkg/registry/apps/application/rest.go#L920-L991&#34;&gt;Conversion functions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We implemented logic to filter resources by chart name, &lt;code&gt;sourceRef&lt;/code&gt;, and prefix in the HelmRelease name:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/aenix-io/cozystack/blob/003edf8cf0a419bd67cd822d61ff806db49e7026/pkg/registry/apps/application/rest.go#L747-L784&#34;&gt;Filtering functions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Then, using this logic, we implemented the methods &lt;code&gt;Get()&lt;/code&gt;, &lt;code&gt;Delete()&lt;/code&gt;, &lt;code&gt;List()&lt;/code&gt;, &lt;code&gt;Create()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You can see the full example here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/aenix-io/cozystack/blob/003edf8cf0a419bd67cd822d61ff806db49e7026/pkg/registry/apps/application/rest.go&#34;&gt;Registry Implementation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At the end of each method, we set the correct &lt;code&gt;Kind&lt;/code&gt; and return an &lt;code&gt;unstructured.Unstructured{}&lt;/code&gt; object
so that Kubernetes serializes the object correctly. Otherwise,
it would always serialize them with &lt;code&gt;kind: Application&lt;/code&gt;, which we don&#39;t want.&lt;/p&gt;
&lt;h2 id=&#34;what-did-we-achieve&#34;&gt;What did we achieve?&lt;/h2&gt;
&lt;p&gt;In Cozystack, all our types from the ConfigMap are now available in Kubernetes as-is:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kubectl api-resources | grep cozystack
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;buckets                   apps.cozystack.io/v1alpha1      true        Bucket
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;clickhouses               apps.cozystack.io/v1alpha1      true        ClickHouse
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;etcds                     apps.cozystack.io/v1alpha1      true        Etcd
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;ferretdb                  apps.cozystack.io/v1alpha1      true        FerretDB
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;httpcaches                apps.cozystack.io/v1alpha1      true        HTTPCache
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;ingresses                 apps.cozystack.io/v1alpha1      true        Ingress
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;kafkas                    apps.cozystack.io/v1alpha1      true        Kafka
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;kuberneteses              apps.cozystack.io/v1alpha1      true        Kubernetes
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;monitorings               apps.cozystack.io/v1alpha1      true        Monitoring
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;mysqls                    apps.cozystack.io/v1alpha1      true        MySQL
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;natses                    apps.cozystack.io/v1alpha1      true        NATS
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;postgreses                apps.cozystack.io/v1alpha1      true        Postgres
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;rabbitmqs                 apps.cozystack.io/v1alpha1      true        RabbitMQ
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;redises                   apps.cozystack.io/v1alpha1      true        Redis
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;seaweedfses               apps.cozystack.io/v1alpha1      true        SeaweedFS
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;tcpbalancers              apps.cozystack.io/v1alpha1      true        TCPBalancer
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;tenants                   apps.cozystack.io/v1alpha1      true        Tenant
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;virtualmachines           apps.cozystack.io/v1alpha1      true        VirtualMachine
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;vmdisks                   apps.cozystack.io/v1alpha1      true        VMDisk
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;vminstances               apps.cozystack.io/v1alpha1      true        VMInstance
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;vpns                      apps.cozystack.io/v1alpha1      true        VPN
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We can work with them just like regular Kubernetes resources.&lt;/p&gt;
&lt;p&gt;Listing S3 Buckets:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kubectl get buckets.apps.cozystack.io -n tenant-kvaps
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Example output:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;NAME         READY   AGE    VERSION
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;foo          True    22h    0.1.0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;testaasd     True    27h    0.1.0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Listing Kubernetes Clusters:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kubectl get kuberneteses.apps.cozystack.io -n tenant-kvaps
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Example output:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;NAME     READY   AGE    VERSION
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;abc      False   19h    0.14.0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;asdte    True    22h    0.13.0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Listing Virtual Machine Disks:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kubectl get vmdisks.apps.cozystack.io -n tenant-kvaps
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Example output:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;NAME               READY   AGE    VERSION
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;docker             True    21d    0.1.0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;test               True    18d    0.1.0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;win2k25-iso        True    21d    0.1.0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;win2k25-system     True    21d    0.1.0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Listing Virtual Machine Instances:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kubectl get vminstances.apps.cozystack.io -n tenant-kvaps
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Example output:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;NAME        READY   AGE    VERSION
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;docker      True    21d    0.1.0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;test        True    18d    0.1.0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;win2k25     True    20d    0.1.0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We can create, modify, and delete each of them, and any interaction with them will be translated
into HelmRelease resources, while also applying the resource structure and prefix in the name.&lt;/p&gt;
&lt;p&gt;To see all related Helm releases:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kubectl get helmreleases -n tenant-kvaps -l cozystack.io/ui
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Example output:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;NAME                     AGE    READY
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;bucket-foo               22h    True
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;bucket-testaasd          27h    True
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;kubernetes-abc           19h    False
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;kubernetes-asdte         22h    True
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;redis-test               18d    True
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;redis-yttt               12d    True
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;vm-disk-docker           21d    True
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;vm-disk-test             18d    True
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;vm-disk-win2k25-iso      21d    True
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;vm-disk-win2k25-system   21d    True
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;vm-instance-docker       21d    True
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;vm-instance-test         18d    True
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;vm-instance-win2k25      20d    True
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;next-steps&#34;&gt;Next Steps&lt;/h2&gt;
&lt;p&gt;We don’t intend to stop here with our API. In the future, we plan to add new features:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add validation based on an OpenAPI spec generated directly from Helm charts.&lt;/li&gt;
&lt;li&gt;Develop a controller that collects release notes from deployed releases and shows users
access information for specific services.&lt;/li&gt;
&lt;li&gt;Revamp our dashboard to work directly with the new API.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;The API Aggregation Layer allowed us to quickly and efficiently solve our problem by providing
a flexible mechanism for extending the Kubernetes API with dynamically registered resources and
converting them on the fly. Ultimately, this made our platform even more flexible and extensible
without the need to write code for each new resource.&lt;/p&gt;
&lt;p&gt;You can test the API yourself in the open-source PaaS platform Cozystack,
starting from &lt;a href=&#34;https://github.com/aenix-io/cozystack/releases/tag/v0.18.0&#34;&gt;version v0.18&lt;/a&gt;.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes v1.32 sneak peek</title>
      <link>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/11/08/kubernetes-1-32-upcoming-changes/</link>
      <pubDate>Fri, 08 Nov 2024 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/11/08/kubernetes-1-32-upcoming-changes/</guid>
      <description>
        
        
        &lt;p&gt;As we get closer to the release date for Kubernetes v1.32, the project develops and matures.
Features may be deprecated, removed, or replaced with better ones for the project&#39;s overall health.&lt;/p&gt;
&lt;p&gt;This blog outlines some of the planned changes for the Kubernetes v1.32 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.
Information listed below is based on the current status of the v1.32 release
and may change before the actual release date.&lt;/p&gt;
&lt;h2 id=&#34;the-kubernetes-api-removal-and-deprecation-process&#34;&gt;The Kubernetes API removal and deprecation process&lt;/h2&gt;
&lt;p&gt;The Kubernetes project has a well-documented &lt;a href=&#34;https://deploy-preview-50011--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 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 will continue to function until
removal (at least one year from the deprecation). Its usage will result in a warning being displayed.
Removed APIs are no longer available in the current version, so you must migrate to use the replacement instead.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&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;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Beta or pre-release API versions must be supported for 3 releases after the deprecation.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&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;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Whether an API is removed due to a feature graduating from beta to stable or because that API 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-50011--kubernetes-io-main-staging.netlify.app/docs/reference/using-api/deprecation-guide/&#34;&gt;deprecation guide&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;note-on-the-withdrawal-of-the-old-dra-implementation&#34;&gt;Note on the withdrawal of the old DRA implementation&lt;/h2&gt;
&lt;p&gt;The enhancement &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/3063&#34;&gt;#3063&lt;/a&gt;
introduced Dynamic Resource Allocation (DRA) in Kubernetes 1.26.&lt;/p&gt;
&lt;p&gt;However, in Kubernetes v1.32, this approach to DRA will be significantly changed.
Code related to the original implementation will be removed, leaving KEP
&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/4381&#34;&gt;#4381&lt;/a&gt; as the &amp;quot;new&amp;quot; base functionality.&lt;/p&gt;
&lt;p&gt;The decision to change the existing approach originated from its incompatibility with cluster autoscaling
as resource availability was non-transparent, complicating decision-making for both Cluster Autoscaler and controllers.
The newly added Structured Parameter model substitutes the functionality.&lt;/p&gt;
&lt;p&gt;This removal will allow Kubernetes to handle new hardware requirements and resource claims more predictably,
bypassing the complexities of back and forth API calls to the kube-apiserver.&lt;/p&gt;
&lt;p&gt;Please also see the enhancement issue &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/3063&#34;&gt;#3063&lt;/a&gt; to find out more.&lt;/p&gt;
&lt;h2 id=&#34;api-removal&#34;&gt;API removal&lt;/h2&gt;
&lt;p&gt;There is only a single API removal planned for &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/reference/using-api/deprecation-guide/#v1-32&#34;&gt;Kubernetes v1.32&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;flowcontrol.apiserver.k8s.io/v1beta3&lt;/code&gt; API version of FlowSchema and PriorityLevelConfiguration has been removed.
To prepare for this, you can edit your existing manifests and rewrite client software to use the
&lt;code&gt;flowcontrol.apiserver.k8s.io/v1 API&lt;/code&gt; version, available since v1.29.
All existing persisted objects are accessible via the new API. Notable changes in &lt;code&gt;flowcontrol.apiserver.k8s.io/v1beta3&lt;/code&gt;
include that the PriorityLevelConfiguration &lt;code&gt;spec.limited.nominalConcurrencyShares&lt;/code&gt; field only defaults to 30 when unspecified,
and an explicit value of 0 is not changed to 30.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For more information, please refer to the &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/reference/using-api/deprecation-guide/#v1-32&#34;&gt;API deprecation guide&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;sneak-peek-of-kubernetes-v1-32&#34;&gt;Sneak peek of Kubernetes v1.32&lt;/h2&gt;
&lt;p&gt;The following list of enhancements is likely to be included in the v1.32 release.
This is not a commitment and the release content is subject to change.&lt;/p&gt;
&lt;h3 id=&#34;even-more-dra-enhancements&#34;&gt;Even more DRA enhancements!&lt;/h3&gt;
&lt;p&gt;In this release, like the previous one, the Kubernetes project continues proposing a number
of enhancements to the Dynamic Resource Allocation (DRA), a key component of the Kubernetes resource management system.
These enhancements aim to improve the flexibility and efficiency of resource allocation for workloads that require specialized hardware,
such as GPUs, FPGAs and network adapters. This release introduces improvements,
including the addition of resource health status in the Pod status, as outlined in
KEP &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/4680&#34;&gt;#4680&lt;/a&gt;.&lt;/p&gt;
&lt;h4 id=&#34;add-resource-health-status-to-the-pod-status&#34;&gt;Add resource health status to the Pod status&lt;/h4&gt;
&lt;p&gt;It isn&#39;t easy to know when a Pod uses a device that has failed or is temporarily unhealthy.
KEP &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/4680&#34;&gt;#4680&lt;/a&gt; proposes exposing device
health via Pod &lt;code&gt;status&lt;/code&gt;, making troubleshooting of Pod crashes easier.&lt;/p&gt;
&lt;h3 id=&#34;windows-strikes-back&#34;&gt;Windows strikes back!&lt;/h3&gt;
&lt;p&gt;KEP &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/4802&#34;&gt;#4802&lt;/a&gt; adds support
for graceful shutdowns of Windows nodes in Kubernetes clusters.
Before this release, Kubernetes provided graceful node shutdown functionality for
Linux nodes but lacked equivalent support for Windows.
This enhancement enables the kubelet on Windows nodes to handle system shutdown events properly.
Doing so, it ensures that Pods running on Windows nodes are gracefully terminated,
allowing workloads to be rescheduled without disruption.
This improvement enhances the reliability and stability of clusters that include Windows nodes,
especially during a planned maintenance or any system updates.&lt;/p&gt;
&lt;h3 id=&#34;allow-special-characters-in-environment-variables&#34;&gt;Allow special characters in environment variables&lt;/h3&gt;
&lt;p&gt;With the graduation of this &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/4369&#34;&gt;enhancement&lt;/a&gt; to beta,
Kubernetes now allows almost all printable ASCII characters (excluding &amp;quot;=&amp;quot;) to be used as environment variable names.
This change addresses the limitations previously imposed on variable naming, facilitating a broader adoption of
Kubernetes by accommodating various application needs. The relaxed validation will be enabled by default via the
&lt;code&gt;RelaxedEnvironmentVariableValidation&lt;/code&gt; feature gate, ensuring that users can easily utilize environment
variables without strict constraints, enhancing flexibility for developers working with applications like
.NET Core that require special characters in their configurations.&lt;/p&gt;
&lt;h3 id=&#34;make-kubernetes-aware-of-the-loadbalancer-behavior&#34;&gt;Make Kubernetes aware of the LoadBalancer behavior&lt;/h3&gt;
&lt;p&gt;KEP &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/1860&#34;&gt;#1860&lt;/a&gt; graduates to GA,
introducing the &lt;code&gt;ipMode&lt;/code&gt; field for a Service of &lt;code&gt;type: LoadBalancer&lt;/code&gt;, which can be set to either
&lt;code&gt;&amp;quot;VIP&amp;quot;&lt;/code&gt; or &lt;code&gt;&amp;quot;Proxy&amp;quot;&lt;/code&gt;. This enhancement is aimed at improving how cloud providers load balancers
interact with kube-proxy and it is a change transparent to the end user.
The existing behavior of kube-proxy is preserved when using &lt;code&gt;&amp;quot;VIP&amp;quot;&lt;/code&gt;,
where kube-proxy handles the load balancing. Using &lt;code&gt;&amp;quot;Proxy&amp;quot;&lt;/code&gt; results in traffic sent directly to the load balancer,
providing cloud providers greater control over relying on kube-proxy;
this means that you could see an improvement in the performance of your load balancer for some cloud providers.&lt;/p&gt;
&lt;h3 id=&#34;retry-generate-name-for-resources&#34;&gt;Retry generate name for resources&lt;/h3&gt;
&lt;p&gt;This &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/4420&#34;&gt;enhancement&lt;/a&gt;
improves how name conflicts are handled for Kubernetes resources created with the &lt;code&gt;generateName&lt;/code&gt; field.
Previously, if a name conflict occurred, the API server returned a 409 HTTP Conflict error and clients
had to manually retry the request. With this update, the API server automatically retries generating
a new name up to seven times in case of a conflict. This significantly reduces the chances of collision,
ensuring smooth generation of up to 1 million names with less than a 0.1% probability of a conflict,
providing more resilience for large-scale workloads.&lt;/p&gt;
&lt;h2 id=&#34;want-to-know-more&#34;&gt;Want to know more?&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.32.md&#34;&gt;Kubernetes v1.32&lt;/a&gt;
as part of the CHANGELOG for this release.&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.31.md&#34;&gt;Kubernetes v1.31&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.30.md&#34;&gt;Kubernetes v1.30&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.29.md&#34;&gt;Kubernetes v1.29&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.28.md&#34;&gt;Kubernetes v1.28&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Spotlight on Kubernetes Upstream Training in Japan</title>
      <link>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/10/28/k8s-upstream-training-japan-spotlight/</link>
      <pubDate>Mon, 28 Oct 2024 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/10/28/k8s-upstream-training-japan-spotlight/</guid>
      <description>
        
        
        &lt;p&gt;We are organizers of &lt;a href=&#34;https://github.com/kubernetes-sigs/contributor-playground/tree/master/japan&#34;&gt;Kubernetes Upstream Training in Japan&lt;/a&gt;.
Our team is composed of members who actively contribute to Kubernetes, including individuals who hold roles such as member, reviewer, approver, and chair.&lt;/p&gt;
&lt;p&gt;Our goal is to increase the number of Kubernetes contributors and foster the growth of the community.
While Kubernetes community is friendly and collaborative, newcomers may find the first step of contributing to be a bit challenging.
Our training program aims to lower that barrier and create an environment where even beginners can participate smoothly.&lt;/p&gt;
&lt;h2 id=&#34;what-is-kubernetes-upstream-training-in-japan&#34;&gt;What is Kubernetes upstream training in Japan?&lt;/h2&gt;
&lt;p&gt;&lt;img alt=&#34;Upstream Training in 2022&#34; src=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/10/28/k8s-upstream-training-japan-spotlight/ood-2022-01.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;Our training started in 2019 and is held 1 to 2 times a year.
Initially, Kubernetes Upstream Training was conducted as a co-located event of KubeCon (Kubernetes Contributor Summit),
but we launched Kubernetes Upstream Training in Japan with the aim of increasing Japanese contributors by hosting a similar event in Japan.&lt;/p&gt;
&lt;p&gt;Before the pandemic, the training was held in person, but since 2020, it has been conducted online.
The training offers the following content for those who have not yet contributed to Kubernetes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Introduction to Kubernetes community&lt;/li&gt;
&lt;li&gt;Overview of Kubernetes codebase and how to create your first PR&lt;/li&gt;
&lt;li&gt;Tips and encouragement to lower participation barriers, such as language&lt;/li&gt;
&lt;li&gt;How to set up the development environment&lt;/li&gt;
&lt;li&gt;Hands-on session using &lt;a href=&#34;https://github.com/kubernetes-sigs/contributor-playground&#34;&gt;kubernetes-sigs/contributor-playground&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At the beginning of the program, we explain why contributing to Kubernetes is important and who can contribute.
We emphasize that contributing to Kubernetes allows you to make a global impact and that Kubernetes community is looking forward to your contributions!&lt;/p&gt;
&lt;p&gt;We also explain Kubernetes community, SIGs, and Working Groups.
Next, we explain the roles and responsibilities of Member, Reviewer, Approver, Tech Lead, and Chair.
Additionally, we introduce the communication tools we primarily use, such as Slack, GitHub, and mailing lists.
Some Japanese speakers may feel that communicating in English is a barrier.
Additionally, those who are new to the community need to understand where and how communication takes place.
We emphasize the importance of taking that first step, which is the most important aspect we focus on in our training!&lt;/p&gt;
&lt;p&gt;We then go over the structure of Kubernetes codebase, the main repositories, how to create a PR, and the CI/CD process using &lt;a href=&#34;https://docs.prow.k8s.io/&#34;&gt;Prow&lt;/a&gt;.
We explain in detail the process from creating a PR to getting it merged.&lt;/p&gt;
&lt;p&gt;After several lectures, participants get to experience hands-on work using &lt;a href=&#34;https://github.com/kubernetes-sigs/contributor-playground&#34;&gt;kubernetes-sigs/contributor-playground&lt;/a&gt;, where they can create a simple PR.
The goal is for participants to get a feel for the process of contributing to Kubernetes.&lt;/p&gt;
&lt;p&gt;At the end of the program, we also provide a detailed explanation of setting up the development environment for contributing to the &lt;code&gt;kubernetes/kubernetes&lt;/code&gt; repository,
including building code locally, running tests efficiently, and setting up clusters.&lt;/p&gt;
&lt;h2 id=&#34;interview-with-participants&#34;&gt;Interview with participants&lt;/h2&gt;
&lt;p&gt;We conducted interviews with those who participated in our training program.
We asked them about their reasons for joining, their impressions, and their future goals.&lt;/p&gt;
&lt;h3 id=&#34;keita-mochizuki-https-github-com-mochizuki875-ntt-data-group-corporation-https-www-nttdata-com-global-en-about-us-profile&#34;&gt;&lt;a href=&#34;https://github.com/mochizuki875&#34;&gt;Keita Mochizuki&lt;/a&gt; (&lt;a href=&#34;https://www.nttdata.com/global/en/about-us/profile&#34;&gt;NTT DATA Group Corporation&lt;/a&gt;)&lt;/h3&gt;
&lt;p&gt;Keita Mochizuki is a contributor who consistently contributes to Kubernetes and related projects.
Keita is also a professional in container security and has recently published a book.
Additionally, he has made available a &lt;a href=&#34;https://github.com/mochizuki875/KubernetesFirstContributionRoadMap&#34;&gt;Roadmap for New Contributors&lt;/a&gt;, which is highly beneficial for those new to contributing.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Junya:&lt;/strong&gt; Why did you decide to participate in Kubernetes Upstream Training?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Keita:&lt;/strong&gt; Actually, I participated twice, in 2020 and 2022.
In 2020, I had just started learning about Kubernetes and wanted to try getting involved in activities outside of work, so I signed up after seeing the event on Twitter by chance.
However, I didn&#39;t have much knowledge at the time, and contributing to OSS felt like something beyond my reach.
As a result, my understanding after the training was shallow, and I left with more of a &amp;quot;hmm, okay&amp;quot; feeling.&lt;/p&gt;
&lt;p&gt;In 2022, I participated again when I was at a stage where I was seriously considering starting contributions.
This time, I did prior research and was able to resolve my questions during the lectures, making it a very productive experience.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Junya:&lt;/strong&gt; How did you feel after participating?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Keita:&lt;/strong&gt; I felt that the significance of this training greatly depends on the participant&#39;s mindset.
The training itself consists of general explanations and simple hands-on exercises, but it doesn&#39;t mean that attending the training will immediately lead to contributions.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Junya:&lt;/strong&gt; What is your purpose for contributing?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Keita:&lt;/strong&gt; My initial motivation was to &amp;quot;gain a deep understanding of Kubernetes and build a track record,&amp;quot; meaning &amp;quot;contributing itself was the goal.&amp;quot;
Nowadays, I also contribute to address bugs or constraints I discover during my work.
Additionally, through contributing, I&#39;ve become less hesitant to analyze undocumented features directly from the source code.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Junya:&lt;/strong&gt; What has been challenging about contributing?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Keita:&lt;/strong&gt; The most difficult part was taking the first step. Contributing to OSS requires a certain level of knowledge, and leveraging resources like this training and support from others was essential.
One phrase that stuck with me was, &amp;quot;Once you take the first step, it becomes easier to move forward.&amp;quot;
Also, in terms of continuing contributions as part of my job, the most challenging aspect is presenting the outcomes as achievements.
To keep contributing over time, it&#39;s important to align it with business goals and strategies, but upstream contributions don&#39;t always lead to immediate results that can be directly tied to performance.
Therefore, it&#39;s crucial to ensure mutual understanding with managers and gain their support.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Junya:&lt;/strong&gt; What are your future goals?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Keita:&lt;/strong&gt; My goal is to contribute to areas with a larger impact.
So far, I&#39;ve mainly contributed by fixing smaller bugs as my primary focus was building a track record,
but moving forward, I&#39;d like to challenge myself with contributions that have a greater impact on Kubernetes users or that address issues related to my work.
Recently, I&#39;ve also been working on reflecting the changes I&#39;ve made to the codebase into the official documentation,
and I see this as a step toward achieving my goals.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Junya:&lt;/strong&gt; Thank you very much!&lt;/p&gt;
&lt;h3 id=&#34;yoshiki-fujikane-https-github-com-ffjlabo-cyberagent-inc-https-www-cyberagent-co-jp-en&#34;&gt;&lt;a href=&#34;https://github.com/ffjlabo&#34;&gt;Yoshiki Fujikane&lt;/a&gt; (&lt;a href=&#34;https://www.cyberagent.co.jp/en/&#34;&gt;CyberAgent, Inc.&lt;/a&gt;)&lt;/h3&gt;
&lt;p&gt;Yoshiki Fujikane is one of the maintainers of &lt;a href=&#34;https://pipecd.dev/&#34;&gt;PipeCD&lt;/a&gt;, a CNCF Sandbox project.
In addition to developing new features for Kubernetes support in PipeCD,
Yoshiki actively participates in community management and speaks at various technical conferences.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Junya:&lt;/strong&gt; Why did you decide to participate in the Kubernetes Upstream Training?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Yoshiki:&lt;/strong&gt; At the time I participated, I was still a student.
I had only briefly worked with EKS, but I thought Kubernetes seemed complex yet cool, and I was casually interested in it.
Back then, OSS felt like something out of reach, and upstream development for Kubernetes seemed incredibly daunting.
While I had always been interested in OSS, I didn&#39;t know where to start.
It was during this time that I learned about the Kubernetes Upstream Training and decided to take the challenge of contributing to Kubernetes.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Junya:&lt;/strong&gt; What were your impressions after participating?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Yoshiki:&lt;/strong&gt; I found it extremely valuable as a way to understand what it&#39;s like to be part of an OSS community.
At the time, my English skills weren&#39;t very strong, so accessing primary sources of information felt like a big hurdle for me.
Kubernetes is a very large project, and I didn&#39;t have a clear understanding of the overall structure, let alone what was necessary for contributing.
The upstream training provided a Japanese explanation of the community structure and allowed me to gain hands-on experience with actual contributions.
Thanks to the guidance I received, I was able to learn how to approach primary sources and use them as entry points for further investigation, which was incredibly helpful.
This experience made me realize the importance of organizing and reviewing primary sources, and now I often dive into GitHub issues and documentation when something piques my interest.
As a result, while I am no longer contributing to Kubernetes itself, the experience has been a great foundation for contributing to other projects.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Junya:&lt;/strong&gt; What areas are you currently contributing to, and what are the other projects you&#39;re involved in?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Yoshiki:&lt;/strong&gt; Right now, I&#39;m no longer working with Kubernetes, but instead, I&#39;m a maintainer of PipeCD, a CNCF Sandbox project.
PipeCD is a CD tool that supports GitOps-style deployments for various application platforms.
The tool originally started as an internal project at CyberAgent.
With different teams adopting different platforms, PipeCD was developed to provide a unified CD platform with a consistent user experience.
Currently, it supports Kubernetes, AWS ECS, Lambda, Cloud Run, and Terraform.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Junya:&lt;/strong&gt; What role do you play within the PipeCD team?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Yoshiki:&lt;/strong&gt; I work full-time on improving and developing Kubernetes-related features within the team.
Since we provide PipeCD as a SaaS internally, my main focus is on adding new features and improving existing ones as part of that support.
In addition to code contributions, I also contribute by giving talks at various events and managing community meetings to help grow the PipeCD community.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Junya:&lt;/strong&gt; Could you explain what kind of improvements or developments you are working on with regards to Kubernetes?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Yoshiki:&lt;/strong&gt; PipeCD supports GitOps and Progressive Delivery for Kubernetes, so I&#39;m involved in the development of those features.
Recently, I&#39;ve been working on features that streamline deployments across multiple clusters.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Junya:&lt;/strong&gt; Have you encountered any challenges while contributing to OSS?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Yoshiki:&lt;/strong&gt; One challenge is developing features that maintain generality while meeting user use cases.
When we receive feature requests while operating the internal SaaS, we first consider adding features to solve those issues.
At the same time, we want PipeCD to be used by a broader audience as an OSS tool.
So, I always think about whether a feature designed for one use case could be applied to another, ensuring the software remains flexible and widely usable.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Junya:&lt;/strong&gt; What are your goals moving forward?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Yoshiki:&lt;/strong&gt; I want to focus on expanding PipeCD&#39;s functionality.
Currently, we are developing PipeCD under the slogan &amp;quot;One CD for All.&amp;quot;
As I mentioned earlier, it supports Kubernetes, AWS ECS, Lambda, Cloud Run, and Terraform, but there are many other platforms out there, and new platforms may emerge in the future.
For this reason, we are currently developing a plugin system that will allow users to extend PipeCD on their own, and I want to push this effort forward.
I&#39;m also working on features for multi-cluster deployments in Kubernetes, and I aim to continue making impactful contributions.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Junya:&lt;/strong&gt; Thank you very much!&lt;/p&gt;
&lt;h2 id=&#34;future-of-kubernetes-upstream-training&#34;&gt;Future of Kubernetes upstream training&lt;/h2&gt;
&lt;p&gt;We plan to continue hosting Kubernetes Upstream Training in Japan and look forward to welcoming many new contributors.
Our next session is scheduled to take place at the end of November during &lt;a href=&#34;https://event.cloudnativedays.jp/cndw2024&#34;&gt;CloudNative Days Winter 2024&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Moreover, our goal is to expand these training programs not only in Japan but also around the world.
&lt;a href=&#34;https://kubernetes.io/blog/2024/06/06/10-years-of-kubernetes/&#34;&gt;Kubernetes celebrated its 10th anniversary&lt;/a&gt; this year, and for the community to become even more active, it&#39;s crucial for people across the globe to continue contributing.
While Upstream Training is already held in several regions, we aim to bring it to even more places.&lt;/p&gt;
&lt;p&gt;We hope that as more people join Kubernetes community and contribute, our community will become even more vibrant!&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Announcing the 2024 Steering Committee Election Results</title>
      <link>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/10/02/steering-committee-results-2024/</link>
      <pubDate>Wed, 02 Oct 2024 15:10:00 -0500</pubDate>
      
      <guid>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/10/02/steering-committee-results-2024/</guid>
      <description>
        
        
        &lt;p&gt;The &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/elections/steering/2024&#34;&gt;2024 Steering Committee Election&lt;/a&gt; is now complete. The Kubernetes Steering Committee consists of 7 seats, 3 of which were up for election in 2024. Incoming committee members serve a term of 2 years, and all members are elected by the Kubernetes Community.&lt;/p&gt;
&lt;p&gt;This community body is significant since it oversees the governance of the entire Kubernetes project. With that great power comes great responsibility. You can learn more about the steering committee’s role in their &lt;a href=&#34;https://github.com/kubernetes/steering/blob/master/charter.md&#34;&gt;charter&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Thank you to everyone who voted in the election; your participation helps support the community’s continued health and success.&lt;/p&gt;
&lt;h2 id=&#34;results&#34;&gt;Results&lt;/h2&gt;
&lt;p&gt;Congratulations to the elected committee members whose two year terms begin immediately (listed in alphabetical order by GitHub handle):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Antonio Ojea (&lt;a href=&#34;https://github.com/aojea&#34;&gt;@aojea&lt;/a&gt;), Google&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Benjamin Elder (&lt;a href=&#34;https://github.com/bentheelder&#34;&gt;@BenTheElder&lt;/a&gt;), Google&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sascha Grunert (&lt;a href=&#34;https://github.com/saschagrunert&#34;&gt;@saschagrunert&lt;/a&gt;), Red Hat&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;They join continuing members:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Stephen Augustus (&lt;a href=&#34;https://github.com/justaugustus&#34;&gt;@justaugustus&lt;/a&gt;), Cisco&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Paco Xu 徐俊杰 (&lt;a href=&#34;https://github.com/pacoxu&#34;&gt;@pacoxu&lt;/a&gt;), DaoCloud&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Patrick Ohly (&lt;a href=&#34;https://github.com/pohly&#34;&gt;@pohly&lt;/a&gt;), Intel&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Maciej Szulik (&lt;a href=&#34;https://github.com/soltysh&#34;&gt;@soltysh&lt;/a&gt;), Defense Unicorns&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Benjamin Elder is a returning Steering Committee Member.&lt;/p&gt;
&lt;h2 id=&#34;big-thanks&#34;&gt;Big thanks!&lt;/h2&gt;
&lt;p&gt;Thank you and congratulations on a successful election to this round’s election officers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Bridget Kromhout (&lt;a href=&#34;https://github.com/bridgetkromhout&#34;&gt;@bridgetkromhout&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Christoph Blecker (&lt;a href=&#34;https://github.com/cblecker&#34;&gt;@cblecker&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Priyanka Saggu (&lt;a href=&#34;https://github.com/Priyankasaggu11929&#34;&gt;@Priyankasaggu11929&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Thanks to the Emeritus Steering Committee Members. Your service is appreciated by the community:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Bob Killen (&lt;a href=&#34;https://github.com/mrbobbytables&#34;&gt;@mrbobbytables&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Nabarun Pal (&lt;a href=&#34;https://github.com/palnabarun&#34;&gt;@palnabarun&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And thank you to all the candidates who came forward to run for election.&lt;/p&gt;
&lt;h2 id=&#34;get-involved-with-the-steering-committee&#34;&gt;Get involved with the Steering Committee&lt;/h2&gt;
&lt;p&gt;This governing body, like all of Kubernetes, is open to all. You can follow along with Steering Committee &lt;a href=&#34;https://bit.ly/k8s-steering-wd&#34;&gt;meeting notes&lt;/a&gt; and weigh in by filing an issue or creating a PR against their &lt;a href=&#34;https://github.com/kubernetes/steering&#34;&gt;repo&lt;/a&gt;. They have an open meeting on &lt;a href=&#34;https://github.com/kubernetes/steering&#34;&gt;the first Monday at 8am PT of every month&lt;/a&gt;. They can also be contacted at their public mailing list &lt;a href=&#34;mailto:steering@kubernetes.io&#34;&gt;steering@kubernetes.io&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You can see what the Steering Committee meetings are all about by watching past meetings on the &lt;a href=&#34;https://www.youtube.com/playlist?list=PL69nYSiGNLP1yP1B_nd9-drjoxp0Q14qM&#34;&gt;YouTube Playlist&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you want to meet some of the newly elected Steering Committee members, join us for the &lt;a href=&#34;https://www.kubernetes.dev/events/2024/kcsna/schedule/#steering-ama&#34;&gt;Steering AMA&lt;/a&gt; at the Kubernetes Contributor Summit North America 2024 in Salt Lake City.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;This post was adapted from one written by the &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/communication/contributor-comms&#34;&gt;Contributor Comms Subproject&lt;/a&gt;. If you want to write stories about the Kubernetes community, learn more about us.&lt;/em&gt;&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Spotlight on CNCF Deaf and Hard-of-hearing Working Group (DHHWG)</title>
      <link>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/09/30/cncf-deaf-and-hard-of-hearing-working-group-spotlight/</link>
      <pubDate>Mon, 30 Sep 2024 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/09/30/cncf-deaf-and-hard-of-hearing-working-group-spotlight/</guid>
      <description>
        
        
        &lt;p&gt;&lt;em&gt;In recognition of Deaf Awareness Month and the importance of inclusivity in the tech community, we are spotlighting &lt;a href=&#34;https://www.linkedin.com/in/catherinepaganini/&#34;&gt;Catherine Paganini&lt;/a&gt;, facilitator and one of the founding members of &lt;a href=&#34;https://contribute.cncf.io/about/deaf-and-hard-of-hearing/&#34;&gt;CNCF Deaf and Hard-of-Hearing Working Group&lt;/a&gt; (DHHWG). In this interview, &lt;a href=&#34;https://www.linkedin.com/in/sandeepkanabar/&#34;&gt;Sandeep Kanabar&lt;/a&gt;, a deaf member of the DHHWG and part of the Kubernetes &lt;a href=&#34;https://github.com/kubernetes/community/blob/master/sig-contributor-experience/README.md#contributor-comms&#34;&gt;SIG ContribEx Communications team&lt;/a&gt;, sits down with Catherine to explore the impact of the DHHWG on cloud native projects like Kubernetes.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Sandeep’s journey is a testament to the power of inclusion. Through his involvement in the DHHWG, he connected with members of the Kubernetes community who encouraged him to join &lt;a href=&#34;https://github.com/kubernetes/community/blob/master/sig-contributor-experience/README.md&#34;&gt;SIG ContribEx&lt;/a&gt; - the group responsible for sustaining the Kubernetes contributor experience. In an ecosystem where open-source projects are actively seeking contributors and maintainers, this story highlights how important it is to create pathways for underrepresented groups, including those with disabilities, to contribute their unique perspectives and skills.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;In this interview, we delve into Catherine’s journey, the challenges and triumphs of establishing the DHHWG, and the vision for a more inclusive future in cloud native. We invite Kubernetes contributors, maintainers, and community members to reflect on the &lt;strong&gt;significance of empathy, advocacy, and community&lt;/strong&gt; in fostering a truly inclusive environment for all, and to think about how they can support efforts to increase diversity and accessibility within their own projects.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&#34;introduction&#34;&gt;Introduction&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Sandeep Kanabar (SK): Hello Catherine, could you please introduce yourself, share your professional background, and explain your connection to the Kubernetes ecosystem?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Catherine Paganini (CP)&lt;/strong&gt;: I&#39;m the Head of Marketing at &lt;a href=&#34;https://buoyant.io/&#34;&gt;Buoyant&lt;/a&gt;, the creator of &lt;a href=&#34;https://linkerd.io/&#34;&gt;Linkerd&lt;/a&gt;, the CNCF-graduated service mesh, and 5th CNCF project. Four years ago, I started contributing to open source. The initial motivation was to make cloud native concepts more accessible to newbies and non-technical people. Without a technical background, it was hard for me to understand what Kubernetes, containers, service meshes, etc. mean. All content was targeted at engineers already familiar with foundational concepts. Clearly, I couldn&#39;t be the only one struggling with wrapping my head around cloud native.&lt;/p&gt;
&lt;p&gt;My first contribution was the &lt;a href=&#34;https://landscape.cncf.io/guide#introduction&#34;&gt;CNCF Landscape Guide&lt;/a&gt;, which I co-authored with my former colleague Jason Morgan. Next, we started the &lt;a href=&#34;https://glossary.cncf.io/&#34;&gt;CNCF Glossary&lt;/a&gt;, which explains cloud native concepts in simple terms. Today, the glossary has been (partially) localised into 14 languages!&lt;/p&gt;
&lt;p&gt;Currently, I&#39;m the co-chair of the &lt;a href=&#34;https://contribute.cncf.io/about/&#34;&gt;TAG Contributor Strategy&lt;/a&gt; and the Facilitator of the Deaf and Hard of Hearing Working Group (DHHWG) and Blind and Visually Impaired WG (BVIWG), which is still in formation. I&#39;m also working on a new Linux Foundation (LF) initiative called ABIDE (Accessibility and Belonging through Inclusion, Diversity, and Equity), so stay tuned to learn more about it!&lt;/p&gt;
&lt;h2 id=&#34;motivation-and-early-milestones&#34;&gt;Motivation and early milestones&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;SK: That&#39;s inspiring! Building on your passion for accessibility, what motivated you to facilitate the creation of the DHHWG? Was there a speecifc moment or experience that sparked this initiative?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;CP&lt;/strong&gt;: Last year at KubeCon Amsterdam, I learned about a great initiative by Jay Tihema that creates &lt;a href=&#34;https://contribute.cncf.io/resources/videos/2023/from-maori-to-deaf-engineers/&#34;&gt;pathways for Maori youth into cloud native&lt;/a&gt; and open source. While telling my CODA (children of deaf adults) high school friend about it, I thought it&#39;d be great to create something similar for deaf folks. A few months later, I posted about it in a LinkedIn post that the CNCF shared. Deaf people started to reach out, wanting to participate. And the rest is history.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SK: Speaking of history, since its launch, how has the DHHWG evolved? Could you highlight some of the key milestones or achievements the group has reached recently?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;CP&lt;/strong&gt;: Our WG is about a year old. It started with a few deaf engineers and me brainstorming how to make KubeCon more accessible. We published an initial draft of &lt;a href=&#34;https://contribute.cncf.io/accessibility/deaf-and-hard-of-hearing/conference-best-practices/&#34;&gt;Best practices for an inclusive conference&lt;/a&gt; and shared it with the LF events team. KubeCon Chicago was two months later, and we had a couple of deaf attendees. It was the &lt;strong&gt;first&lt;/strong&gt;  KubeCon accessible to deaf signers. &lt;a href=&#34;https://www.linkedin.com/in/destiny-o-connor-28b2a5255/&#34;&gt;Destiny&lt;/a&gt;, one of our co-chairs, even participated in a &lt;a href=&#34;https://youtu.be/3WJ_s4Jvbsk?si=iscthTiCyMxoMUqY&amp;t=347&#34;&gt;keynote panel&lt;/a&gt;. It was incredible how quickly everything happened!&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;DHHWG members at KubeCon Chicago&#34; src=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/09/30/cncf-deaf-and-hard-of-hearing-working-group-spotlight/cncf-dhhwg-chicago.jpg&#34;&gt;
&lt;em&gt;DHHWG members at KubeCon Chicago&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The team has grown since then, and we&#39;ve been able to do much more. With a kiosk in the project pavilion, an open space discussion, a sign language crash course, and a few media interviews, KubeCon Paris had a stronger advocacy and outreach focus. &lt;a href=&#34;https://www.youtube.com/watch?v=E8AcyqsgAyQ&#34;&gt;Check out this video of our team in Paris&lt;/a&gt; to get a glimpse of all the different KubeCon activities — it was such a great event! The team also launched the first CNCF Community Group in sign language, &lt;a href=&#34;https://community.cncf.io/deaf-in-cloud-native/&#34;&gt;Deaf in Cloud Native&lt;/a&gt;, a glossary team that creates sign language videos for each technical term to help standardize technical signs across the globe. It&#39;s crazy to think that it all happened within one year!&lt;/p&gt;
&lt;h2 id=&#34;overcoming-challenges-and-addressing-misconceptions&#34;&gt;Overcoming challenges and addressing misconceptions&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;SK: That&#39;s remarkable progress in just a year! Building such momentum must have come with its challenges. What barriers have you encountered in facilitating the DHHWG, and how did you and the group work to overcome them?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;CP&lt;/strong&gt;: The support from the community, LF, and CNCF has been incredible. The fact that we achieved so much is proof of it. The challenges are more in helping some team members overcome their fear of contributing. Most are new to open source, and it can be intimidating to put your work out there for everyone to see. The fear of being criticized in public is real; however, as they will hopefully realize over time, our community is incredibly supportive. Instead of criticizing, people tend to help improve the work, leading to better outcomes.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SK: Are there any misconceptions about the deaf and hard-of-hearing community in tech that you&#39;d like to address?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;CP&lt;/strong&gt;: Deaf and hard of hearing individuals are very diverse — there is no one-size-fits-all. Some deaf people are oral (speak), others sign, while some lip read or prefer captions. It generally depends on how people grew up. While some people come from deaf families and sign language is their native language, others were born into hearing families who may or may not have learned how to sign. Some deaf people grew up surrounded by hearing people, while others grew up deeply embedded in Deaf culture. Hard-of-hearing individuals, on the other hand, typically can communicate well with hearing peers one-on-one in quiet settings, but loud environments or conversations with multiple people can make it hard to follow the conversation. Most rely heavily on captions. Each background and experience will shape their communication style and preferences. In short, what works for one person, doesn&#39;t necessarily work for others. So &lt;strong&gt;never assume&lt;/strong&gt; and &lt;strong&gt;always ask&lt;/strong&gt; about accessibility needs and preferences.&lt;/p&gt;
&lt;h2 id=&#34;impact-and-the-role-of-allies&#34;&gt;Impact and the role of allies&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;SK: Can you share some key impacts/outcomes of the conference best practices document?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;CP&lt;/strong&gt;: Here are the two most important ones: Captions should be on the monitor, not in an app. That&#39;s especially important during technical talks with live demos. Deaf and hard of hearing attendees will miss important information switching between captions on their phone and code on the screen.&lt;/p&gt;
&lt;p&gt;Interpreters are most valuable during networking, not in talks (with captions). Most people come to conferences for the hallway track. That is no different for deaf attendees. If they can&#39;t network, they are missing out on key professional connections, affecting their career prospects.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SK: In your view, how crucial is the role of allies within the DHHWG, and what contributions have they made to the group’s success?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;CP&lt;/strong&gt;: Deaf and hard of hearing individuals are a minority and can only do so much. &lt;em&gt;&lt;strong&gt;Allies are the key to any diversity and inclusion initiative&lt;/strong&gt;&lt;/em&gt;. As a majority, allies can help spread the word and educate their peers, playing a key role in scaling advocacy efforts. They also have the power to demand change. It&#39;s easy for companies to ignore minorities, but if the majority demands that their employers be accessible, environmentally conscious, and good citizens, they will ultimately be pushed to adapt to new societal values.&lt;/p&gt;
&lt;h2 id=&#34;expanding-dei-efforts-and-future-vision&#34;&gt;Expanding DEI efforts and future vision&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;SK: The importance of allies in driving change is clear. Beyond the DHHWG, are you involved in any other DEI groups or initiatives within the tech community?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;CP&lt;/strong&gt;: As mentioned above, I&#39;m working on an initiative called ABIDE, which is still work in progress. I don&#39;t want to share too much about it yet, but what I can say is that the DHHWG will be part of it and that we just started a Blind and Visually Impaired WG (BVIWG). ABIDE will start by focusing on accessibility, so if anyone reading this has an idea for another WG, please reach out to me via the CNCF Slack @Catherine Paganini.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SK: What does the future hold for the DHHWG? Can you share details about any ongoing or upcoming initiatives?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;CP&lt;/strong&gt;: I think we&#39;ve been very successful in terms of visibility and awareness so far. We can&#39;t stop, though. Awareness work is ongoing, and most people in our community haven&#39;t heard about us or met anyone on our team yet, so a lot of work still lies ahead.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;DHHWG members at KubeCon Paris&#34; src=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/09/30/cncf-deaf-and-hard-of-hearing-working-group-spotlight/cncf-dhhwg-paris.jpg&#34;&gt;
&lt;em&gt;DHHWG members at KubeCon Paris&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The next step is to refocus on advocacy. The same thing we did with the conference best practices but for other areas. The goal is to help educate the community about what real accessibility looks like, how projects can be more accessible, and why employers should seriously consider deaf candidates while providing them with the tools they need to conduct successful interviews and employee onboarding. We need to capture all that in documents, publish it, and then get the word out. That last part is certainly the most challenging, but it&#39;s also where everyone can get involved.&lt;/p&gt;
&lt;h2 id=&#34;call-to-action&#34;&gt;Call to action&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;SK: Thank you for sharing your insights, Catherine. As we wrap up, do you have any final thoughts or a call to action for our readers?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;CP&lt;/strong&gt;: As we build our &lt;a href=&#34;https://contribute.cncf.io/accessibility/deaf-and-hard-of-hearing/&#34;&gt;accessibility page&lt;/a&gt;, check in regularly to see what&#39;s new. Share the docs with your team, employer, and network — anyone, really. The more people understand what accessibility really means and why it matters, the more people will recognize when something isn&#39;t accessible, and be able to call out marketing-BS, which, unfortunately, is more often the case than not. We need allies to help push for change. &lt;strong&gt;No minority can do this on their own&lt;/strong&gt;. So please learn about accessibility, keep an eye out for it, and call it out when something isn&#39;t accessible. We need your help!&lt;/p&gt;
&lt;h2 id=&#34;wrapping-up&#34;&gt;Wrapping up&lt;/h2&gt;
&lt;p&gt;Catherine and the DHHWG&#39;s work exemplify the power of community and advocacy. As we celebrate Deaf Awareness Month, let&#39;s reflect on her role as an ally and consider how we can all contribute to building a more inclusive tech community, particularly within open-source projects like Kubernetes.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Together, we can break down barriers, challenge misconceptions, and ensure that everyone feels welcome and valued. By advocating for accessibility, supporting initiatives like the DHHWG, and fostering a culture of empathy, we can create a truly inclusive and welcoming space for all.&lt;/em&gt;&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Spotlight on SIG Scheduling</title>
      <link>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/09/24/sig-scheduling-spotlight-2024/</link>
      <pubDate>Tue, 24 Sep 2024 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/09/24/sig-scheduling-spotlight-2024/</guid>
      <description>
        
        
        &lt;p&gt;In this SIG Scheduling spotlight we talked with &lt;a href=&#34;https://github.com/sanposhiho/&#34;&gt;Kensei Nakada&lt;/a&gt;, an
approver in SIG Scheduling.&lt;/p&gt;
&lt;h2 id=&#34;introductions&#34;&gt;Introductions&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Arvind:&lt;/strong&gt; &lt;strong&gt;Hello, thank you for the opportunity to learn more about SIG Scheduling! Would you
like to introduce yourself and tell us a bit about your role, and how you got involved with
Kubernetes?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Kensei&lt;/strong&gt;: Hi, thanks for the opportunity! I’m Kensei Nakada
(&lt;a href=&#34;https://github.com/sanposhiho/&#34;&gt;@sanposhiho&lt;/a&gt;), a software engineer at
&lt;a href=&#34;https://tetrate.io/&#34;&gt;Tetrate.io&lt;/a&gt;. I have been contributing to Kubernetes in my free time for more
than 3 years, and now I’m an approver of SIG Scheduling in Kubernetes. Also, I’m a founder/owner of
two SIG subprojects,
&lt;a href=&#34;https://github.com/kubernetes-sigs/kube-scheduler-simulator&#34;&gt;kube-scheduler-simulator&lt;/a&gt; and
&lt;a href=&#34;https://github.com/kubernetes-sigs/kube-scheduler-wasm-extension&#34;&gt;kube-scheduler-wasm-extension&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;about-sig-scheduling&#34;&gt;About SIG Scheduling&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;AP: That&#39;s awesome! You&#39;ve been involved with the project since a long time. Can you provide a
brief overview of SIG Scheduling and explain its role within the Kubernetes ecosystem?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;KN&lt;/strong&gt;: As the name implies, our responsibility is to enhance scheduling within
Kubernetes. Specifically, we develop the components that determine which Node is the best place for
each Pod. In Kubernetes, our main focus is on maintaining the
&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/scheduling-eviction/kube-scheduler/&#34;&gt;kube-scheduler&lt;/a&gt;, along
with other scheduling-related components as part of our SIG subprojects.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;AP: I see, got it! That makes me curious--what recent innovations or developments has SIG
Scheduling introduced to Kubernetes scheduling?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;KN&lt;/strong&gt;: From a feature perspective, there have been
&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2023/04/17/fine-grained-pod-topology-spread-features-beta/&#34;&gt;several enhancements&lt;/a&gt;
to &lt;code&gt;PodTopologySpread&lt;/code&gt; recently. &lt;code&gt;PodTopologySpread&lt;/code&gt; is a relatively new feature in the scheduler,
and we are still in the process of gathering feedback and making improvements.&lt;/p&gt;
&lt;p&gt;Most recently, we have been focusing on a new internal enhancement called
&lt;a href=&#34;https://github.com/kubernetes/enhancements/blob/master/keps/sig-scheduling/4247-queueinghint/README.md&#34;&gt;QueueingHint&lt;/a&gt;
which aims to enhance scheduling throughput. Throughput is one of our crucial metrics in
scheduling. Traditionally, we have primarily focused on optimizing the latency of each scheduling
cycle. QueueingHint takes a different approach, optimizing when to retry scheduling, thereby
reducing the likelihood of wasting scheduling cycles.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A: That sounds interesting! Are there any other interesting topics or projects you are currently
working on within SIG Scheduling?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;KN&lt;/strong&gt;: I’m leading the development of &lt;code&gt;QueueingHint&lt;/code&gt; which I just shared. Given that it’s a big new
challenge for us, we’ve been facing many unexpected challenges, especially around the scalability,
and we’re trying to solve each of them to eventually enable it by default.&lt;/p&gt;
&lt;p&gt;And also, I believe
&lt;a href=&#34;https://github.com/kubernetes-sigs/kube-scheduler-wasm-extension&#34;&gt;kube-scheduler-wasm-extension&lt;/a&gt;
(a SIG subproject) that I started last year would be interesting to many people. Kubernetes has
various extensions from many components. Traditionally, extensions are provided via webhooks
(&lt;a href=&#34;https://github.com/kubernetes/design-proposals-archive/blob/main/scheduling/scheduler_extender.md&#34;&gt;extender&lt;/a&gt;
in the scheduler) or Go SDK (&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/scheduling-eviction/scheduling-framework/&#34;&gt;Scheduling Framework&lt;/a&gt;
in the scheduler). However, these come with drawbacks - performance issues with webhooks and the need to
rebuild and replace schedulers with Go SDK, posing difficulties for those seeking to extend the
scheduler but lacking familiarity with it. The project is trying to introduce a new solution to
this general challenge - a &lt;a href=&#34;https://webassembly.org/&#34;&gt;WebAssembly&lt;/a&gt; based extension. Wasm allows
users to build plugins easily, without worrying about recompiling or replacing their scheduler, and
sidestepping performance concerns.&lt;/p&gt;
&lt;p&gt;Through this project, SIG Scheduling has been learning valuable insights about WebAssembly&#39;s
interaction with large Kubernetes objects. And I believe the experience that we’re gaining should be
useful broadly within the community, beyond SIG Scheduling.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A: Definitely! Now, there are 8 subprojects inside SIG Scheduling. Would you like to
talk about them? Are there some interesting contributions by those teams you want to highlight?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;KN&lt;/strong&gt;: Let me pick up three subprojects: Kueue, KWOK and descheduler.&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;&lt;a href=&#34;https://github.com/kubernetes-sigs/kueue&#34;&gt;Kueue&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;Recently, many people have been trying to manage batch workloads with Kubernetes, and in 2022,
Kubernetes community founded
&lt;a href=&#34;https://github.com/kubernetes/community/blob/master/wg-batch/README.md&#34;&gt;WG-Batch&lt;/a&gt; for better
support for such batch workloads in Kubernetes. &lt;a href=&#34;https://github.com/kubernetes-sigs/kueue&#34;&gt;Kueue&lt;/a&gt;
is a project that takes a crucial role for it. It’s a job queueing controller, deciding when a job
should wait, when a job should be admitted to start, and when a job should be preempted. Kueue aims
to be installed on a vanilla Kubernetes cluster while cooperating with existing matured controllers
(scheduler, cluster-autoscaler, kube-controller-manager, etc).&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://github.com/kubernetes-sigs/kwok&#34;&gt;KWOK&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;KWOK is a component in which you can create a cluster of thousands of Nodes in seconds. It’s
mostly useful for simulation/testing as a lightweight cluster, and actually another SIG sub
project &lt;a href=&#34;https://github.com/kubernetes-sigs/kube-scheduler-simulator&#34;&gt;kube-scheduler-simulator&lt;/a&gt;
uses KWOK background.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://github.com/kubernetes-sigs/descheduler&#34;&gt;descheduler&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;Descheduler is a component recreating pods that are running on undesired Nodes. In Kubernetes,
scheduling constraints (&lt;code&gt;PodAffinity&lt;/code&gt;, &lt;code&gt;NodeAffinity&lt;/code&gt;, &lt;code&gt;PodTopologySpread&lt;/code&gt;, etc) are honored only at
Pod schedule, but it’s not guaranteed that the contrtaints are kept being satisfied afterwards.
Descheduler evicts Pods violating their scheduling constraints (or other undesired conditions) so
that they’re recreated and rescheduled.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://github.com/kubernetes-sigs/descheduler/blob/master/keps/753-descheduling-framework/README.md&#34;&gt;Descheduling Framework&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;One very interesting on-going project, similar to
&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/scheduling-eviction/scheduling-framework/&#34;&gt;Scheduling Framework&lt;/a&gt; in the
scheduler, aiming to make descheduling logic extensible and allow maintainers to focus on building
a core engine of descheduler.&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;&lt;strong&gt;AP: Thank you for letting us know! And I have to ask, what are some of your favorite things about
this SIG?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;KN&lt;/strong&gt;: What I really like about this SIG is how actively engaged everyone is. We come from various
companies and industries, bringing diverse perspectives to the table. Instead of these differences
causing division, they actually generate a wealth of opinions. Each view is respected, and this
makes our discussions both rich and productive.&lt;/p&gt;
&lt;p&gt;I really appreciate this collaborative atmosphere, and I believe it has been key to continuously
improving our components over the years.&lt;/p&gt;
&lt;h2 id=&#34;contributing-to-sig-scheduling&#34;&gt;Contributing to SIG Scheduling&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;AP: Kubernetes is a community-driven project. Any recommendations for new contributors or
beginners looking to get involved and contribute to SIG scheduling? Where should they start?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;KN&lt;/strong&gt;: Let me start with a general recommendation for contributing to any SIG: a common approach is to look for
&lt;a href=&#34;https://github.com/kubernetes/kubernetes/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22&#34;&gt;good-first-issue&lt;/a&gt;.
However, you&#39;ll soon realize that many people worldwide are trying to contribute to the Kubernetes
repository.&lt;/p&gt;
&lt;p&gt;I suggest starting by examining the implementation of a component that interests you. If you have
any questions about it, ask in the corresponding Slack channel (e.g., #sig-scheduling for the
scheduler, #sig-node for kubelet, etc). Once you have a rough understanding of the implementation,
look at issues within the SIG (e.g.,
&lt;a href=&#34;https://github.com/kubernetes/kubernetes/issues?q=is%3Aopen+is%3Aissue+label%3Asig%2Fscheduling&#34;&gt;sig-scheduling&lt;/a&gt;),
where you&#39;ll find more unassigned issues compared to good-first-issue ones. You may also want to
filter issues with the
&lt;a href=&#34;https://github.com/kubernetes/kubernetes/issues?q=is%3Aopen+is%3Aissue++label%3Akind%2Fcleanup+&#34;&gt;kind/cleanup&lt;/a&gt;
label, which often indicates lower-priority tasks and can be starting points.&lt;/p&gt;
&lt;p&gt;Specifically for SIG Scheduling, you should first understand the
&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/scheduling-eviction/scheduling-framework/&#34;&gt;Scheduling Framework&lt;/a&gt;, which is
the fundamental architecture of kube-scheduler. Most of the implementation is found in
&lt;a href=&#34;https://github.com/kubernetes/kubernetes/tree/master/pkg/scheduler&#34;&gt;pkg/scheduler&lt;/a&gt;.
I suggest starting with
&lt;a href=&#34;https://github.com/kubernetes/kubernetes/blob/0590bb1ac495ae8af2a573f879408e48800da2c5/pkg/scheduler/schedule_one.go#L66&#34;&gt;ScheduleOne&lt;/a&gt;
function and then exploring deeper from there.&lt;/p&gt;
&lt;p&gt;Additionally, apart from the main kubernetes/kubernetes repository, consider looking into
sub-projects. These typically have fewer maintainers and offer more opportunities to make a
significant impact. Despite being called &amp;quot;sub&amp;quot; projects, many have a large number of users and a
considerable impact on the community.&lt;/p&gt;
&lt;p&gt;And last but not least, remember contributing to the community isn’t just about code. While I
talked a lot about the implementation contribution, there are many ways to contribute, and each one
is valuable. One comment to an issue, one feedback to an existing feature, one review comment in PR,
one clarification on the documentation; every small contribution helps drive the Kubernetes
ecosystem forward.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;AP: Those are some pretty useful tips! And if I may ask, how do you assist new contributors in
getting started, and what skills are contributors likely to learn by participating in SIG Scheduling?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;KN&lt;/strong&gt;: Our maintainers are available to answer your questions in the #sig-scheduling Slack
channel. By participating, you&#39;ll gain a deeper understanding of Kubernetes scheduling and have the
opportunity to collaborate and network with maintainers from diverse backgrounds. You&#39;ll learn not
just how to write code, but also how to maintain a large project, design and discuss new features,
address bugs, and much more.&lt;/p&gt;
&lt;h2 id=&#34;future-directions&#34;&gt;Future Directions&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;AP: What are some Kubernetes-specific challenges in terms of scheduling? Are there any particular
pain points?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;KN&lt;/strong&gt;: Scheduling in Kubernetes can be quite challenging because of the diverse needs of different
organizations with different business requirements. Supporting all possible use cases in
kube-scheduler is impossible. Therefore, extensibility is a key focus for us. A few years ago, we
rearchitected kube-scheduler with &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/scheduling-eviction/scheduling-framework/&#34;&gt;Scheduling Framework&lt;/a&gt;,
which offers flexible extensibility for users to implement various scheduling needs through plugins. This
allows maintainers to focus on the core scheduling features and the framework runtime.&lt;/p&gt;
&lt;p&gt;Another major issue is maintaining sufficient scheduling throughput. Typically, a Kubernetes cluster
has only one kube-scheduler, so its throughput directly affects the overall scheduling scalability
and, consequently, the cluster&#39;s scalability. Although we have an internal performance test
(&lt;a href=&#34;https://github.com/kubernetes/kubernetes/tree/master/test/integration/scheduler_perf&#34;&gt;scheduler_perf&lt;/a&gt;),
unfortunately, we sometimes overlook performance degradation in less common scenarios. It’s
difficult as even small changes, which look irrelevant to performance, can lead to degradation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;AP: What are some upcoming goals or initiatives for SIG Scheduling? How do you envision the SIG evolving in the future?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;KN&lt;/strong&gt;: Our primary goal is always to build and maintain &lt;em&gt;extensible&lt;/em&gt; and &lt;em&gt;stable&lt;/em&gt; scheduling
runtime, and I bet this goal will remain unchanged forever.&lt;/p&gt;
&lt;p&gt;As already mentioned, extensibility is key to solving the challenge of the diverse needs of
scheduling. Rather than trying to support every different use case directly in kube-scheduler, we
will continue to focus on enhancing extensibility so that it can accommodate various use
cases. &lt;a href=&#34;https://github.com/kubernetes-sigs/kube-scheduler-wasm-extension&#34;&gt;kube-scheduler-wasm-extension&lt;/a&gt;
that I mentioned is also part of this initiative.&lt;/p&gt;
&lt;p&gt;Regarding stability, introducing new optimizations like QueueHint is one of our
strategies. Additionally, maintaining throughput is also a crucial goal towards the future. We’re
planning to enhance our throughput monitoring
(&lt;a href=&#34;https://github.com/kubernetes/kubernetes/issues/124774&#34;&gt;ref&lt;/a&gt;), so that we can notice degradation
as much as possible on our own before releasing. But, realistically, we can&#39;t cover every possible
scenario. We highly appreciate any attention the community can give to scheduling throughput and
encourage feedback and alerts regarding performance issues!&lt;/p&gt;
&lt;h2 id=&#34;closing-remarks&#34;&gt;Closing Remarks&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;AP: Finally, what message would you like to convey to those who are interested in learning more
about SIG Scheduling?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;KN&lt;/strong&gt;: Scheduling is one of the most complicated areas in Kubernetes, and you may find it difficult
at first. But, as I shared earlier, you can find many opportunities for contributions, and many
maintainers are willing to help you understand things. We know your unique perspective and skills
are what makes our open source so powerful 😊&lt;/p&gt;
&lt;p&gt;Feel free to reach out to us in Slack
(&lt;a href=&#34;https://kubernetes.slack.com/archives/C09TP78DV&#34;&gt;#sig-scheduling&lt;/a&gt;) or
&lt;a href=&#34;https://github.com/kubernetes/community/blob/master/sig-scheduling/README.md#meetings&#34;&gt;meetings&lt;/a&gt;.
I hope this article interests everyone and we can see new contributors!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;AP: Thank you so much for taking the time to do this! I&#39;m confident that many will find this
information invaluable for understanding more about SIG Scheduling and for contributing to the SIG.&lt;/strong&gt;&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes v1.31: kubeadm v1beta4</title>
      <link>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/08/23/kubernetes-1-31-kubeadm-v1beta4/</link>
      <pubDate>Fri, 23 Aug 2024 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/08/23/kubernetes-1-31-kubeadm-v1beta4/</guid>
      <description>
        
        
        &lt;p&gt;As part of the Kubernetes v1.31 release, &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/reference/setup-tools/kubeadm/&#34;&gt;&lt;code&gt;kubeadm&lt;/code&gt;&lt;/a&gt; is
adopting a new (&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/reference/config-api/kubeadm-config.v1beta4/&#34;&gt;v1beta4&lt;/a&gt;) version of
its configuration file format. Configuration in the previous v1beta3 format is now formally
deprecated, which means it&#39;s supported but you should migrate to v1beta4 and stop using
the deprecated format.
Support for v1beta3 configuration will be removed after a minimum of 3 Kubernetes minor releases.&lt;/p&gt;
&lt;p&gt;In this article, I&#39;ll walk you through key changes;
I&#39;ll explain about the kubeadm v1beta4 configuration format,
and how to migrate from v1beta3 to v1beta4.&lt;/p&gt;
&lt;p&gt;You can read the reference for the v1beta4 configuration format:
&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/reference/config-api/kubeadm-config.v1beta4/&#34;&gt;kubeadm Configuration (v1beta4)&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;a-list-of-changes-since-v1beta3&#34;&gt;A list of changes since v1beta3&lt;/h3&gt;
&lt;p&gt;This version improves on the &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/reference/config-api/kubeadm-config.v1beta3/&#34;&gt;v1beta3&lt;/a&gt;
format by fixing some minor issues and adding a few new fields.&lt;/p&gt;
&lt;p&gt;To put it simply,&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Two new configuration elements: ResetConfiguration and UpgradeConfiguration&lt;/li&gt;
&lt;li&gt;For InitConfiguration and JoinConfiguration, &lt;code&gt;dryRun&lt;/code&gt; mode and &lt;code&gt;nodeRegistration.imagePullSerial&lt;/code&gt; are supported&lt;/li&gt;
&lt;li&gt;For ClusterConfiguration, there are new fields including &lt;code&gt;certificateValidityPeriod&lt;/code&gt;,
&lt;code&gt;caCertificateValidityPeriod&lt;/code&gt;, &lt;code&gt;encryptionAlgorithm&lt;/code&gt;, &lt;code&gt;dns.disabled&lt;/code&gt; and &lt;code&gt;proxy.disabled&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Support &lt;code&gt;extraEnvs&lt;/code&gt; for all control plan components&lt;/li&gt;
&lt;li&gt;&lt;code&gt;extraArgs&lt;/code&gt; changed from a map to structured extra arguments for duplicates&lt;/li&gt;
&lt;li&gt;Add a &lt;code&gt;timeouts&lt;/code&gt; structure for init, join, upgrade and reset.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For details, you can see the &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/reference/config-api/kubeadm-config.v1beta4/&#34;&gt;official document&lt;/a&gt; below:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Support custom environment variables in control plane components under &lt;code&gt;ClusterConfiguration&lt;/code&gt;.
Use &lt;code&gt;apiServer.extraEnvs&lt;/code&gt;, &lt;code&gt;controllerManager.extraEnvs&lt;/code&gt;, &lt;code&gt;scheduler.extraEnvs&lt;/code&gt;, &lt;code&gt;etcd.local.extraEnvs&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The ResetConfiguration API type is now supported in v1beta4. Users are able to reset a node by passing
a &lt;code&gt;--config&lt;/code&gt; file to &lt;code&gt;kubeadm reset&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;dryRun&lt;/code&gt; mode is now configurable in InitConfiguration and JoinConfiguration.&lt;/li&gt;
&lt;li&gt;Replace the existing string/string extra argument maps with structured extra arguments that support duplicates.
The change applies to &lt;code&gt;ClusterConfiguration&lt;/code&gt; - &lt;code&gt;apiServer.extraArgs&lt;/code&gt;, &lt;code&gt;controllerManager.extraArgs&lt;/code&gt;,
&lt;code&gt;scheduler.extraArgs&lt;/code&gt;, &lt;code&gt;etcd.local.extraArgs&lt;/code&gt;. Also to &lt;code&gt;nodeRegistrationOptions.kubeletExtraArgs&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Added &lt;code&gt;ClusterConfiguration.encryptionAlgorithm&lt;/code&gt; that can be used to set the asymmetric encryption
algorithm used for this cluster&#39;s keys and certificates. Can be one of &amp;quot;RSA-2048&amp;quot; (default), &amp;quot;RSA-3072&amp;quot;,
&amp;quot;RSA-4096&amp;quot; or &amp;quot;ECDSA-P256&amp;quot;.&lt;/li&gt;
&lt;li&gt;Added &lt;code&gt;ClusterConfiguration.dns.disabled&lt;/code&gt; and &lt;code&gt;ClusterConfiguration.proxy.disabled&lt;/code&gt; that can be used
to disable the CoreDNS and kube-proxy addons during cluster initialization.
Skipping the related addons phases, during cluster creation will set the same fields to &lt;code&gt;true&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Added the &lt;code&gt;nodeRegistration.imagePullSerial&lt;/code&gt; field in &lt;code&gt;InitConfiguration&lt;/code&gt; and &lt;code&gt;JoinConfiguration&lt;/code&gt;,
which can be used to control if kubeadm pulls images serially or in parallel.&lt;/li&gt;
&lt;li&gt;The UpgradeConfiguration kubeadm API is now supported in v1beta4 when passing &lt;code&gt;--config&lt;/code&gt; to
&lt;code&gt;kubeadm upgrade&lt;/code&gt; subcommands.
For upgrade subcommands, the usage of component configuration for kubelet and kube-proxy, as well as
InitConfiguration and ClusterConfiguration, is now deprecated and will be ignored when passing &lt;code&gt;--config&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Added a &lt;code&gt;timeouts&lt;/code&gt; structure to &lt;code&gt;InitConfiguration&lt;/code&gt;, &lt;code&gt;JoinConfiguration&lt;/code&gt;, &lt;code&gt;ResetConfiguration&lt;/code&gt; and
&lt;code&gt;UpgradeConfiguration&lt;/code&gt; that can be used to configure various timeouts.
The &lt;code&gt;ClusterConfiguration.timeoutForControlPlane&lt;/code&gt; field is replaced by &lt;code&gt;timeouts.controlPlaneComponentHealthCheck&lt;/code&gt;.
The &lt;code&gt;JoinConfiguration.discovery.timeout&lt;/code&gt; is replaced by &lt;code&gt;timeouts.discovery&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Added a &lt;code&gt;certificateValidityPeriod&lt;/code&gt; and &lt;code&gt;caCertificateValidityPeriod&lt;/code&gt; fields to &lt;code&gt;ClusterConfiguration&lt;/code&gt;.
These fields can be used to control the validity period of certificates generated by kubeadm during
sub-commands such as &lt;code&gt;init&lt;/code&gt;, &lt;code&gt;join&lt;/code&gt;, &lt;code&gt;upgrade&lt;/code&gt; and &lt;code&gt;certs&lt;/code&gt;.
Default values continue to be 1 year for non-CA certificates and 10 years for CA certificates.
Also note that only non-CA certificates are renewable by &lt;code&gt;kubeadm certs renew&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These changes simplify the configuration of tools that use kubeadm
and improve the extensibility of kubeadm itself.&lt;/p&gt;
&lt;h3 id=&#34;how-to-migrate-v1beta3-configuration-to-v1beta4&#34;&gt;How to migrate v1beta3 configuration to v1beta4?&lt;/h3&gt;
&lt;p&gt;If your configuration is not using the latest version, it is recommended that you migrate using
the &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/reference/setup-tools/kubeadm/kubeadm-config/#cmd-config-migrate&#34;&gt;kubeadm config migrate&lt;/a&gt; command.&lt;/p&gt;
&lt;p&gt;This command reads an existing configuration file that uses the old format, and writes a new
file that uses the current format.&lt;/p&gt;
&lt;h4 id=&#34;example-kubeadm-config-migrate&#34;&gt;Example&lt;/h4&gt;
&lt;p&gt;Using kubeadm v1.31, run &lt;code&gt;kubeadm config migrate --old-config old-v1beta3.yaml --new-config new-v1beta4.yaml&lt;/code&gt;&lt;/p&gt;
&lt;h2 id=&#34;how-do-i-get-involved&#34;&gt;How do I get involved?&lt;/h2&gt;
&lt;p&gt;Huge thanks to all the contributors who helped with the design, implementation,
and review of this feature:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Lubomir I. Ivanov (&lt;a href=&#34;https://github.com/neolit123&#34;&gt;neolit123&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Dave Chen(&lt;a href=&#34;https://github.com/chendave&#34;&gt;chendave&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Paco Xu (&lt;a href=&#34;https://github.com/pacoxu&#34;&gt;pacoxu&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Sata Qiu(&lt;a href=&#34;https://github.com/sataqiu&#34;&gt;sataqiu&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Baofa Fan(&lt;a href=&#34;https://github.com/carlory&#34;&gt;carlory&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Calvin Chen(&lt;a href=&#34;https://github.com/calvin0327&#34;&gt;calvin0327&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Ruquan Zhao(&lt;a href=&#34;https://github.com/ruquanzhao&#34;&gt;ruquanzhao&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For those interested in getting involved in future discussions on kubeadm configuration,
you can reach out kubeadm or &lt;a href=&#34;https://github.com/kubernetes/community/blob/master/sig-cluster-lifecycle/README.md&#34;&gt;SIG-cluster-lifecycle&lt;/a&gt; by several means:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;v1beta4 related items are tracked in &lt;a href=&#34;https://github.com/kubernetes/kubeadm/issues/2890&#34;&gt;kubeadm issue #2890&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Slack: &lt;a href=&#34;https://kubernetes.slack.com/messages/kubeadm&#34;&gt;#kubeadm&lt;/a&gt; or &lt;a href=&#34;https://kubernetes.slack.com/messages/sig-cluster-lifecycle&#34;&gt;#sig-cluster-lifecycle&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://groups.google.com/forum/#!forum/kubernetes-sig-cluster-lifecycle&#34;&gt;Mailing list&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes 1.31: Custom Profiling in Kubectl Debug Graduates to Beta</title>
      <link>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/08/22/kubernetes-1-31-custom-profiling-kubectl-debug/</link>
      <pubDate>Thu, 22 Aug 2024 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/08/22/kubernetes-1-31-custom-profiling-kubectl-debug/</guid>
      <description>
        
        
        &lt;p&gt;There are many ways of troubleshooting the pods and nodes in the cluster. However, &lt;code&gt;kubectl debug&lt;/code&gt; is one of the easiest, highly used and most prominent ones. It
provides a set of static profiles and each profile serves for a different kind of role. For instance, from the network administrator&#39;s point of view,
debugging the node should be as easy as this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ kubectl debug node/mynode -it --image&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;busybox --profile&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;netadmin
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;On the other hand, static profiles also bring about inherent rigidity, which has some implications for some pods contrary to their ease of use.
Because there are various kinds of pods (or nodes) that all have their specific
necessities, and unfortunately, some can&#39;t be debugged by only using the static profiles.&lt;/p&gt;
&lt;p&gt;Take an instance of a simple pod consisting of a container whose healthiness relies on an environment variable:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;v1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Pod&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;example-pod&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;spec&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;containers&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;example-container&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;image&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;customapp:latest&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;env&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;REQUIRED_ENV_VAR&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;value&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;value1&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Currently, copying the pod is the sole mechanism that supports debugging this pod in kubectl debug. Furthermore, what if user needs to modify the &lt;code&gt;REQUIRED_ENV_VAR&lt;/code&gt; to something different
for advanced troubleshooting?. There is no mechanism to achieve this.&lt;/p&gt;
&lt;h2 id=&#34;custom-profiling&#34;&gt;Custom Profiling&lt;/h2&gt;
&lt;p&gt;Custom profiling is a new functionality available under &lt;code&gt;--custom&lt;/code&gt; flag, introduced in kubectl debug to provide extensibility. It expects partial &lt;code&gt;Container&lt;/code&gt; spec in either YAML or JSON format.
In order to debug the example-container above by creating an ephemeral container, we simply have to define this YAML:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# partial_container.yaml&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;env&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;REQUIRED_ENV_VAR&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;value&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;value2&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and execute:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kubectl debug example-pod -it --image&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;customapp --custom&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;partial_container.yaml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Here is another example that modifies multiple fields at once (change port number, add resource limits, modify environment variable) in JSON:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;&amp;#34;ports&amp;#34;&lt;/span&gt;: [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;&amp;#34;containerPort&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#666&#34;&gt;80&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ],
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;&amp;#34;resources&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;&amp;#34;limits&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;&amp;#34;cpu&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;0.5&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;&amp;#34;memory&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;512Mi&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;&amp;#34;requests&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;&amp;#34;cpu&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;0.2&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;&amp;#34;memory&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;256Mi&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;&amp;#34;env&amp;#34;&lt;/span&gt;: [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;REQUIRED_ENV_VAR&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;&amp;#34;value&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;value2&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#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&#34;&gt;Constraints&lt;/h2&gt;
&lt;p&gt;Uncontrolled extensibility hurts the usability. So that, custom profiling is not allowed for certain fields such as command, image, lifecycle, volume devices and container name.
In the future, more fields can be added to the disallowed list if required.&lt;/p&gt;
&lt;h2 id=&#34;limitations&#34;&gt;Limitations&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;kubectl debug&lt;/code&gt; command has 3 aspects: Debugging with ephemeral containers, pod copying, and node debugging. The largest intersection set of these aspects is the container spec within a Pod
That&#39;s why, custom profiling only supports the modification of the fields that are defined with &lt;code&gt;containers&lt;/code&gt;. This leads to a limitation that if user needs to modify the other fields in the Pod spec, it is not supported.&lt;/p&gt;
&lt;h2 id=&#34;acknowledgments&#34;&gt;Acknowledgments&lt;/h2&gt;
&lt;p&gt;Special thanks to all the contributors who reviewed and commented on this feature, from the initial conception to its actual implementation (alphabetical order):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/eddiezane&#34;&gt;Eddie Zaneski&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/verb&#34;&gt;Lee Verberne&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes 1.31: Fine-grained SupplementalGroups control</title>
      <link>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/08/22/fine-grained-supplementalgroups-control/</link>
      <pubDate>Thu, 22 Aug 2024 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/08/22/fine-grained-supplementalgroups-control/</guid>
      <description>
        
        
        &lt;p&gt;This blog discusses a new feature in Kubernetes 1.31 to improve the handling of supplementary groups in containers within Pods.&lt;/p&gt;
&lt;h2 id=&#34;motivation-implicit-group-memberships-defined-in-etc-group-in-the-container-image&#34;&gt;Motivation: Implicit group memberships defined in &lt;code&gt;/etc/group&lt;/code&gt; in the container image&lt;/h2&gt;
&lt;p&gt;Although this behavior may not be popular with many Kubernetes cluster users/admins, kubernetes, by default, &lt;em&gt;merges&lt;/em&gt; group information from the Pod with information defined in &lt;code&gt;/etc/group&lt;/code&gt; in the container image.&lt;/p&gt;
&lt;p&gt;Let&#39;s see an example, below Pod specifies &lt;code&gt;runAsUser=1000&lt;/code&gt;, &lt;code&gt;runAsGroup=3000&lt;/code&gt; and &lt;code&gt;supplementalGroups=4000&lt;/code&gt; in the Pod&#39;s security context.&lt;/p&gt;
&lt;div class=&#34;highlight code-sample&#34;&gt;
    &lt;div class=&#34;copy-code-icon&#34;&gt;
    &lt;a href=&#34;https://raw.githubusercontent.com/kubernetes/website/main/content/en/examples/implicit-groups.yaml&#34; download=&#34;implicit-groups.yaml&#34;&gt;&lt;code&gt;implicit-groups.yaml&lt;/code&gt;
    &lt;/a&gt;&lt;img src=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/images/copycode.svg&#34; class=&#34;icon-copycode&#34; onclick=&#34;copyCode(&#39;implicit-groups-yaml&#39;)&#34; title=&#34;Copy implicit-groups.yaml to clipboard&#34;&gt;&lt;/img&gt;&lt;/div&gt;
    &lt;div class=&#34;includecode&#34; id=&#34;implicit-groups-yaml&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;v1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Pod&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;implicit-groups&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;spec&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;securityContext&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;runAsUser&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;1000&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;runAsGroup&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;3000&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;supplementalGroups&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;[&lt;span style=&#34;color:#666&#34;&gt;4000&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;containers&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;ctr&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;image&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;registry.k8s.io/e2e-test-images/agnhost:2.45&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;command&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;[&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;sh&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;-c&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;sleep 1h&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;securityContext&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;allowPrivilegeEscalation&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;false&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;What is the result of &lt;code&gt;id&lt;/code&gt; command in the &lt;code&gt;ctr&lt;/code&gt; container?&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;#&lt;/span&gt; Create the Pod:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;$&lt;/span&gt; kubectl apply -f https://k8s.io/blog/2024-08-22-Fine-grained-SupplementalGroups-control/implicit-groups.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;#&lt;/span&gt; Verify that the Pod&lt;span style=&#34;&#34;&gt;&amp;#39;&lt;/span&gt;s Container is running:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;$&lt;/span&gt; kubectl get pod implicit-groups
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;#&lt;/span&gt; Check the id &lt;span style=&#34;color:#a2f&#34;&gt;command&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;$&lt;/span&gt; kubectl &lt;span style=&#34;color:#a2f&#34;&gt;exec&lt;/span&gt; implicit-groups -- id
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then, output should be similar to this:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-none&#34; data-lang=&#34;none&#34;&gt;uid=1000 gid=3000 groups=3000,4000,50000
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Where does group ID &lt;code&gt;50000&lt;/code&gt; in supplementary groups (&lt;code&gt;groups&lt;/code&gt; field) come from, even though &lt;code&gt;50000&lt;/code&gt; is not defined in the Pod&#39;s manifest at all? The answer is &lt;code&gt;/etc/group&lt;/code&gt; file in the container image.&lt;/p&gt;
&lt;p&gt;Checking the contents of &lt;code&gt;/etc/group&lt;/code&gt; in the container image should show below:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;$&lt;/span&gt; kubectl &lt;span style=&#34;color:#a2f&#34;&gt;exec&lt;/span&gt; implicit-groups -- cat /etc/group
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;user-defined-in-image:x:1000:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;group-defined-in-image:x:50000:user-defined-in-image
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Aha! The container&#39;s primary user &lt;code&gt;1000&lt;/code&gt; belongs to the group &lt;code&gt;50000&lt;/code&gt; in the last entry.&lt;/p&gt;
&lt;p&gt;Thus, the group membership defined in &lt;code&gt;/etc/group&lt;/code&gt; in the container image for the container&#39;s primary user is &lt;em&gt;implicitly&lt;/em&gt; merged to the information from the Pod. Please note that this was a design decision the current CRI implementations inherited from Docker, and the community never really reconsidered it until now.&lt;/p&gt;
&lt;h3 id=&#34;what-s-wrong-with-it&#34;&gt;What&#39;s wrong with it?&lt;/h3&gt;
&lt;p&gt;The &lt;em&gt;implicitly&lt;/em&gt; merged group information from &lt;code&gt;/etc/group&lt;/code&gt; in the container image may cause some concerns particularly in accessing volumes (see &lt;a href=&#34;https://issue.k8s.io/112879&#34;&gt;kubernetes/kubernetes#112879&lt;/a&gt; for details) because file permission is controlled by uid/gid in Linux. Even worse, the implicit gids from &lt;code&gt;/etc/group&lt;/code&gt; can not be detected/validated by any policy engines because there is no clue for the implicit group information in the manifest. This can also be a concern for Kubernetes security.&lt;/p&gt;
&lt;h2 id=&#34;fine-grained-supplementalgroups-control-in-a-pod-supplementarygroupspolicy&#34;&gt;Fine-grained SupplementalGroups control in a Pod: &lt;code&gt;SupplementaryGroupsPolicy&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;To tackle the above problem, Kubernetes 1.31 introduces new field &lt;code&gt;supplementalGroupsPolicy&lt;/code&gt; in Pod&#39;s &lt;code&gt;.spec.securityContext&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This field provies a way to control how to calculate supplementary groups for the container processes in a Pod. The available policy is below:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Merge&lt;/em&gt;: The group membership defined in &lt;code&gt;/etc/group&lt;/code&gt; for the container&#39;s primary user will be merged. If not specified, this policy will be applied (i.e. as-is behavior for backword compatibility).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Strict&lt;/em&gt;: it only attaches specified group IDs in &lt;code&gt;fsGroup&lt;/code&gt;, &lt;code&gt;supplementalGroups&lt;/code&gt;, or &lt;code&gt;runAsGroup&lt;/code&gt; fields as the supplementary groups of the container processes. This means no group membership defined in &lt;code&gt;/etc/group&lt;/code&gt; for the container&#39;s primary user will be merged.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let&#39;s see how &lt;code&gt;Strict&lt;/code&gt; policy works.&lt;/p&gt;
&lt;div class=&#34;highlight code-sample&#34;&gt;
    &lt;div class=&#34;copy-code-icon&#34;&gt;
    &lt;a href=&#34;https://raw.githubusercontent.com/kubernetes/website/main/content/en/examples/strict-supplementalgroups-policy.yaml&#34; download=&#34;strict-supplementalgroups-policy.yaml&#34;&gt;&lt;code&gt;strict-supplementalgroups-policy.yaml&lt;/code&gt;
    &lt;/a&gt;&lt;img src=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/images/copycode.svg&#34; class=&#34;icon-copycode&#34; onclick=&#34;copyCode(&#39;strict-supplementalgroups-policy-yaml&#39;)&#34; title=&#34;Copy strict-supplementalgroups-policy.yaml to clipboard&#34;&gt;&lt;/img&gt;&lt;/div&gt;
    &lt;div class=&#34;includecode&#34; id=&#34;strict-supplementalgroups-policy-yaml&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;v1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Pod&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;strict-supplementalgroups-policy&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;spec&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;securityContext&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;runAsUser&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;1000&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;runAsGroup&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;3000&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;supplementalGroups&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;[&lt;span style=&#34;color:#666&#34;&gt;4000&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;supplementalGroupsPolicy&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Strict&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;containers&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;ctr&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;image&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;registry.k8s.io/e2e-test-images/agnhost:2.45&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;command&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;[&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;sh&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;-c&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;sleep 1h&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;securityContext&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;allowPrivilegeEscalation&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;false&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;#&lt;/span&gt; Create the Pod:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;$&lt;/span&gt; kubectl apply -f https://k8s.io/blog/2024-08-22-Fine-grained-SupplementalGroups-control/strict-supplementalgroups-policy.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;#&lt;/span&gt; Verify that the Pod&lt;span style=&#34;&#34;&gt;&amp;#39;&lt;/span&gt;s Container is running:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;$&lt;/span&gt; kubectl get pod strict-supplementalgroups-policy
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;#&lt;/span&gt; Check the process identity:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;kubectl exec -it strict-supplementalgroups-policy -- id
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The output should be similar to this:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-none&#34; data-lang=&#34;none&#34;&gt;uid=1000 gid=3000 groups=3000,4000
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can see &lt;code&gt;Strict&lt;/code&gt; policy can exclude group &lt;code&gt;50000&lt;/code&gt; from &lt;code&gt;groups&lt;/code&gt;!&lt;/p&gt;
&lt;p&gt;Thus, ensuring &lt;code&gt;supplementalGroupsPolicy: Strict&lt;/code&gt; (enforced by some policy mechanism) helps prevent the implicit supplementary groups in a Pod.&lt;/p&gt;

&lt;div class=&#34;alert alert-info&#34; role=&#34;alert&#34;&gt;&lt;h4 class=&#34;alert-heading&#34;&gt;Note:&lt;/h4&gt;Actually, this is not enough because container with sufficient privileges / capability can change its process identity. Please see the following section for details.&lt;/div&gt;

&lt;h2 id=&#34;attached-process-identity-in-pod-status&#34;&gt;Attached process identity in Pod status&lt;/h2&gt;
&lt;p&gt;This feature also exposes the process identity attached to the first container process of the container
via &lt;code&gt;.status.containerStatuses[].user.linux&lt;/code&gt; field. It would be helpful to see if implicit group IDs are attached.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f;font-weight:bold&#34;&gt;...&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;status&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;containerStatuses&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;ctr&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;user&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;linux&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;gid&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;3000&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;supplementalGroups&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;- &lt;span style=&#34;color:#666&#34;&gt;3000&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;- &lt;span style=&#34;color:#666&#34;&gt;4000&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;uid&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;1000&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#00f;font-weight:bold&#34;&gt;...&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&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;alert&#34;&gt;&lt;h4 class=&#34;alert-heading&#34;&gt;Note:&lt;/h4&gt;Please note that the values in &lt;code&gt;status.containerStatuses[].user.linux&lt;/code&gt; field is &lt;em&gt;the firstly attached&lt;/em&gt;
process identity to the first container process in the container. If the container has sufficient privilege
to call system calls related to process identity (e.g. &lt;a href=&#34;https://man7.org/linux/man-pages/man2/setuid.2.html&#34;&gt;&lt;code&gt;setuid(2)&lt;/code&gt;&lt;/a&gt;, &lt;a href=&#34;https://man7.org/linux/man-pages/man2/setgid.2.html&#34;&gt;&lt;code&gt;setgid(2)&lt;/code&gt;&lt;/a&gt; or &lt;a href=&#34;https://man7.org/linux/man-pages/man2/setgroups.2.html&#34;&gt;&lt;code&gt;setgroups(2)&lt;/code&gt;&lt;/a&gt;, etc.), the container process can change its identity. Thus, the &lt;em&gt;actual&lt;/em&gt; process identity will be dynamic.&lt;/div&gt;

&lt;h2 id=&#34;feature-availability&#34;&gt;Feature availability&lt;/h2&gt;
&lt;p&gt;To enable &lt;code&gt;supplementalGroupsPolicy&lt;/code&gt; field, the following components have to be used:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Kubernetes: v1.31 or later, with the &lt;code&gt;SupplementalGroupsPolicy&lt;/code&gt; &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/reference/command-line-tools-reference/feature-gates/&#34;&gt;feature gate&lt;/a&gt; enabled. As of v1.31, the gate is marked as alpha.&lt;/li&gt;
&lt;li&gt;CRI runtime:
&lt;ul&gt;
&lt;li&gt;containerd: v2.0 or later&lt;/li&gt;
&lt;li&gt;CRI-O: v1.31 or later&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can see if the feature is supported in the Node&#39;s &lt;code&gt;.status.features.supplementalGroupsPolicy&lt;/code&gt; field.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;v1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Node&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#00f;font-weight:bold&#34;&gt;...&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;status&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;features&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;supplementalGroupsPolicy&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;true&lt;/span&gt;&lt;span style=&#34;color:#bbb&#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;/h2&gt;
&lt;p&gt;Kubernetes SIG Node hope - and expect - that the feature will be promoted to beta and eventually
general availability (GA) in future releases of Kubernetes, so that users no longer need to enable
the feature gate manually.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Merge&lt;/code&gt; policy is applied when &lt;code&gt;supplementalGroupsPolicy&lt;/code&gt; is not specified, for backwards compatibility.&lt;/p&gt;
&lt;h2 id=&#34;how-can-i-learn-more&#34;&gt;How can I learn more?&lt;/h2&gt;
&lt;!-- https://github.com/kubernetes/website/pull/46920 --&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/tasks/configure-pod-container/security-context/&#34;&gt;Configure a Security Context for a Pod or Container&lt;/a&gt;
for the further details of &lt;code&gt;supplementalGroupsPolicy&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/3619&#34;&gt;KEP-3619: Fine-grained SupplementalGroups control&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;how-to-get-involved&#34;&gt;How to get involved?&lt;/h2&gt;
&lt;p&gt;This feature is driven by the SIG Node community. Please join us to connect with
the community and share your ideas and feedback around the above feature and
beyond. We look forward to hearing from you!&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes v1.31: New Kubernetes CPUManager Static Policy: Distribute CPUs Across Cores</title>
      <link>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/08/22/cpumanager-static-policy-distributed-cpu-across-cores/</link>
      <pubDate>Thu, 22 Aug 2024 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/08/22/cpumanager-static-policy-distributed-cpu-across-cores/</guid>
      <description>
        
        
        &lt;p&gt;In Kubernetes v1.31, we are excited to introduce a significant enhancement to CPU management capabilities: the &lt;code&gt;distribute-cpus-across-cores&lt;/code&gt; option for the &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/tasks/administer-cluster/cpu-management-policies/#static-policy-options&#34;&gt;CPUManager static policy&lt;/a&gt;. This feature is currently in alpha and hidden by default, marking a strategic shift aimed at optimizing CPU utilization and improving system performance across multi-core processors.&lt;/p&gt;
&lt;h2 id=&#34;understanding-the-feature&#34;&gt;Understanding the feature&lt;/h2&gt;
&lt;p&gt;Traditionally, Kubernetes&#39; CPUManager tends to allocate CPUs as compactly as possible, typically packing them onto the fewest number of physical cores. However, allocation strategy matters, CPUs on the same physical host still share some resources of the physical core, such as the cache and execution units, etc.&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/08/22/cpumanager-static-policy-distributed-cpu-across-cores/cpu-cache-architecture.png&#34;
         alt=&#34;cpu-cache-architecture&#34;/&gt; 
&lt;/figure&gt;
&lt;p&gt;While default approach minimizes inter-core communication and can be beneficial under certain scenarios, it also poses a challenge. CPUs sharing a physical core can lead to resource contention, which in turn may cause performance bottlenecks, particularly noticeable in CPU-intensive applications.&lt;/p&gt;
&lt;p&gt;The new &lt;code&gt;distribute-cpus-across-cores&lt;/code&gt; feature addresses this issue by modifying the allocation strategy. When enabled, this policy option instructs the CPUManager to spread out the CPUs (hardware threads) across as many physical cores as possible. This distribution is designed to minimize contention among CPUs sharing the same physical core, potentially enhancing the performance of applications by providing them dedicated core resources.&lt;/p&gt;
&lt;p&gt;Technically, within this static policy, the free CPU list is reordered in the manner depicted in the diagram, aiming to allocate CPUs from separate physical cores.&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/08/22/cpumanager-static-policy-distributed-cpu-across-cores/cpu-ordering.png&#34;
         alt=&#34;cpu-ordering&#34;/&gt; 
&lt;/figure&gt;
&lt;h2 id=&#34;enabling-the-feature&#34;&gt;Enabling the feature&lt;/h2&gt;
&lt;p&gt;To enable this feature, users firstly need to add &lt;code&gt;--cpu-manager-policy=static&lt;/code&gt; kubelet flag or the &lt;code&gt;cpuManagerPolicy: static&lt;/code&gt; field in KubeletConfiuration. Then user can add &lt;code&gt;--cpu-manager-policy-options distribute-cpus-across-cores=true&lt;/code&gt; or &lt;code&gt;distribute-cpus-across-cores=true&lt;/code&gt; to their CPUManager policy options in the Kubernetes configuration or. This setting directs the CPUManager to adopt the new distribution strategy. It is important to note that this policy option cannot currently be used in conjunction with &lt;code&gt;full-pcpus-only&lt;/code&gt; or &lt;code&gt;distribute-cpus-across-numa&lt;/code&gt; options.&lt;/p&gt;
&lt;h2 id=&#34;current-limitations-and-future-directions&#34;&gt;Current limitations and future directions&lt;/h2&gt;
&lt;p&gt;As with any new feature, especially one in alpha, there are limitations and areas for future improvement. One significant current limitation is that &lt;code&gt;distribute-cpus-across-cores&lt;/code&gt; cannot be combined with other policy options that might conflict in terms of CPU allocation strategies. This restriction can affect compatibility with certain workloads and deployment scenarios that rely on more specialized resource management.&lt;/p&gt;
&lt;p&gt;Looking forward, we are committed to enhancing the compatibility and functionality of the &lt;code&gt;distribute-cpus-across-cores&lt;/code&gt; option. Future updates will focus on resolving these compatibility issues, allowing this policy to be combined with other CPUManager policies seamlessly. Our goal is to provide a more flexible and robust CPU allocation framework that can adapt to a variety of workloads and performance demands.&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;The introduction of the &lt;code&gt;distribute-cpus-across-cores&lt;/code&gt; policy in Kubernetes CPUManager is a step forward in our ongoing efforts to refine resource management and improve application performance. By reducing the contention on physical cores, this feature offers a more balanced approach to CPU resource allocation, particularly beneficial for environments running heterogeneous workloads. We encourage Kubernetes users to test this new feature and provide feedback, which will be invaluable in shaping its future development.&lt;/p&gt;
&lt;p&gt;This draft aims to clearly explain the new feature while setting expectations for its current stage and future improvements.&lt;/p&gt;
&lt;h2 id=&#34;further-reading&#34;&gt;Further reading&lt;/h2&gt;
&lt;p&gt;Please check out the &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/tasks/administer-cluster/cpu-management-policies/&#34;&gt;Control CPU Management Policies on the Node&lt;/a&gt;
task page to learn more about the CPU Manager, and how it fits in relation to the other node-level resource managers.&lt;/p&gt;
&lt;h2 id=&#34;getting-involved&#34;&gt;Getting involved&lt;/h2&gt;
&lt;p&gt;This feature is driven by the &lt;a href=&#34;https://github.com/Kubernetes/community/blob/master/sig-node/README.md&#34;&gt;SIG Node&lt;/a&gt;. If you are interested in helping develop this feature, sharing feedback, or participating in any other ongoing SIG Node projects, please attend the SIG Node meeting for more details.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes 1.31: Autoconfiguration For Node Cgroup Driver (beta)</title>
      <link>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/08/21/cri-cgroup-driver-lookup-now-beta/</link>
      <pubDate>Wed, 21 Aug 2024 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/08/21/cri-cgroup-driver-lookup-now-beta/</guid>
      <description>
        
        
        &lt;p&gt;Historically, configuring the correct cgroup driver has been a pain point for users running new
Kubernetes clusters. On Linux systems, there are two different cgroup drivers:
&lt;code&gt;cgroupfs&lt;/code&gt; and &lt;code&gt;systemd&lt;/code&gt;. In the past, both the &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/reference/command-line-tools-reference/kubelet/&#34;&gt;kubelet&lt;/a&gt;
and CRI implementation (like CRI-O or containerd) needed to be configured to use
the same cgroup driver, or else the kubelet would exit with an error. This was a
source of headaches for many cluster admins. However, there is light at the end of the tunnel!&lt;/p&gt;
&lt;h2 id=&#34;automated-cgroup-driver-detection&#34;&gt;Automated cgroup driver detection&lt;/h2&gt;
&lt;p&gt;In v1.28.0, the SIG Node community introduced the feature gate
&lt;code&gt;KubeletCgroupDriverFromCRI&lt;/code&gt;, which instructs the kubelet to ask the CRI
implementation which cgroup driver to use. A few minor releases of Kubernetes
happened whilst we waited for support to land in the major two CRI implementations
(containerd and CRI-O), but as of v1.31.0, this feature is now beta!&lt;/p&gt;
&lt;p&gt;In addition to setting the feature gate, a cluster admin needs to ensure their
CRI implementation is new enough:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;containerd: Support was added in v2.0.0&lt;/li&gt;
&lt;li&gt;CRI-O: Support was added in v1.28.0&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Then, they should ensure their CRI implementation is configured to the
cgroup_driver they would like to use.&lt;/p&gt;
&lt;h2 id=&#34;future-work&#34;&gt;Future work&lt;/h2&gt;
&lt;p&gt;Eventually, support for the kubelet&#39;s &lt;code&gt;cgroupDriver&lt;/code&gt; configuration field will be
dropped, and the kubelet will fail to start if the CRI implementation isn&#39;t new
enough to have support for this feature.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes 1.31: Streaming Transitions from SPDY to WebSockets</title>
      <link>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/08/20/websockets-transition/</link>
      <pubDate>Tue, 20 Aug 2024 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/08/20/websockets-transition/</guid>
      <description>
        
        
        &lt;p&gt;In Kubernetes 1.31, by default kubectl now uses the WebSocket protocol
instead of SPDY for streaming.&lt;/p&gt;
&lt;p&gt;This post describes what these changes mean for you and why these streaming APIs
matter.&lt;/p&gt;
&lt;h2 id=&#34;streaming-apis-in-kubernetes&#34;&gt;Streaming APIs in Kubernetes&lt;/h2&gt;
&lt;p&gt;In Kubernetes, specific endpoints that are exposed as an HTTP or RESTful
interface are upgraded to streaming connections, which require a streaming
protocol. Unlike HTTP, which is a request-response protocol, a streaming
protocol provides a persistent connection that&#39;s bi-directional, low-latency,
and lets you interact in real-time. Streaming protocols support reading and
writing data between your client and the server, in both directions, over the
same connection. This type of connection is useful, for example, when you create
a shell in a running container from your local workstation and run commands in
the container.&lt;/p&gt;
&lt;h2 id=&#34;why-change-the-streaming-protocol&#34;&gt;Why change the streaming protocol?&lt;/h2&gt;
&lt;p&gt;Before the v1.31 release, Kubernetes used the SPDY/3.1 protocol by default when
upgrading streaming connections. SPDY/3.1 has been deprecated for eight years,
and it was never standardized. Many modern proxies, gateways, and load balancers
no longer support the protocol. As a result, you might notice that commands like
&lt;code&gt;kubectl cp&lt;/code&gt;, &lt;code&gt;kubectl attach&lt;/code&gt;, &lt;code&gt;kubectl exec&lt;/code&gt;, and &lt;code&gt;kubectl port-forward&lt;/code&gt;
stop working when you try to access your cluster through a proxy or gateway.&lt;/p&gt;
&lt;p&gt;As of Kubernetes v1.31, SIG API Machinery has modified the streaming
protocol that a Kubernetes client (such as &lt;code&gt;kubectl&lt;/code&gt;) uses for these commands
to the more modern &lt;a href=&#34;https://datatracker.ietf.org/doc/html/rfc6455&#34;&gt;WebSocket streaming protocol&lt;/a&gt;.
The WebSocket protocol is a currently supported standardized streaming protocol
that guarantees compatibility and interoperability with different components and
programming languages. The WebSocket protocol is more widely supported by modern
proxies and gateways than SPDY.&lt;/p&gt;
&lt;h2 id=&#34;how-streaming-apis-work&#34;&gt;How streaming APIs work&lt;/h2&gt;
&lt;p&gt;Kubernetes upgrades HTTP connections to streaming connections by adding
specific upgrade headers to the originating HTTP request. For example, an HTTP
upgrade request for running the &lt;code&gt;date&lt;/code&gt; command on an &lt;code&gt;nginx&lt;/code&gt; container within
a cluster is similar to the following:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;$&lt;/span&gt; kubectl &lt;span style=&#34;color:#a2f&#34;&gt;exec&lt;/span&gt; -v&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;8&lt;/span&gt; nginx -- date
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;GET https://127.0.0.1:43251/api/v1/namespaces/default/pods/nginx/exec?command=date…
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;Request Headers:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;    Connection: Upgrade
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;    Upgrade: websocket
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;    Sec-Websocket-Protocol: v5.channel.k8s.io
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;    User-Agent: kubectl/v1.31.0 (linux/amd64) kubernetes/6911225
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If the container runtime supports the WebSocket streaming protocol and at least
one of the subprotocol versions (e.g. &lt;code&gt;v5.channel.k8s.io&lt;/code&gt;), the server responds
with a successful &lt;code&gt;101 Switching Protocols&lt;/code&gt; status, along with the negotiated
subprotocol version:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;Response Status: 101 Switching Protocols in 3 milliseconds
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;Response Headers:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;    Upgrade: websocket
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;    Connection: Upgrade
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;    Sec-Websocket-Accept: j0/jHW9RpaUoGsUAv97EcKw8jFM=
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;    Sec-Websocket-Protocol: v5.channel.k8s.io
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;At this point the TCP connection used for the HTTP protocol has changed to a
streaming connection. Subsequent STDIN, STDOUT, and STDERR data (as well as
terminal resizing data and process exit code data) for this shell interaction is
then streamed over this upgraded connection.&lt;/p&gt;
&lt;h2 id=&#34;how-to-use-the-new-websocket-streaming-protocol&#34;&gt;How to use the new WebSocket streaming protocol&lt;/h2&gt;
&lt;p&gt;If your cluster and kubectl are on version 1.29 or later, there are two
control plane feature gates and two kubectl environment variables that
govern the use of the WebSockets rather than SPDY. In Kubernetes 1.31,
all of the following feature gates are in beta and are enabled by
default:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/reference/command-line-tools-reference/feature-gates/&#34;&gt;Feature gates&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;TranslateStreamCloseWebsocketRequests&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;.../exec&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.../attach&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PortForwardWebsockets&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;.../port-forward&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;kubectl feature control environment variables
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;KUBECTL_REMOTE_COMMAND_WEBSOCKETS&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;kubectl exec&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;kubectl cp&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;kubectl attach&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;KUBECTL_PORT_FORWARD_WEBSOCKETS&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;kubectl port-forward&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you&#39;re connecting to an older cluster but can manage the feature gate
settings, turn on both &lt;code&gt;TranslateStreamCloseWebsocketRequests&lt;/code&gt; (added in
Kubernetes v1.29) and &lt;code&gt;PortForwardWebsockets&lt;/code&gt; (added in Kubernetes
v1.30) to try this new behavior. Version 1.31 of &lt;code&gt;kubectl&lt;/code&gt; can automatically use
the new behavior, but you do need to connect to a cluster where the server-side
features are explicitly enabled.&lt;/p&gt;
&lt;h2 id=&#34;learn-more-about-streaming-apis&#34;&gt;Learn more about streaming APIs&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/4006-transition-spdy-to-websockets&#34;&gt;KEP 4006 - Transitioning from SPDY to WebSockets&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://datatracker.ietf.org/doc/html/rfc6455&#34;&gt;RFC 6455 - The WebSockets Protocol&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kubernetes.io/blog/2024/05/01/cri-streaming-explained/&#34;&gt;Container Runtime Interface streaming explained&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes 1.31: Pod Failure Policy for Jobs Goes GA</title>
      <link>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/08/19/kubernetes-1-31-pod-failure-policy-for-jobs-goes-ga/</link>
      <pubDate>Mon, 19 Aug 2024 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/08/19/kubernetes-1-31-pod-failure-policy-for-jobs-goes-ga/</guid>
      <description>
        
        
        &lt;p&gt;This post describes &lt;em&gt;Pod failure policy&lt;/em&gt;, which graduates to stable in Kubernetes
1.31, and how to use it in your Jobs.&lt;/p&gt;
&lt;h2 id=&#34;about-pod-failure-policy&#34;&gt;About Pod failure policy&lt;/h2&gt;
&lt;p&gt;When you run workloads on Kubernetes, Pods might fail for a variety of reasons.
Ideally, workloads like Jobs should be able to ignore transient, retriable
failures and continue running to completion.&lt;/p&gt;
&lt;p&gt;To allow for these transient failures, Kubernetes Jobs include the &lt;code&gt;backoffLimit&lt;/code&gt;
field, which lets you specify a number of Pod failures that you&#39;re willing to tolerate
during Job execution. However, if you set a large value for the &lt;code&gt;backoffLimit&lt;/code&gt; field
and rely solely on this field, you might notice unnecessary increases in operating
costs as Pods restart excessively until the backoffLimit is met.&lt;/p&gt;
&lt;p&gt;This becomes particularly problematic when running large-scale Jobs with
thousands of long-running Pods across thousands of nodes.&lt;/p&gt;
&lt;p&gt;The Pod failure policy extends the backoff limit mechanism to help you reduce
costs in the following ways:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Gives you control to fail the Job as soon as a non-retriable Pod failure occurs.&lt;/li&gt;
&lt;li&gt;Allows you to ignore retriable errors without increasing the &lt;code&gt;backoffLimit&lt;/code&gt; field.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For example, you can use a Pod failure policy to run your workload on more affordable spot machines
by ignoring Pod failures caused by
&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/cluster-administration/node-shutdown/#graceful-node-shutdown&#34;&gt;graceful node shutdown&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The policy allows you to distinguish between retriable and non-retriable Pod
failures based on container exit codes or Pod conditions in a failed Pod.&lt;/p&gt;
&lt;h2 id=&#34;how-it-works&#34;&gt;How it works&lt;/h2&gt;
&lt;p&gt;You specify a Pod failure policy in the Job specification, represented as a list
of rules.&lt;/p&gt;
&lt;p&gt;For each rule you define &lt;em&gt;match requirements&lt;/em&gt; based on one of the following properties:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Container exit codes: the &lt;code&gt;onExitCodes&lt;/code&gt; property.&lt;/li&gt;
&lt;li&gt;Pod conditions: the &lt;code&gt;onPodConditions&lt;/code&gt; property.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Additionally, for each rule, you specify one of the following actions to take
when a Pod matches the rule:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Ignore&lt;/code&gt;: Do not count the failure towards the &lt;code&gt;backoffLimit&lt;/code&gt; or &lt;code&gt;backoffLimitPerIndex&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;FailJob&lt;/code&gt;: Fail the entire Job and terminate all running Pods.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;FailIndex&lt;/code&gt;: Fail the index corresponding to the failed Pod.
This action works with the &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/workloads/controllers/job/#backoff-limit-per-index&#34;&gt;Backoff limit per index&lt;/a&gt; feature.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Count&lt;/code&gt;: Count the failure towards the &lt;code&gt;backoffLimit&lt;/code&gt; or &lt;code&gt;backoffLimitPerIndex&lt;/code&gt;.
This is the default behavior.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When Pod failures occur in a running Job, Kubernetes matches the
failed Pod status against the list of Pod failure policy rules, in the specified
order, and takes the corresponding actions for the first matched rule.&lt;/p&gt;
&lt;p&gt;Note that when specifying the Pod failure policy, you must also set the Job&#39;s
Pod template with &lt;code&gt;restartPolicy: Never&lt;/code&gt;. This prevents race conditions between
the kubelet and the Job controller when counting Pod failures.&lt;/p&gt;
&lt;h3 id=&#34;kubernetes-initiated-pod-disruptions&#34;&gt;Kubernetes-initiated Pod disruptions&lt;/h3&gt;
&lt;p&gt;To allow matching Pod failure policy rules against failures caused by
disruptions initiated by Kubernetes, this feature introduces the &lt;code&gt;DisruptionTarget&lt;/code&gt;
Pod condition.&lt;/p&gt;
&lt;p&gt;Kubernetes adds this condition to any Pod, regardless of whether it&#39;s managed by
a Job controller, that fails because of a retriable
&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/workloads/pods/disruptions/#pod-disruption-conditions&#34;&gt;disruption scenario&lt;/a&gt;.
The &lt;code&gt;DisruptionTarget&lt;/code&gt; condition contains one of the following reasons that
corresponds to these disruption scenarios:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;PreemptionByKubeScheduler&lt;/code&gt;: &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/scheduling-eviction/pod-priority-preemption/&#34;&gt;Preemption&lt;/a&gt;
by &lt;code&gt;kube-scheduler&lt;/code&gt; to accommodate a new Pod that has a higher priority.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;DeletionByTaintManager&lt;/code&gt; - the Pod is due to be deleted by
&lt;code&gt;kube-controller-manager&lt;/code&gt; due to a &lt;code&gt;NoExecute&lt;/code&gt; &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/scheduling-eviction/taint-and-toleration/&#34;&gt;taint&lt;/a&gt;
that the Pod doesn&#39;t tolerate.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;EvictionByEvictionAPI&lt;/code&gt; - the Pod is due to be deleted by an
&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/scheduling-eviction/api-eviction/&#34;&gt;API-initiated eviction&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;DeletionByPodGC&lt;/code&gt; - the Pod is bound to a node that no longer exists, and is due to
be deleted by &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/workloads/pods/pod-lifecycle/#pod-garbage-collection&#34;&gt;Pod garbage collection&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;TerminationByKubelet&lt;/code&gt; - the Pod was terminated by
&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/cluster-administration/node-shutdown/#graceful-node-shutdown&#34;&gt;graceful node shutdown&lt;/a&gt;,
&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/scheduling-eviction/node-pressure-eviction/&#34;&gt;node pressure eviction&lt;/a&gt;
or preemption for &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/tasks/administer-cluster/guaranteed-scheduling-critical-addon-pods/&#34;&gt;system critical pods&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In all other disruption scenarios, like eviction due to exceeding
&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/configuration/manage-resources-containers/&#34;&gt;Pod container limits&lt;/a&gt;,
Pods don&#39;t receive the &lt;code&gt;DisruptionTarget&lt;/code&gt; condition because the disruptions were
likely caused by the Pod and would reoccur on retry.&lt;/p&gt;
&lt;h3 id=&#34;example&#34;&gt;Example&lt;/h3&gt;
&lt;p&gt;The Pod failure policy snippet below demonstrates an example use:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;podFailurePolicy&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;rules&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;action&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Ignore&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;onPodConditions&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;type&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;DisruptionTarget&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;action&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;FailJob&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;onPodConditions&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;type&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;ConfigIssue&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;action&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;FailJob&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;onExitCodes&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;operator&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;In&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;values&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;[&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;42&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;]&lt;span style=&#34;color:#bbb&#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 Pod failure policy does the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ignores any failed Pods that have the built-in &lt;code&gt;DisruptionTarget&lt;/code&gt;
condition. These Pods don&#39;t count towards Job backoff limits.&lt;/li&gt;
&lt;li&gt;Fails the Job if any failed Pods have the custom user-supplied
&lt;code&gt;ConfigIssue&lt;/code&gt; condition, which was added either by a custom controller or webhook.&lt;/li&gt;
&lt;li&gt;Fails the Job if any containers exited with the exit code 42.&lt;/li&gt;
&lt;li&gt;Counts all other Pod failures towards the default &lt;code&gt;backoffLimit&lt;/code&gt; (or
&lt;code&gt;backoffLimitPerIndex&lt;/code&gt; if used).&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;learn-more&#34;&gt;Learn more&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;For a hands-on guide to using Pod failure policy, see
&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/tasks/job/pod-failure-policy/&#34;&gt;Handling retriable and non-retriable pod failures with Pod failure policy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Read the documentation for
&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/workloads/controllers/job/#pod-failure-policy&#34;&gt;Pod failure policy&lt;/a&gt; and
&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/workloads/controllers/job/#backoff-limit-per-index&#34;&gt;Backoff limit per index&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Read the documentation for
&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/workloads/pods/disruptions/#pod-disruption-conditions&#34;&gt;Pod disruption conditions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Read the KEP for &lt;a href=&#34;https://github.com/kubernetes/enhancements/tree/master/keps/sig-apps/3329-retriable-and-non-retriable-failures&#34;&gt;Pod failure policy&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;related-work&#34;&gt;Related work&lt;/h2&gt;
&lt;p&gt;Based on the concepts introduced by Pod failure policy, the following additional work is in progress:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;JobSet integration: &lt;a href=&#34;https://github.com/kubernetes-sigs/jobset/issues/262&#34;&gt;Configurable Failure Policy API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/4443&#34;&gt;Pod failure policy extension to add more granular failure reasons&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Support for Pod failure policy via JobSet in &lt;a href=&#34;https://github.com/kubeflow/training-operator/pull/2171&#34;&gt;Kubeflow Training v2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Proposal: &lt;a href=&#34;https://docs.google.com/document/d/1t25jgO_-LRHhjRXf4KJ5xY_t8BZYdapv7MDAxVGY6R8&#34;&gt;Disrupted Pods should be removed from endpoints&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;get-involved&#34;&gt;Get involved&lt;/h2&gt;
&lt;p&gt;This work was sponsored by
&lt;a href=&#34;https://github.com/kubernetes/community/tree/master/wg-batch&#34;&gt;batch working group&lt;/a&gt;
in close collaboration with the
&lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-apps&#34;&gt;SIG Apps&lt;/a&gt;,
and &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-node&#34;&gt;SIG Node&lt;/a&gt;,
and &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-scheduling&#34;&gt;SIG Scheduling&lt;/a&gt;
communities.&lt;/p&gt;
&lt;p&gt;If you are interested in working on new features in the space we recommend
subscribing to our &lt;a href=&#34;https://kubernetes.slack.com/messages/wg-batch&#34;&gt;Slack&lt;/a&gt;
channel and attending the regular community meetings.&lt;/p&gt;
&lt;h2 id=&#34;acknowledgments&#34;&gt;Acknowledgments&lt;/h2&gt;
&lt;p&gt;I would love to thank everyone who was involved in this project over the years -
it&#39;s been a journey and a joint community effort! The list below is
my best-effort attempt to remember and recognize people who made an impact.
Thank you!&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/alculquicondor/&#34;&gt;Aldo Culquicondor&lt;/a&gt; for guidance and reviews throughout the process&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/liggitt&#34;&gt;Jordan Liggitt&lt;/a&gt; for KEP and API reviews&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/deads2k&#34;&gt;David Eads&lt;/a&gt; for API reviews&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/soltysh&#34;&gt;Maciej Szulik&lt;/a&gt; for KEP reviews from SIG Apps PoV&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/smarterclayton&#34;&gt;Clayton Coleman&lt;/a&gt; for guidance and SIG Node reviews&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/SergeyKanzhelev&#34;&gt;Sergey Kanzhelev&lt;/a&gt; for KEP reviews from SIG Node PoV&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/dchen1107&#34;&gt;Dawn Chen&lt;/a&gt; for KEP reviews from SIG Node PoV&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/lavalamp&#34;&gt;Daniel Smith&lt;/a&gt; for reviews from SIG API machinery PoV&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/apelisse&#34;&gt;Antoine Pelisse&lt;/a&gt; for reviews from SIG API machinery PoV&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/johnbelamaric&#34;&gt;John Belamaric&lt;/a&gt; for PRR reviews&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/atiratree&#34;&gt;Filip Křepinský&lt;/a&gt; for thorough reviews from SIG Apps PoV and bug-fixing&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/bobbypage&#34;&gt;David Porter&lt;/a&gt; for thorough reviews from SIG Node PoV&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/jensentanlo&#34;&gt;Jensen Lo&lt;/a&gt; for early requirements discussions, testing and reporting issues&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/danielvegamyhre&#34;&gt;Daniel Vega-Myhre&lt;/a&gt; for advancing JobSet integration and reporting issues&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/ahg-g&#34;&gt;Abdullah Gharaibeh&lt;/a&gt; for early design discussions and guidance&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/aojea&#34;&gt;Antonio Ojea&lt;/a&gt; for test reviews&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/tenzen-y&#34;&gt;Yuki Iwai&lt;/a&gt; for reviews and aligning implementation of the closely related Job features&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kannon92&#34;&gt;Kevin Hannon&lt;/a&gt; for reviews and aligning implementation of the closely related Job features&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/sftim&#34;&gt;Tim Bannister&lt;/a&gt; for docs reviews&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/shannonxtreme&#34;&gt;Shannon Kularathna&lt;/a&gt; for docs reviews&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/cortespao&#34;&gt;Paola Cortés&lt;/a&gt; for docs reviews&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes 1.31: MatchLabelKeys in PodAffinity graduates to beta</title>
      <link>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/08/16/matchlabelkeys-podaffinity/</link>
      <pubDate>Fri, 16 Aug 2024 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/08/16/matchlabelkeys-podaffinity/</guid>
      <description>
        
        
        &lt;p&gt;Kubernetes 1.29 introduced new fields &lt;code&gt;matchLabelKeys&lt;/code&gt; and &lt;code&gt;mismatchLabelKeys&lt;/code&gt; in &lt;code&gt;podAffinity&lt;/code&gt; and &lt;code&gt;podAntiAffinity&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In Kubernetes 1.31, this feature moves to beta and the corresponding feature gate (&lt;code&gt;MatchLabelKeysInPodAffinity&lt;/code&gt;) gets enabled by default.&lt;/p&gt;
&lt;h2 id=&#34;matchlabelkeys-enhanced-scheduling-for-versatile-rolling-updates&#34;&gt;&lt;code&gt;matchLabelKeys&lt;/code&gt; - Enhanced scheduling for versatile rolling updates&lt;/h2&gt;
&lt;p&gt;During a workload&#39;s (e.g., Deployment) rolling update, a cluster may have Pods from multiple versions at the same time.
However, the scheduler cannot distinguish between old and new versions based on the &lt;code&gt;labelSelector&lt;/code&gt; specified in &lt;code&gt;podAffinity&lt;/code&gt; or &lt;code&gt;podAntiAffinity&lt;/code&gt;. As a result, it will co-locate or disperse Pods regardless of their versions.&lt;/p&gt;
&lt;p&gt;This can lead to sub-optimal scheduling outcome, for example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;New version Pods are co-located with old version Pods (&lt;code&gt;podAffinity&lt;/code&gt;), which will eventually be removed after rolling updates.&lt;/li&gt;
&lt;li&gt;Old version Pods are distributed across all available topologies, preventing new version Pods from finding nodes due to &lt;code&gt;podAntiAffinity&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;matchLabelKeys&lt;/code&gt; is a set of Pod label keys and addresses this problem.
The scheduler looks up the values of these keys from the new Pod&#39;s labels and combines them with &lt;code&gt;labelSelector&lt;/code&gt;
so that podAffinity matches Pods that have the same key-value in labels.&lt;/p&gt;
&lt;p&gt;By using label &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/workloads/controllers/deployment/#pod-template-hash-label&#34;&gt;pod-template-hash&lt;/a&gt; in &lt;code&gt;matchLabelKeys&lt;/code&gt;,
you can ensure that only Pods of the same version are evaluated for &lt;code&gt;podAffinity&lt;/code&gt; or &lt;code&gt;podAntiAffinity&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;apps/v1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Deployment&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;application-server&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#00f;font-weight:bold&#34;&gt;...&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;affinity&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;podAffinity&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;requiredDuringSchedulingIgnoredDuringExecution&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;labelSelector&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;matchExpressions&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;          &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;key&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;app&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;operator&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;In&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;values&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;- database&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;topologyKey&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;topology.kubernetes.io/zone&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;matchLabelKeys&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;- pod-template-hash&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The above &lt;code&gt;matchLabelKeys&lt;/code&gt; will be translated in Pods like:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Pod&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;application-server&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;labels&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;pod-template-hash&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;xyz&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#00f;font-weight:bold&#34;&gt;...&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;affinity&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;podAffinity&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;requiredDuringSchedulingIgnoredDuringExecution&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;labelSelector&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;matchExpressions&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;          &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;key&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;app&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;operator&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;In&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;values&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;- database&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;          &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;key&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;pod-template-hash&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Added from matchLabelKeys; Only Pods from the same replicaset will match this affinity.&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;operator&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;In&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;values&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;- xyz&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;topologyKey&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;topology.kubernetes.io/zone&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;matchLabelKeys&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;- pod-template-hash&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;mismatchlabelkeys-service-isolation&#34;&gt;&lt;code&gt;mismatchLabelKeys&lt;/code&gt; - Service isolation&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;mismatchLabelKeys&lt;/code&gt; is a set of Pod label keys, like &lt;code&gt;matchLabelKeys&lt;/code&gt;,
which looks up the values of these keys from the new Pod&#39;s labels, and merge them with &lt;code&gt;labelSelector&lt;/code&gt; as &lt;code&gt;key notin (value)&lt;/code&gt;
so that &lt;code&gt;podAffinity&lt;/code&gt; does &lt;em&gt;not&lt;/em&gt; match Pods that have the same key-value in labels.&lt;/p&gt;
&lt;p&gt;Suppose all Pods for each tenant get &lt;code&gt;tenant&lt;/code&gt; label via a controller or a manifest management tool like Helm.&lt;/p&gt;
&lt;p&gt;Although the value of &lt;code&gt;tenant&lt;/code&gt; label is unknown when composing each workload&#39;s manifest,
the cluster admin wants to achieve exclusive 1:1 tenant to domain placement for a tenant isolation.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;mismatchLabelKeys&lt;/code&gt; works for this usecase;
By applying the following affinity globally using a mutating webhook,
the cluster admin can ensure that the Pods from the same tenant will land on the same domain exclusively,
meaning Pods from other tenants won&#39;t land on the same domain.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;affinity&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;podAffinity&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# ensures the pods of this tenant land on the same node pool&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;requiredDuringSchedulingIgnoredDuringExecution&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;matchLabelKeys&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;- tenant&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;topologyKey&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;node-pool&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;podAntiAffinity&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# ensures only Pods from this tenant lands on the same node pool&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;requiredDuringSchedulingIgnoredDuringExecution&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;mismatchLabelKeys&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;- tenant&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;labelSelector&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;matchExpressions&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;key&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;tenant&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;operator&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Exists&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;topologyKey&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;node-pool&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The above &lt;code&gt;matchLabelKeys&lt;/code&gt; and &lt;code&gt;mismatchLabelKeys&lt;/code&gt; will be translated to like:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Pod&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;application-server&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;labels&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;tenant&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;service-a&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;spec&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;affinity&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;podAffinity&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# ensures the pods of this tenant land on the same node pool&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;requiredDuringSchedulingIgnoredDuringExecution&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;matchLabelKeys&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;          &lt;/span&gt;- tenant&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;topologyKey&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;node-pool&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;labelSelector&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;matchExpressions&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;          &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;key&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;tenant&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;operator&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;In&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;values&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;- service-a &lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;podAntiAffinity&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# ensures only Pods from this tenant lands on the same node pool&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;requiredDuringSchedulingIgnoredDuringExecution&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;mismatchLabelKeys&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;          &lt;/span&gt;- tenant&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;labelSelector&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;matchExpressions&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;          &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;key&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;tenant&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;operator&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Exists&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;          &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;key&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;tenant&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;operator&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;NotIn&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;values&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;- service-a&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;topologyKey&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;node-pool&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;getting-involved&#34;&gt;Getting involved&lt;/h2&gt;
&lt;p&gt;These features are managed by Kubernetes &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-scheduling&#34;&gt;SIG Scheduling&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Please join us and share your feedback. We look forward to hearing from you!&lt;/p&gt;
&lt;h2 id=&#34;how-can-i-learn-more&#34;&gt;How can I learn more?&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity&#34;&gt;The official document of podAffinity&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/enhancements/blob/master/keps/sig-scheduling/3633-matchlabelkeys-to-podaffinity/README.md#story-2&#34;&gt;KEP-3633: Introduce matchLabelKeys and mismatchLabelKeys to podAffinity and podAntiAffinity&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes 1.31: Prevent PersistentVolume Leaks When Deleting out of Order</title>
      <link>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/08/16/kubernetes-1-31-prevent-persistentvolume-leaks-when-deleting-out-of-order/</link>
      <pubDate>Fri, 16 Aug 2024 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/08/16/kubernetes-1-31-prevent-persistentvolume-leaks-when-deleting-out-of-order/</guid>
      <description>
        
        
        &lt;p&gt;&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/storage/persistent-volumes/&#34;&gt;PersistentVolume&lt;/a&gt; (or PVs for short) are
associated with &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/storage/persistent-volumes/#reclaim-policy&#34;&gt;Reclaim Policy&lt;/a&gt;.
The reclaim policy is used to determine the actions that need to be taken by the storage
backend on deletion of the PVC Bound to a PV.
When the reclaim policy is &lt;code&gt;Delete&lt;/code&gt;, the expectation is that the storage backend
releases the storage resource allocated for the PV. In essence, the reclaim
policy needs to be honored on PV deletion.&lt;/p&gt;
&lt;p&gt;With the recent Kubernetes v1.31 release, a beta feature lets you configure your
cluster to behave that way and honor the configured reclaim policy.&lt;/p&gt;
&lt;h2 id=&#34;how-did-reclaim-work-in-previous-kubernetes-releases&#34;&gt;How did reclaim work in previous Kubernetes releases?&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/storage/persistent-volumes/#Introduction&#34;&gt;PersistentVolumeClaim&lt;/a&gt; (or PVC for short) is
a user&#39;s request for storage. A PV and PVC are considered &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/storage/persistent-volumes/#Binding&#34;&gt;Bound&lt;/a&gt;
if a newly created PV or a matching PV is found. The PVs themselves are
backed by volumes allocated by the storage backend.&lt;/p&gt;
&lt;p&gt;Normally, if the volume is to be deleted, then the expectation is to delete the
PVC for a bound PV-PVC pair. However, there are no restrictions on deleting a PV
before deleting a PVC.&lt;/p&gt;
&lt;p&gt;First, I&#39;ll demonstrate the behavior for clusters running an older version of Kubernetes.&lt;/p&gt;
&lt;h4 id=&#34;retrieve-a-pvc-that-is-bound-to-a-pv&#34;&gt;Retrieve a PVC that is bound to a PV&lt;/h4&gt;
&lt;p&gt;Retrieve an existing PVC &lt;code&gt;example-vanilla-block-pvc&lt;/code&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;kubectl get pvc example-vanilla-block-pvc
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The following output shows the PVC and its bound PV; the PV is shown under the &lt;code&gt;VOLUME&lt;/code&gt; column:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;NAME                        STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS               AGE
example-vanilla-block-pvc   Bound    pvc-6791fdd4-5fad-438e-a7fb-16410363e3da   5Gi        RWO            example-vanilla-block-sc   19s
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id=&#34;delete-pv&#34;&gt;Delete PV&lt;/h4&gt;
&lt;p&gt;When I try to delete a bound PV, the kubectl session blocks and the &lt;code&gt;kubectl&lt;/code&gt;
tool does not return back control to the shell; for example:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;kubectl delete pv pvc-6791fdd4-5fad-438e-a7fb-16410363e3da
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;persistentvolume &amp;#34;pvc-6791fdd4-5fad-438e-a7fb-16410363e3da&amp;#34; deleted
^C
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id=&#34;retrieving-the-pv&#34;&gt;Retrieving the PV&lt;/h4&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;kubectl get pv pvc-6791fdd4-5fad-438e-a7fb-16410363e3da
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It can be observed that the PV is in a &lt;code&gt;Terminating&lt;/code&gt; state&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS        CLAIM                               STORAGECLASS               REASON   AGE
pvc-6791fdd4-5fad-438e-a7fb-16410363e3da   5Gi        RWO            Delete           Terminating   default/example-vanilla-block-pvc   example-vanilla-block-sc            2m23s
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id=&#34;delete-pvc&#34;&gt;Delete PVC&lt;/h4&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;kubectl delete pvc example-vanilla-block-pvc
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The following output is seen if the PVC gets successfully deleted:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;persistentvolumeclaim &amp;#34;example-vanilla-block-pvc&amp;#34; deleted
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The PV object from the cluster also gets deleted. When attempting to retrieve the PV
it will be observed that the PV is no longer found:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;kubectl get pv pvc-6791fdd4-5fad-438e-a7fb-16410363e3da
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Error from server (NotFound): persistentvolumes &amp;#34;pvc-6791fdd4-5fad-438e-a7fb-16410363e3da&amp;#34; not found
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Although the PV is deleted, the underlying storage resource is not deleted and
needs to be removed manually.&lt;/p&gt;
&lt;p&gt;To sum up, the reclaim policy associated with the PersistentVolume is currently
ignored under certain circumstances. For a &lt;code&gt;Bound&lt;/code&gt; PV-PVC pair, the ordering of PV-PVC
deletion determines whether the PV reclaim policy is honored. The reclaim policy
is honored if the PVC is deleted first; however, if the PV is deleted prior to
deleting the PVC, then the reclaim policy is not exercised. As a result of this behavior,
the associated storage asset in the external infrastructure is not removed.&lt;/p&gt;
&lt;h2 id=&#34;pv-reclaim-policy-with-kubernetes-v1-31&#34;&gt;PV reclaim policy with Kubernetes v1.31&lt;/h2&gt;
&lt;p&gt;The new behavior ensures that the underlying storage object is deleted from the backend when users attempt to delete a PV manually.&lt;/p&gt;
&lt;h4 id=&#34;how-to-enable-new-behavior&#34;&gt;How to enable new behavior?&lt;/h4&gt;
&lt;p&gt;To take advantage of the new behavior, you must have upgraded your cluster to the v1.31 release of Kubernetes
and run the CSI &lt;a href=&#34;https://github.com/kubernetes-csi/external-provisioner&#34;&gt;&lt;code&gt;external-provisioner&lt;/code&gt;&lt;/a&gt; version &lt;code&gt;5.0.1&lt;/code&gt; or later.&lt;/p&gt;
&lt;h4 id=&#34;how-does-it-work&#34;&gt;How does it work?&lt;/h4&gt;
&lt;p&gt;For CSI volumes, the new behavior is achieved by adding a &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/overview/working-with-objects/finalizers/&#34;&gt;finalizer&lt;/a&gt; &lt;code&gt;external-provisioner.volume.kubernetes.io/finalizer&lt;/code&gt;
on new and existing PVs. The finalizer is only removed after the storage from the backend is deleted.
`&lt;/p&gt;
&lt;p&gt;An example of a PV with the finalizer, notice the new finalizer in the finalizers list&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;kubectl get pv pvc-a7b7e3ba-f837-45ba-b243-dec7d8aaed53 -o yaml
&lt;/code&gt;&lt;/pre&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;v1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;PersistentVolume&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;annotations&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;pv.kubernetes.io/provisioned-by&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;csi.vsphere.vmware.com&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;creationTimestamp&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;2021-11-17T19:28:56Z&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;finalizers&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- kubernetes.io/pv-protection&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- external-provisioner.volume.kubernetes.io/finalizer&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;pvc-a7b7e3ba-f837-45ba-b243-dec7d8aaed53&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;resourceVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;194711&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;uid&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;087f14f2-4157-4e95-8a70-8294b039d30e&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;spec&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;accessModes&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- ReadWriteOnce&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;capacity&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;storage&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;1Gi&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;claimRef&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;v1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;PersistentVolumeClaim&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;example-vanilla-block-pvc&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;namespace&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;default&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;resourceVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;194677&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;uid&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;a7b7e3ba-f837-45ba-b243-dec7d8aaed53&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;csi&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;driver&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;csi.vsphere.vmware.com&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;fsType&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;ext4&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;volumeAttributes&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;storage.kubernetes.io/csiProvisionerIdentity&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;1637110610497-8081&lt;/span&gt;-csi.vsphere.vmware.com&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;type&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;vSphere CNS Block Volume&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;volumeHandle&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;2dacf297-803f-4ccc-afc7-3d3c3f02051e&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;persistentVolumeReclaimPolicy&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Delete&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;storageClassName&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;example-vanilla-block-sc&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;volumeMode&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Filesystem&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;status&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;phase&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Bound&lt;span style=&#34;color:#bbb&#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;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/overview/working-with-objects/finalizers/&#34;&gt;finalizer&lt;/a&gt; prevents this
PersistentVolume from being removed from the
cluster. As stated previously, the finalizer is only removed from the PV object
after it is successfully deleted from the storage backend. To learn more about
finalizers, please refer to &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2021/05/14/using-finalizers-to-control-deletion/&#34;&gt;Using Finalizers to Control Deletion&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Similarly, the finalizer &lt;code&gt;kubernetes.io/pv-controller&lt;/code&gt; is added to dynamically provisioned in-tree plugin volumes.&lt;/p&gt;
&lt;h4 id=&#34;what-about-csi-migrated-volumes&#34;&gt;What about CSI migrated volumes?&lt;/h4&gt;
&lt;p&gt;The fix applies to CSI migrated volumes as well.&lt;/p&gt;
&lt;h3 id=&#34;some-caveats&#34;&gt;Some caveats&lt;/h3&gt;
&lt;p&gt;The fix does not apply to statically provisioned in-tree plugin volumes.&lt;/p&gt;
&lt;h3 id=&#34;references&#34;&gt;References&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/enhancements/tree/master/keps/sig-storage/2644-honor-pv-reclaim-policy&#34;&gt;KEP-2644&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes-csi/external-provisioner/issues/546&#34;&gt;Volume leak issue&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;how-do-i-get-involved&#34;&gt;How do I get involved?&lt;/h3&gt;
&lt;p&gt;The Kubernetes Slack channel &lt;a href=&#34;https://github.com/kubernetes/community/blob/master/sig-storage/README.md#contact&#34;&gt;SIG Storage communication channels&lt;/a&gt; are great mediums to reach out to the SIG Storage and migration working group teams.&lt;/p&gt;
&lt;p&gt;Special thanks to the following people for the insightful reviews, thorough consideration and valuable contribution:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fan Baofa (carlory)&lt;/li&gt;
&lt;li&gt;Jan Šafránek (jsafrane)&lt;/li&gt;
&lt;li&gt;Xing Yang (xing-yang)&lt;/li&gt;
&lt;li&gt;Matthew Wong (wongma7)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Join the &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-storage&#34;&gt;Kubernetes Storage Special Interest Group (SIG)&lt;/a&gt; if you&#39;re interested in getting involved with the design and development of CSI or any part of the Kubernetes Storage system. We’re rapidly growing and always welcome new contributors.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes 1.31: Read Only Volumes Based On OCI Artifacts (alpha)</title>
      <link>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/08/16/kubernetes-1-31-image-volume-source/</link>
      <pubDate>Fri, 16 Aug 2024 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/08/16/kubernetes-1-31-image-volume-source/</guid>
      <description>
        
        
        &lt;p&gt;The Kubernetes community is moving towards fulfilling more Artificial
Intelligence (AI) and Machine Learning (ML) use cases in the future. While the
project has been designed to fulfill microservice architectures in the past,
it’s now time to listen to the end users and introduce features which have a
stronger focus on AI/ML.&lt;/p&gt;
&lt;p&gt;One of these requirements is to support &lt;a href=&#34;https://opencontainers.org&#34;&gt;Open Container Initiative (OCI)&lt;/a&gt;
compatible images and artifacts (referred as OCI objects) directly as a native
volume source. This allows users to focus on OCI standards as well as enables
them to store and distribute any content using OCI registries. A feature like
this gives the Kubernetes project a chance to grow into use cases which go
beyond running particular images.&lt;/p&gt;
&lt;p&gt;Given that, the Kubernetes community is proud to present a new alpha feature
introduced in v1.31: The Image Volume Source
(&lt;a href=&#34;https://kep.k8s.io/4639&#34;&gt;KEP-4639&lt;/a&gt;). This feature allows users to specify an
image reference as volume in a pod while reusing it as volume mount within
containers:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;…&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Pod&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;spec&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;containers&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- …&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;volumeMounts&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;my-volume&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;mountPath&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;/path/to/directory&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;volumes&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;my-volume&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;image&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;reference&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;my-image:tag&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The above example would result in mounting &lt;code&gt;my-image:tag&lt;/code&gt; to
&lt;code&gt;/path/to/directory&lt;/code&gt; in the pod’s container.&lt;/p&gt;
&lt;h2 id=&#34;use-cases&#34;&gt;Use cases&lt;/h2&gt;
&lt;p&gt;The goal of this enhancement is to stick as close as possible to the existing
&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/containers/images/&#34;&gt;container image&lt;/a&gt; implementation within the
kubelet, while introducing a new API surface to allow more extended use cases.&lt;/p&gt;
&lt;p&gt;For example, users could share a configuration file among multiple containers in
a pod without including the file in the main image, so that they can minimize
security risks and the overall image size. They can also package and distribute
binary artifacts using OCI images and mount them directly into Kubernetes pods,
so that they can streamline their CI/CD pipeline as an example.&lt;/p&gt;
&lt;p&gt;Data scientists, MLOps engineers, or AI developers, can mount large language
model weights or machine learning model weights in a pod alongside a
model-server, so that they can efficiently serve them without including them in
the model-server container image. They can package these in an OCI object to
take advantage of OCI distribution and ensure efficient model deployment. This
allows them to separate the model specifications/content from the executables
that process them.&lt;/p&gt;
&lt;p&gt;Another use case is that security engineers can use a public image for a malware
scanner and mount in a volume of private (commercial) malware signatures, so
that they can load those signatures without baking their own combined image
(which might not be allowed by the copyright on the public image). Those files
work regardless of the OS or version of the scanner software.&lt;/p&gt;
&lt;p&gt;But in the long term it will be up to &lt;strong&gt;you&lt;/strong&gt; as an end user of this project to
outline further important use cases for the new feature.
&lt;a href=&#34;https://github.com/kubernetes/community/blob/54a67f5/sig-node/README.md&#34;&gt;SIG Node&lt;/a&gt;
is happy to retrieve any feedback or suggestions for further enhancements to
allow more advanced usage scenarios. Feel free to provide feedback by either
using the &lt;a href=&#34;https://kubernetes.slack.com/messages/sig-node&#34;&gt;Kubernetes Slack (#sig-node)&lt;/a&gt;
channel or the &lt;a href=&#34;https://groups.google.com/g/kubernetes-sig-node&#34;&gt;SIG Node mailinglist&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;example&#34;&gt;Detailed example&lt;/h2&gt;
&lt;p&gt;The Kubernetes alpha feature gate &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/reference/command-line-tools-reference/feature-gates/&#34;&gt;&lt;code&gt;ImageVolume&lt;/code&gt;&lt;/a&gt;
needs to be enabled on the &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/reference/command-line-tools-reference/kube-apiserver/&#34;&gt;API Server&lt;/a&gt;
as well as the &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/reference/command-line-tools-reference/kubelet/&#34;&gt;kubelet&lt;/a&gt;
to make it functional. If that’s the case and the &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/setup/production-environment/container-runtimes/&#34;&gt;container runtime&lt;/a&gt;
has support for the feature (like CRI-O ≥ v1.31), then an example &lt;code&gt;pod.yaml&lt;/code&gt;
like this can be created:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;v1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Pod&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;pod&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;spec&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;containers&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;test&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;image&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;registry.k8s.io/e2e-test-images/echoserver:2.3&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;volumeMounts&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;volume&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;mountPath&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;/volume&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;volumes&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;volume&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;image&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;reference&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;quay.io/crio/artifact:v1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;pullPolicy&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;IfNotPresent&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The pod declares a new volume using the &lt;code&gt;image.reference&lt;/code&gt; of
&lt;code&gt;quay.io/crio/artifact:v1&lt;/code&gt;, which refers to an OCI object containing two files.
The &lt;code&gt;pullPolicy&lt;/code&gt; behaves in the same way as for container images and allows the
following values:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Always&lt;/code&gt;: the kubelet always attempts to pull the reference and the container
creation will fail if the pull fails.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Never&lt;/code&gt;: the kubelet never pulls the reference and only uses a local image or
artifact. The container creation will fail if the reference isn’t present.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;IfNotPresent&lt;/code&gt;: the kubelet pulls if the reference isn’t already present on
disk. The container creation will fail if the reference isn’t present and the
pull fails.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The &lt;code&gt;volumeMounts&lt;/code&gt; field is indicating that the container with the name &lt;code&gt;test&lt;/code&gt;
should mount the volume under the path &lt;code&gt;/volume&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If you now create the pod:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kubectl apply -f pod.yaml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And exec into it:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kubectl &lt;span style=&#34;color:#a2f&#34;&gt;exec&lt;/span&gt; -it pod -- sh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then you’re able to investigate what has been mounted:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;/ # ls /volume
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;dir   file
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;/ # cat /volume/file
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;2
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;/ # ls /volume/dir
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;file
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;/ # cat /volume/dir/file
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;You managed to consume an OCI artifact using Kubernetes!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The container runtime pulls the image (or artifact), mounts it to the
container and makes it finally available for direct usage. There are a bunch of
details in the implementation, which closely align to the existing image pull
behavior of the kubelet. For example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If a &lt;code&gt;:latest&lt;/code&gt; tag as &lt;code&gt;reference&lt;/code&gt; is provided, then the &lt;code&gt;pullPolicy&lt;/code&gt; will
default to &lt;code&gt;Always&lt;/code&gt;, while in any other case it will default to &lt;code&gt;IfNotPresent&lt;/code&gt;
if unset.&lt;/li&gt;
&lt;li&gt;The volume gets re-resolved if the pod gets deleted and recreated, which means
that new remote content will become available on pod recreation. A failure to
resolve or pull the image during pod startup will block containers from
starting and may add significant latency. Failures will be retried using
normal volume backoff and will be reported on the pod reason and message.&lt;/li&gt;
&lt;li&gt;Pull secrets will be assembled in the same way as for the container image by
looking up node credentials, service account image pull secrets, and pod spec
image pull secrets.&lt;/li&gt;
&lt;li&gt;The OCI object gets mounted in a single directory by merging the manifest
layers in the same way as for container images.&lt;/li&gt;
&lt;li&gt;The volume is mounted as read-only (&lt;code&gt;ro&lt;/code&gt;) and non-executable files
(&lt;code&gt;noexec&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Sub-path mounts for containers are not supported
(&lt;code&gt;spec.containers[*].volumeMounts.subpath&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;The field &lt;code&gt;spec.securityContext.fsGroupChangePolicy&lt;/code&gt; has no effect on this
volume type.&lt;/li&gt;
&lt;li&gt;The feature will also work with the &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/reference/access-authn-authz/admission-controllers/#alwayspullimages&#34;&gt;&lt;code&gt;AlwaysPullImages&lt;/code&gt; admission plugin&lt;/a&gt;
if enabled.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Thank you for reading through the end of this blog post! SIG Node is proud and
happy to deliver this feature as part of Kubernetes v1.31.&lt;/p&gt;
&lt;p&gt;As writer of this blog post, I would like to emphasize my special thanks to
&lt;strong&gt;all&lt;/strong&gt; involved individuals out there! You all rock, let’s keep on hacking!&lt;/p&gt;
&lt;h2 id=&#34;further-reading&#34;&gt;Further reading&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/tasks/configure-pod-container/image-volumes/&#34;&gt;Use an Image Volume With a Pod&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/storage/volumes/#image&#34;&gt;&lt;code&gt;image&lt;/code&gt; volume overview&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes 1.31: VolumeAttributesClass for Volume Modification Beta</title>
      <link>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/08/15/kubernetes-1-31-volume-attributes-class/</link>
      <pubDate>Thu, 15 Aug 2024 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/08/15/kubernetes-1-31-volume-attributes-class/</guid>
      <description>
        
        
        &lt;p&gt;Volumes in Kubernetes have been described by two attributes: their storage class, and
their capacity. The storage class is an immutable property of the volume, while the
capacity can be changed dynamically with &lt;a href=&#34;https://kubernetes.io/docs/concepts/storage/persistent-volumes/#expanding-persistent-volumes-claims&#34;&gt;volume
resize&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This complicates vertical scaling of workloads with volumes. While cloud providers and
storage vendors often offer volumes which allow specifying IO quality of service
(Performance) parameters like IOPS or throughput and tuning them as workloads operate,
Kubernetes has no API which allows changing them.&lt;/p&gt;
&lt;p&gt;We are pleased to announce that the &lt;a href=&#34;https://github.com/kubernetes/enhancements/blob/master/keps/sig-storage/3751-volume-attributes-class/README.md&#34;&gt;VolumeAttributesClass
KEP&lt;/a&gt;,
alpha since Kubernetes 1.29, will be beta in 1.31. This provides a generic,
Kubernetes-native API for modifying volume parameters like provisioned IO.&lt;/p&gt;
&lt;p&gt;Like all new volume features in Kubernetes, this API is implemented via the &lt;a href=&#34;https://kubernetes-csi.github.io/docs/&#34;&gt;container
storage interface (CSI)&lt;/a&gt;. In addition to the
VolumeAttributesClass feature gate, your provisioner-specific CSI driver must support the
new ModifyVolume API which is the CSI side of this feature.&lt;/p&gt;
&lt;p&gt;See the &lt;a href=&#34;https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/&#34;&gt;full
documentation&lt;/a&gt;
for all details. Here we show the common workflow.&lt;/p&gt;
&lt;h3 id=&#34;dynamically-modifying-volume-attributes&#34;&gt;Dynamically modifying volume attributes.&lt;/h3&gt;
&lt;p&gt;A &lt;code&gt;VolumeAttributesClass&lt;/code&gt; is a cluster-scoped resource that specifies provisioner-specific
attributes. These are created by the cluster administrator in the same way as storage
classes. For example, a series of gold, silver and bronze volume attribute classes can be
created for volumes with greater or lessor amounts of provisioned IO.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;storage.k8s.io/v1alpha1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;VolumeAttributesClass&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;silver&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;driverName&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;your-csi-driver&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;parameters&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;provisioned-iops&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;500&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;provisioned-throughput&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;50MiB/s&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#00f;font-weight:bold&#34;&gt;---&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;storage.k8s.io/v1alpha1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;VolumeAttributesClass&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;gold&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;driverName&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;your-csi-driver&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;parameters&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;provisioned-iops&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;10000&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;provisioned-throughput&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;500MiB/s&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;An attribute class is added to a PVC in much the same way as a storage class.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;v1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;PersistentVolumeClaim&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;test-pv-claim&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;spec&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;storageClassName&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;any-storage-class&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;volumeAttributesClassName&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;silver&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;accessModes&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- ReadWriteOnce&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;resources&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;requests&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;storage&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;64Gi&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Unlike a storage class, the volume attributes class can be changed:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;kubectl patch pvc test-pv-claim -p &amp;#39;{&amp;#34;spec&amp;#34;: &amp;#34;volumeAttributesClassName&amp;#34;: &amp;#34;gold&amp;#34;}&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Kubernetes will work with the CSI driver to update the attributes of the
volume. The status of the PVC will track the current and desired attributes
class. The PV resource will also be updated with the new volume attributes class
which will be set to the currently active attributes of the PV.&lt;/p&gt;
&lt;h3 id=&#34;limitations-with-the-beta&#34;&gt;Limitations with the beta&lt;/h3&gt;
&lt;p&gt;As a beta feature, there are still some features which are planned for GA but not yet
present. The largest is quota support, see the
&lt;a href=&#34;https://github.com/kubernetes/enhancements/blob/master/keps/sig-storage/3751-volume-attributes-class/README.md&#34;&gt;KEP&lt;/a&gt;
and discussion in
&lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-storage&#34;&gt;sig-storage&lt;/a&gt; for details.&lt;/p&gt;
&lt;p&gt;See the &lt;a href=&#34;https://kubernetes-csi.github.io/docs/drivers.html&#34;&gt;Kubernetes CSI driver
list&lt;/a&gt; for up-to-date
information of support for this feature in CSI drivers.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes v1.31: Accelerating Cluster Performance with Consistent Reads from Cache</title>
      <link>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/08/15/consistent-read-from-cache-beta/</link>
      <pubDate>Thu, 15 Aug 2024 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/08/15/consistent-read-from-cache-beta/</guid>
      <description>
        
        
        &lt;p&gt;Kubernetes is renowned for its robust orchestration of containerized applications,
but as clusters grow, the demands on the control plane can become a bottleneck.
A key challenge has been ensuring strongly consistent reads from the etcd datastore,
requiring resource-intensive quorum reads.&lt;/p&gt;
&lt;p&gt;Today, the Kubernetes community is excited to announce a major improvement:
&lt;em&gt;consistent reads from cache&lt;/em&gt;, graduating to Beta in Kubernetes v1.31.&lt;/p&gt;
&lt;h3 id=&#34;why-consistent-reads-matter&#34;&gt;Why consistent reads matter&lt;/h3&gt;
&lt;p&gt;Consistent reads are essential for ensuring that Kubernetes components have an accurate view of the latest cluster state.
Guaranteeing consistent reads is crucial for maintaining the accuracy and reliability of Kubernetes operations,
enabling components to make informed decisions based on up-to-date information.
In large-scale clusters, fetching and processing this data can be a performance bottleneck,
especially for requests that involve filtering results.
While Kubernetes can filter data by namespace directly within etcd,
any other filtering by labels or field selectors requires the entire dataset to be fetched from etcd and then filtered in-memory by the Kubernetes API server.
This is particularly impactful for components like the kubelet,
which only needs to list pods scheduled to its node - but previously required the API Server and etcd to process all pods in the cluster.&lt;/p&gt;
&lt;h3 id=&#34;the-breakthrough-caching-with-confidence&#34;&gt;The breakthrough: Caching with confidence&lt;/h3&gt;
&lt;p&gt;Kubernetes has long used a watch cache to optimize read operations.
The watch cache stores a snapshot of the cluster state and receives updates through etcd watches.
However, until now, it couldn&#39;t serve consistent reads directly, as there was no guarantee the cache was sufficiently up-to-date.&lt;/p&gt;
&lt;p&gt;The &lt;em&gt;consistent reads from cache&lt;/em&gt; feature addresses this by leveraging etcd&#39;s
&lt;a href=&#34;https://etcd.io/docs/v3.5/dev-guide/interacting_v3/#watch-progress&#34;&gt;progress notifications&lt;/a&gt;
mechanism.
These notifications inform the watch cache about how current its data is compared to etcd.
When a consistent read is requested, the system first checks if the watch cache is up-to-date.
If the cache is not up-to-date, the system queries etcd for progress notifications until it&#39;s confirmed that the cache is sufficiently fresh.
Once ready, the read is efficiently served directly from the cache,
which can significantly improve performance,
particularly in cases where it would require fetching a lot of data from etcd.
This enables requests that filter data to be served from the cache,
with only minimal metadata needing to be read from etcd.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Important Note:&lt;/strong&gt; To benefit from this feature, your Kubernetes cluster must be running etcd version 3.4.31+ or 3.5.13+.
For older etcd versions, Kubernetes will automatically fall back to serving consistent reads directly from etcd.&lt;/p&gt;
&lt;h3 id=&#34;performance-gains-you-ll-notice&#34;&gt;Performance gains you&#39;ll notice&lt;/h3&gt;
&lt;p&gt;This seemingly simple change has a profound impact on Kubernetes performance and scalability:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Reduced etcd Load:&lt;/strong&gt; Kubernetes v1.31 can offload work from etcd,
freeing up resources for other critical operations.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Lower Latency:&lt;/strong&gt; Serving reads from cache is significantly faster than fetching
and processing data from etcd. This translates to quicker responses for components,
improving overall cluster responsiveness.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Improved Scalability:&lt;/strong&gt; Large clusters with thousands of nodes and pods will
see the most significant gains, as the reduction in etcd load allows the
control plane to handle more requests without sacrificing performance.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;5k Node Scalability Test Results:&lt;/strong&gt; In recent scalability tests on 5,000 node
clusters, enabling consistent reads from cache delivered impressive improvements:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;30% reduction&lt;/strong&gt; in kube-apiserver CPU usage&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;25% reduction&lt;/strong&gt; in etcd CPU usage&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Up to 3x reduction&lt;/strong&gt; (from 5 seconds to 1.5 seconds) in 99th percentile pod LIST request latency&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;what-s-next&#34;&gt;What&#39;s next?&lt;/h3&gt;
&lt;p&gt;With the graduation to beta, consistent reads from cache are enabled by default,
offering a seamless performance boost to all Kubernetes users running a supported
etcd version.&lt;/p&gt;
&lt;p&gt;Our journey doesn&#39;t end here. Kubernetes community is actively exploring
pagination support in the watch cache, which will unlock even more performance
optimizations in the future.&lt;/p&gt;
&lt;h3 id=&#34;getting-started&#34;&gt;Getting started&lt;/h3&gt;
&lt;p&gt;Upgrading to Kubernetes v1.31 and ensuring you are using etcd version 3.4.31+ or
3.5.13+ is the easiest way to experience the benefits of consistent reads from
cache.
If you have any questions or feedback, don&#39;t hesitate to reach out to the Kubernetes community.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Let us know how&lt;/strong&gt; &lt;em&gt;consistent reads from cache&lt;/em&gt; &lt;strong&gt;transforms your Kubernetes experience!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Special thanks to @ah8ad3 and @p0lyn0mial for their contributions to this feature!&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes 1.31: Moving cgroup v1 Support into Maintenance Mode</title>
      <link>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/08/14/kubernetes-1-31-moving-cgroup-v1-support-maintenance-mode/</link>
      <pubDate>Wed, 14 Aug 2024 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/08/14/kubernetes-1-31-moving-cgroup-v1-support-maintenance-mode/</guid>
      <description>
        
        
        &lt;p&gt;As Kubernetes continues to evolve and adapt to the changing landscape of
container orchestration, the community has decided to move cgroup v1 support
into &lt;a href=&#34;#what-does-maintenance-mode-mean&#34;&gt;maintenance mode&lt;/a&gt; in v1.31.
This shift aligns with the broader industry&#39;s move towards cgroup v2, offering
improved functionalities: including scalability and a more consistent interface.
Before we dive into the consequences for Kubernetes, let&#39;s take a step back to
understand what cgroups are and their significance in Linux.&lt;/p&gt;
&lt;h2 id=&#34;understanding-cgroups&#34;&gt;Understanding cgroups&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://man7.org/linux/man-pages/man7/cgroups.7.html&#34;&gt;Control groups&lt;/a&gt;, or
cgroups, are a Linux kernel feature that allows the allocation, prioritization,
denial, and management of system resources (such as CPU, memory, disk I/O,
and network bandwidth) among processes. This functionality is crucial for
maintaining system performance and ensuring that no single process can
monopolize system resources, which is especially important in multi-tenant
environments.&lt;/p&gt;
&lt;p&gt;There are two versions of cgroups:
&lt;a href=&#34;https://docs.kernel.org/admin-guide/cgroup-v1/index.html&#34;&gt;v1&lt;/a&gt; and
&lt;a href=&#34;https://docs.kernel.org/admin-guide/cgroup-v2.html&#34;&gt;v2&lt;/a&gt;. While cgroup v1
provided sufficient capabilities for resource management, it had limitations
that led to the development of cgroup v2. Cgroup v2 offers a more unified and
consistent interface, on top of better resource control features.&lt;/p&gt;
&lt;h2 id=&#34;cgroups-in-kubernetes&#34;&gt;Cgroups in Kubernetes&lt;/h2&gt;
&lt;p&gt;For Linux nodes, Kubernetes relies heavily on cgroups to manage and isolate the
resources consumed by containers running in pods. Each container in Kubernetes
is placed in its own cgroup, which allows Kubernetes to enforce resource limits,
monitor usage, and ensure fair resource distribution among all containers.&lt;/p&gt;
&lt;h3 id=&#34;how-kubernetes-uses-cgroups&#34;&gt;How Kubernetes uses cgroups&lt;/h3&gt;
&lt;dl&gt;
&lt;dt&gt;&lt;strong&gt;Resource Allocation&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;Ensures that containers do not exceed their allocated CPU and memory limits.&lt;/dd&gt;
&lt;dt&gt;&lt;strong&gt;Isolation&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;Isolates containers from each other to prevent resource contention.&lt;/dd&gt;
&lt;dt&gt;&lt;strong&gt;Monitoring&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;Tracks resource usage for each container to provide insights and metrics.&lt;/dd&gt;
&lt;/dl&gt;
&lt;h2 id=&#34;transitioning-to-cgroup-v2&#34;&gt;Transitioning to Cgroup v2&lt;/h2&gt;
&lt;p&gt;The Linux community has been focusing on cgroup v2 for new features and
improvements. Major Linux distributions and projects like
&lt;a href=&#34;https://systemd.io/&#34;&gt;systemd&lt;/a&gt; are
&lt;a href=&#34;https://github.com/systemd/systemd/issues/30852&#34;&gt;transitioning&lt;/a&gt; towards cgroup v2.
Using cgroup v2 provides several benefits over cgroupv1, such as Unified Hierarchy,
Improved Interface, Better Resource Control,
&lt;a href=&#34;https://github.com/kubernetes/kubernetes/pull/117793&#34;&gt;cgroup aware OOM killer&lt;/a&gt;,
&lt;a href=&#34;https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/2033-kubelet-in-userns-aka-rootless/README.md#cgroup&#34;&gt;rootless support&lt;/a&gt; etc.&lt;/p&gt;
&lt;p&gt;Given these advantages, Kubernetes is also making the move to embrace cgroup
v2 more fully. However, this transition needs to be handled carefully to avoid
disrupting existing workloads and to provide a smooth migration path for users.&lt;/p&gt;
&lt;h2 id=&#34;moving-cgroup-v1-support-into-maintenance-mode&#34;&gt;Moving cgroup v1 support into maintenance mode&lt;/h2&gt;
&lt;h3 id=&#34;what-does-maintenance-mode-mean&#34;&gt;What does maintenance mode mean?&lt;/h3&gt;
&lt;p&gt;When cgroup v1 is placed into maintenance mode in Kubernetes, it means that:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Feature Freeze&lt;/strong&gt;: No new features will be added to cgroup v1 support.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Security Fixes&lt;/strong&gt;: Critical security fixes will still be provided.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Best-Effort Bug Fixes&lt;/strong&gt;: Major bugs may be fixed if feasible, but some
issues might remain unresolved.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;why-move-to-maintenance-mode&#34;&gt;Why move to maintenance mode?&lt;/h3&gt;
&lt;p&gt;The move to maintenance mode is driven by the need to stay in line with the
broader ecosystem and to encourage the adoption of cgroup v2, which offers
better performance, security, and usability. By transitioning cgroup v1 to
maintenance mode, Kubernetes can focus on enhancing support for cgroup v2
and ensure it meets the needs of modern workloads. It&#39;s important to note
that maintenance mode does not mean deprecation; cgroup v1 will continue to
receive critical security fixes and major bug fixes as needed.&lt;/p&gt;
&lt;h2 id=&#34;what-this-means-for-cluster-administrators&#34;&gt;What this means for cluster administrators&lt;/h2&gt;
&lt;p&gt;Users currently relying on cgroup v1 are highly encouraged to plan for the
transition to cgroup v2. This transition involves:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Upgrading Systems&lt;/strong&gt;: Ensuring that the underlying operating systems and
container runtimes support cgroup v2.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Testing Workloads&lt;/strong&gt;: Verifying that workloads and applications function
correctly with cgroup v2.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;further-reading&#34;&gt;Further reading&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://man7.org/linux/man-pages/man7/cgroups.7.html&#34;&gt;Linux cgroups&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/architecture/cgroups/&#34;&gt;Cgroup v2 in Kubernetes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2022/08/31/cgroupv2-ga-1-25/&#34;&gt;Kubernetes 1.25: cgroup v2 graduates to GA&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes v1.31: PersistentVolume Last Phase Transition Time Moves to GA</title>
      <link>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/08/14/last-phase-transition-time-ga/</link>
      <pubDate>Wed, 14 Aug 2024 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/08/14/last-phase-transition-time-ga/</guid>
      <description>
        
        
        &lt;p&gt;Announcing the graduation to General Availability (GA) of the PersistentVolume &lt;code&gt;lastTransitionTime&lt;/code&gt; status
field, in Kubernetes v1.31!&lt;/p&gt;
&lt;p&gt;The Kubernetes SIG Storage team is excited to announce that the &amp;quot;PersistentVolumeLastPhaseTransitionTime&amp;quot; feature, introduced
as an alpha in Kubernetes v1.28, has now reached GA status and is officially part of the Kubernetes v1.31 release. This enhancement
helps Kubernetes users understand when a &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/storage/persistent-volumes/&#34;&gt;PersistentVolume&lt;/a&gt; transitions between
different phases, allowing for more efficient and informed resource management.&lt;/p&gt;
&lt;p&gt;For a v1.31 cluster, you can now assume that every PersistentVolume object has a
&lt;code&gt;.status.lastTransitionTime&lt;/code&gt; field, that holds a timestamp of
when the volume last transitioned its phase. This change is not immediate; the new field will be populated whenever a PersistentVolume
is updated and first transitions between phases (&lt;code&gt;Pending&lt;/code&gt;, &lt;code&gt;Bound&lt;/code&gt;, or &lt;code&gt;Released&lt;/code&gt;) after upgrading to Kubernetes v1.31.&lt;/p&gt;
&lt;h2 id=&#34;what-changed&#34;&gt;What changed?&lt;/h2&gt;
&lt;p&gt;The API strategy for updating PersistentVolume objects has been modified to populate the &lt;code&gt;.status.lastTransitionTime&lt;/code&gt; field with the
current timestamp whenever a PersistentVolume transitions phases. Users are allowed to set this field manually if needed, but it will
be overwritten when the PersistentVolume transitions phases again.&lt;/p&gt;
&lt;p&gt;For more details, read about
&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/storage/persistent-volumes/#phase-transition-timestamp&#34;&gt;Phase transition timestamp&lt;/a&gt; in the Kubernetes documentation.
You can also read the previous &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2023/10/23/persistent-volume-last-phase-transition-time&#34;&gt;blog post&lt;/a&gt; announcing the feature as alpha in v1.28.&lt;/p&gt;
&lt;p&gt;To provide feedback, join our &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-storage&#34;&gt;Kubernetes Storage Special-Interest-Group&lt;/a&gt; (SIG)
or participate in discussions on our &lt;a href=&#34;https://app.slack.com/client/T09NY5SBT/C09QZFCE5&#34;&gt;public Slack channel&lt;/a&gt;.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes v1.31: Elli</title>
      <link>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/08/13/kubernetes-v1-31-release/</link>
      <pubDate>Tue, 13 Aug 2024 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/08/13/kubernetes-v1-31-release/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Editors:&lt;/strong&gt; Matteo Bianchi, Yigit Demirbas, Abigail McCarthy, Edith Puclla, Rashan Smith&lt;/p&gt;
&lt;p&gt;Announcing the release of Kubernetes v1.31: Elli!&lt;/p&gt;
&lt;p&gt;Similar to previous releases, the release of Kubernetes v1.31 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.
This release consists of 45 enhancements.
Of those enhancements, 11 have graduated to Stable, 22 are entering Beta,
and 12 have graduated to Alpha.&lt;/p&gt;
&lt;h2 id=&#34;release-theme-and-logo&#34;&gt;Release theme and logo&lt;/h2&gt;


&lt;figure class=&#34;release-logo &#34;&gt;
    &lt;img src=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/images/blog/2024-08-13-kubernetes-1.31-release/k8s-1.31.png&#34;
         alt=&#34;Kubernetes v1.31 Elli logo&#34;/&gt; 
&lt;/figure&gt;
&lt;p&gt;The Kubernetes v1.31 Release Theme is &amp;quot;Elli&amp;quot;.&lt;/p&gt;
&lt;p&gt;Kubernetes v1.31&#39;s Elli is a cute and joyful dog, with a heart of gold and a nice sailor&#39;s cap, as a playful wink to the huge and diverse family of Kubernetes contributors.&lt;/p&gt;
&lt;p&gt;Kubernetes v1.31 marks the first release after the project has successfully celebrated &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/06/06/10-years-of-kubernetes/&#34;&gt;its first 10 years&lt;/a&gt;.
Kubernetes has come a very long way since its inception, and it&#39;s still moving towards exciting new directions with each release.
After 10 years, it is awe-inspiring to reflect on the effort, dedication, skill, wit and tiring work of the countless Kubernetes contributors who have made this a reality.&lt;/p&gt;
&lt;p&gt;And yet, despite the herculean effort needed to run the project, there is no shortage of people who show up, time and again, with enthusiasm, smiles and a sense of pride for contributing and being part of the community.
This &amp;quot;spirit&amp;quot; that we see from new and old contributors alike is the sign of a vibrant community, a &amp;quot;joyful&amp;quot; community, if we might call it that.&lt;/p&gt;
&lt;p&gt;Kubernetes v1.31&#39;s Elli is all about celebrating this wonderful spirit! Here&#39;s to the next decade of Kubernetes!&lt;/p&gt;
&lt;h2 id=&#34;highlights-of-features-graduating-to-stable&#34;&gt;Highlights of features graduating to Stable&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.31 release.&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&#34;apparmor-support-is-now-stable&#34;&gt;AppArmor support is now stable&lt;/h3&gt;
&lt;p&gt;Kubernetes support for AppArmor is now GA. Protect your containers using AppArmor by setting the &lt;code&gt;appArmorProfile.type&lt;/code&gt; field in the container&#39;s &lt;code&gt;securityContext&lt;/code&gt;.
Note that before Kubernetes v1.30, AppArmor was controlled via annotations; starting in v1.30 it is controlled using fields.
It is recommended that you should migrate away from using annotations and start using the &lt;code&gt;appArmorProfile.type&lt;/code&gt; field.&lt;/p&gt;
&lt;p&gt;To learn more read the &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/tutorials/security/apparmor/&#34;&gt;AppArmor tutorial&lt;/a&gt;.
This work was done as a part of &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/24&#34;&gt;KEP #24&lt;/a&gt;, by &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-node&#34;&gt;SIG Node&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;improved-ingress-connectivity-reliability-for-kube-proxy&#34;&gt;Improved ingress connectivity reliability for kube-proxy&lt;/h3&gt;
&lt;p&gt;Kube-proxy improved ingress connectivity reliability is stable in v1.31.
One of the common problems with load balancers in Kubernetes is the synchronization between the different components involved to avoid traffic drop.
This feature implements a mechanism in kube-proxy for load balancers to do connection draining for terminating Nodes exposed by services of &lt;code&gt;type: LoadBalancer&lt;/code&gt; and &lt;code&gt;externalTrafficPolicy: Cluster&lt;/code&gt; and establish some best practices for cloud providers and Kubernetes load balancers implementations.&lt;/p&gt;
&lt;p&gt;To use this feature, kube-proxy needs to run as default service proxy on the cluster and the load balancer needs to support connection draining.
There are no specific changes required for using this feature, it has been enabled by default in kube-proxy since v1.30 and been promoted to stable in v1.31.&lt;/p&gt;
&lt;p&gt;For more details about this feature please visit the &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/reference/networking/virtual-ips/#external-traffic-policy&#34;&gt;Virtual IPs and Service Proxies documentation page&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/3836&#34;&gt;KEP #3836&lt;/a&gt; by &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-network&#34;&gt;SIG Network&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;persistent-volume-last-phase-transition-time&#34;&gt;Persistent Volume last phase transition time&lt;/h3&gt;
&lt;p&gt;Persistent Volume last phase transition time feature moved to GA in v1.31.
This feature adds a &lt;code&gt;PersistentVolumeStatus&lt;/code&gt; field which holds a timestamp of when a PersistentVolume last transitioned to a different phase.
With this feature enabled, every PersistentVolume object will have a new field &lt;code&gt;.status.lastTransitionTime&lt;/code&gt;, that holds a timestamp of
when the volume last transitioned its phase.
This change is not immediate; the new field will be populated whenever a PersistentVolume is updated and first transitions between phases (&lt;code&gt;Pending&lt;/code&gt;, &lt;code&gt;Bound&lt;/code&gt;, or &lt;code&gt;Released&lt;/code&gt;) after upgrading to Kubernetes v1.31.
This allows you to measure time between when a PersistentVolume moves from &lt;code&gt;Pending&lt;/code&gt; to &lt;code&gt;Bound&lt;/code&gt;. This can be also useful for providing metrics and SLOs.&lt;/p&gt;
&lt;p&gt;For more details about this feature please visit the &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/storage/persistent-volumes/&#34;&gt;PersistentVolume documentation page&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This work was done as a part of &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/3762&#34;&gt;KEP #3762&lt;/a&gt; by &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-storage&#34;&gt;SIG Storage&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;highlights-of-features-graduating-to-beta&#34;&gt;Highlights of features graduating to Beta&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.31 release.&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&#34;nftables-backend-for-kube-proxy&#34;&gt;nftables backend for kube-proxy&lt;/h3&gt;
&lt;p&gt;The nftables backend moves to beta in v1.31, behind the &lt;code&gt;NFTablesProxyMode&lt;/code&gt; feature gate which is now enabled by default.&lt;/p&gt;
&lt;p&gt;The nftables API is the successor to the iptables API and is designed to provide better performance and scalability than iptables.
The &lt;code&gt;nftables&lt;/code&gt; proxy mode is able to process changes to service endpoints faster and more efficiently than the &lt;code&gt;iptables&lt;/code&gt; mode, and is also able to more efficiently process packets in the kernel (though this only
becomes noticeable in clusters with tens of thousands of services).&lt;/p&gt;
&lt;p&gt;As of Kubernetes v1.31, the &lt;code&gt;nftables&lt;/code&gt; mode is still relatively new, and may not be compatible with all network plugins; consult the documentation for your network plugin.
This proxy mode is only available on Linux nodes, and requires kernel 5.13 or later.
Before migrating, note that some features, especially around NodePort services, are not implemented exactly the same in nftables mode as they are in iptables mode.
Check the &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/reference/networking/virtual-ips/#migrating-from-iptables-mode-to-nftables&#34;&gt;migration guide&lt;/a&gt; to see if you need to override the default configuration.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/3866&#34;&gt;KEP #3866&lt;/a&gt; by &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-network&#34;&gt;SIG Network&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;changes-to-reclaim-policy-for-persistentvolumes&#34;&gt;Changes to reclaim policy for PersistentVolumes&lt;/h3&gt;
&lt;p&gt;The Always Honor PersistentVolume Reclaim Policy feature has advanced to beta in Kubernetes v1.31.
This enhancement ensures that the PersistentVolume (PV) reclaim policy is respected even after the associated PersistentVolumeClaim (PVC) is deleted, thereby preventing the leakage of volumes.&lt;/p&gt;
&lt;p&gt;Prior to this feature, the reclaim policy linked to a PV could be disregarded under specific conditions, depending on whether the PV or PVC was deleted first.
Consequently, the corresponding storage resource in the external infrastructure might not be removed, even if the reclaim policy was set to &amp;quot;Delete&amp;quot;.
This led to potential inconsistencies and resource leaks.&lt;/p&gt;
&lt;p&gt;With the introduction of this feature, Kubernetes now guarantees that the &amp;quot;Delete&amp;quot; reclaim policy will be enforced, ensuring the deletion of the underlying storage object from the backend infrastructure, regardless of the deletion sequence of the PV and PVC.&lt;/p&gt;
&lt;p&gt;This work was done as a part of &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/2644&#34;&gt;KEP #2644&lt;/a&gt; and by &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-storage&#34;&gt;SIG Storage&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;bound-service-account-token-improvements&#34;&gt;Bound service account token improvements&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;ServiceAccountTokenNodeBinding&lt;/code&gt; feature is promoted to beta in v1.31.
This feature allows requesting a token bound only to a node, not to a pod, which includes node information in claims in the token and validates the existence of the node when the token is used.
For more information, read the &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/reference/access-authn-authz/service-accounts-admin/#bound-service-account-tokens&#34;&gt;bound service account tokens documentation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/4193&#34;&gt;KEP #4193&lt;/a&gt; by &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-auth&#34;&gt;SIG Auth&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;multiple-service-cidrs&#34;&gt;Multiple Service CIDRs&lt;/h3&gt;
&lt;p&gt;Support for clusters with multiple Service CIDRs moves to beta in v1.31 (disabled by default).&lt;/p&gt;
&lt;p&gt;There are multiple components in a Kubernetes cluster that consume IP addresses: Nodes, Pods and Services.
Nodes and Pods IP ranges can be dynamically changed because depend on the infrastructure or the network plugin respectively.
However, Services IP ranges are defined during the cluster creation as a hardcoded flag in the kube-apiserver.
IP exhaustion has been a problem for long lived or large clusters, as admins needed to expand, shrink or even replace entirely the assigned Service CIDR range.
These operations were never supported natively and were performed via complex and delicate maintenance operations, often causing downtime on their clusters. This new feature allows users and cluster admins to dynamically modify Service CIDR ranges with zero downtime.&lt;/p&gt;
&lt;p&gt;For more details about this feature please visit the
&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/reference/networking/virtual-ips/#ip-address-objects&#34;&gt;Virtual IPs and Service Proxies&lt;/a&gt; documentation page.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/1880&#34;&gt;KEP #1880&lt;/a&gt; by &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-network&#34;&gt;SIG Network&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;traffic-distribution-for-services&#34;&gt;Traffic distribution for Services&lt;/h3&gt;
&lt;p&gt;Traffic distribution for Services moves to beta in v1.31 and is enabled by default.&lt;/p&gt;
&lt;p&gt;After several iterations on finding the best user experience and traffic engineering capabilities for Services networking, SIG Networking implemented the &lt;code&gt;trafficDistribution&lt;/code&gt; field in the Service specification, which serves as a guideline for the underlying implementation to consider while making routing decisions.&lt;/p&gt;
&lt;p&gt;For more details about this feature please read the
&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/04/17/kubernetes-v1-30-release/#traffic-distribution-for-services-sig-network-https-github-com-kubernetes-community-tree-master-sig-network&#34;&gt;1.30 Release Blog&lt;/a&gt;
or visit the &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/services-networking/service/#traffic-distribution&#34;&gt;Service&lt;/a&gt; documentation page.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/4444&#34;&gt;KEP #4444&lt;/a&gt; by &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-network&#34;&gt;SIG Network&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;kubernetes-volumeattributesclass-modifyvolume&#34;&gt;Kubernetes VolumeAttributesClass ModifyVolume&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/storage/volume-attributes-classes/&#34;&gt;VolumeAttributesClass&lt;/a&gt; API is moving to beta in v1.31.
The VolumeAttributesClass provides a generic,
Kubernetes-native API for modifying dynamically volume parameters like provisioned IO.
This allows workloads to vertically scale their volumes on-line to balance cost and performance, if supported by their provider.
This feature had been alpha since Kubernetes 1.29.&lt;/p&gt;
&lt;p&gt;This work was done as a part of &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/3751&#34;&gt;KEP #3751&lt;/a&gt; and lead by &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-storage&#34;&gt;SIG Storage&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;new-features-in-alpha&#34;&gt;New features in Alpha&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;This is a selection of some of the improvements that are now alpha following the v1.31 release.&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&#34;new-dra-apis-for-better-accelerators-and-other-hardware-management&#34;&gt;New DRA APIs for better accelerators and other hardware management&lt;/h3&gt;
&lt;p&gt;Kubernetes v1.31 brings an updated dynamic resource allocation (DRA) API and design.
The main focus in the update is on structured parameters because they make resource information and requests transparent to Kubernetes and clients and enable implementing features like cluster autoscaling.
DRA support in the kubelet was updated such that version skew between kubelet and the control plane is possible. With structured parameters, the scheduler allocates ResourceClaims while scheduling a pod.
Allocation by a DRA driver controller is still supported through what is now called &amp;quot;classic DRA&amp;quot;.&lt;/p&gt;
&lt;p&gt;With Kubernetes v1.31, classic DRA has a separate feature gate named &lt;code&gt;DRAControlPlaneController&lt;/code&gt;, which you need to enable explicitly.
With such a control plane controller, a DRA driver can implement allocation policies that are not supported yet through structured parameters.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/3063&#34;&gt;KEP #3063&lt;/a&gt; by &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-node&#34;&gt;SIG Node&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;support-for-image-volumes&#34;&gt;Support for image volumes&lt;/h3&gt;
&lt;p&gt;The Kubernetes community is moving towards fulfilling more Artificial Intelligence (AI) and Machine Learning (ML) use cases in the future.&lt;/p&gt;
&lt;p&gt;One of the requirements to fulfill these use cases is to support Open Container Initiative (OCI) compatible images and artifacts (referred as OCI objects) directly as a native volume source.
This allows users to focus on OCI standards as well as enables them to store and distribute any content using OCI registries.&lt;/p&gt;
&lt;p&gt;Given that, v1.31 adds a new alpha feature to allow using an OCI image as a volume in a Pod.
This feature allows users to specify an image reference as volume in a pod while reusing it as volume
mount within containers. You need to enable the &lt;code&gt;ImageVolume&lt;/code&gt; feature gate to try this out.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/4639&#34;&gt;KEP #4639&lt;/a&gt; by &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-node&#34;&gt;SIG Node&lt;/a&gt; and &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-storage&#34;&gt;SIG Storage&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;exposing-device-health-information-through-pod-status&#34;&gt;Exposing device health information through Pod status&lt;/h3&gt;
&lt;p&gt;Expose device health information through the Pod Status is added as a new alpha feature in v1.31, disabled by default.&lt;/p&gt;
&lt;p&gt;Before Kubernetes v1.31, the way to know whether or not a Pod is associated with the failed device is to use the &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins/#monitoring-device-plugin-resources&#34;&gt;PodResources API&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;By enabling this feature, the field &lt;code&gt;allocatedResourcesStatus&lt;/code&gt; will be added to each container status, within the &lt;code&gt;.status&lt;/code&gt; for each Pod. The &lt;code&gt;allocatedResourcesStatus&lt;/code&gt; field reports health information for each device assigned to the container.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/4680&#34;&gt;KEP #4680&lt;/a&gt; by &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-node&#34;&gt;SIG Node&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;finer-grained-authorization-based-on-selectors&#34;&gt;Finer-grained authorization based on selectors&lt;/h3&gt;
&lt;p&gt;This feature allows webhook authorizers and future (but not currently designed) in-tree authorizers to
allow &lt;strong&gt;list&lt;/strong&gt; and &lt;strong&gt;watch&lt;/strong&gt; requests, provided those requests use label and/or field selectors.
For example, it is now possible for an authorizer to express: this user cannot list all pods, but can list all pods where &lt;code&gt;.spec.nodeName&lt;/code&gt; matches some specific value. Or to allow a user to watch all Secrets in a namespace
that are &lt;em&gt;not&lt;/em&gt; labelled as &lt;code&gt;confidential: true&lt;/code&gt;.
Combined with CRD field selectors (also moving to beta in v1.31), it is possible to write more secure
per-node extensions.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/4601&#34;&gt;KEP #4601&lt;/a&gt; by &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-auth&#34;&gt;SIG Auth&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;restrictions-on-anonymous-api-access&#34;&gt;Restrictions on anonymous API access&lt;/h3&gt;
&lt;p&gt;By enabling the feature gate &lt;code&gt;AnonymousAuthConfigurableEndpoints&lt;/code&gt; users can now use the authentication configuration file to configure the endpoints that can be accessed by anonymous requests.
This allows users to protect themselves against RBAC misconfigurations that can give anonymous users broad access to the cluster.&lt;/p&gt;
&lt;p&gt;This work was done as a part of &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/4633&#34;&gt;KEP #4633&lt;/a&gt; and by &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-auth&#34;&gt;SIG Auth&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;graduations-deprecations-and-removals-in-1-31&#34;&gt;Graduations, deprecations, and removals in 1.31&lt;/h2&gt;
&lt;h3 id=&#34;graduations-to-stable&#34;&gt;Graduations to Stable&lt;/h3&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 11 enhancements promoted to Stable:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/3762&#34;&gt;PersistentVolume last phase transition time&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/2305&#34;&gt;Metric cardinality enforcement&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/3836&#34;&gt;Kube-proxy improved ingress connectivity reliability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/4009&#34;&gt;Add CDI devices to device plugin API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/4569&#34;&gt;Move cgroup v1 support into maintenance mode&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/24&#34;&gt;AppArmor support&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/3017&#34;&gt;PodHealthyPolicy for PodDisruptionBudget&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/3329&#34;&gt;Retriable and non-retriable Pod failures for Jobs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/3715&#34;&gt;Elastic Indexed Jobs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/3335&#34;&gt;Allow StatefulSet to control start replica ordinal numbering&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/2185&#34;&gt;Random Pod selection on ReplicaSet downscaling&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;deprecations-and-removals&#34;&gt;Deprecations and Removals&lt;/h3&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-50011--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.&lt;/p&gt;
&lt;h4 id=&#34;cgroup-v1-enters-the-maintenance-mode&#34;&gt;Cgroup v1 enters the maintenance mode&lt;/h4&gt;
&lt;p&gt;As Kubernetes continues to evolve and adapt to the changing landscape of container orchestration, the community has decided to move cgroup v1 support into maintenance mode in v1.31.
This shift aligns with the broader industry&#39;s move towards &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/architecture/cgroups/&#34;&gt;cgroup v2&lt;/a&gt;, offering improved functionality, scalability, and a more consistent interface.
Kubernetes maintance mode means that no new features will be added to cgroup v1 support.
Critical security fixes will still be provided, however, bug-fixing is now best-effort, meaning major bugs may be fixed if feasible, but some issues might remain unresolved.&lt;/p&gt;
&lt;p&gt;It is recommended that you start switching to use cgroup v2 as soon as possible.
This transition depends on your architecture, including ensuring the underlying operating systems and container runtimes support cgroup v2 and testing workloads to verify that workloads and applications function correctly with cgroup v2.&lt;/p&gt;
&lt;p&gt;Please report any problems you encounter by filing an &lt;a href=&#34;https://github.com/kubernetes/kubernetes/issues/new/choose&#34;&gt;issue&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This work was done as part of &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/4569&#34;&gt;KEP #4569&lt;/a&gt; by &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-node&#34;&gt;SIG Node&lt;/a&gt;.&lt;/p&gt;
&lt;h4 id=&#34;a-note-about-sha-1-signature-support&#34;&gt;A note about SHA-1 signature support&lt;/h4&gt;
&lt;p&gt;In &lt;a href=&#34;https://go.dev/doc/go1.18#sha1&#34;&gt;go1.18&lt;/a&gt; (released in March 2022), the crypto/x509 library started to reject certificates signed with a SHA-1 hash function.
While SHA-1 is established to be unsafe and publicly trusted Certificate Authorities have not issued SHA-1 certificates since 2015, there might still be cases in the context of Kubernetes where user-provided certificates are signed using a SHA-1 hash function through private authorities with them being used for Aggregated API Servers or webhooks.
If you have relied on SHA-1 based certificates, you must explicitly opt back into its support by setting &lt;code&gt;GODEBUG=x509sha1=1&lt;/code&gt; in your environment.&lt;/p&gt;
&lt;p&gt;Given Go&#39;s &lt;a href=&#34;https://go.dev/blog/compat&#34;&gt;compatibility policy for GODEBUGs&lt;/a&gt;, the &lt;code&gt;x509sha1&lt;/code&gt; GODEBUG and the support for SHA-1 certificates will &lt;a href=&#34;https://tip.golang.org/doc/go1.23&#34;&gt;fully go away in go1.24&lt;/a&gt; which will be released in the first half of 2025.
If you rely on SHA-1 certificates, please start moving off them.&lt;/p&gt;
&lt;p&gt;Please see &lt;a href=&#34;https://github.com/kubernetes/kubernetes/issues/125689&#34;&gt;Kubernetes issue #125689&lt;/a&gt; to get a better idea of timelines around the support for SHA-1 going away, when Kubernetes releases plans to adopt go1.24, and for more details on how to detect usage of SHA-1 certificates via metrics and audit logging.&lt;/p&gt;
&lt;h4 id=&#34;deprecation-of-status-nodeinfo-kubeproxyversion-field-for-nodes-kep-4004-https-github-com-kubernetes-enhancements-issues-4004&#34;&gt;Deprecation of &lt;code&gt;status.nodeInfo.kubeProxyVersion&lt;/code&gt; field for Nodes (&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/4004&#34;&gt;KEP 4004&lt;/a&gt;)&lt;/h4&gt;
&lt;p&gt;The &lt;code&gt;.status.nodeInfo.kubeProxyVersion&lt;/code&gt; field of Nodes has been deprecated in Kubernetes v1.31,
and will be removed in a later release.
It&#39;s being deprecated because the value of this field wasn&#39;t (and isn&#39;t) accurate.
This field is set by the kubelet, which does not have reliable information about the kube-proxy version or whether kube-proxy is running.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;DisableNodeKubeProxyVersion&lt;/code&gt; &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/reference/command-line-tools-reference/feature-gates/&#34;&gt;feature gate&lt;/a&gt; will be set to &lt;code&gt;true&lt;/code&gt; in by default in v1.31 and the kubelet will no longer attempt to set the &lt;code&gt;.status.kubeProxyVersion&lt;/code&gt; field for its associated Node.&lt;/p&gt;
&lt;h4 id=&#34;removal-of-all-in-tree-integrations-with-cloud-providers&#34;&gt;Removal of all in-tree integrations with cloud providers&lt;/h4&gt;
&lt;p&gt;As highlighted in a &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/05/20/completing-cloud-provider-migration/&#34;&gt;previous article&lt;/a&gt;, the last remaining in-tree support for cloud provider integration has been removed as part of the v1.31 release.
This doesn&#39;t mean you can&#39;t integrate with a cloud provider, however you now &lt;strong&gt;must&lt;/strong&gt; use the
recommended approach using an external integration. Some integrations are part of the Kubernetes
project and others are third party software.&lt;/p&gt;
&lt;p&gt;This milestone marks the completion of the externalization process for all cloud providers&#39; integrations from the Kubernetes core (&lt;a href=&#34;https://github.com/kubernetes/enhancements/blob/master/keps/sig-cloud-provider/2395-removing-in-tree-cloud-providers/README.md&#34;&gt;KEP-2395&lt;/a&gt;), a process started with Kubernetes v1.26.
This change helps Kubernetes to get closer to being a truly vendor-neutral platform.&lt;/p&gt;
&lt;p&gt;For further details on the cloud provider integrations, read our &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2023/12/14/cloud-provider-integration-changes/&#34;&gt;v1.29 Cloud Provider Integrations feature blog&lt;/a&gt;.
For additional context about the in-tree code removal, we invite you to check the (&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2023/11/16/kubernetes-1-29-upcoming-changes/#removal-of-in-tree-integrations-with-cloud-providers-kep-2395-https-kep-k8s-io-2395&#34;&gt;v1.29 deprecation blog&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;The latter blog also contains useful information for users who need to migrate to version v1.29 and later.&lt;/p&gt;
&lt;h4 id=&#34;removal-of-in-tree-provider-feature-gates&#34;&gt;Removal of in-tree provider feature gates&lt;/h4&gt;
&lt;p&gt;In Kubernetes v1.31, the following alpha feature gates &lt;code&gt;InTreePluginAWSUnregister&lt;/code&gt;, &lt;code&gt;InTreePluginAzureDiskUnregister&lt;/code&gt;, &lt;code&gt;InTreePluginAzureFileUnregister&lt;/code&gt;, &lt;code&gt;InTreePluginGCEUnregister&lt;/code&gt;, &lt;code&gt;InTreePluginOpenStackUnregister&lt;/code&gt;, and &lt;code&gt;InTreePluginvSphereUnregister&lt;/code&gt; have been removed. These feature gates were introduced to facilitate the testing of scenarios where in-tree volume plugins were removed from the codebase, without actually removing them. Since Kubernetes 1.30 had deprecated these in-tree volume plugins, these feature gates were redundant and no longer served a purpose. The only CSI migration gate still standing is &lt;code&gt;InTreePluginPortworxUnregister&lt;/code&gt;, which will remain in alpha until the CSI migration for Portworx is completed and its in-tree volume plugin will be ready for removal.&lt;/p&gt;
&lt;h4 id=&#34;removal-of-kubelet-keep-terminated-pod-volumes-command-line-flag&#34;&gt;Removal of kubelet &lt;code&gt;--keep-terminated-pod-volumes&lt;/code&gt; command line flag&lt;/h4&gt;
&lt;p&gt;The kubelet flag &lt;code&gt;--keep-terminated-pod-volumes&lt;/code&gt;, which was deprecated in 2017, has been removed as
part of the v1.31 release.&lt;/p&gt;
&lt;p&gt;You can find more details in the pull request &lt;a href=&#34;https://github.com/kubernetes/kubernetes/pull/122082&#34;&gt;#122082&lt;/a&gt;.&lt;/p&gt;
&lt;h4 id=&#34;removal-of-cephfs-volume-plugin&#34;&gt;Removal of CephFS volume plugin&lt;/h4&gt;
&lt;p&gt;&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/storage/volumes/#cephfs&#34;&gt;CephFS volume plugin&lt;/a&gt; was removed in this release and the &lt;code&gt;cephfs&lt;/code&gt; volume type became non-functional.&lt;/p&gt;
&lt;p&gt;It is recommended that you use the &lt;a href=&#34;https://github.com/ceph/ceph-csi/&#34;&gt;CephFS CSI driver&lt;/a&gt; as a third-party storage driver instead. If you were using the CephFS volume plugin before upgrading the cluster version to v1.31, you must re-deploy your application to use the new driver.&lt;/p&gt;
&lt;p&gt;CephFS volume plugin was formally marked as deprecated in v1.28.&lt;/p&gt;
&lt;h4 id=&#34;removal-of-ceph-rbd-volume-plugin&#34;&gt;Removal of Ceph RBD volume plugin&lt;/h4&gt;
&lt;p&gt;The v1.31 release removes the &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/storage/volumes/#rbd&#34;&gt;Ceph RBD volume plugin&lt;/a&gt; and its CSI migration support, making the &lt;code&gt;rbd&lt;/code&gt; volume type non-functional.&lt;/p&gt;
&lt;p&gt;It&#39;s recommended that you use the &lt;a href=&#34;https://github.com/ceph/ceph-csi/&#34;&gt;RBD CSI driver&lt;/a&gt; in your clusters instead.
If you were using Ceph RBD volume plugin before upgrading the cluster version to v1.31, you must re-deploy your application to use the new driver.&lt;/p&gt;
&lt;p&gt;The Ceph RBD volume plugin was formally marked as deprecated in v1.28.&lt;/p&gt;
&lt;h4 id=&#34;deprecation-of-non-csi-volume-limit-plugins-in-kube-scheduler&#34;&gt;Deprecation of non-CSI volume limit plugins in kube-scheduler&lt;/h4&gt;
&lt;p&gt;The v1.31 release will deprecate all non-CSI volume limit scheduler plugins, and will remove some
already deprected plugins from the &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/reference/scheduling/config/&#34;&gt;default plugins&lt;/a&gt;, including:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;AzureDiskLimits&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CinderLimits&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;EBSLimits&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GCEPDLimits&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It&#39;s recommended that you use the &lt;code&gt;NodeVolumeLimits&lt;/code&gt; plugin instead because it can handle the same functionality as the removed plugins since those volume types have been migrated to CSI.
Please replace the deprecated plugins with the &lt;code&gt;NodeVolumeLimits&lt;/code&gt; plugin if you explicitly use them in the &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/reference/scheduling/config/&#34;&gt;scheduler config&lt;/a&gt;.
The &lt;code&gt;AzureDiskLimits&lt;/code&gt;, &lt;code&gt;CinderLimits&lt;/code&gt;, &lt;code&gt;EBSLimits&lt;/code&gt;, and &lt;code&gt;GCEPDLimits&lt;/code&gt; plugins will be removed in a future release.&lt;/p&gt;
&lt;p&gt;These plugins will be removed from the default scheduler plugins list as they have been deprecated since Kubernetes v1.14.&lt;/p&gt;
&lt;h3 id=&#34;release-notes-and-upgrade-actions-required&#34;&gt;Release notes and upgrade actions required&lt;/h3&gt;
&lt;p&gt;Check out the full details of the Kubernetes v1.31 release in our &lt;a href=&#34;https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.31.md&#34;&gt;release notes&lt;/a&gt;.&lt;/p&gt;
&lt;h4 id=&#34;scheduler-now-uses-queueinghint-when-schedulerqueueinghints-is-enabled&#34;&gt;Scheduler now uses QueueingHint when &lt;code&gt;SchedulerQueueingHints&lt;/code&gt; is enabled&lt;/h4&gt;
&lt;p&gt;Added support to the scheduler to start using a QueueingHint registered for Pod/Updated events,
to determine whether updates to  previously unschedulable Pods have made them schedulable.
The new support is active when the feature gate &lt;code&gt;SchedulerQueueingHints&lt;/code&gt; is enabled.&lt;/p&gt;
&lt;p&gt;Previously, when unschedulable Pods were updated, the scheduler always put Pods back to into a queue
(&lt;code&gt;activeQ&lt;/code&gt; / &lt;code&gt;backoffQ&lt;/code&gt;). However not all updates to Pods make Pods schedulable, especially considering
many scheduling constraints nowadays are immutable. Under the new behaviour, once unschedulable Pods
are updated, the scheduling queue checks with QueueingHint(s) whether the update may make the
pod(s) schedulable, and requeues them to &lt;code&gt;activeQ&lt;/code&gt; or &lt;code&gt;backoffQ&lt;/code&gt; only when at least one
QueueingHint returns &lt;code&gt;Queue&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Action required for custom scheduler plugin developers&lt;/strong&gt;:
Plugins have to implement a QueueingHint for Pod/Update event if the rejection from them could be resolved by updating unscheduled Pods themselves. Example: suppose you develop a custom plugin that denies Pods that have a &lt;code&gt;schedulable=false&lt;/code&gt; label. Given Pods with a &lt;code&gt;schedulable=false&lt;/code&gt; label will be schedulable if the &lt;code&gt;schedulable=false&lt;/code&gt; label is removed, this plugin would implement QueueingHint for Pod/Update event that returns Queue when such label changes are made in unscheduled Pods. You can find more details in the pull request &lt;a href=&#34;https://github.com/kubernetes/kubernetes/pull/122234&#34;&gt;#122234&lt;/a&gt;.&lt;/p&gt;
&lt;h4 id=&#34;removal-of-kubelet-keep-terminated-pod-volumes-command-line-flag-1&#34;&gt;Removal of kubelet --keep-terminated-pod-volumes command line flag&lt;/h4&gt;
&lt;p&gt;The kubelet flag &lt;code&gt;--keep-terminated-pod-volumes&lt;/code&gt;, which was deprecated in 2017, was removed as part of the v1.31 release.&lt;/p&gt;
&lt;p&gt;You can find more details in the pull request &lt;a href=&#34;https://github.com/kubernetes/kubernetes/pull/122082&#34;&gt;#122082&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;availability&#34;&gt;Availability&lt;/h2&gt;
&lt;p&gt;Kubernetes v1.31 is available for download on &lt;a href=&#34;https://github.com/kubernetes/kubernetes/releases/tag/v1.31.0&#34;&gt;GitHub&lt;/a&gt; or on the &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/releases/download/&#34;&gt;Kubernetes download page&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To get started with Kubernetes, check out these &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/tutorials/&#34;&gt;interactive 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.31 using &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/setup/independent/create-cluster-kubeadm/&#34;&gt;kubeadm&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;release-team&#34;&gt;Release team&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.31/release-team.md&#34;&gt;release team&lt;/a&gt; for the hours spent hard at work to deliver the Kubernetes v1.31 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 our release lead, Angelos Kolaitis, 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;h2 id=&#34;project-velocity&#34;&gt;Project velocity&lt;/h2&gt;
&lt;p&gt;The CNCF K8s DevStats 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;In the v1.31 release cycle, which ran for 14 weeks (May 7th to August 13th), we saw contributions to Kubernetes from 113 different companies and 528 individuals.&lt;/p&gt;
&lt;p&gt;In the whole Cloud Native ecosystem we have 379 companies counting 2268 total contributors - which means that respect to the previous release cycle we experienced an astounding 63% increase on individuals contributing!&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=1715032800000&amp;to=1723586399000&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=1715032800000&amp;to=1723586399000&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 visit &lt;a href=&#34;https://www.kubernetes.dev/docs/guide/#getting-started&#34;&gt;this page&lt;/a&gt; to get started.&lt;/p&gt;
&lt;p&gt;&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;Check out DevStats&lt;/a&gt; to learn more about the overall velocity of the Kubernetes project and community.&lt;/p&gt;
&lt;h2 id=&#34;event-update&#34;&gt;Event update&lt;/h2&gt;
&lt;p&gt;Explore the upcoming Kubernetes and cloud-native events from August to November 2024, featuring KubeCon, KCD, and other notable conferences worldwide. Stay informed and engage with the Kubernetes community.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;August 2024&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://events.linuxfoundation.org/kubecon-cloudnativecon-open-source-summit-ai-dev-china/&#34;&gt;&lt;strong&gt;KubeCon + CloudNativeCon + Open Source Summit China 2024&lt;/strong&gt;&lt;/a&gt;: August 21-23, 2024 | Hong Kong&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://events.linuxfoundation.org/kubeday-japan/&#34;&gt;&lt;strong&gt;KubeDay Japan&lt;/strong&gt;&lt;/a&gt;: August 27, 2024 | Tokyo, Japan&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;September 2024&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://community.cncf.io/events/details/cncf-kcd-lahore-presents-kcd-lahore-pakistan-2024/&#34;&gt;&lt;strong&gt;KCD Lahore - Pakistan 2024&lt;/strong&gt;&lt;/a&gt;: September 1, 2024 | Lahore, Pakistan&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://community.cncf.io/events/details/cncf-stockholm-presents-kubertenes-birthday-bash-stockholm-a-couple-of-months-late/&#34;&gt;&lt;strong&gt;KuberTENes Birthday Bash Stockholm&lt;/strong&gt;&lt;/a&gt;: September 5, 2024 | Stockholm, Sweden&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://community.cncf.io/events/details/cncf-kcd-australia-presents-kcd-sydney-24/&#34;&gt;&lt;strong&gt;KCD Sydney ’24&lt;/strong&gt;&lt;/a&gt;: September 5-6, 2024 | Sydney, Australia&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://community.cncf.io/events/details/cncf-kcd-washington-dc-presents-kcd-washington-dc-2024/&#34;&gt;&lt;strong&gt;KCD Washington DC 2024&lt;/strong&gt;&lt;/a&gt;: September 24, 2024 | Washington, DC, United States&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://community.cncf.io/events/details/cncf-kcd-porto-presents-kcd-porto-2024/&#34;&gt;&lt;strong&gt;KCD Porto 2024&lt;/strong&gt;&lt;/a&gt;: September 27-28, 2024 | Porto, Portugal&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;October 2024&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://community.cncf.io/events/details/cncf-kcd-austria-presents-kcd-austria-2024/&#34;&gt;&lt;strong&gt;KCD Austria 2024&lt;/strong&gt;&lt;/a&gt;: October 8-10, 2024 | Wien, Austria&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://events.linuxfoundation.org/kubeday-australia/&#34;&gt;&lt;strong&gt;KubeDay Australia&lt;/strong&gt;&lt;/a&gt;: October 15, 2024 | Melbourne, Australia&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://community.cncf.io/events/details/cncf-kcd-uk-presents-kubernetes-community-days-uk-london-2024/&#34;&gt;&lt;strong&gt;KCD UK - London 2024&lt;/strong&gt;&lt;/a&gt;: October 22-23, 2024 | Greater London, United Kingdom&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;November 2024&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://events.linuxfoundation.org/kubecon-cloudnativecon-north-america/&#34;&gt;&lt;strong&gt;KubeCon + CloudNativeCon North America 2024&lt;/strong&gt;&lt;/a&gt;: November 12-15, 2024 | Salt Lake City, United States&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://events.linuxfoundation.org/kubecon-cloudnativecon-north-america/co-located-events/kubernetes-on-edge-day/&#34;&gt;&lt;strong&gt;Kubernetes on EDGE Day North America&lt;/strong&gt;&lt;/a&gt;: November 12, 2024 | Salt Lake City, United States&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;upcoming-release-webinar&#34;&gt;Upcoming release webinar&lt;/h2&gt;
&lt;p&gt;Join members of the Kubernetes v1.31 release team on Thursday, Thu Sep 12, 2024 10am PT to learn about the major features of this release, as well as deprecations and removals to help plan for upgrades.
For more information and registration, visit the &lt;a href=&#34;https://community.cncf.io/events/details/cncf-cncf-online-programs-presents-cncf-live-webinar-kubernetes-131-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;/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 X &lt;a href=&#34;https://x.com/kubernetesio&#34;&gt;@Kubernetesio&lt;/a&gt; for 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;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>Introducing Feature Gates to Client-Go: Enhancing Flexibility and Control</title>
      <link>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/08/12/feature-gates-in-client-go/</link>
      <pubDate>Mon, 12 Aug 2024 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/08/12/feature-gates-in-client-go/</guid>
      <description>
        
        
        &lt;p&gt;Kubernetes components use on-off switches called &lt;em&gt;feature gates&lt;/em&gt; to manage the risk of adding a new feature.
The feature gate mechanism is what enables incremental graduation of a feature through the stages Alpha, Beta, and GA.&lt;/p&gt;
&lt;p&gt;Kubernetes components, such as kube-controller-manager and kube-scheduler, use the client-go library to interact with the API.
The same library is used across the Kubernetes ecosystem to build controllers, tools, webhooks, and more. client-go now includes
its own feature gating mechanism, giving developers and cluster administrators more control over how they adopt client features.&lt;/p&gt;
&lt;p&gt;To learn more about feature gates in Kubernetes, visit &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/reference/command-line-tools-reference/feature-gates/&#34;&gt;Feature Gates&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;motivation&#34;&gt;Motivation&lt;/h2&gt;
&lt;p&gt;In the absence of client-go feature gates, each new feature separated feature availability from enablement in its own way, if at all.
Some features were enabled by updating to a newer version of client-go. Others needed to be actively configured in each program that used them.
A few were configurable at runtime using environment variables. Consuming a feature-gated functionality exposed by the kube-apiserver sometimes
required a client-side fallback mechanism to remain compatible with servers that don’t support the functionality due to their age or configuration.
In cases where issues were discovered in these fallback mechanisms, mitigation required updating to a fixed version of client-go or rolling back.&lt;/p&gt;
&lt;p&gt;None of these approaches offer good support for enabling a feature by default in some, but not all, programs that consume client-go.
Instead of enabling a new feature at first only for a single component, a change in the default setting immediately affects the default
for all Kubernetes components, which broadens the blast radius significantly.&lt;/p&gt;
&lt;h2 id=&#34;feature-gates-in-client-go&#34;&gt;Feature gates in client-go&lt;/h2&gt;
&lt;p&gt;To address these challenges, substantial client-go features will be phased in using the new feature gate mechanism.
It will allow developers and users to enable or disable features in a way that will be familiar to anyone who has experience
with feature gates  in the Kubernetes components.&lt;/p&gt;
&lt;p&gt;Out of the box, simply by using a recent version of client-go, this offers several benefits.&lt;/p&gt;
&lt;p&gt;For people who use software built with client-go:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Early adopters can enable a default-off client-go feature on a per-process basis.&lt;/li&gt;
&lt;li&gt;Misbehaving features can be disabled without building a new binary.&lt;/li&gt;
&lt;li&gt;The state of all known client-go feature gates is logged, allowing users to inspect it.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For people who develop software built with client-go:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;By default, client-go feature gate overrides are read from environment variables.
If a bug is found in a client-go feature, users will be able to disable it without waiting for a new release.&lt;/li&gt;
&lt;li&gt;Developers can replace the default environment-variable-based overrides in a program to change defaults,
read overrides from another source, or disable runtime overrides completely.
The Kubernetes components use this customizability to integrate client-go feature gates with
the existing &lt;code&gt;--feature-gates&lt;/code&gt; command-line flag, feature enablement metrics, and logging.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;overriding-client-go-feature-gates&#34;&gt;Overriding client-go feature gates&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: This describes the default method for overriding client-go feature gates at runtime.
It can be disabled or customized by the developer of a particular program.
In Kubernetes components, client-go feature gate overrides are controlled by the &lt;code&gt;--feature-gates&lt;/code&gt; flag.&lt;/p&gt;
&lt;p&gt;Features of client-go can be enabled or disabled by setting environment variables prefixed with &lt;code&gt;KUBE_FEATURE&lt;/code&gt;.
For example, to enable a feature named &lt;code&gt;MyFeature&lt;/code&gt;, set the environment variable as follows:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt; KUBE_FEATURE_MyFeature=true
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To disable the feature, set the environment variable to &lt;code&gt;false&lt;/code&gt;:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt; KUBE_FEATURE_MyFeature=false
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: Environment variables are case-sensitive on some operating systems.
Therefore, &lt;code&gt;KUBE_FEATURE_MyFeature&lt;/code&gt; and &lt;code&gt;KUBE_FEATURE_MYFEATURE&lt;/code&gt; would be considered two different variables.&lt;/p&gt;
&lt;h2 id=&#34;customizing-client-go-feature-gates&#34;&gt;Customizing client-go feature gates&lt;/h2&gt;
&lt;p&gt;The default environment-variable based mechanism for feature gate overrides can be sufficient for many programs in the Kubernetes ecosystem,
and requires no special integration. Programs that require different behavior can replace it with their own custom feature gate provider.
This allows a program to do things like force-disable a feature that is known to work poorly,
read feature gates directly from a remote configuration service, or accept feature gate overrides through command-line options.&lt;/p&gt;
&lt;p&gt;The Kubernetes components replace client-go’s default feature gate provider with a shim to the existing Kubernetes feature gate provider.
For all practical purposes, client-go feature gates are treated the same as other Kubernetes
feature gates: they are wired to the &lt;code&gt;--feature-gates&lt;/code&gt; command-line flag, included in feature enablement metrics, and logged on startup.&lt;/p&gt;
&lt;p&gt;To replace the default feature gate provider, implement the Gates interface and call ReplaceFeatureGates
at package initialization time, as in this simple example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;import&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;&#34;&gt;“&lt;/span&gt;k8s.io&lt;span style=&#34;color:#666&#34;&gt;/&lt;/span&gt;client&lt;span style=&#34;color:#666&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;go&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;/&lt;/span&gt;features&lt;span style=&#34;&#34;&gt;”&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;type&lt;/span&gt; AlwaysEnabledGates &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;struct&lt;/span&gt;{}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;func&lt;/span&gt; (AlwaysEnabledGates) &lt;span style=&#34;color:#00a000&#34;&gt;Enabled&lt;/span&gt;(features.Feature) &lt;span style=&#34;color:#0b0;font-weight:bold&#34;&gt;bool&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#00a000&#34;&gt;init&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; features.&lt;span style=&#34;color:#00a000&#34;&gt;ReplaceFeatureGates&lt;/span&gt;(AlwaysEnabledGates{})
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Implementations that need the complete list of defined client-go features can get it by implementing the Registry interface
and calling &lt;code&gt;AddFeaturesToExistingFeatureGates&lt;/code&gt;.
For a complete example, refer to &lt;a href=&#34;https://github.com/kubernetes/kubernetes/blob/64ba17c605a41700f7f4c4e27dca3684b593b2b9/pkg/features/kube_features.go#L990-L997&#34;&gt;the usage within Kubernetes&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;p&gt;With the introduction of feature gates in client-go v1.30, rolling out a new client-go feature has become safer and easier.
Users and developers can control the pace of their own adoption of client-go features.
The work of Kubernetes contributors is streamlined by having a common mechanism for graduating features that span both sides of the Kubernetes API boundary.&lt;/p&gt;
&lt;p&gt;Special shoutout to &lt;a href=&#34;https://github.com/sttts&#34;&gt;@sttts&lt;/a&gt; and &lt;a href=&#34;https://github.com/deads2k&#34;&gt;@deads2k&lt;/a&gt; for their help in shaping this feature.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Spotlight on SIG API Machinery</title>
      <link>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/08/07/sig-api-machinery-spotlight-2024/</link>
      <pubDate>Wed, 07 Aug 2024 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/08/07/sig-api-machinery-spotlight-2024/</guid>
      <description>
        
        
        &lt;p&gt;We recently talked with &lt;a href=&#34;https://github.com/fedebongio&#34;&gt;Federico Bongiovanni&lt;/a&gt; (Google) and &lt;a href=&#34;https://github.com/deads2k&#34;&gt;David
Eads&lt;/a&gt; (Red Hat), Chairs of SIG API Machinery, to know a bit more about
this Kubernetes Special Interest Group.&lt;/p&gt;
&lt;h2 id=&#34;introductions&#34;&gt;Introductions&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Frederico (FSM): Hello, and thank your for your time. To start with, could you tell us about
yourselves and how you got involved in Kubernetes?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;David&lt;/strong&gt;: I started working on
&lt;a href=&#34;https://www.redhat.com/en/technologies/cloud-computing/openshift&#34;&gt;OpenShift&lt;/a&gt; (the Red Hat
distribution of Kubernetes) in the fall of 2014 and got involved pretty quickly in API Machinery. My
first PRs were fixing kube-apiserver error messages and from there I branched out to &lt;code&gt;kubectl&lt;/code&gt;
(&lt;em&gt;kubeconfigs&lt;/em&gt; are my fault!), &lt;code&gt;auth&lt;/code&gt; (&lt;a href=&#34;https://kubernetes.io/docs/reference/access-authn-authz/rbac/&#34;&gt;RBAC&lt;/a&gt; and &lt;code&gt;*Review&lt;/code&gt; APIs are ports
from OpenShift), &lt;code&gt;apps&lt;/code&gt; (&lt;em&gt;workqueues&lt;/em&gt; and &lt;em&gt;sharedinformers&lt;/em&gt; for example). Don’t tell the others,
but API Machinery is still my favorite :)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Federico&lt;/strong&gt;: I was not as early in Kubernetes as David, but now it&#39;s been more than six years. At
my previous company we were starting to use Kubernetes for our own products, and when I came across
the opportunity to work directly with Kubernetes I left everything and boarded the ship (no pun
intended). I joined Google and Kubernetes in early 2018, and have been involved since.&lt;/p&gt;
&lt;h2 id=&#34;sig-machinery-s-scope&#34;&gt;SIG Machinery&#39;s scope&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;FSM: It only takes a quick look at the SIG API Machinery charter to see that it has quite a
significant scope, nothing less than the Kubernetes control plane. Could you describe this scope in
your own words?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;David&lt;/strong&gt;: We own the &lt;code&gt;kube-apiserver&lt;/code&gt; and how to efficiently use it. On the backend, that includes
its contract with backend storage and how it allows API schema evolution over time.  On the
frontend, that includes schema best practices, serialization, client patterns, and controller
patterns on top of all of it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Federico&lt;/strong&gt;: Kubernetes has a lot of different components, but the control plane has a really
critical mission: it&#39;s your communication layer with the cluster and also owns all the extensibility
mechanisms that make Kubernetes so powerful. We can&#39;t make mistakes like a regression, or an
incompatible change, because the blast radius is huge.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;FSM: Given this breadth, how do you manage the different aspects of it?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Federico&lt;/strong&gt;: We try to organize the large amount of work into smaller areas. The working groups and
subprojects are part of it. Different people on the SIG have their own areas of expertise, and if
everything fails, we are really lucky to have people like David, Joe, and Stefan who really are &amp;quot;all
terrain&amp;quot;, in a way that keeps impressing me even after all these years.  But on the other hand this
is the reason why we need more people to help us carry the quality and excellence of Kubernetes from
release to release.&lt;/p&gt;
&lt;h2 id=&#34;an-evolving-collaboration-model&#34;&gt;An evolving collaboration model&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;FSM: Was the existing model always like this, or did it evolve with time - and if so, what would
you consider the main changes and the reason behind them?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;David&lt;/strong&gt;: API Machinery has evolved over time both growing and contracting in scope.  When trying
to satisfy client access patterns it’s very easy to add scope both in terms of features and applying
them.&lt;/p&gt;
&lt;p&gt;A good example of growing scope is the way that we identified a need to reduce memory utilization by
clients writing controllers and developed shared informers.  In developing shared informers and the
controller patterns use them (workqueues, error handling, and listers), we greatly reduced memory
utilization and eliminated many expensive lists.  The downside: we grew a new set of capability to
support and effectively took ownership of that area from sig-apps.&lt;/p&gt;
&lt;p&gt;For an example of more shared ownership: building out cooperative resource management (the goal of
server-side apply), &lt;code&gt;kubectl&lt;/code&gt; expanded to take ownership of leveraging the server-side apply
capability.  The transition isn’t yet complete, but &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-cli&#34;&gt;SIG
CLI&lt;/a&gt; manages that usage and owns it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;FSM: And for the boundary between approaches, do you have any guidelines?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;David&lt;/strong&gt;: I think much depends on the impact. If the impact is local in immediate effect, we advise
other SIGs and let them move at their own pace.  If the impact is global in immediate effect without
a natural incentive, we’ve found a need to press for adoption directly.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;FSM: Still on that note, SIG Architecture has an API Governance subproject, is it mostly
independent from SIG API Machinery or are there important connection points?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;David&lt;/strong&gt;: The projects have similar sounding names and carry some impacts on each other, but have
different missions and scopes.  API Machinery owns the how and API Governance owns the what.  API
conventions, the API approval process, and the final say on individual k8s.io APIs belong to API
Governance.  API Machinery owns the REST semantics and non-API specific behaviors.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Federico&lt;/strong&gt;: I really like how David put it: &lt;em&gt;&amp;quot;API Machinery owns the how and API Governance owns
the what&amp;quot;&lt;/em&gt;: we don&#39;t own the actual APIs, but the actual APIs live through us.&lt;/p&gt;
&lt;h2 id=&#34;the-challenges-of-kubernetes-popularity&#34;&gt;The challenges of Kubernetes popularity&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;FSM: With the growth in Kubernetes adoption we have certainly seen increased demands from the
Control Plane: how is this felt and how does it influence the work of the SIG?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;David&lt;/strong&gt;: It’s had a massive influence on API Machinery.  Over the years we have often responded to
and many times enabled the evolutionary stages of Kubernetes.  As the central orchestration hub of
nearly all capability on Kubernetes clusters, we both lead and follow the community.  In broad
strokes I see a few evolution stages for API Machinery over the years, with constantly high
activity.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Finding purpose&lt;/strong&gt;: &lt;code&gt;pre-1.0&lt;/code&gt; up until &lt;code&gt;v1.3&lt;/code&gt; (up to our first 1000+ nodes/namespaces) or
so. This time was characterized by rapid change.  We went through five different versions of our
schemas and rose to meet the need.  We optimized for quick, in-tree API evolution (sometimes to
the detriment of longer term goals), and defined patterns for the first time.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Scaling to meet the need&lt;/strong&gt;: &lt;code&gt;v1.3-1.9&lt;/code&gt; (up to shared informers in controllers) or so.  When we
started trying to meet customer needs as we gained adoption, we found severe scale limitations in
terms of CPU and memory. This was where we broadened API machinery to include access patterns, but
were still heavily focused on in-tree types.  We built the watch cache, protobuf serialization,
and shared caches.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Fostering the ecosystem&lt;/strong&gt;: &lt;code&gt;v1.8-1.21&lt;/code&gt; (up to CRD v1) or so.  This was when we designed and wrote
CRDs (the considered replacement for third-party-resources), the immediate needs we knew were
coming (admission webhooks), and evolution to best practices we knew we needed (API schemas).
This enabled an explosion of early adopters willing to work very carefully within the constraints
to enable their use-cases for servicing pods.  The adoption was very fast, sometimes outpacing
our capability, and creating new problems.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Simplifying deployments&lt;/strong&gt;: &lt;code&gt;v1.22+&lt;/code&gt;.  In the relatively recent past, we’ve been responding to
pressures or running kube clusters at scale with large numbers of sometimes-conflicting ecosystem
projects using our extensions mechanisms.  Lots of effort is now going into making platform
extensions easier to write and safer to manage by people who don&#39;t hold PhDs in kubernetes.  This
started with things like server-side-apply and continues today with features like webhook match
conditions and validating admission policies.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Work in API Machinery has a broad impact across the project and the ecosystem.  It’s an exciting
area to work for those able to make a significant time investment on a long time horizon.&lt;/p&gt;
&lt;h2 id=&#34;the-road-ahead&#34;&gt;The road ahead&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;FSM: With those different evolutionary stages in mind, what would you pinpoint as the top
priorities for the SIG at this time?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;David:&lt;/strong&gt; &lt;strong&gt;Reliability, efficiency, and capability&lt;/strong&gt; in roughly that order.&lt;/p&gt;
&lt;p&gt;With the increased usage of our &lt;code&gt;kube-apiserver&lt;/code&gt; and extensions mechanisms, we find that our first
set of extensions mechanisms, while fairly complete in terms of capability, carry significant risks
in terms of potential mis-use with large blast radius.  To mitigate these risks, we’re investing in
features that reduce the blast radius for accidents (webhook match conditions) and which provide
alternative mechanisms with lower risk profiles for most actions (validating admission policy).&lt;/p&gt;
&lt;p&gt;At the same time, the increased usage has made us more aware of scaling limitations that we can
improve both server and client-side.  Efforts here include more efficient serialization (CBOR),
reduced etcd load (consistent reads from cache), and reduced peak memory usage (streaming lists).&lt;/p&gt;
&lt;p&gt;And finally, the increased usage has highlighted some long existing
gaps that we’re closing.  Things like field selectors for CRDs which
the &lt;a href=&#34;https://github.com/kubernetes/community/blob/master/wg-batch/README.md&#34;&gt;Batch Working Group&lt;/a&gt;
is eager to leverage and will eventually form the basis for a new way
to prevent trampoline pod attacks from exploited nodes.&lt;/p&gt;
&lt;h2 id=&#34;joining-the-fun&#34;&gt;Joining the fun&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;FSM: For anyone wanting to start contributing, what&#39;s your suggestions?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Federico&lt;/strong&gt;: SIG API Machinery is not an exception to the Kubernetes motto: &lt;strong&gt;Chop Wood and Carry
Water&lt;/strong&gt;. There are multiple weekly meetings that are open to everybody, and there is always more
work to be done than people to do it.&lt;/p&gt;
&lt;p&gt;I acknowledge that API Machinery is not easy, and the ramp up will be steep. The bar is high,
because of the reasons we&#39;ve been discussing: we carry a huge responsibility. But of course with
passion and perseverance many people has ramped up through the years, and we hope more will come.&lt;/p&gt;
&lt;p&gt;In terms of concrete opportunities, there is the SIG meeting every two weeks. Everyone is welcome to
attend and listen, see what the group talks about, see what&#39;s going on in this release, etc.&lt;/p&gt;
&lt;p&gt;Also two times a week, Tuesday and Thursday, we have the public Bug Triage, where we go through
everything new from the last meeting. We&#39;ve been keeping this practice for more than 7 years
now. It&#39;s a great opportunity to volunteer to review code, fix bugs, improve documentation,
etc. Tuesday&#39;s it&#39;s at 1 PM (PST) and Thursday is on an EMEA friendly time (9:30 AM PST).  We are
always looking to improve, and we hope to be able to provide more concrete opportunities to join and
participate in the future.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;FSM: Excellent, thank you! Any final comments you would like to share with our readers?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Federico&lt;/strong&gt;: As I mentioned, the first steps might be hard, but the reward is also larger. Working
on API Machinery is working on an area of huge impact (millions of users?), and your contributions
will have a direct outcome in the way that Kubernetes works and the way that it&#39;s used. For me
that&#39;s enough reward and motivation!&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes Removals and Major Changes In v1.31</title>
      <link>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/07/19/kubernetes-1-31-upcoming-changes/</link>
      <pubDate>Fri, 19 Jul 2024 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/07/19/kubernetes-1-31-upcoming-changes/</guid>
      <description>
        
        
        &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.
This article outlines some planned changes for the Kubernetes v1.31 release that the release team feels you should be aware of for the continued maintenance of your Kubernetes environment.
The information listed below is based on the current status of the v1.31 release.
It may change before the actual release date.&lt;/p&gt;
&lt;h2 id=&#34;the-kubernetes-api-removal-and-deprecation-process&#34;&gt;The Kubernetes API removal and deprecation process&lt;/h2&gt;
&lt;p&gt;The Kubernetes project has a well-documented &lt;a href=&#34;https://deploy-preview-50011--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 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 display a warning.
Removed APIs are no longer available in the current version, so you must migrate to using the replacement.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&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;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Beta or pre-release API versions must be supported for 3 releases after the deprecation.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Alpha or experimental API versions may be removed in any release without prior deprecation notice.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Whether an API is removed because a feature graduated from beta to stable or because that API 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-50011--kubernetes-io-main-staging.netlify.app/docs/reference/using-api/deprecation-guide/&#34;&gt;documentation&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;a-note-about-sha-1-signature-support&#34;&gt;A note about SHA-1 signature support&lt;/h2&gt;
&lt;p&gt;In &lt;a href=&#34;https://go.dev/doc/go1.18#sha1&#34;&gt;go1.18&lt;/a&gt; (released in March 2022), the crypto/x509 library started to reject certificates signed with a SHA-1 hash function.
While SHA-1 is established to be unsafe and publicly trusted Certificate Authorities have not issued SHA-1 certificates since 2015, there might still be cases in the context of Kubernetes where user-provided certificates are signed using a SHA-1 hash function through private authorities with them being used for Aggregated API Servers or webhooks.
If you have relied on SHA-1 based certificates, you must explicitly opt back into its support by setting &lt;code&gt;GODEBUG=x509sha1=1&lt;/code&gt; in your environment.&lt;/p&gt;
&lt;p&gt;Given Go&#39;s &lt;a href=&#34;https://go.dev/blog/compat&#34;&gt;compatibility policy for GODEBUGs&lt;/a&gt;, the &lt;code&gt;x509sha1&lt;/code&gt; GODEBUG and the support for SHA-1 certificates will &lt;a href=&#34;https://tip.golang.org/doc/go1.23&#34;&gt;fully go away in go1.24&lt;/a&gt; which will be released in the first half of 2025.
If you rely on SHA-1 certificates, please start moving off them.&lt;/p&gt;
&lt;p&gt;Please see &lt;a href=&#34;https://github.com/kubernetes/kubernetes/issues/125689&#34;&gt;Kubernetes issue #125689&lt;/a&gt; to get a better idea of timelines around the support for SHA-1 going away, when Kubernetes releases plans to adopt go1.24, and for more details on how to detect usage of SHA-1 certificates via metrics and audit logging.&lt;/p&gt;
&lt;h2 id=&#34;deprecations-and-removals-in-kubernetes-1-31&#34;&gt;Deprecations and removals in Kubernetes 1.31&lt;/h2&gt;
&lt;h3 id=&#34;deprecation-of-status-nodeinfo-kubeproxyversion-field-for-nodes-kep-4004-https-github-com-kubernetes-enhancements-issues-4004&#34;&gt;Deprecation of &lt;code&gt;status.nodeInfo.kubeProxyVersion&lt;/code&gt; field for Nodes (&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/4004&#34;&gt;KEP 4004&lt;/a&gt;)&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;.status.nodeInfo.kubeProxyVersion&lt;/code&gt; field of Nodes is being deprecated in Kubernetes v1.31,
and will be removed in a later release.
It&#39;s being deprecated because the value of this field wasn&#39;t (and isn&#39;t) accurate.
This field is set by the kubelet, which does not have reliable information about the kube-proxy version or whether kube-proxy is running.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;DisableNodeKubeProxyVersion&lt;/code&gt; &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/reference/command-line-tools-reference/feature-gates/&#34;&gt;feature gate&lt;/a&gt; will be set to &lt;code&gt;true&lt;/code&gt; in by default in v1.31 and the kubelet will no longer attempt to set the &lt;code&gt;.status.kubeProxyVersion&lt;/code&gt; field for its associated Node.&lt;/p&gt;
&lt;h3 id=&#34;removal-of-all-in-tree-integrations-with-cloud-providers&#34;&gt;Removal of all in-tree integrations with cloud providers&lt;/h3&gt;
&lt;p&gt;As highlighted in a &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/05/20/completing-cloud-provider-migration/&#34;&gt;previous article&lt;/a&gt;, the last remaining in-tree support for cloud provider integration will be removed as part of the v1.31 release.
This doesn&#39;t mean you can&#39;t integrate with a cloud provider, however you now &lt;strong&gt;must&lt;/strong&gt; use the
recommended approach using an external integration. Some integrations are part of the Kubernetes
project and others are third party software.&lt;/p&gt;
&lt;p&gt;This milestone marks the completion of the externalization process for all cloud providers&#39; integrations from the Kubernetes core (&lt;a href=&#34;https://github.com/kubernetes/enhancements/blob/master/keps/sig-cloud-provider/2395-removing-in-tree-cloud-providers/README.md&#34;&gt;KEP-2395&lt;/a&gt;), a process started with Kubernetes v1.26.
This change helps Kubernetes to get closer to being a truly vendor-neutral platform.&lt;/p&gt;
&lt;p&gt;For further details on the cloud provider integrations, read our &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2023/12/14/cloud-provider-integration-changes/&#34;&gt;v1.29 Cloud Provider Integrations feature blog&lt;/a&gt;.
For additional context about the in-tree code removal, we invite you to check the (&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2023/11/16/kubernetes-1-29-upcoming-changes/#removal-of-in-tree-integrations-with-cloud-providers-kep-2395-https-kep-k8s-io-2395&#34;&gt;v1.29 deprecation blog&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;The latter blog also contains useful information for users who need to migrate to version v1.29 and later.&lt;/p&gt;
&lt;h3 id=&#34;removal-of-kubelet-keep-terminated-pod-volumes-command-line-flag&#34;&gt;Removal of kubelet &lt;code&gt;--keep-terminated-pod-volumes&lt;/code&gt; command line flag&lt;/h3&gt;
&lt;p&gt;The kubelet flag &lt;code&gt;--keep-terminated-pod-volumes&lt;/code&gt;, which was deprecated in 2017, will be removed as
part of the v1.31 release.&lt;/p&gt;
&lt;p&gt;You can find more details in the pull request &lt;a href=&#34;https://github.com/kubernetes/kubernetes/pull/122082&#34;&gt;#122082&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;removal-of-cephfs-volume-plugin&#34;&gt;Removal of CephFS volume plugin&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/storage/volumes/#cephfs&#34;&gt;CephFS volume plugin&lt;/a&gt; was removed in this release and the &lt;code&gt;cephfs&lt;/code&gt; volume type became non-functional.&lt;/p&gt;
&lt;p&gt;It is recommended that you use the &lt;a href=&#34;https://github.com/ceph/ceph-csi/&#34;&gt;CephFS CSI driver&lt;/a&gt; as a third-party storage driver instead. If you were using the CephFS volume plugin before upgrading the cluster version to v1.31, you must re-deploy your application to use the new driver.&lt;/p&gt;
&lt;p&gt;CephFS volume plugin was formally marked as deprecated in v1.28.&lt;/p&gt;
&lt;h3 id=&#34;removal-of-ceph-rbd-volume-plugin&#34;&gt;Removal of Ceph RBD volume plugin&lt;/h3&gt;
&lt;p&gt;The v1.31 release will remove the &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/storage/volumes/#rbd&#34;&gt;Ceph RBD volume plugin&lt;/a&gt; and its CSI migration support, making the &lt;code&gt;rbd&lt;/code&gt; volume type non-functional.&lt;/p&gt;
&lt;p&gt;It&#39;s recommended that you use the &lt;a href=&#34;https://github.com/ceph/ceph-csi/&#34;&gt;RBD CSI driver&lt;/a&gt; in your clusters instead.
If you were using Ceph RBD volume plugin before upgrading the cluster version to v1.31, you must re-deploy your application to use the new driver.&lt;/p&gt;
&lt;p&gt;The Ceph RBD volume plugin was formally marked as deprecated in v1.28.&lt;/p&gt;
&lt;h3 id=&#34;deprecation-of-non-csi-volume-limit-plugins-in-kube-scheduler&#34;&gt;Deprecation of non-CSI volume limit plugins in kube-scheduler&lt;/h3&gt;
&lt;p&gt;The v1.31 release will deprecate all non-CSI volume limit scheduler plugins, and will remove some
already deprected plugins from the &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/reference/scheduling/config/&#34;&gt;default plugins&lt;/a&gt;, including:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;AzureDiskLimits&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CinderLimits&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;EBSLimits&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GCEPDLimits&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It&#39;s recommended that you use the &lt;code&gt;NodeVolumeLimits&lt;/code&gt; plugin instead because it can handle the same functionality as the removed plugins since those volume types have been migrated to CSI.
Please replace the deprecated plugins with the &lt;code&gt;NodeVolumeLimits&lt;/code&gt; plugin if you explicitly use them in the &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/reference/scheduling/config/&#34;&gt;scheduler config&lt;/a&gt;.
The &lt;code&gt;AzureDiskLimits&lt;/code&gt;, &lt;code&gt;CinderLimits&lt;/code&gt;, &lt;code&gt;EBSLimits&lt;/code&gt;, and &lt;code&gt;GCEPDLimits&lt;/code&gt; plugins will be removed in a future release.&lt;/p&gt;
&lt;p&gt;These plugins will be removed from the default scheduler plugins list as they have been deprecated since Kubernetes v1.14.&lt;/p&gt;
&lt;h2 id=&#34;looking-ahead&#34;&gt;Looking ahead&lt;/h2&gt;
&lt;p&gt;The official list of API removals planned for &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/reference/using-api/deprecation-guide/#v1-32&#34;&gt;Kubernetes v1.32&lt;/a&gt; include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;flowcontrol.apiserver.k8s.io/v1beta3&lt;/code&gt; API version of FlowSchema and PriorityLevelConfiguration will be removed.
To prepare for this, you can edit your existing manifests and rewrite client software to use the &lt;code&gt;flowcontrol.apiserver.k8s.io/v1 API&lt;/code&gt; version, available since v1.29.
All existing persisted objects are accessible via the new API. Notable changes in flowcontrol.apiserver.k8s.io/v1beta3 include that the PriorityLevelConfiguration &lt;code&gt;spec.limited.nominalConcurrencyShares&lt;/code&gt; field only defaults to 30 when unspecified, and an explicit value of 0 is not changed to 30.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For more information, please refer to the &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/reference/using-api/deprecation-guide/#v1-32&#34;&gt;API deprecation guide&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;want-to-know-more&#34;&gt;Want to know more?&lt;/h2&gt;
&lt;p&gt;The Kubernetes release notes announce deprecations.
We will formally announce the deprecations in &lt;a href=&#34;https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.31.md#deprecation&#34;&gt;Kubernetes v1.31&lt;/a&gt; as part of the CHANGELOG for that release.&lt;/p&gt;
&lt;p&gt;You can see the announcements of pending deprecations 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.30.md#deprecation&#34;&gt;Kubernetes v1.30&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.29.md#deprecation&#34;&gt;Kubernetes v1.29&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.28.md#deprecation&#34;&gt;Kubernetes v1.28&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.27.md#deprecation&#34;&gt;Kubernetes v1.27&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Spotlight on SIG Node</title>
      <link>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/06/20/sig-node-spotlight-2024/</link>
      <pubDate>Thu, 20 Jun 2024 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/06/20/sig-node-spotlight-2024/</guid>
      <description>
        
        
        &lt;p&gt;In the world of container orchestration, &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/&#34;&gt;Kubernetes&lt;/a&gt; reigns
supreme, powering some of the most complex and dynamic applications across the globe. Behind the
scenes, a network of Special Interest Groups (SIGs) drives Kubernetes&#39; innovation and stability.&lt;/p&gt;
&lt;p&gt;Today, I have the privilege of speaking with &lt;a href=&#34;https://www.linkedin.com/in/matthias-bertschy-b427b815/&#34;&gt;Matthias
Bertschy&lt;/a&gt;, &lt;a href=&#34;https://www.linkedin.com/in/gunju-kim-916b33190/&#34;&gt;Gunju
Kim&lt;/a&gt;, and &lt;a href=&#34;https://www.linkedin.com/in/sergeykanzhelev/&#34;&gt;Sergey
Kanzhelev&lt;/a&gt;, members of &lt;a href=&#34;https://github.com/kubernetes/community/blob/master/sig-node/README.md&#34;&gt;SIG
Node&lt;/a&gt;, who will shed some
light on their roles, challenges, and the exciting developments within SIG Node.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Answers given collectively by all interviewees will be marked by their initials.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&#34;introductions&#34;&gt;Introductions&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Arpit:&lt;/strong&gt; Thank you for joining us today. Could you please introduce yourselves and provide a brief
overview of your roles within SIG Node?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Matthias:&lt;/strong&gt; My name is Matthias Bertschy, I am French and live next to Lake Geneva, near the
French Alps. I have been a Kubernetes contributor since 2017, a reviewer for SIG Node and a
maintainer of &lt;a href=&#34;https://docs.prow.k8s.io/docs/overview/&#34;&gt;Prow&lt;/a&gt;. I work as a Senior Kubernetes
Developer for a security startup named &lt;a href=&#34;https://www.armosec.io/&#34;&gt;ARMO&lt;/a&gt;, which donated
&lt;a href=&#34;https://www.cncf.io/projects/kubescape/&#34;&gt;Kubescape&lt;/a&gt; to the CNCF.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;Lake Geneva and the Alps&#34; src=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/06/20/sig-node-spotlight-2024/Lake_Geneva_and_the_Alps.jpg&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Gunju:&lt;/strong&gt; My name is Gunju Kim. I am a software engineer at
&lt;a href=&#34;https://www.navercorp.com/naver/naverMain&#34;&gt;NAVER&lt;/a&gt;, where I focus on developing a cloud platform for
search services. I have been contributing to the Kubernetes project in my free time since 2021.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Sergey:&lt;/strong&gt; My name is Sergey Kanzhelev. I have worked on Kubernetes and &lt;a href=&#34;https://cloud.google.com/kubernetes-engine&#34;&gt;Google Kubernetes
Engine&lt;/a&gt; for 3 years and have worked on open-source
projects for many years now. I am a chair of SIG Node.&lt;/p&gt;
&lt;h2 id=&#34;understanding-sig-node&#34;&gt;Understanding SIG Node&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Arpit:&lt;/strong&gt; Thank you! Could you provide our readers with an overview of SIG Node&#39;s responsibilities
within the Kubernetes ecosystem?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;M/G/S:&lt;/strong&gt; SIG Node is one of the first if not the very first SIG in Kubernetes. The SIG is
responsible for all iterations between Kubernetes and node resources, as well as node maintenance
itself. This is quite a large scope, and the SIG owns a large part of the Kubernetes codebase. Because
of this wide ownership, SIG Node is always in contact with other SIGs such as SIG Network, SIG
Storage, and SIG Security and almost any new features and developments in Kubernetes involves SIG
Node in some way.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Arpit&lt;/strong&gt;: How does SIG Node contribute to Kubernetes&#39; performance and stability?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;M/G/S:&lt;/strong&gt; Kubernetes works on nodes of many different sizes and shapes, from small physical VMs
with cheap hardware to large AI/ML-optimized GPU-enabled nodes. Nodes may stay online for months or
maybe be short-lived and be preempted at any moment as they are running on excess compute of a cloud
provider.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/architecture/#kubelet&#34;&gt;&lt;code&gt;kubelet&lt;/code&gt;&lt;/a&gt; — the
Kubernetes agent on a node — must work in all these environments reliably. As for the performance
of kubelet operations, this is becoming increasingly important today. On one hand, as Kubernetes is
being used on extra small nodes more and more often in telecom and retail environments, it needs to
scale into the smallest footprint possible. On the other hand, with AI/ML workloads where every node
is extremely expensive, every second of delayed operations can visibly change the price of
computation.&lt;/p&gt;
&lt;h2 id=&#34;challenges-and-opportunities&#34;&gt;Challenges and Opportunities&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Arpit:&lt;/strong&gt; What upcoming challenges and opportunities is SIG Node keeping an eye on?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;M/G/S:&lt;/strong&gt; As Kubernetes enters the second decade of its life, we see a huge demand to support new
workload types. And SIG Node will play a big role in this. The Sidecar KEP, which we will be talking
about later, is one of the examples of increased emphasis on supporting new workload types.&lt;/p&gt;
&lt;p&gt;The key challenge we will have in the next few years is how to keep innovations while maintaining
high quality and backward compatibility of existing scenarios. SIG Node will continue to play a
central role in Kubernetes.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Arpit:&lt;/strong&gt; And are there any ongoing research or development areas within SIG Node that excite you?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;M/G/S:&lt;/strong&gt; Supporting new workload types is a fascinating area for us. Our recent exploration of
sidecar containers is a testament to this. Sidecars offer a versatile solution for enhancing
application functionality without altering the core codebase.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Arpit:&lt;/strong&gt; What are some of the challenges you&#39;ve faced while maintaining SIG Node, and how have you
overcome them?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;M/G/S:&lt;/strong&gt; The biggest challenge of SIG Node is its size and the many feature requests it
receives. We are encouraging more people to join as reviewers and are always open to improving
processes and addressing feedback. For every release, we run the feedback session at the SIG Node
meeting and identify problematic areas and action items.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Arpit:&lt;/strong&gt; Are there specific technologies or advancements that SIG Node is closely monitoring or
integrating into Kubernetes?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;M/G/S:&lt;/strong&gt; Developments in components that the SIG depends on, like
&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/setup/production-environment/container-runtimes/&#34;&gt;container runtimes&lt;/a&gt;
(e.g. &lt;a href=&#34;https://containerd.io/&#34;&gt;containerd&lt;/a&gt; and &lt;a href=&#34;https://cri-o.io/&#34;&gt;CRI-O&lt;/a&gt;, and OS features are
something we contribute to and monitor closely. For example, there is an upcoming &lt;em&gt;cgroup v1&lt;/em&gt;
deprecation and removal that Kubernetes and SIG Node will need to guide Kubernetes users
through. Containerd is also releasing version &lt;code&gt;2.0&lt;/code&gt;, which removes deprecated features, which will
affect Kubernetes users.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Arpit:&lt;/strong&gt; Could you share a memorable experience or achievement from your time as a SIG Node
maintainer that you&#39;re particularly proud of?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Mathias:&lt;/strong&gt; I think the best moment was when my first KEP (introducing the
&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/workloads/pods/pod-lifecycle/#container-probes&#34;&gt;&lt;code&gt;startupProbe&lt;/code&gt;&lt;/a&gt;)
finally graduated to GA (General Availability). I also enjoy seeing my contributions being used
daily by contributors, such as the comment containing the GitHub tree hash used to retain LGTM
despite squash commits.&lt;/p&gt;
&lt;h2 id=&#34;sidecar-containers&#34;&gt;Sidecar containers&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Arpit:&lt;/strong&gt; Can you provide more context on the concept of sidecar containers and their evolution in
the context of Kubernetes?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;M/G/S:&lt;/strong&gt; The concept of
&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/workloads/pods/sidecar-containers/&#34;&gt;sidecar containers&lt;/a&gt; dates back to
2015 when Kubernetes introduced the idea of composite containers. These additional containers,
running alongside the main application container within the same pod, were seen as a way to extend
and enhance application functionality without modifying the core codebase. Early adopters of
sidecars employed custom scripts and configurations to manage them, but this approach presented
challenges in terms of consistency and scalability.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Arpit:&lt;/strong&gt; Can you share specific use cases or examples where sidecar containers are particularly
beneficial?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;M/G/S:&lt;/strong&gt; Sidecar containers are a versatile tool that can be used to enhance the functionality of
applications in a variety of ways:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Logging and monitoring:&lt;/strong&gt; Sidecar containers can be used to collect logs and metrics from the
primary application container and send them to a centralized logging and monitoring system.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Traffic filtering and routing:&lt;/strong&gt; Sidecar containers can be used to filter and route traffic to
and from the primary application container.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Encryption and decryption:&lt;/strong&gt; Sidecar containers can be used to encrypt and decrypt data as it
flows between the primary application container and external services.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Data synchronization:&lt;/strong&gt; Sidecar containers can be used to synchronize data between the primary
application container and external databases or services.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Fault injection:&lt;/strong&gt; Sidecar containers can be used to inject faults into the primary application
container in order to test its resilience to failures.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Arpit:&lt;/strong&gt; The proposal mentions that some companies are using a fork of Kubernetes with sidecar
functionality added. Can you provide insights into the level of adoption and community interest in
this feature?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;M/G/S:&lt;/strong&gt; While we lack concrete metrics to measure adoption rates, the KEP has garnered
significant interest from the community, particularly among service mesh vendors like Istio, who
actively participated in its alpha testing phase. The KEP&#39;s visibility through numerous blog posts,
interviews, talks, and workshops further demonstrates its widespread appeal. The KEP addresses the
growing demand for additional capabilities alongside main containers in Kubernetes pods, such as
network proxies, logging systems, and security measures. The community acknowledges the importance
of providing easy migration paths for existing workloads to facilitate widespread adoption of the
feature.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Arpit:&lt;/strong&gt; Are there any notable examples or success stories from companies using sidecar containers
in production?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;M/G/S:&lt;/strong&gt; It is still too early to expect widespread adoption in production environments. The 1.29
release has only been available in Google Kubernetes Engine (GKE) since January 11, 2024, and there
still needs to be comprehensive documentation on how to enable and use them effectively via
universal injector. Istio, a popular service mesh platform, also lacks proper documentation for
enabling native sidecars, making it difficult for developers to get started with this new
feature. However, as native sidecar support matures and documentation improves, we can expect to see
wider adoption of this technology in production environments.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Arpit:&lt;/strong&gt; The proposal suggests introducing a &lt;code&gt;restartPolicy&lt;/code&gt; field for init containers to indicate
sidecar functionality. Can you explain how this solution addresses the outlined challenges?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;M/G/S:&lt;/strong&gt; The proposal to introduce a &lt;code&gt;restartPolicy&lt;/code&gt; field for init containers addresses the
outlined challenges by utilizing existing infrastructure and simplifying sidecar management. This
approach avoids adding new fields to the pod specification, keeping it manageable and avoiding more
clutter. By leveraging the existing init container mechanism, sidecars can be run alongside regular
init containers during pod startup, ensuring a consistent ordering of initialization. Additionally,
setting the restart policy of sidecar init containers to &lt;code&gt;Always&lt;/code&gt; explicitly states that they continue
running even after the main application container terminates, enabling persistent services like
logging and monitoring until the end of the workload.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Arpit:&lt;/strong&gt; How will the introduction of the &lt;code&gt;restartPolicy&lt;/code&gt; field for init containers affect
backward compatibility with existing Kubernetes configurations?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;M/G/S:&lt;/strong&gt; The introduction of the &lt;code&gt;restartPolicy&lt;/code&gt; field for init containers will maintain backward
compatibility with existing Kubernetes configurations. Existing init containers will continue to
function as they have before, and the new &lt;code&gt;restartPolicy&lt;/code&gt; field will only apply to init containers
explicitly marked as sidecars. This approach ensures that existing applications and deployments will
not be disrupted by the new feature, and provides a more streamlined way to define and manage
sidecars.&lt;/p&gt;
&lt;h2 id=&#34;contributing-to-sig-node&#34;&gt;Contributing to SIG Node&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Arpit:&lt;/strong&gt; What is the best place for the new members and especially beginners to contribute?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;M/G/S:&lt;/strong&gt; New members and beginners can contribute to the Sidecar KEP (Kubernetes Enhancement
Proposal) by:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Raising awareness:&lt;/strong&gt; Create content that highlights the benefits and use cases of sidecars. This
can educate others about the feature and encourage its adoption.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Providing feedback:&lt;/strong&gt; Share your experiences with sidecars, both positive and negative. This
feedback can be used to improve the feature and make it more widely usable.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sharing your use cases:&lt;/strong&gt; If you are using sidecars in production,
share your experiences with others. This can help to demonstrate the
real-world value of the feature and encourage others to adopt it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Improving the documentation:&lt;/strong&gt; Help to clarify and expand the documentation for the
feature. This can make it easier for others to understand and use sidecars.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In addition to the Sidecar KEP, there are many other areas where SIG Node needs more contributors:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Test coverage:&lt;/strong&gt; SIG Node is always looking for ways to improve the test coverage of Kubernetes
components.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CI maintenance:&lt;/strong&gt; SIG Node maintains a suite of e2e tests ensuring Kubernetes components
function as intended across a variety of scenarios.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;In conclusion, SIG Node stands as a cornerstone in Kubernetes&#39; journey, ensuring its reliability and
adaptability in the ever-changing landscape of cloud-native computing. With dedicated members like
Matthias, Gunju, and Sergey leading the charge, SIG Node remains at the forefront of innovation,
driving Kubernetes towards new horizons.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>10 Years of Kubernetes</title>
      <link>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/06/06/10-years-of-kubernetes/</link>
      <pubDate>Thu, 06 Jun 2024 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/06/06/10-years-of-kubernetes/</guid>
      <description>
        
        
        &lt;p&gt;&lt;img alt=&#34;KCSEU 2024 group photo&#34; src=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/06/06/10-years-of-kubernetes/kcseu2024.jpg&#34;&gt;&lt;/p&gt;
&lt;p&gt;Ten (10) years ago, on June 6th, 2014, the
&lt;a href=&#34;https://github.com/kubernetes/kubernetes/commit/2c4b3a562ce34cddc3f8218a2c4d11c7310e6d56&#34;&gt;first commit&lt;/a&gt;
of Kubernetes was pushed to GitHub. That first commit with 250 files and 47,501 lines of go, bash
and markdown kicked off the project we have today. Who could have predicted that 10 years later,
Kubernetes would grow to become one of the largest Open Source projects to date with over
&lt;a href=&#34;https://k8s.devstats.cncf.io/d/24/overall-project-statistics?orgId=1&#34;&gt;88,000 contributors&lt;/a&gt; from
more than &lt;a href=&#34;https://www.cncf.io/reports/kubernetes-project-journey-report/&#34;&gt;8,000 companies&lt;/a&gt;, across
44 countries.&lt;/p&gt;
&lt;img src=&#34;kcscn2019.jpg&#34; alt=&#34;KCSCN 2019&#34; class=&#34;left&#34; style=&#34;max-width: 20em; margin: 1em&#34; &gt;
&lt;p&gt;This milestone isn&#39;t just for Kubernetes but for the Cloud Native ecosystem that blossomed from
it. There are close to &lt;a href=&#34;https://all.devstats.cncf.io/d/18/overall-project-statistics-table?orgId=1&#34;&gt;200 projects&lt;/a&gt;
within the CNCF itself, with contributions from
&lt;a href=&#34;https://all.devstats.cncf.io/d/18/overall-project-statistics-table?orgId=1&#34;&gt;240,000+ individual contributors&lt;/a&gt; and
thousands more in the greater ecosystem. Kubernetes would not be where it is today without them, the
&lt;a href=&#34;https://www.cncf.io/blog/2022/05/18/slashdata-cloud-native-continues-to-grow-with-more-than-7-million-developers-worldwide/&#34;&gt;7M+ Developers&lt;/a&gt;,
and the even larger user community that have all helped shape the ecosystem that it is today.&lt;/p&gt;
&lt;h2 id=&#34;kubernetes-beginnings-a-converging-of-technologies&#34;&gt;Kubernetes&#39; beginnings - a converging of technologies&lt;/h2&gt;
&lt;p&gt;The ideas underlying Kubernetes started well before the first commit, or even the first prototype
(&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2018/07/20/the-history-of-kubernetes-the-community-behind-it/&#34;&gt;which came about in 2013&lt;/a&gt;).
In the early 2000s, Moore&#39;s Law was well in effect. Computing hardware was becoming more and more
powerful at an incredibly fast rate. Correspondingly, applications were growing more and more
complex. This combination of hardware commoditization and application complexity pointed to a need
to further abstract software from hardware, and solutions started to emerge.&lt;/p&gt;
&lt;p&gt;Like many companies at the time, Google was scaling rapidly, and its engineers were interested in
the idea of creating a form of isolation in the Linux kernel. Google engineer Rohit Seth described
the concept in an &lt;a href=&#34;https://lwn.net/Articles/199643/&#34;&gt;email in 2006&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;We use the term container to indicate a structure against which we track and charge utilization of
system resources like memory, tasks, etc. for a Workload.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;img src=&#34;future.png&#34; alt=&#34;The future of Linux containers&#34; class=&#34;right&#34; style=&#34;max-width: 20em; margin: 1em&#34;&gt;
&lt;p&gt;In March of 2013, a 5-minute lightning talk called
&lt;a href=&#34;https://youtu.be/wW9CAH9nSLs?si=VtK_VFQHymOT7BIB&#34;&gt;&amp;quot;The future of Linux Containers,&amp;quot; presented by Solomon Hykes at PyCon&lt;/a&gt;,
introduced an upcoming open source tool called &amp;quot;Docker&amp;quot; for creating and using Linux
Containers. Docker introduced a level of usability to Linux Containers that made them accessible to
more users than ever before, and the popularity of Docker, and thus of Linux Containers,
skyrocketed. With Docker making the abstraction of Linux Containers accessible to all, running
applications in much more portable and repeatable ways was suddenly possible, but the question of
scale remained.&lt;/p&gt;
&lt;p&gt;Google&#39;s Borg system for managing application orchestration at scale had adopted Linux containers as
they were developed in the mid-2000s. Since then, the company had also started working on a new
version of the system called &amp;quot;Omega.&amp;quot; Engineers at Google who were familiar with the Borg and Omega
systems saw the popularity of containerization driven by Docker. They recognized not only the need
for an open source container orchestration system but its &amp;quot;inevitability,&amp;quot; as described by Brendan
Burns in
&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2018/07/20/the-history-of-kubernetes-the-community-behind-it/&#34;&gt;this blog post&lt;/a&gt;.
That realization in the fall of 2013 inspired a small team to start working on a project that would
later become &lt;strong&gt;Kubernetes&lt;/strong&gt;. That team included Joe Beda, Brendan Burns, Craig McLuckie, Ville
Aikas, Tim Hockin, Dawn Chen, Brian Grant, and Daniel Smith.&lt;/p&gt;
&lt;h2 id=&#34;a-decade-of-kubernetes&#34;&gt;A decade of Kubernetes&lt;/h2&gt;
&lt;img src=&#34;kubeconeu2017.jpg&#34; alt=&#34;KubeCon EU 2017&#34; class=&#34;left&#34; style=&#34;max-width: 20em; margin: 1em&#34;&gt;
&lt;p&gt;Kubernetes&#39; history begins with that historic commit on June 6th, 2014, and the subsequent
announcement of the project in a June 10th
&lt;a href=&#34;https://youtu.be/YrxnVKZeqK8?si=Q_wYBFn7dsS9H3k3&#34;&gt;keynote by Google engineer Eric Brewer at DockerCon 2014&lt;/a&gt;
(and its corresponding &lt;a href=&#34;https://cloudplatform.googleblog.com/2014/06/an-update-on-container-support-on-google-cloud-platform.html&#34;&gt;Google blog&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Over the next year, a small community of
&lt;a href=&#34;https://k8s.devstats.cncf.io/d/9/companies-table?orgId=1&amp;var-period_name=Before%20joining%20CNCF&amp;var-metric=contributors&#34;&gt;contributors, largely from Google and Red Hat&lt;/a&gt;,
worked hard on the project, culminating in a &lt;a href=&#34;https://cloudplatform.googleblog.com/2015/07/Kubernetes-V1-Released.html&#34;&gt;version 1.0 release on July 21st, 2015&lt;/a&gt;.
Alongside 1.0, Google announced that Kubernetes would be donated to a newly formed branch of the
Linux Foundation called the
&lt;a href=&#34;https://www.cncf.io/announcements/2015/06/21/new-cloud-native-computing-foundation-to-drive-alignment-among-container-technologies/&#34;&gt;Cloud Native Computing Foundation (CNCF)&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Despite reaching 1.0, the Kubernetes project was still very challenging to use and
understand. Kubernetes contributor Kelsey Hightower took special note of the project&#39;s shortcomings
in ease of use and on July 7, 2016, he pushed the
&lt;a href=&#34;https://github.com/kelseyhightower/kubernetes-the-hard-way/commit/9d7ace8b186f6ebd2e93e08265f3530ec2fba81c&#34;&gt;first commit of his famed &amp;quot;Kubernetes the Hard Way&amp;quot; guide&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The project has changed enormously since its original 1.0 release; experiencing a number of big wins
such as
&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2019/09/18/kubernetes-1-16-release-announcement/&#34;&gt;Custom Resource Definitions (CRD) going GA in 1.16&lt;/a&gt;
or &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2021/12/08/dual-stack-networking-ga/&#34;&gt;full dual stack support launching in 1.23&lt;/a&gt; and
community &amp;quot;lessons learned&amp;quot; from the &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2021/07/14/upcoming-changes-in-kubernetes-1-22/&#34;&gt;removal of widely used beta APIs in 1.22&lt;/a&gt;
or the deprecation of &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2020/12/02/dockershim-faq/&#34;&gt;Dockershim&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Some notable updates, milestones and events since 1.0 include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;December 2016 - &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2016/12/kubernetes-1-5-supporting-production-workloads/&#34;&gt;Kubernetes 1.5&lt;/a&gt; introduces runtime pluggability with initial CRI support and alpha Windows node support. OpenAPI also appears for the first time, paving the way for clients to be able to discover extension APIs.
&lt;ul&gt;
&lt;li&gt;This release also introduced StatefulSets and PodDisruptionBudgets in Beta.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;April 2017 — &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2017/04/rbac-support-in-kubernetes/&#34;&gt;Introduction of Role-Based Access Controls or RBAC&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;June 2017 — In &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2017/06/kubernetes-1-7-security-hardening-stateful-application-extensibility-updates/&#34;&gt;Kubernetes 1.7&lt;/a&gt;, ThirdPartyResources or &amp;quot;TPRs&amp;quot; are replaced with CustomResourceDefinitions (CRDs).&lt;/li&gt;
&lt;li&gt;December 2017 — &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2017/12/kubernetes-19-workloads-expanded-ecosystem/&#34;&gt;Kubernetes 1.9&lt;/a&gt; sees the Workloads API becoming GA (Generally Available). The release blog states: &lt;em&gt;&amp;quot;Deployment and ReplicaSet, two of the most commonly used objects in Kubernetes, are now stabilized after more than a year of real-world use and feedback.&amp;quot;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;December 2018 — In 1.13, the Container Storage Interface (CSI) reaches GA, kubeadm tool for bootstrapping minimum viable clusters reaches GA, and CoreDNS becomes the default DNS server.&lt;/li&gt;
&lt;li&gt;September 2019 — &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2019/09/18/kubernetes-1-16-release-announcement/&#34;&gt;Custom Resource Definitions go GA&lt;/a&gt; in Kubernetes 1.16.&lt;/li&gt;
&lt;li&gt;August 2020 — &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2020/08/31/kubernetes-1-19-feature-one-year-support/&#34;&gt;Kubernetes 1.19&lt;/a&gt; increases the support window for releases to 1 year.&lt;/li&gt;
&lt;li&gt;December 2020 — &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2020/12/18/kubernetes-1.20-pod-impersonation-short-lived-volumes-in-csi/&#34;&gt;Dockershim is deprecated&lt;/a&gt;  in 1.20&lt;/li&gt;
&lt;li&gt;April 2021 — the &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2021/07/20/new-kubernetes-release-cadence/#:~:text=On%20April%2023%2C%202021%2C%20the,Kubernetes%20community&#39;s%20contributors%20and%20maintainers.&#34;&gt;Kubernetes release cadence changes&lt;/a&gt; from 4 releases per year to 3 releases per year.&lt;/li&gt;
&lt;li&gt;July 2021 — Widely used beta APIs are &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2021/07/14/upcoming-changes-in-kubernetes-1-22/&#34;&gt;removed&lt;/a&gt;  in Kubernetes 1.22.&lt;/li&gt;
&lt;li&gt;May 2022 — Kubernetes 1.24 sees  &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2022/05/03/kubernetes-1-24-release-announcement/&#34;&gt;beta APIs become disabled by default&lt;/a&gt; to reduce upgrade conflicts and removal of &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/dockershim&#34;&gt;Dockershim&lt;/a&gt;, leading to &lt;a href=&#34;https://www.youtube.com/watch?v=a03Hh1kd6KE&#34;&gt;widespread user confusion&lt;/a&gt; (we&#39;ve since &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/communication/contributor-comms&#34;&gt;improved our communication!&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;December 2022 — In 1.26, there was a significant batch and  &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2022/12/29/scalable-job-tracking-ga/&#34;&gt;Job API overhaul&lt;/a&gt; that paved the way for better support for AI  /ML / batch workloads.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;PS:&lt;/strong&gt; Curious to see how far the project has come for yourself? Check out this &lt;a href=&#34;https://github.com/spurin/kubernetes-v1.0-lab&#34;&gt;tutorial for spinning up a Kubernetes 1.0 cluster&lt;/a&gt; created by community members Carlos Santana, Amim Moises Salum Knabben, and James Spurin.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Kubernetes offers more extension points than we can count. Originally designed to work with Docker
and only Docker, now you can plug in any container runtime that adheres to the CRI standard. There
are other similar interfaces: CSI for storage and CNI for networking. And that&#39;s far from all you
can do. In the last decade, whole new patterns have emerged, such as using&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/extend-kubernetes/api-extension/custom-resources/&#34;&gt;Custom Resource Definitions&lt;/a&gt;
(CRDs) to support third-party controllers - now a huge part of the Kubernetes ecosystem.&lt;/p&gt;
&lt;p&gt;The community building the project has also expanded immensely over the last decade. Using
&lt;a href=&#34;https://k8s.devstats.cncf.io/d/24/overall-project-statistics?orgId=1&#34;&gt;DevStats&lt;/a&gt;, we can see the
incredible volume of contribution over the last decade that has made Kubernetes the
&lt;a href=&#34;https://www.cncf.io/reports/kubernetes-project-journey-report/&#34;&gt;second-largest open source project in the world&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;88,474&lt;/strong&gt; contributors&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;15,121&lt;/strong&gt; code committers&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;4,228,347&lt;/strong&gt; contributions&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;158,530&lt;/strong&gt; issues&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;311,787&lt;/strong&gt; pull requests&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;kubernetes-today&#34;&gt;Kubernetes today&lt;/h2&gt;
&lt;img src=&#34;welcome.jpg&#34; alt=&#34;KubeCon NA 2023&#34; class=&#34;left&#34; style=&#34;max-width: 20em; margin: 1em&#34;&gt;
&lt;p&gt;Since its early days, the project has seen enormous growth in technical capability, usage, and
contribution. The project is still actively working to improve and better serve its users.&lt;/p&gt;
&lt;p&gt;In the upcoming 1.31 release, the project will celebrate the culmination of an important long-term
project: the removal of in-tree cloud provider code. In this
&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/05/20/completing-cloud-provider-migration/&#34;&gt;largest migration in Kubernetes history&lt;/a&gt;,
roughly 1.5 million lines of code have been removed, reducing the binary sizes of core components
by approximately 40%. In the project&#39;s early days, it was clear that extensibility would be key to
success. However, it wasn&#39;t always clear how that extensibility should be achieved. This migration
removes a variety of vendor-specific capabilities from the core Kubernetes code
base. Vendor-specific capabilities can now be better served by other pluggable extensibility
features or patterns, such as
&lt;a href=&#34;https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/&#34;&gt;Custom Resource Definitions (CRDs)&lt;/a&gt;
or API standards like the &lt;a href=&#34;https://gateway-api.sigs.k8s.io/&#34;&gt;Gateway API&lt;/a&gt;.
Kubernetes also faces new challenges in serving its vast user base, and the community is adapting
accordingly. One example of this is the migration of image hosting to the new, community-owned
registry.k8s.io. The egress bandwidth and costs of providing pre-compiled binary images for user
consumption have become immense. This new registry change enables the community to continue
providing these convenient images in more cost- and performance-efficient ways. Make sure you check
out the &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2022/11/28/registry-k8s-io-faster-cheaper-ga/&#34;&gt;blog post&lt;/a&gt; and
update any automation you have to use registry.k8s.io!&lt;/p&gt;
&lt;h2 id=&#34;the-future-of-kubernetes&#34;&gt;The future of Kubernetes&lt;/h2&gt;
&lt;img src=&#34;lts.jpg&#34; alt=&#34;&#34; class=&#34;right&#34; width=&#34;300px&#34; style=&#34;max-width: 20em; margin: 1em&#34;&gt;
&lt;p&gt;A decade in, the future of Kubernetes still looks bright. The community is prioritizing changes that
both improve the user experiences, and enhance the sustainability of the project. The world of
application development continues to evolve, and Kubernetes is poised to change along with it.&lt;/p&gt;
&lt;p&gt;In 2024, the advent of AI changed a once-niche workload type into one of prominent
importance. Distributed computing and workload scheduling has always gone hand-in-hand with the
resource-intensive needs of Artificial Intelligence, Machine Learning, and High Performance
Computing workloads. Contributors are paying close attention to the needs of newly developed
workloads and how Kubernetes can best serve them. The new
&lt;a href=&#34;https://github.com/kubernetes/community/tree/master/wg-serving&#34;&gt;Serving Working Group&lt;/a&gt; is one
example of how the community is organizing to address these workloads&#39; needs. It&#39;s likely that the
next few years will see improvements to Kubernetes&#39; ability to manage various types of hardware, and
its ability to manage the scheduling of large batch-style workloads which are run across hardware in
chunks.&lt;/p&gt;
&lt;p&gt;The ecosystem around Kubernetes will continue to grow and evolve. In the future, initiatives to
maintain the sustainability of the project, like the migration of in-tree vendor code and the
registry change, will be ever more important.&lt;/p&gt;
&lt;p&gt;The next 10 years of Kubernetes will be guided by its users and the ecosystem, but most of all, by
the people who contribute to it. The community remains open to new contributors. You can find more
information about contributing in our New Contributor Course at
&lt;a href=&#34;https://k8s.dev/docs/onboarding&#34;&gt;https://k8s.dev/docs/onboarding&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We look forward to building the future of Kubernetes with you!&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/06/06/10-years-of-kubernetes/kcsna2023.jpg&#34;
         alt=&#34;KCSNA 2023&#34;/&gt; 
&lt;/figure&gt;

      </description>
    </item>
    
    <item>
      <title>Completing the largest migration in Kubernetes history</title>
      <link>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/05/20/completing-cloud-provider-migration/</link>
      <pubDate>Mon, 20 May 2024 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/05/20/completing-cloud-provider-migration/</guid>
      <description>
        
        
        &lt;p&gt;Since as early as Kubernetes v1.7, the Kubernetes project has pursued the ambitious goal of removing built-in cloud provider integrations (&lt;a href=&#34;https://github.com/kubernetes/enhancements/blob/master/keps/sig-cloud-provider/2395-removing-in-tree-cloud-providers/README.md&#34;&gt;KEP-2395&lt;/a&gt;).
While these integrations were instrumental in Kubernetes&#39; early development and growth, their removal was driven by two key factors:
the growing complexity of maintaining native support for every cloud provider across millions of lines of Go code, and the desire to establish
Kubernetes as a truly vendor-neutral platform.&lt;/p&gt;
&lt;p&gt;After many releases, we&#39;re thrilled to announce that all cloud provider integrations have been successfully migrated from the core Kubernetes repository to external plugins.
In addition to achieving our initial objectives, we&#39;ve also significantly streamlined Kubernetes by removing roughly 1.5 million lines of code and reducing the binary sizes of core components by approximately 40%.&lt;/p&gt;
&lt;p&gt;This migration was a complex and long-running effort due to the numerous impacted components and the critical code paths that relied on the built-in integrations for the
five initial cloud providers: Google Cloud, AWS, Azure, OpenStack, and vSphere. To successfully complete this migration, we had to build four new subsystems from the ground up:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Cloud controller manager&lt;/strong&gt; (&lt;a href=&#34;https://github.com/kubernetes/enhancements/blob/master/keps/sig-cloud-provider/2392-cloud-controller-manager/README.md&#34;&gt;KEP-2392&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;API server network proxy&lt;/strong&gt; (&lt;a href=&#34;https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/1281-network-proxy&#34;&gt;KEP-1281&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;kubelet credential provider plugins&lt;/strong&gt; (&lt;a href=&#34;https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/2133-kubelet-credential-providers&#34;&gt;KEP-2133&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Storage migration to use &lt;a href=&#34;https://github.com/container-storage-interface/spec?tab=readme-ov-file#container-storage-interface-csi-specification-&#34;&gt;CSI&lt;/a&gt;&lt;/strong&gt; (&lt;a href=&#34;https://github.com/kubernetes/enhancements/blob/master/keps/sig-storage/625-csi-migration/README.md&#34;&gt;KEP-625&lt;/a&gt;)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Each subsystem was critical to achieve full feature parity with built-in capabilities and required several releases to bring each subsystem to GA-level maturity with a safe and
reliable migration path. More on each subsystem below.&lt;/p&gt;
&lt;h3 id=&#34;cloud-controller-manager&#34;&gt;Cloud controller manager&lt;/h3&gt;
&lt;p&gt;The cloud controller manager was the first external component introduced in this effort, replacing functionality within the kube-controller-manager and kubelet that directly interacted with cloud APIs.
This essential component is responsible for initializing nodes by applying metadata labels that indicate the cloud region and zone a Node is running on, as well as IP addresses that are only known to the cloud provider.
Additionally, it runs the service controller, which is responsible for provisioning cloud load balancers for Services of type LoadBalancer.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;Kubernetes components&#34; src=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/images/docs/components-of-kubernetes.svg&#34;&gt;&lt;/p&gt;
&lt;p&gt;To learn more, read &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/architecture/cloud-controller/&#34;&gt;Cloud Controller Manager&lt;/a&gt; in the Kubernetes documentation.&lt;/p&gt;
&lt;h3 id=&#34;api-server-network-proxy&#34;&gt;API server network proxy&lt;/h3&gt;
&lt;p&gt;The API Server Network Proxy project, initiated in 2018 in collaboration with SIG API Machinery, aimed to replace the SSH tunneler functionality within the kube-apiserver.
This tunneler had been used to securely proxy traffic between the Kubernetes control plane and nodes, but it heavily relied on provider-specific implementation details embedded in the kube-apiserver to establish these SSH tunnels.&lt;/p&gt;
&lt;p&gt;Now, the API Server Network Proxy is a GA-level extension point within the kube-apiserver. It offers a generic proxying mechanism that can route traffic from the API server to nodes through a secure proxy,
eliminating the need for the API server to have any knowledge of the specific cloud provider it is running on. This project also introduced the Konnectivity project, which has seen growing adoption in production environments.&lt;/p&gt;
&lt;p&gt;You can learn more about the API Server Network Proxy from its &lt;a href=&#34;https://github.com/kubernetes-sigs/apiserver-network-proxy#readme&#34;&gt;README&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;credential-provider-plugins-for-the-kubelet&#34;&gt;Credential provider plugins for the kubelet&lt;/h3&gt;
&lt;p&gt;The Kubelet credential provider plugin was developed to replace the kubelet&#39;s built-in functionality for dynamically fetching credentials for image registries hosted on Google Cloud, AWS, or Azure.
The legacy capability was convenient as it allowed the kubelet to seamlessly retrieve short-lived tokens for pulling images from GCR, ECR, or ACR. However, like other areas of Kubernetes, supporting
this required the kubelet to have specific knowledge of different cloud environments and APIs.&lt;/p&gt;
&lt;p&gt;Introduced in 2019, the credential provider plugin mechanism offers a generic extension point for the kubelet to execute plugin binaries that dynamically provide credentials for images hosted on various clouds.
This extensibility expands the kubelet&#39;s capabilities to fetch short-lived tokens beyond the initial three cloud providers.&lt;/p&gt;
&lt;p&gt;To learn more, read &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/containers/images/#kubelet-credential-provider&#34;&gt;kubelet credential provider for authenticated image pulls&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;storage-plugin-migration-from-in-tree-to-csi&#34;&gt;Storage plugin migration from in-tree to CSI&lt;/h3&gt;
&lt;p&gt;The Container Storage Interface (CSI) is a control plane standard for managing block and file storage systems in Kubernetes and other container orchestrators that went GA in 1.13.
It was designed to replace the in-tree volume plugins built directly into Kubernetes with drivers that can run as Pods within the Kubernetes cluster.
These drivers communicate with kube-controller-manager storage controllers via the Kubernetes API, and with kubelet through a local gRPC endpoint.
Now there are over 100 CSI drivers available across all major cloud and storage vendors, making stateful workloads in Kubernetes a reality.&lt;/p&gt;
&lt;p&gt;However, a major challenge remained on how to handle all the existing users of in-tree volume APIs. To retain API backwards compatibility,
we built an API translation layer into our controllers that will convert the in-tree volume API into the equivalent CSI API. This allowed us to redirect all storage operations to the CSI driver,
paving the way for us to remove the code for the built-in volume plugins without removing the API.&lt;/p&gt;
&lt;p&gt;You can learn more about In-tree Storage migration in &lt;a href=&#34;https://kubernetes.io/blog/2019/12/09/kubernetes-1-17-feature-csi-migration-beta/&#34;&gt;Kubernetes In-Tree to CSI Volume Migration Moves to Beta&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;what-s-next&#34;&gt;What&#39;s next?&lt;/h2&gt;
&lt;p&gt;This migration has been the primary focus for SIG Cloud Provider over the past few years. With this significant milestone achieved, we will be shifting our efforts towards exploring new
and innovative ways for Kubernetes to better integrate with cloud providers, leveraging the external subsystems we&#39;ve built over the years. This includes making Kubernetes smarter in
hybrid environments where nodes in the cluster can run on both public and private clouds, as well as providing better tools and frameworks for developers of external providers to simplify and streamline their integration efforts.&lt;/p&gt;
&lt;p&gt;With all the new features, tools, and frameworks being planned, SIG Cloud Provider is not forgetting about the other side of the equation: testing. Another area of focus for the SIG&#39;s future activities is the improvement of
cloud controller testing to include more providers. The ultimate goal of this effort being to create a testing framework that will include as many providers as possible so that we give the Kubernetes community the highest
levels of confidence about their Kubernetes environments.&lt;/p&gt;
&lt;p&gt;If you&#39;re using a version of Kubernetes older than v1.29 and haven&#39;t migrated to an external cloud provider yet, we recommend checking out our previous blog post &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2023/12/14/cloud-provider-integration-changes/&#34;&gt;Kubernetes 1.29: Cloud Provider Integrations Are Now Separate Components&lt;/a&gt;.It provides detailed information on the changes we&#39;ve made and offers guidance on how to migrate to an external provider. Starting in v1.31, in-tree cloud providers will be permanently disabled and removed from core Kubernetes components.&lt;/p&gt;
&lt;p&gt;If you’re interested in contributing, come join our &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-cloud-provider#meetings&#34;&gt;bi-weekly SIG meetings&lt;/a&gt;!&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Gateway API v1.1: Service mesh, GRPCRoute, and a whole lot more</title>
      <link>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/05/09/gateway-api-v1-1/</link>
      <pubDate>Thu, 09 May 2024 09:00:00 -0800</pubDate>
      
      <guid>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/05/09/gateway-api-v1-1/</guid>
      <description>
        
        
        &lt;p&gt;&lt;img alt=&#34;Gateway API logo&#34; src=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/05/09/gateway-api-v1-1/gateway-api-logo.svg&#34;&gt;&lt;/p&gt;
&lt;p&gt;Following the GA release of Gateway API last October, Kubernetes
SIG Network is pleased to announce the v1.1 release of
&lt;a href=&#34;https://gateway-api.sigs.k8s.io/&#34;&gt;Gateway API&lt;/a&gt;. In this release, several features are graduating to
&lt;em&gt;Standard Channel&lt;/em&gt; (GA), notably including support for service mesh and
GRPCRoute. We&#39;re also introducing some new experimental features, including
session persistence and client certificate verification.&lt;/p&gt;
&lt;h2 id=&#34;what-s-new&#34;&gt;What&#39;s new&lt;/h2&gt;
&lt;h3 id=&#34;graduation-to-standard&#34;&gt;Graduation to Standard&lt;/h3&gt;
&lt;p&gt;This release includes the graduation to Standard of four eagerly awaited features.
This means they are no longer experimental concepts; inclusion in the Standard
release channel denotes a high level of confidence in the API surface and
provides guarantees of backward compatibility. Of course, as with any other
Kubernetes API, Standard Channel features can continue to evolve with
backward-compatible additions over time, and we certainly expect further
refinements and improvements to these new features in the future.
For more information on how all of this works, refer to the
&lt;a href=&#34;https://gateway-api.sigs.k8s.io/concepts/versioning/&#34;&gt;Gateway API Versioning Policy&lt;/a&gt;.&lt;/p&gt;
&lt;h4 id=&#34;service-mesh-support-https-gateway-api-sigs-k8s-io-mesh&#34;&gt;&lt;a href=&#34;https://gateway-api.sigs.k8s.io/mesh/&#34;&gt;Service Mesh Support&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Service mesh support in Gateway API allows service mesh users to use the same
API to manage ingress traffic and mesh traffic, reusing the same policy and
routing interfaces. In Gateway API v1.1, routes (such as HTTPRoute) can now have
a Service as a &lt;code&gt;parentRef&lt;/code&gt;, to control how traffic to specific services behave.
For more information, read the
&lt;a href=&#34;https://gateway-api.sigs.k8s.io/mesh/&#34;&gt;Gateway API service mesh documentation&lt;/a&gt;
or see the
&lt;a href=&#34;https://gateway-api.sigs.k8s.io/implementations/#service-mesh-implementation-status&#34;&gt;list of Gateway API implementations&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;As an example, one could do a canary deployment of a workload deep in an
application&#39;s call graph with an HTTPRoute as follows:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;gateway.networking.k8s.io/v1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;HTTPRoute&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;color-canary&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;namespace&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;faces&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;spec&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;parentRefs&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;color&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Service&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;group&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;port&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;80&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;rules&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;backendRefs&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;color&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;port&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;80&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;weight&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;50&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;color2&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;port&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;80&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;weight&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;50&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This would split traffic sent to the &lt;code&gt;color&lt;/code&gt; Service in the &lt;code&gt;faces&lt;/code&gt; namespace
50/50 between the original &lt;code&gt;color&lt;/code&gt; Service and the &lt;code&gt;color2&lt;/code&gt; Service, using a
portable configuration that&#39;s easy to move from one mesh to another.&lt;/p&gt;
&lt;h4 id=&#34;grpcroute-https-gateway-api-sigs-k8s-io-guides-grpc-routing&#34;&gt;&lt;a href=&#34;https://gateway-api.sigs.k8s.io/guides/grpc-routing/&#34;&gt;GRPCRoute&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;If you are already using the experimental version of GRPCRoute, we recommend holding
off on upgrading to the standard channel version of GRPCRoute until the
controllers you&#39;re using have been updated to support GRPCRoute v1. Until then,
it is safe to upgrade to the experimental channel version of GRPCRoute in v1.1
that includes both v1alpha2 and v1 API versions.&lt;/p&gt;
&lt;h4 id=&#34;parentreference-port-https-gateway-api-sigs-k8s-io-reference-spec-gateway-networking-k8s-io-2fv1-parentreference&#34;&gt;&lt;a href=&#34;https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io%2fv1.ParentReference&#34;&gt;ParentReference Port&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;The &lt;code&gt;port&lt;/code&gt; field was added to ParentReference, allowing you to attach resources
to Gateway Listeners, Services, or other parent resources
(depending on the implementation). Binding to a port also allows you to attach
to multiple Listeners at once.&lt;/p&gt;
&lt;p&gt;For example, you can attach an HTTPRoute to one or more specific Listeners of a
Gateway as specified by the Listener &lt;code&gt;port&lt;/code&gt;, instead of the Listener &lt;code&gt;name&lt;/code&gt; field.&lt;/p&gt;
&lt;p&gt;For more information, see
&lt;a href=&#34;https://gateway-api.sigs.k8s.io/api-types/httproute/#attaching-to-gateways&#34;&gt;Attaching to Gateways&lt;/a&gt;.&lt;/p&gt;
&lt;h4 id=&#34;conformance-profiles-and-reports-https-gateway-api-sigs-k8s-io-concepts-conformance-conformance-profiles&#34;&gt;&lt;a href=&#34;https://gateway-api.sigs.k8s.io/concepts/conformance/#conformance-profiles&#34;&gt;Conformance Profiles and Reports&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;The conformance report API has been expanded with the &lt;code&gt;mode&lt;/code&gt; field (intended to
specify the working mode of the implementation), and the &lt;code&gt;gatewayAPIChannel&lt;/code&gt;
(standard or experimental). The &lt;code&gt;gatewayAPIVersion&lt;/code&gt; and &lt;code&gt;gatewayAPIChannel&lt;/code&gt; are
now filled in automatically by the suite machinery, along with a brief
description of the testing outcome. The Reports have been reorganized in a more
structured way, and the implementations can now add information on how the tests
have been run and provide reproduction steps.&lt;/p&gt;
&lt;h3 id=&#34;new-additions-to-experimental-channel&#34;&gt;New additions to Experimental channel&lt;/h3&gt;
&lt;h4 id=&#34;gateway-client-certificate-verification-https-gateway-api-sigs-k8s-io-geps-gep-91&#34;&gt;&lt;a href=&#34;https://gateway-api.sigs.k8s.io/geps/gep-91/&#34;&gt;Gateway Client Certificate Verification&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Gateways can now configure client cert verification for each Gateway Listener by
introducing a new &lt;code&gt;frontendValidation&lt;/code&gt; field within &lt;code&gt;tls&lt;/code&gt;. This field
supports configuring a list of CA Certificates that can be used as a trust
anchor to validate the certificates presented by the client.&lt;/p&gt;
&lt;p&gt;The following example shows how the CACertificate stored in
the &lt;code&gt;foo-example-com-ca-cert&lt;/code&gt; ConfigMap can be used to validate the certificates
presented by clients connecting to the &lt;code&gt;foo-https&lt;/code&gt; Gateway Listener.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;gateway.networking.k8s.io/v1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Gateway&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;client-validation-basic&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;spec&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;gatewayClassName&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;acme-lb&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;listeners&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;foo-https&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;protocol&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;HTTPS&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;port&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;443&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;hostname&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;foo.example.com&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;tls&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;certificateRefs&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Secret&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;group&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;foo-example-com-cert&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;frontendValidation&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;caCertificateRefs&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;ConfigMap&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;group&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;foo-example-com-ca-cert&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;session-persistence-and-backendlbpolicy-https-gateway-api-sigs-k8s-io-geps-gep-1619&#34;&gt;&lt;a href=&#34;https://gateway-api.sigs.k8s.io/geps/gep-1619/&#34;&gt;Session Persistence and BackendLBPolicy&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;&lt;a href=&#34;https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io%2fv1.SessionPersistence&#34;&gt;Session Persistence&lt;/a&gt;
is being introduced to Gateway API via a new policy
(&lt;a href=&#34;https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.BackendLBPolicy&#34;&gt;BackendLBPolicy&lt;/a&gt;)
for Service-level configuration and as fields within HTTPRoute
and GRPCRoute for route-level configuration. The BackendLBPolicy and route-level
APIs provide the same session persistence configuration, including session
timeouts, session name, session type, and cookie lifetime type.&lt;/p&gt;
&lt;p&gt;Below is an example configuration of &lt;code&gt;BackendLBPolicy&lt;/code&gt; that enables cookie-based
session persistence for the &lt;code&gt;foo&lt;/code&gt; service. It sets the session name to
&lt;code&gt;foo-session&lt;/code&gt;, defines absolute and idle timeouts, and configures the cookie to
be a session cookie:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;gateway.networking.k8s.io/v1alpha2&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;BackendLBPolicy&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;lb-policy&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;namespace&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;foo-ns&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;spec&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;targetRefs&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;group&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;core&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;service&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;foo&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;sessionPersistence&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;sessionName&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;foo-session&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;absoluteTimeout&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;1h&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;idleTimeout&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;30m&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;type&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Cookie&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;cookieConfig&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;lifetimeType&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Session&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;everything-else&#34;&gt;Everything else&lt;/h3&gt;
&lt;h4 id=&#34;tls-terminology-clarifications-https-gateway-api-sigs-k8s-io-geps-gep-2907&#34;&gt;&lt;a href=&#34;https://gateway-api.sigs.k8s.io/geps/gep-2907/&#34;&gt;TLS Terminology Clarifications&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;As part of a broader goal of making our TLS terminology more consistent
throughout the API, we&#39;ve introduced some breaking changes to BackendTLSPolicy.
This has resulted in a new API version (v1alpha3) and will require any existing
implementations of this policy to properly handle the version upgrade, e.g.
by backing up data and uninstalling the v1alpha2 version before installing this
newer version.&lt;/p&gt;
&lt;p&gt;Any references to v1alpha2 BackendTLSPolicy fields will need to be updated to
v1alpha3. Specific changes to fields include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;targetRef&lt;/code&gt; becomes &lt;code&gt;targetRefs&lt;/code&gt; to allow a BackendTLSPolicy to attach to
multiple targets&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tls&lt;/code&gt; becomes &lt;code&gt;validation&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tls.caCertRefs&lt;/code&gt; becomes &lt;code&gt;validation.caCertificateRefs&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tls.wellKnownCACerts&lt;/code&gt; becomes &lt;code&gt;validation.wellKnownCACertificates&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For a full list of the changes included in this release, please refer to the
&lt;a href=&#34;https://github.com/kubernetes-sigs/gateway-api/releases/tag/v1.1.0&#34;&gt;v1.1.0 release notes&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;gateway-api-background&#34;&gt;Gateway API background&lt;/h2&gt;
&lt;p&gt;The idea of Gateway API was initially &lt;a href=&#34;https://youtu.be/Ne9UJL6irXY?si=wgtC9w8PMB5ZHil2&#34;&gt;proposed&lt;/a&gt;
at the 2019 KubeCon San Diego as the next generation
of Ingress API. Since then, an incredible community has formed to develop what
has likely become the
&lt;a href=&#34;https://www.youtube.com/watch?v=V3Vu_FWb4l4&#34;&gt;most collaborative API in Kubernetes history&lt;/a&gt;.
Over 200 people have contributed to this API so far, and that number continues to grow.&lt;/p&gt;
&lt;p&gt;The maintainers would like to thank &lt;em&gt;everyone&lt;/em&gt; who&#39;s contributed to Gateway API, whether in the
form of commits to the repo, discussion, ideas, or general support. We literally
couldn&#39;t have gotten this far without the support of this dedicated and active
community.&lt;/p&gt;
&lt;h2 id=&#34;try-it-out&#34;&gt;Try it out&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.26 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 our &lt;a href=&#34;https://gateway-api.sigs.k8s.io/guides/&#34;&gt;Getting Started Guide&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;get-involved&#34;&gt;Get involved&lt;/h2&gt;
&lt;p&gt;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;h2 id=&#34;related-kubernetes-blog-articles&#34;&gt;Related Kubernetes blog articles&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2023/11/28/gateway-api-ga/&#34;&gt;New Experimental Features in Gateway API v1.0&lt;/a&gt;
11/2023&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2023/10/31/gateway-api-ga/&#34;&gt;Gateway API v1.0: GA Release&lt;/a&gt;
10/2023&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2023/10/25/introducing-ingress2gateway/&#34;&gt;Introducing ingress2gateway; Simplifying Upgrades to Gateway API&lt;/a&gt;
10/2023&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2023/08/29/gateway-api-v0-8/&#34;&gt;Gateway API v0.8.0: Introducing Service Mesh Support&lt;/a&gt;
08/2023&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Container Runtime Interface streaming explained</title>
      <link>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/05/01/cri-streaming-explained/</link>
      <pubDate>Wed, 01 May 2024 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/05/01/cri-streaming-explained/</guid>
      <description>
        
        
        &lt;p&gt;The Kubernetes &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/architecture/cri/&#34;&gt;Container Runtime Interface (CRI)&lt;/a&gt;
acts as the main connection between the &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/reference/command-line-tools-reference/kubelet/&#34;&gt;kubelet&lt;/a&gt;
and the &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/setup/production-environment/container-runtimes/&#34;&gt;Container Runtime&lt;/a&gt;.
Those runtimes have to provide a &lt;a href=&#34;https://grpc.io&#34;&gt;gRPC&lt;/a&gt; server which has to
fulfill a Kubernetes defined &lt;a href=&#34;https://protobuf.dev&#34;&gt;Protocol Buffer&lt;/a&gt; interface.
&lt;a href=&#34;https://github.com/kubernetes/cri-api/blob/63929b3/pkg/apis/runtime/v1/api.proto&#34;&gt;This API definition&lt;/a&gt;
evolves over time, for example when contributors add new features or fields are
going to become deprecated.&lt;/p&gt;
&lt;p&gt;In this blog post, I&#39;d like to dive into the functionality and history of three
extraordinary Remote Procedure Calls (RPCs), which are truly outstanding in
terms of how they work: &lt;code&gt;Exec&lt;/code&gt;, &lt;code&gt;Attach&lt;/code&gt; and &lt;code&gt;PortForward&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Exec&lt;/strong&gt; can be used to run dedicated commands within the container and stream
the output to a client like &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/reference/kubectl/&#34;&gt;kubectl&lt;/a&gt; or
&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/tasks/debug/debug-cluster/crictl/&#34;&gt;crictl&lt;/a&gt;. It also allows interaction with
that process using standard input (stdin), for example if users want to run a
new shell instance within an existing workload.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Attach&lt;/strong&gt; streams the output of the currently running process via &lt;a href=&#34;https://en.wikipedia.org/wiki/Standard_streams&#34;&gt;standard I/O&lt;/a&gt;
from the container to the client and also allows interaction with them. This is
particularly useful if users want to see what is going on in the container and
be able to interact with the process.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;PortForward&lt;/strong&gt; can be utilized to forward a port from the host to the container
to be able to interact with it using third party network tools. This allows it
to bypass &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/services-networking/service/&#34;&gt;Kubernetes services&lt;/a&gt;
for a certain workload and interact with its network interface.&lt;/p&gt;
&lt;h2 id=&#34;what-is-so-special-about-them&#34;&gt;What is so special about them?&lt;/h2&gt;
&lt;p&gt;All RPCs of the CRI either use the &lt;a href=&#34;https://grpc.io/docs/what-is-grpc/core-concepts/#unary-rpc&#34;&gt;gRPC unary calls&lt;/a&gt;
for communication or the &lt;a href=&#34;https://grpc.io/docs/what-is-grpc/core-concepts/#server-streaming-rpc&#34;&gt;server side streaming&lt;/a&gt;
feature (only &lt;code&gt;GetContainerEvents&lt;/code&gt; right now). This means that mainly all RPCs
retrieve a single client request and have to return a single server response.
The same applies to &lt;code&gt;Exec&lt;/code&gt;, &lt;code&gt;Attach&lt;/code&gt;, and &lt;code&gt;PortForward&lt;/code&gt;, where their &lt;a href=&#34;https://github.com/kubernetes/cri-api/blob/63929b3/pkg/apis/runtime/v1/api.proto#L94-L99&#34;&gt;protocol definition&lt;/a&gt;
looks like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-protobuf&#34; data-lang=&#34;protobuf&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Exec prepares a streaming endpoint to execute a command in the container.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;rpc&lt;/span&gt; Exec(ExecRequest) &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;returns&lt;/span&gt; (ExecResponse) {}&lt;span style=&#34;&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-protobuf&#34; data-lang=&#34;protobuf&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Attach prepares a streaming endpoint to attach to a running container.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;rpc&lt;/span&gt; Attach(AttachRequest) &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;returns&lt;/span&gt; (AttachResponse) {}&lt;span style=&#34;&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-protobuf&#34; data-lang=&#34;protobuf&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// PortForward prepares a streaming endpoint to forward ports from a PodSandbox.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;rpc&lt;/span&gt; PortForward(PortForwardRequest) &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;returns&lt;/span&gt; (PortForwardResponse) {}&lt;span style=&#34;&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The requests carry everything required to allow the server to do the work,
for example, the &lt;code&gt;ContainerId&lt;/code&gt; or command (&lt;code&gt;Cmd&lt;/code&gt;) to be run in case of &lt;code&gt;Exec&lt;/code&gt;.
More interestingly, all of their responses only contain a &lt;code&gt;url&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-protobuf&#34; data-lang=&#34;protobuf&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;message&lt;/span&gt; &lt;span style=&#34;color:#00f&#34;&gt;ExecResponse&lt;/span&gt; {&lt;span style=&#34;&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Fully qualified URL of the exec streaming server.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#0b0;font-weight:bold&#34;&gt;string&lt;/span&gt; url &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;1&lt;/span&gt;;&lt;span style=&#34;&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;&#34;&gt;&lt;/span&gt;}&lt;span style=&#34;&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-protobuf&#34; data-lang=&#34;protobuf&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;message&lt;/span&gt; &lt;span style=&#34;color:#00f&#34;&gt;AttachResponse&lt;/span&gt; {&lt;span style=&#34;&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Fully qualified URL of the attach streaming server.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#0b0;font-weight:bold&#34;&gt;string&lt;/span&gt; url &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;1&lt;/span&gt;;&lt;span style=&#34;&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;&#34;&gt;&lt;/span&gt;}&lt;span style=&#34;&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-protobuf&#34; data-lang=&#34;protobuf&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;message&lt;/span&gt; &lt;span style=&#34;color:#00f&#34;&gt;PortForwardResponse&lt;/span&gt; {&lt;span style=&#34;&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Fully qualified URL of the port-forward streaming server.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#0b0;font-weight:bold&#34;&gt;string&lt;/span&gt; url &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;1&lt;/span&gt;;&lt;span style=&#34;&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;&#34;&gt;&lt;/span&gt;}&lt;span style=&#34;&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Why is it implemented like that? Well, &lt;a href=&#34;https://docs.google.com/document/d/1MreuHzNvkBW6q7o_zehm1CBOBof3shbtMTGtUpjpRmY&#34;&gt;the original design document&lt;/a&gt;
for those RPCs even predates &lt;a href=&#34;https://github.com/kubernetes/enhancements&#34;&gt;Kubernetes Enhancements Proposals (KEPs)&lt;/a&gt;
and was originally outlined back in 2016. The kubelet had a native
implementation for &lt;code&gt;Exec&lt;/code&gt;, &lt;code&gt;Attach&lt;/code&gt;, and &lt;code&gt;PortForward&lt;/code&gt; before the
initiative to bring the functionality to the CRI started. Before that,
everything was bound to &lt;a href=&#34;https://www.docker.com&#34;&gt;Docker&lt;/a&gt; or the later abandoned
container runtime &lt;a href=&#34;https://github.com/rkt/rkt&#34;&gt;rkt&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The CRI related design document also elaborates on the option to use native RPC
streaming for exec, attach, and port forward. The downsides outweighed this
approach: the kubelet would still create a network bottleneck and future
runtimes would not be free in choosing the server implementation details. Also,
another option that the Kubelet implements a portable, runtime-agnostic solution
has been abandoned over the final one, because this would mean another project
to maintain which nevertheless would be runtime dependent.&lt;/p&gt;
&lt;p&gt;This means, that the basic flow for &lt;code&gt;Exec&lt;/code&gt;, &lt;code&gt;Attach&lt;/code&gt; and &lt;code&gt;PortForward&lt;/code&gt;
was proposed to look like this:&lt;/p&gt;


&lt;figure class=&#34;diagram-large &#34;&gt;
    &lt;img src=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/05/01/cri-streaming-explained/flow.svg&#34;
         alt=&#34;CRI Streaming flow&#34;/&gt; 
&lt;/figure&gt;
&lt;p&gt;Clients like crictl or the kubelet (via kubectl) request a new exec, attach or
port forward session from the runtime using the gRPC interface. The runtime
implements a streaming server that also manages the active sessions. This
streaming server provides an HTTP endpoint for the client to connect to. The
client upgrades the connection to use the &lt;a href=&#34;https://en.wikipedia.org/wiki/SPDY&#34;&gt;SPDY&lt;/a&gt;
streaming protocol or (in the future) to a &lt;a href=&#34;https://en.wikipedia.org/wiki/WebSocket&#34;&gt;WebSocket&lt;/a&gt;
connection and starts to stream the data back and forth.&lt;/p&gt;
&lt;p&gt;This implementation allows runtimes to have the flexibility to implement
&lt;code&gt;Exec&lt;/code&gt;, &lt;code&gt;Attach&lt;/code&gt; and &lt;code&gt;PortForward&lt;/code&gt; the way they want, and also allows a
simple test path. Runtimes can change the underlying implementation to support
any kind of feature without having a need to modify the CRI at all.&lt;/p&gt;
&lt;p&gt;Many smaller enhancements to this overall approach have been merged into
Kubernetes in the past years, but the general pattern has always stayed the
same. The kubelet source code transformed into &lt;a href=&#34;https://github.com/kubernetes/kubernetes/blob/db9fcfe/staging/src/k8s.io/kubelet/pkg/cri/streaming&#34;&gt;a reusable library&lt;/a&gt;,
which is nowadays usable from container runtimes to implement the basic
streaming capability.&lt;/p&gt;
&lt;h2 id=&#34;how-does-the-streaming-actually-work&#34;&gt;How does the streaming actually work?&lt;/h2&gt;
&lt;p&gt;At a first glance, it looks like all three RPCs work the same way, but that&#39;s
not the case. It&#39;s possible to group the functionality of &lt;strong&gt;Exec&lt;/strong&gt; and
&lt;strong&gt;Attach&lt;/strong&gt;, while &lt;strong&gt;PortForward&lt;/strong&gt; follows a distinct internal protocol
definition.&lt;/p&gt;
&lt;h3 id=&#34;exec-and-attach&#34;&gt;Exec and Attach&lt;/h3&gt;
&lt;p&gt;Kubernetes defines &lt;strong&gt;Exec&lt;/strong&gt; and &lt;strong&gt;Attach&lt;/strong&gt; as &lt;em&gt;remote commands&lt;/em&gt;, where its
protocol definition exists in &lt;a href=&#34;https://github.com/kubernetes/kubernetes/blob/9791f0d/staging/src/k8s.io/apimachinery/pkg/util/remotecommand/constants.go#L28-L52&#34;&gt;five different versions&lt;/a&gt;:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;#&lt;/th&gt;
&lt;th&gt;Version&lt;/th&gt;
&lt;th&gt;Note&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;code&gt;channel.k8s.io&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Initial (unversioned) SPDY sub protocol (&lt;a href=&#34;https://issues.k8s.io/13394&#34;&gt;#13394&lt;/a&gt;, &lt;a href=&#34;https://issues.k8s.io/13395&#34;&gt;#13395&lt;/a&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;&lt;code&gt;v2.channel.k8s.io&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Resolves the issues present in the first version (&lt;a href=&#34;https://github.com/kubernetes/kubernetes/pull/15961&#34;&gt;#15961&lt;/a&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;&lt;code&gt;v3.channel.k8s.io&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Adds support for resizing container terminals (&lt;a href=&#34;https://github.com/kubernetes/kubernetes/pull/25273&#34;&gt;#25273&lt;/a&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;&lt;code&gt;v4.channel.k8s.io&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Adds support for exit codes using JSON errors (&lt;a href=&#34;https://github.com/kubernetes/kubernetes/pull/26541&#34;&gt;#26541&lt;/a&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;&lt;code&gt;v5.channel.k8s.io&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Adds support for a CLOSE signal (&lt;a href=&#34;https://github.com/kubernetes/kubernetes/pull/119157&#34;&gt;#119157&lt;/a&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;On top of that, there is an overall effort to replace the SPDY transport
protocol using WebSockets as part &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/4006&#34;&gt;KEP #4006&lt;/a&gt;.
Runtimes have to satisfy those protocols over their life cycle to stay up to
date with the Kubernetes implementation.&lt;/p&gt;
&lt;p&gt;Let&#39;s assume that a client uses the latest (&lt;code&gt;v5&lt;/code&gt;) version of the protocol as
well as communicating over WebSockets. In that case, the general flow would be:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;The client requests an URL endpoint for &lt;strong&gt;Exec&lt;/strong&gt; or &lt;strong&gt;Attach&lt;/strong&gt; using the CRI.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The server (runtime) validates the request, inserts it into a connection
tracking cache, and provides the HTTP endpoint URL for that request.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The client connects to that URL, upgrades the connection to establish
a WebSocket, and starts to stream data.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In the case of &lt;strong&gt;Attach&lt;/strong&gt;, the server has to stream the main container process
data to the client.&lt;/li&gt;
&lt;li&gt;In the case of &lt;strong&gt;Exec&lt;/strong&gt;, the server has to create the subprocess command within
the container and then streams the output to the client.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If stdin is required, then the server needs to listen for that as well and
redirect it to the corresponding process.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Interpreting data for the defined protocol is fairly simple: The first
byte of every input and output packet &lt;a href=&#34;https://github.com/kubernetes/kubernetes/blob/9791f0d/staging/src/k8s.io/apimachinery/pkg/util/remotecommand/constants.go#L57-L64&#34;&gt;defines&lt;/a&gt;
the actual stream:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;First Byte&lt;/th&gt;
&lt;th&gt;Type&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;0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;standard input&lt;/td&gt;
&lt;td&gt;Data streamed from stdin&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;standard output&lt;/td&gt;
&lt;td&gt;Data streamed to stdout&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;standard error&lt;/td&gt;
&lt;td&gt;Data streamed to stderr&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;3&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;stream error&lt;/td&gt;
&lt;td&gt;A streaming error occurred&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;4&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;stream resize&lt;/td&gt;
&lt;td&gt;A terminal resize event&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;255&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;stream close&lt;/td&gt;
&lt;td&gt;Stream should be closed (for WebSockets)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;How should runtimes now implement the streaming server methods for &lt;strong&gt;Exec&lt;/strong&gt; and
&lt;strong&gt;Attach&lt;/strong&gt; by using the provided kubelet library? The key is that the streaming
server implementation in the kubelet &lt;a href=&#34;https://github.com/kubernetes/kubernetes/blob/db9fcfe/staging/src/k8s.io/kubelet/pkg/cri/streaming/server.go#L63-L68&#34;&gt;outlines an interface&lt;/a&gt;
called &lt;code&gt;Runtime&lt;/code&gt; which has to be fulfilled by the actual container runtime if it
wants to use that library:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Runtime is the interface to execute the commands and provide the streams.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;type&lt;/span&gt; Runtime &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;interface&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#00a000&#34;&gt;Exec&lt;/span&gt;(ctx context.Context, containerID &lt;span style=&#34;color:#0b0;font-weight:bold&#34;&gt;string&lt;/span&gt;, cmd []&lt;span style=&#34;color:#0b0;font-weight:bold&#34;&gt;string&lt;/span&gt;, in io.Reader, out, err io.WriteCloser, tty &lt;span style=&#34;color:#0b0;font-weight:bold&#34;&gt;bool&lt;/span&gt;, resize &lt;span style=&#34;color:#666&#34;&gt;&amp;lt;-&lt;/span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;chan&lt;/span&gt; remotecommand.TerminalSize) &lt;span style=&#34;color:#0b0;font-weight:bold&#34;&gt;error&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#00a000&#34;&gt;Attach&lt;/span&gt;(ctx context.Context, containerID &lt;span style=&#34;color:#0b0;font-weight:bold&#34;&gt;string&lt;/span&gt;, in io.Reader, out, err io.WriteCloser, tty &lt;span style=&#34;color:#0b0;font-weight:bold&#34;&gt;bool&lt;/span&gt;, resize &lt;span style=&#34;color:#666&#34;&gt;&amp;lt;-&lt;/span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;chan&lt;/span&gt; remotecommand.TerminalSize) &lt;span style=&#34;color:#0b0;font-weight:bold&#34;&gt;error&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#00a000&#34;&gt;PortForward&lt;/span&gt;(ctx context.Context, podSandboxID &lt;span style=&#34;color:#0b0;font-weight:bold&#34;&gt;string&lt;/span&gt;, port &lt;span style=&#34;color:#0b0;font-weight:bold&#34;&gt;int32&lt;/span&gt;, stream io.ReadWriteCloser) &lt;span style=&#34;color:#0b0;font-weight:bold&#34;&gt;error&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Everything related to the protocol interpretation is
already in place and runtimes only have to implement the actual &lt;code&gt;Exec&lt;/code&gt; and
&lt;code&gt;Attach&lt;/code&gt; logic. For example, the container runtime &lt;a href=&#34;https://github.com/cri-o/cri-o&#34;&gt;CRI-O&lt;/a&gt;
does it &lt;a href=&#34;https://github.com/cri-o/cri-o/blob/2a0867/server/container_exec.go#L27-L46&#34;&gt;like this pseudo code&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;func&lt;/span&gt; (s StreamService) &lt;span style=&#34;color:#00a000&#34;&gt;Exec&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ctx context.Context,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    containerID &lt;span style=&#34;color:#0b0;font-weight:bold&#34;&gt;string&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    cmd []&lt;span style=&#34;color:#0b0;font-weight:bold&#34;&gt;string&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    stdin io.Reader, stdout, stderr io.WriteCloser,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    tty &lt;span style=&#34;color:#0b0;font-weight:bold&#34;&gt;bool&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    resizeChan &lt;span style=&#34;color:#666&#34;&gt;&amp;lt;-&lt;/span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;chan&lt;/span&gt; remotecommand.TerminalSize,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;) &lt;span style=&#34;color:#0b0;font-weight:bold&#34;&gt;error&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Retrieve the container by the provided containerID
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// …
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Update the container status and verify that the workload is running
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// …
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Execute the command and stream the data
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;return&lt;/span&gt; s.runtimeServer.&lt;span style=&#34;color:#00a000&#34;&gt;Runtime&lt;/span&gt;().&lt;span style=&#34;color:#00a000&#34;&gt;ExecContainer&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        s.ctx, c, cmd, stdin, stdout, stderr, tty, resizeChan,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    )
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;portforward&#34;&gt;PortForward&lt;/h3&gt;
&lt;p&gt;Forwarding ports to a container works a bit differently when comparing it to
streaming IO data from a workload. The server still has to provide a URL
endpoint for the client to connect to, but then the container runtime has to
enter the network namespace of the container, allocate the port as well as
stream the data back and forth. There is no simple protocol definition available
like for &lt;strong&gt;Exec&lt;/strong&gt; or &lt;strong&gt;Attach&lt;/strong&gt;. This means that the client will stream the
plain SPDY frames (with or without an additional WebSocket connection) which can
be interpreted using libraries like &lt;a href=&#34;https://github.com/moby/spdystream&#34;&gt;moby/spdystream&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Luckily, the kubelet library already provides the &lt;code&gt;PortForward&lt;/code&gt; interface method
which has to be implemented by the runtime. &lt;a&gt;CRI-O does that&lt;/a&gt; by (simplified):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;func&lt;/span&gt; (s StreamService) &lt;span style=&#34;color:#00a000&#34;&gt;PortForward&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ctx context.Context,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    podSandboxID &lt;span style=&#34;color:#0b0;font-weight:bold&#34;&gt;string&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    port &lt;span style=&#34;color:#0b0;font-weight:bold&#34;&gt;int32&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    stream io.ReadWriteCloser,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;) &lt;span style=&#34;color:#0b0;font-weight:bold&#34;&gt;error&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Retrieve the pod sandbox by the provided podSandboxID
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;&lt;/span&gt;    sandboxID, err &lt;span style=&#34;color:#666&#34;&gt;:=&lt;/span&gt; s.runtimeServer.&lt;span style=&#34;color:#00a000&#34;&gt;PodIDIndex&lt;/span&gt;().&lt;span style=&#34;color:#00a000&#34;&gt;Get&lt;/span&gt;(podSandboxID)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    sb &lt;span style=&#34;color:#666&#34;&gt;:=&lt;/span&gt; s.runtimeServer.&lt;span style=&#34;color:#00a000&#34;&gt;GetSandbox&lt;/span&gt;(sandboxID)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// …
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Get the network namespace path on disk for that sandbox
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;&lt;/span&gt;    netNsPath &lt;span style=&#34;color:#666&#34;&gt;:=&lt;/span&gt; sb.&lt;span style=&#34;color:#00a000&#34;&gt;NetNsPath&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// …
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Enter the network namespace and stream the data
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;return&lt;/span&gt; s.runtimeServer.&lt;span style=&#34;color:#00a000&#34;&gt;Runtime&lt;/span&gt;().&lt;span style=&#34;color:#00a000&#34;&gt;PortForwardContainer&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ctx, sb.&lt;span style=&#34;color:#00a000&#34;&gt;InfraContainer&lt;/span&gt;(), netNsPath, port, stream,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    )
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;future-work&#34;&gt;Future work&lt;/h2&gt;
&lt;p&gt;The flexibility Kubernetes provides for the RPCs &lt;code&gt;Exec&lt;/code&gt;, &lt;code&gt;Attach&lt;/code&gt; and
&lt;code&gt;PortForward&lt;/code&gt; is truly outstanding compared to other methods. Nevertheless,
container runtimes have to keep up with the latest and greatest implementations
to support those features in a meaningful way. The general effort to support
WebSockets is not only a plain Kubernetes thing, it also has to be supported by
container runtimes as well as clients like &lt;code&gt;crictl&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For example, &lt;code&gt;crictl&lt;/code&gt; v1.30 features a new &lt;code&gt;--transport&lt;/code&gt; flag for the
subcommands &lt;code&gt;exec&lt;/code&gt;, &lt;code&gt;attach&lt;/code&gt; and &lt;code&gt;port-forward&lt;/code&gt;
(&lt;a href=&#34;https://github.com/kubernetes-sigs/cri-tools/pull/1383&#34;&gt;#1383&lt;/a&gt;,
&lt;a href=&#34;https://github.com/kubernetes-sigs/cri-tools/pull/1385&#34;&gt;#1385&lt;/a&gt;)
to allow choosing between &lt;code&gt;websocket&lt;/code&gt; and &lt;code&gt;spdy&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;CRI-O is going an experimental path by moving the streaming server
implementation into &lt;a href=&#34;https://github.com/containers/conmon-rs&#34;&gt;conmon-rs&lt;/a&gt;
(a substitute for the container monitor &lt;a href=&#34;https://github.com/containers/conmon&#34;&gt;conmon&lt;/a&gt;). conmon-rs is
a &lt;a href=&#34;https://www.rust-lang.org&#34;&gt;Rust&lt;/a&gt; implementation of the original container
monitor and allows streaming WebSockets directly using supported libraries
(&lt;a href=&#34;https://github.com/containers/conmon-rs/pull/2070&#34;&gt;#2070&lt;/a&gt;). The major benefit
of this approach is that CRI-O does not even have to be running while conmon-rs
can keep active &lt;strong&gt;Exec&lt;/strong&gt;, &lt;strong&gt;Attach&lt;/strong&gt; and &lt;strong&gt;PortForward&lt;/strong&gt; sessions open. The
simplified flow when using crictl directly will then look like this:&lt;/p&gt;
&lt;figure&gt;
&lt;div class=&#34;mermaid&#34;&gt;
    
sequenceDiagram
    autonumber
    participant crictl
    participant runtime as Container Runtime
    participant conmon-rs
    Note over crictl,runtime: Container Runtime Interface (CRI)
    crictl-&gt;&gt;runtime: Exec, Attach, PortForward
    Note over runtime,conmon-rs: Cap’n Proto
    runtime-&gt;&gt;conmon-rs: Serve Exec, Attach, PortForward
    conmon-rs-&gt;&gt;runtime: HTTP endpoint (URL)
    runtime-&gt;&gt;crictl: Response URL
    crictl--&gt;&gt;conmon-rs: Connection upgrade to WebSocket
    conmon-rs-)crictl: Stream data

&lt;/div&gt;
&lt;/figure&gt;

&lt;noscript&gt;
  &lt;div class=&#34;alert alert-secondary callout&#34; role=&#34;alert&#34;&gt;
    &lt;em class=&#34;javascript-required&#34;&gt;JavaScript must be &lt;a href=&#34;https://www.enable-javascript.com/&#34;&gt;enabled&lt;/a&gt; to view this content&lt;/em&gt;
  &lt;/div&gt;
&lt;/noscript&gt;
&lt;p&gt;All of those enhancements require iterative design decisions, while the original
well-conceived implementation acts as the foundation for those. I really hope
you&#39;ve enjoyed this compact journey through the history of CRI RPCs. Feel free
to reach out to me anytime for suggestions or feedback using the
&lt;a href=&#34;https://kubernetes.slack.com/team/U53SUDBD4&#34;&gt;official Kubernetes Slack&lt;/a&gt;.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes 1.30: Preventing unauthorized volume mode conversion moves to GA</title>
      <link>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/04/30/prevent-unauthorized-volume-mode-conversion-ga/</link>
      <pubDate>Tue, 30 Apr 2024 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/04/30/prevent-unauthorized-volume-mode-conversion-ga/</guid>
      <description>
        
        
        &lt;p&gt;With the release of Kubernetes 1.30, the feature to prevent the modification of the volume mode
of a &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/storage/persistent-volumes/&#34;&gt;PersistentVolumeClaim&lt;/a&gt; that was created from
an existing VolumeSnapshot in a Kubernetes cluster, has moved to GA!&lt;/p&gt;
&lt;h2 id=&#34;the-problem&#34;&gt;The problem&lt;/h2&gt;
&lt;p&gt;The &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/storage/persistent-volumes/#volume-mode&#34;&gt;Volume Mode&lt;/a&gt; of a PersistentVolumeClaim
refers to whether the underlying volume on the storage device is formatted into a filesystem or
presented as a raw block device to the Pod that uses it.&lt;/p&gt;
&lt;p&gt;Users can leverage the VolumeSnapshot feature, which has been stable since Kubernetes v1.20,
to create a PersistentVolumeClaim (shortened as PVC) from an existing VolumeSnapshot in
the Kubernetes cluster. The PVC spec includes a dataSource field, which can point to an
existing VolumeSnapshot instance.
Visit &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/storage/persistent-volumes/#create-persistent-volume-claim-from-volume-snapshot&#34;&gt;Create a PersistentVolumeClaim from a Volume Snapshot&lt;/a&gt;
for more details on how to create a PVC from an existing VolumeSnapshot in a Kubernetes cluster.&lt;/p&gt;
&lt;p&gt;When leveraging the above capability, there is no logic that validates whether the mode of the
original volume, whose snapshot was taken, matches the mode of the newly created volume.&lt;/p&gt;
&lt;p&gt;This presents a security gap that allows malicious users to potentially exploit an
as-yet-unknown vulnerability in the host operating system.&lt;/p&gt;
&lt;p&gt;There is a valid use case to allow some users to perform such conversions. Typically, storage backup
vendors convert the volume mode during the course of a backup operation, to retrieve changed blocks
for greater efficiency of operations. This prevents Kubernetes from blocking the operation completely
and presents a challenge in distinguishing trusted users from malicious ones.&lt;/p&gt;
&lt;h2 id=&#34;preventing-unauthorized-users-from-converting-the-volume-mode&#34;&gt;Preventing unauthorized users from converting the volume mode&lt;/h2&gt;
&lt;p&gt;In this context, an authorized user is one who has access rights to perform &lt;strong&gt;update&lt;/strong&gt;
or &lt;strong&gt;patch&lt;/strong&gt; operations on VolumeSnapshotContents, which is a cluster-level resource.&lt;br&gt;
It is up to the cluster administrator to provide these rights only to trusted users
or applications, like backup vendors.
Users apart from such authorized ones will never be allowed to modify the volume mode
of a PVC when it is being created from a VolumeSnapshot.&lt;/p&gt;
&lt;p&gt;To convert the volume mode, an authorized user must do the following:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Identify the VolumeSnapshot that is to be used as the data source for a newly
created PVC in the given namespace.&lt;/li&gt;
&lt;li&gt;Identify the VolumeSnapshotContent bound to the above VolumeSnapshot.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kubectl describe volumesnapshot -n &amp;lt;namespace&amp;gt; &amp;lt;name&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;Add the annotation &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/reference/labels-annotations-taints/#snapshot-storage-kubernetes-io-allowvolumemodechange&#34;&gt;&lt;code&gt;snapshot.storage.kubernetes.io/allow-volume-mode-change: &amp;quot;true&amp;quot;&lt;/code&gt;&lt;/a&gt;
to the above VolumeSnapshotContent. The VolumeSnapshotContent annotations must include one similar to the following manifest fragment:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;VolumeSnapshotContent&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;annotations&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;snapshot.storage.kubernetes.io/allow-volume-mode-change&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;true&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#00f;font-weight:bold&#34;&gt;...&lt;/span&gt;&lt;span style=&#34;color:#bbb&#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;Note&lt;/strong&gt;: For pre-provisioned VolumeSnapshotContents, you must take an extra
step of setting &lt;code&gt;spec.sourceVolumeMode&lt;/code&gt; field to either &lt;code&gt;Filesystem&lt;/code&gt; or &lt;code&gt;Block&lt;/code&gt;,
depending on the mode of the volume from which this snapshot was taken.&lt;/p&gt;
&lt;p&gt;An example is shown below:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;snapshot.storage.k8s.io/v1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;VolumeSnapshotContent&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;annotations&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;snapshot.storage.kubernetes.io/allow-volume-mode-change&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;true&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&amp;lt;volume-snapshot-content-name&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;spec&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;deletionPolicy&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Delete&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;driver&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;hostpath.csi.k8s.io&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;source&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;snapshotHandle&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&amp;lt;snapshot-handle&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;sourceVolumeMode&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Filesystem&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;volumeSnapshotRef&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&amp;lt;volume-snapshot-name&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;namespace&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&amp;lt;namespace&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Repeat steps 1 to 3 for all VolumeSnapshotContents whose volume mode needs to be
converted during a backup or restore operation. This can be done either via software
with credentials of an authorized user or manually by the authorized user(s).&lt;/p&gt;
&lt;p&gt;If the annotation shown above is present on a VolumeSnapshotContent object,
Kubernetes will not prevent the volume mode from being converted.
Users should keep this in mind before they attempt to add the annotation
to any VolumeSnapshotContent.&lt;/p&gt;
&lt;h2 id=&#34;action-required&#34;&gt;Action required&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;prevent-volume-mode-conversion&lt;/code&gt; feature flag is enabled by default in the
external-provisioner &lt;code&gt;v4.0.0&lt;/code&gt; and external-snapshotter &lt;code&gt;v7.0.0&lt;/code&gt;. Volume mode change
will be rejected when creating a PVC from a VolumeSnapshot unless the steps
described above have been performed.&lt;/p&gt;
&lt;h2 id=&#34;what-s-next&#34;&gt;What&#39;s next&lt;/h2&gt;
&lt;p&gt;To determine which CSI external sidecar versions support this feature, please head
over to the &lt;a href=&#34;https://kubernetes-csi.github.io/docs/&#34;&gt;CSI docs page&lt;/a&gt;.
For any queries or issues, join &lt;a href=&#34;https://slack.k8s.io/&#34;&gt;Kubernetes on Slack&lt;/a&gt; and
create a thread in the #csi or #sig-storage channel. Alternately, create an issue in the
CSI external-snapshotter &lt;a href=&#34;https://github.com/kubernetes-csi/external-snapshotter&#34;&gt;repository&lt;/a&gt;.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes 1.30: Multi-Webhook and Modular Authorization Made Much Easier</title>
      <link>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/04/26/multi-webhook-and-modular-authorization-made-much-easier/</link>
      <pubDate>Fri, 26 Apr 2024 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/04/26/multi-webhook-and-modular-authorization-made-much-easier/</guid>
      <description>
        
        
        &lt;p&gt;With Kubernetes 1.30, we (SIG Auth) are moving Structured Authorization
Configuration to beta.&lt;/p&gt;
&lt;p&gt;Today&#39;s article is about &lt;em&gt;authorization&lt;/em&gt;: deciding what someone can and cannot
access. Check a previous article from yesterday to find about what&#39;s new in
Kubernetes v1.30 around &lt;em&gt;authentication&lt;/em&gt; (finding out who&#39;s performing a task,
and checking that they are who they say they are).&lt;/p&gt;
&lt;h2 id=&#34;introduction&#34;&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Kubernetes continues to evolve to meet the intricate requirements of system
administrators and developers alike. A critical aspect of Kubernetes that
ensures the security and integrity of the cluster is the API server
authorization. Until recently, the configuration of the authorization chain in
kube-apiserver was somewhat rigid, limited to a set of command-line flags and
allowing only a single webhook in the authorization chain. This approach, while
functional, restricted the flexibility needed by cluster administrators to
define complex, fine-grained authorization policies. The latest Structured
Authorization Configuration feature (&lt;a href=&#34;https://kep.k8s.io/3221&#34;&gt;KEP-3221&lt;/a&gt;) aims
to revolutionize this aspect by introducing a more structured and versatile way
to configure the authorization chain, focusing on enabling multiple webhooks and
providing explicit control mechanisms.&lt;/p&gt;
&lt;h2 id=&#34;the-need-for-improvement&#34;&gt;The Need for Improvement&lt;/h2&gt;
&lt;p&gt;Cluster administrators have long sought the ability to specify multiple
authorization webhooks within the API Server handler chain and have control over
detailed behavior like timeout and failure policy for each webhook. This need
arises from the desire to create layered security policies, where requests can
be validated against multiple criteria or sets of rules in a specific order. The
previous limitations also made it difficult to dynamically configure the
authorizer chain, leaving no room to manage complex authorization scenarios
efficiently.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/reference/access-authn-authz/authorization/#configuring-the-api-server-using-an-authorization-config-file&#34;&gt;Structured Authorization Configuration
feature&lt;/a&gt;
addresses these limitations by introducing a configuration file format to
configure the Kubernetes API Server Authorization chain. This format allows
specifying multiple webhooks in the authorization chain (all other authorization
types are specified no more than once). Each webhook authorizer has well-defined
parameters, including timeout settings, failure policies, and conditions for
invocation with &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/reference/using-api/cel/&#34;&gt;CEL&lt;/a&gt; rules to pre-filter
requests before they are dispatched to webhooks, helping you prevent unnecessary
invocations. The configuration also supports automatic reloading, ensuring
changes can be applied dynamically without restarting the kube-apiserver. This
feature addresses current limitations and opens up new possibilities for
securing and managing Kubernetes clusters more effectively.&lt;/p&gt;
&lt;h2 id=&#34;sample-configurations&#34;&gt;Sample Configurations&lt;/h2&gt;
&lt;p&gt;Here is a sample structured authorization configuration along with descriptions
for all fields, their defaults, and possible values.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;apiserver.config.k8s.io/v1beta1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;AuthorizationConfiguration&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;authorizers&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;type&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Webhook&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Name used to describe the authorizer&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# This is explicitly used in monitoring machinery for metrics&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Note:&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;#   - Validation for this field is similar to how K8s labels are validated today.&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Required, with no default&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;webhook&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;webhook&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# The duration to cache &amp;#39;authorized&amp;#39; responses from the webhook&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# authorizer.&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Same as setting `--authorization-webhook-cache-authorized-ttl` flag&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Default: 5m0s&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;authorizedTTL&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;30s&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# The duration to cache &amp;#39;unauthorized&amp;#39; responses from the webhook&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# authorizer.&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Same as setting `--authorization-webhook-cache-unauthorized-ttl` flag&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Default: 30s&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;unauthorizedTTL&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;30s&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Timeout for the webhook request&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Maximum allowed is 30s.&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Required, with no default.&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;timeout&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;3s&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# The API version of the authorization.k8s.io SubjectAccessReview to&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# send to and expect from the webhook.&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Same as setting `--authorization-webhook-version` flag&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Required, with no default&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Valid values: v1beta1, v1&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;subjectAccessReviewVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;v1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# MatchConditionSubjectAccessReviewVersion specifies the SubjectAccessReview&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# version the CEL expressions are evaluated against&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Valid values: v1&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Required, no default value&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;matchConditionSubjectAccessReviewVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;v1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Controls the authorization decision when a webhook request fails to&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# complete or returns a malformed response or errors evaluating&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# matchConditions.&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Valid values:&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;#   - NoOpinion: continue to subsequent authorizers to see if one of&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;#     them allows the request&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;#   - Deny: reject the request without consulting subsequent authorizers&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Required, with no default.&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;failurePolicy&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Deny&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;connectionInfo&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Controls how the webhook should communicate with the server.&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Valid values:&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# - KubeConfigFile: use the file specified in kubeConfigFile to locate the&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;#   server.&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# - InClusterConfig: use the in-cluster configuration to call the&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;#   SubjectAccessReview API hosted by kube-apiserver. This mode is not&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;#   allowed for kube-apiserver.&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;type&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;KubeConfigFile&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Path to KubeConfigFile for connection info&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Required, if connectionInfo.Type is KubeConfigFile&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kubeConfigFile&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;/kube-system-authz-webhook.yaml&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# matchConditions is a list of conditions that must be met for a request to be sent to this&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# webhook. An empty list of matchConditions matches all requests.&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# There are a maximum of 64 match conditions allowed.&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;#&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# The exact matching logic is (in order):&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;#   1. If at least one matchCondition evaluates to FALSE, then the webhook is skipped.&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;#   2. If ALL matchConditions evaluate to TRUE, then the webhook is called.&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;#   3. If at least one matchCondition evaluates to an error (but none are FALSE):&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;#      - If failurePolicy=Deny, then the webhook rejects the request&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;#      - If failurePolicy=NoOpinion, then the error is ignored and the webhook is skipped&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;matchConditions&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# expression represents the expression which will be evaluated by CEL. Must evaluate to bool.&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# CEL expressions have access to the contents of the SubjectAccessReview in v1 version.&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# If version specified by subjectAccessReviewVersion in the request variable is v1beta1,&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# the contents would be converted to the v1 version before evaluating the CEL expression.&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;#&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;#&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# only send resource requests to the webhook&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;expression&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;has(request.resourceAttributes)&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# only intercept requests to kube-system&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;expression&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;request.resourceAttributes.namespace == &amp;#39;kube-system&amp;#39;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# don&amp;#39;t intercept requests from kube-system service accounts&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;expression&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;!(&amp;#39;system:serviceaccounts:kube-system&amp;#39; in request.groups)&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;type&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Node&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;node&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;type&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;RBAC&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;rbac&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;type&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Webhook&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;in-cluster-authorizer&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;webhook&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;authorizedTTL&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;5m&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;unauthorizedTTL&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;30s&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;timeout&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;3s&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;subjectAccessReviewVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;v1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;failurePolicy&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;NoOpinion&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;connectionInfo&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;type&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;InClusterConfig&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The following configuration examples illustrate real-world scenarios that need
the ability to specify multiple webhooks with distinct settings, precedence
order, and failure modes.&lt;/p&gt;
&lt;h3 id=&#34;protecting-installed-crds&#34;&gt;Protecting Installed CRDs&lt;/h3&gt;
&lt;p&gt;Ensuring of Custom Resource Definitions (CRDs) availability at cluster startup
has been a key demand. One of the blockers of having a controller reconcile
those CRDs is having a protection mechanism for them, which can be achieved
through multiple authorization webhooks. This was not possible before as
specifying multiple authorization webhooks in the Kubernetes API Server
authorization chain was simply not possible. Now, with the Structured
Authorization Configuration feature, administrators can specify multiple
webhooks, offering a solution where RBAC falls short, especially when denying
permissions to &#39;non-system&#39; users for certain CRDs.&lt;/p&gt;
&lt;p&gt;Assuming the following for this scenario:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &amp;quot;protected&amp;quot; CRDs are installed.&lt;/li&gt;
&lt;li&gt;They can only be modified by users in the group &lt;code&gt;admin&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;apiserver.config.k8s.io/v1beta1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;AuthorizationConfiguration&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;authorizers&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;type&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Webhook&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;system-crd-protector&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;webhook&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;unauthorizedTTL&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;30s&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;timeout&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;3s&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;subjectAccessReviewVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;v1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;matchConditionSubjectAccessReviewVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;v1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;failurePolicy&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Deny&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;connectionInfo&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;type&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;KubeConfigFile&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kubeConfigFile&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;/files/kube-system-authz-webhook.yaml&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;matchConditions&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# only send resource requests to the webhook&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;expression&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;has(request.resourceAttributes)&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# only intercept requests for CRDs&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;expression&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;request.resourceAttributes.resource.resource = &amp;#34;customresourcedefinitions&amp;#34;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;expression&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;request.resourceAttributes.resource.group = &amp;#34;&amp;#34;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# only intercept update, patch, delete, or deletecollection requests&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;expression&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;request.resourceAttributes.verb in [&amp;#39;update&amp;#39;, &amp;#39;patch&amp;#39;, &amp;#39;delete&amp;#39;,&amp;#39;deletecollection&amp;#39;]&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;type&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Node&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;type&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;RBAC&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;preventing-unnecessarily-nested-webhooks&#34;&gt;Preventing unnecessarily nested webhooks&lt;/h3&gt;
&lt;p&gt;A system administrator wants to apply specific validations to requests before
handing them off to webhooks using frameworks like Open Policy Agent. In the
past, this would require running nested webhooks within the one added to the
authorization chain to achieve the desired result. The Structured Authorization
Configuration feature simplifies this process, offering a structured API to
selectively trigger additional webhooks when needed. It also enables
administrators to set distinct failure policies for each webhook, ensuring more
consistent and predictable responses.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;apiserver.config.k8s.io/v1beta1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;AuthorizationConfiguration&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;authorizers&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;type&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Webhook&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;system-crd-protector&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;webhook&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;unauthorizedTTL&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;30s&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;timeout&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;3s&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;subjectAccessReviewVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;v1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;matchConditionSubjectAccessReviewVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;v1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;failurePolicy&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Deny&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;connectionInfo&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;type&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;KubeConfigFile&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kubeConfigFile&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;/files/kube-system-authz-webhook.yaml&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;matchConditions&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# only send resource requests to the webhook&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;expression&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;has(request.resourceAttributes)&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# only intercept requests for CRDs&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;expression&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;request.resourceAttributes.resource.resource = &amp;#34;customresourcedefinitions&amp;#34;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;expression&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;request.resourceAttributes.resource.group = &amp;#34;&amp;#34;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# only intercept update, patch, delete, or deletecollection requests&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;expression&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;request.resourceAttributes.verb in [&amp;#39;update&amp;#39;, &amp;#39;patch&amp;#39;, &amp;#39;delete&amp;#39;,&amp;#39;deletecollection&amp;#39;]&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;type&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Node&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;type&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;RBAC&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;opa&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;type&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Webhook&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;webhook&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;unauthorizedTTL&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;30s&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;timeout&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;3s&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;subjectAccessReviewVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;v1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;matchConditionSubjectAccessReviewVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;v1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;failurePolicy&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Deny&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;connectionInfo&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;type&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;KubeConfigFile&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kubeConfigFile&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;/files/opa-default-authz-webhook.yaml&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;matchConditions&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# only send resource requests to the webhook&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;expression&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;has(request.resourceAttributes)&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# only intercept requests to default namespace&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;expression&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;request.resourceAttributes.namespace == &amp;#39;default&amp;#39;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# don&amp;#39;t intercept requests from default service accounts&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;expression&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;!(&amp;#39;system:serviceaccounts:default&amp;#39; in request.groups)&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#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;/h2&gt;
&lt;p&gt;From Kubernetes 1.30, the feature is in beta and enabled by default. For
Kubernetes v1.31, we expect the feature to stay in beta while we get more
feedback from users. Once it is ready for GA, the feature flag will be removed,
and the configuration file version will be promoted to v1.&lt;/p&gt;
&lt;p&gt;Learn more about this feature on the &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/reference/access-authn-authz/authorization/#configuring-the-api-server-using-an-authorization-config-file&#34;&gt;structured authorization
configuration&lt;/a&gt;
Kubernetes doc website. You can also follow along with
&lt;a href=&#34;https://kep.k8s.io/3221&#34;&gt;KEP-3221&lt;/a&gt; to track progress in coming Kubernetes
releases.&lt;/p&gt;
&lt;h2 id=&#34;call-to-action&#34;&gt;Call to action&lt;/h2&gt;
&lt;p&gt;In this post, we have covered the benefits of the Structured Authorization
Configuration feature in Kubernetes v1.30 and a few sample configurations for
real-world scenarios. To use this feature, you must specify the path to the
authorization configuration using the &lt;code&gt;--authorization-config&lt;/code&gt; command line
argument. From Kubernetes 1.30, the feature is in beta and enabled by default.
If you want to keep using command line flags instead of a configuration file,
those will continue to work as-is. Specifying both &lt;code&gt;--authorization-config&lt;/code&gt; and
&lt;code&gt;--authorization-modes&lt;/code&gt;/&lt;code&gt;--authorization-webhook-*&lt;/code&gt; won&#39;t work. You need to drop
the older flags from your kube-apiserver command.&lt;/p&gt;
&lt;p&gt;The following kind Cluster configuration sets that command argument on the
APIserver to load an AuthorizationConfiguration from a file
(&lt;code&gt;authorization_config.yaml&lt;/code&gt;) in the files folder. Any needed kubeconfig and
certificate files can also be put in the files directory.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Cluster&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;kind.x-k8s.io/v1alpha4&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;featureGates&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;StructuredAuthorizationConfiguration&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;true&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# enabled by default in v1.30&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kubeadmConfigPatches&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- |&lt;span style=&#34;color:#b44;font-style:italic&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44;font-style:italic&#34;&gt;    kind: ClusterConfiguration
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44;font-style:italic&#34;&gt;    metadata:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44;font-style:italic&#34;&gt;      name: config
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44;font-style:italic&#34;&gt;    apiServer:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44;font-style:italic&#34;&gt;      extraArgs:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44;font-style:italic&#34;&gt;        authorization-config: &amp;#34;/files/authorization_config.yaml&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44;font-style:italic&#34;&gt;      extraVolumes:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44;font-style:italic&#34;&gt;      - name: files
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44;font-style:italic&#34;&gt;        hostPath: &amp;#34;/files&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44;font-style:italic&#34;&gt;        mountPath: &amp;#34;/files&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44;font-style:italic&#34;&gt;        readOnly: true&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;nodes&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;role&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;control-plane&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;extraMounts&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;hostPath&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;files&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;containerPath&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;/files&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We would love to hear your feedback on this feature. In particular, we would
like feedback from Kubernetes cluster administrators and authorization webhook
implementors as they build their integrations with this new API. Please reach
out to us on the
&lt;a href=&#34;https://kubernetes.slack.com/archives/C05EZFX1Z2L&#34;&gt;#sig-auth-authorizers-dev&lt;/a&gt;
channel on Kubernetes Slack.&lt;/p&gt;
&lt;h2 id=&#34;how-to-get-involved&#34;&gt;How to get involved&lt;/h2&gt;
&lt;p&gt;If you are interested in helping develop this feature, sharing feedback, or
participating in any other ongoing SIG Auth projects, please reach out on the
&lt;a href=&#34;https://kubernetes.slack.com/archives/C0EN96KUY&#34;&gt;#sig-auth&lt;/a&gt; channel on
Kubernetes Slack.&lt;/p&gt;
&lt;p&gt;You are also welcome to join the bi-weekly &lt;a href=&#34;https://github.com/kubernetes/community/blob/master/sig-auth/README.md#meetings&#34;&gt;SIG Auth
meetings&lt;/a&gt;
held every other Wednesday.&lt;/p&gt;
&lt;h2 id=&#34;acknowledgments&#34;&gt;Acknowledgments&lt;/h2&gt;
&lt;p&gt;This feature was driven by contributors from several different companies. We
would like to extend a huge thank you to everyone who contributed their time and
effort to make this possible.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes 1.30: Structured Authentication Configuration Moves to Beta</title>
      <link>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/04/25/structured-authentication-moves-to-beta/</link>
      <pubDate>Thu, 25 Apr 2024 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/04/25/structured-authentication-moves-to-beta/</guid>
      <description>
        
        
        &lt;p&gt;With Kubernetes 1.30, we (SIG Auth) are moving Structured Authentication Configuration to beta.&lt;/p&gt;
&lt;p&gt;Today&#39;s article is about &lt;em&gt;authentication&lt;/em&gt;: finding out who&#39;s performing a task, and checking
that they are who they say they are. Check back in tomorrow to find about what&#39;s new in
Kubernetes v1.30 around &lt;em&gt;authorization&lt;/em&gt; (deciding what someone can and can&#39;t access).&lt;/p&gt;
&lt;h2 id=&#34;motivation&#34;&gt;Motivation&lt;/h2&gt;
&lt;p&gt;Kubernetes has had a long-standing need for a more flexible and extensible
authentication system. The current system, while powerful, has some limitations
that make it difficult to use in certain scenarios. For example, it is not
possible to use multiple authenticators of the same type (e.g., multiple JWT
authenticators) or to change the configuration without restarting the API server. The
Structured Authentication Configuration feature is the first step towards
addressing these limitations and providing a more flexible and extensible way
to configure authentication in Kubernetes.&lt;/p&gt;
&lt;h2 id=&#34;what-is-structured-authentication-configuration&#34;&gt;What is structured authentication configuration?&lt;/h2&gt;
&lt;p&gt;Kubernetes v1.30 builds on the experimental support for configurating authentication based on
a file, that was added as alpha in Kubernetes v1.30. At this beta stage, Kubernetes only supports configuring JWT
authenticators, which serve as the next iteration of the existing OIDC
authenticator. JWT authenticator is an authenticator to
authenticate Kubernetes users using JWT compliant tokens. The authenticator
will attempt to parse a raw ID token, verify it&#39;s been signed by the configured
issuer.&lt;/p&gt;
&lt;p&gt;The Kubernetes project added configuration from a file so that it can provide more
flexibility than using command line options (which continue to work, and are still supported).
Supporting a configuration file also makes it easy to deliver further improvements in upcoming
releases.&lt;/p&gt;
&lt;h3 id=&#34;benefits-of-structured-authentication-configuration&#34;&gt;Benefits of structured authentication configuration&lt;/h3&gt;
&lt;p&gt;Here&#39;s why using a configuration file to configure cluster authentication is a benefit:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Multiple JWT authenticators&lt;/strong&gt;: You can configure multiple JWT authenticators
simultaneously. This allows you to use multiple identity providers (e.g.,
Okta, Keycloak, GitLab) without needing to use an intermediary like Dex
that handles multiplexing between multiple identity providers.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dynamic configuration&lt;/strong&gt;: You can change the configuration without
restarting the API server. This allows you to add, remove, or modify
authenticators without disrupting the API server.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Any JWT-compliant token&lt;/strong&gt;: You can use any JWT-compliant token for
authentication. This allows you to use tokens from any identity provider that
supports JWT. The minimum valid JWT payload must contain the claims documented
in &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/reference/access-authn-authz/authentication/#using-authentication-configuration&#34;&gt;structured authentication configuration&lt;/a&gt;
page in the Kubernetes documentation.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CEL (Common Expression Language) support&lt;/strong&gt;: You can use &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/reference/using-api/cel/&#34;&gt;CEL&lt;/a&gt;
to determine whether the token&#39;s claims match the user&#39;s attributes in Kubernetes (e.g.,
username, group). This allows you to use complex logic to determine whether a
token is valid.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Multiple audiences&lt;/strong&gt;: You can configure multiple audiences for a single
authenticator. This allows you to use the same authenticator for multiple
audiences, such as using a different OAuth client for &lt;code&gt;kubectl&lt;/code&gt; and dashboard.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Using identity providers that don&#39;t support OpenID connect discovery&lt;/strong&gt;: You
can use identity providers that don&#39;t support &lt;a href=&#34;https://openid.net/specs/openid-connect-discovery-1_0.html&#34;&gt;OpenID Connect
discovery&lt;/a&gt;. The only
requirement is to host the discovery document at a different location than the
issuer (such as locally in the cluster) and specify the &lt;code&gt;issuer.discoveryURL&lt;/code&gt; in
the configuration file.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;how-to-use-structured-authentication-configuration&#34;&gt;How to use Structured Authentication Configuration&lt;/h2&gt;
&lt;p&gt;To use structured authentication configuration, you specify
the path to the authentication configuration using the &lt;code&gt;--authentication-config&lt;/code&gt;
command line argument in the API server. The configuration file is a YAML file
that specifies the authenticators and their configuration. Here is an example
configuration file that configures two JWT authenticators:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;apiserver.config.k8s.io/v1beta1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;AuthenticationConfiguration&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Someone with a valid token from either of these issuers could authenticate&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# against this cluster.&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;jwt&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;issuer&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;url&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;https://issuer1.example.com&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;audiences&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- audience1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- audience2&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;audienceMatchPolicy&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;MatchAny&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;claimValidationRules&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;expression&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;claims.hd == &amp;#34;example.com&amp;#34;&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;message&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;the hosted domain name must be example.com&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;claimMappings&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;username&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;expression&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;claims.username&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;groups&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;expression&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;claims.groups&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;uid&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;expression&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;claims.uid&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;extra&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;key&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;example.com/tenant&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;expression&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;claims.tenant&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;userValidationRules&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;expression&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;!user.username.startsWith(&amp;#39;system:&amp;#39;)&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;message&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;username cannot use reserved system: prefix&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# second authenticator that exposes the discovery document at a different location&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# than the issuer&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;issuer&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;url&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;https://issuer2.example.com&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;discoveryURL&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;https://discovery.example.com/.well-known/openid-configuration&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;audiences&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- audience3&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- audience4&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;audienceMatchPolicy&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;MatchAny&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;claimValidationRules&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;expression&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;claims.hd == &amp;#34;example.com&amp;#34;&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;message&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;the hosted domain name must be example.com&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;claimMappings&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;username&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;expression&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;claims.username&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;groups&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;expression&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;claims.groups&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;uid&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;expression&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;claims.uid&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;extra&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;key&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;example.com/tenant&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;expression&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;claims.tenant&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;userValidationRules&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;expression&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;!user.username.startsWith(&amp;#39;system:&amp;#39;)&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;message&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;username cannot use reserved system: prefix&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;migration-from-command-line-arguments-to-configuration-file&#34;&gt;Migration from command line arguments to configuration file&lt;/h2&gt;
&lt;p&gt;The Structured Authentication Configuration feature is designed to be
backwards-compatible with the existing approach, based on command line options, for
configuring the JWT authenticator. This means that you can continue to use the existing
command-line options to configure the JWT authenticator. However, we (Kubernetes SIG Auth)
recommend migrating to the new configuration file-based approach, as it provides more
flexibility and extensibility.&lt;/p&gt;


&lt;div class=&#34;alert alert-primary&#34; role=&#34;alert&#34;&gt;
&lt;h4 class=&#34;alert-heading&#34;&gt;Note&lt;/h4&gt;

    &lt;p&gt;If you specify &lt;code&gt;--authentication-config&lt;/code&gt; along with any of the &lt;code&gt;--oidc-*&lt;/code&gt; command line arguments, this is
a misconfiguration. In this situation, the API server reports an error and then immediately exits.&lt;/p&gt;
&lt;p&gt;If you want to switch to using structured authentication configuration, you have to remove the &lt;code&gt;--oidc-*&lt;/code&gt;
command line arguments, and use the configuration file instead.&lt;/p&gt;


&lt;/div&gt;

&lt;p&gt;Here is an example of how to migrate from the command-line flags to the
configuration file:&lt;/p&gt;
&lt;h3 id=&#34;command-line-arguments&#34;&gt;Command-line arguments&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;--oidc-issuer-url&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;https://issuer.example.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;--oidc-client-id&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;example-client-id
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;--oidc-username-claim&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;username
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;--oidc-groups-claim&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;groups
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;--oidc-username-prefix&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;oidc:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;--oidc-groups-prefix&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;oidc:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;--oidc-required-claim&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;hd=example.com&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;--oidc-required-claim&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;admin=true&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;--oidc-ca-file&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;/path/to/ca.pem
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;There is no equivalent in the configuration file for the &lt;code&gt;--oidc-signing-algs&lt;/code&gt;.
For Kubernetes v1.30, the authenticator supports all the asymmetric algorithms listed in
&lt;a href=&#34;https://github.com/kubernetes/kubernetes/blob/b4935d910dcf256288694391ef675acfbdb8e7a3/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/oidc/oidc.go#L222-L233&#34;&gt;&lt;code&gt;oidc.go&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;configuration-file&#34;&gt;Configuration file&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;apiserver.config.k8s.io/v1beta1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;AuthenticationConfiguration&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;jwt&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;issuer&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;url&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;https://issuer.example.com&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;audiences&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- example-client-id&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;certificateAuthority&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&amp;lt;value is the content of file /path/to/ca.pem&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;claimMappings&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;username&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;claim&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;username&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;prefix&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;oidc:&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;groups&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;claim&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;groups&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;prefix&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;oidc:&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;claimValidationRules&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;claim&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;hd&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;requiredValue&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;example.com&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;claim&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;admin&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;requiredValue&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;true&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#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;/h2&gt;
&lt;p&gt;For Kubernetes v1.31, we expect the feature to stay in beta while we get more
feedback. In the coming releases, we want to investigate:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Making distributed claims work via CEL expressions.&lt;/li&gt;
&lt;li&gt;Egress selector configuration support for calls to &lt;code&gt;issuer.url&lt;/code&gt; and
&lt;code&gt;issuer.discoveryURL&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can learn more about this feature on the &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/reference/access-authn-authz/authentication/#using-authentication-configuration&#34;&gt;structured authentication
configuration&lt;/a&gt;
page in the Kubernetes documentation. You can also follow along on the
&lt;a href=&#34;https://kep.k8s.io/3331&#34;&gt;KEP-3331&lt;/a&gt; to track progress across the coming
Kubernetes releases.&lt;/p&gt;
&lt;h2 id=&#34;try-it-out&#34;&gt;Try it out&lt;/h2&gt;
&lt;p&gt;In this post, I have covered the benefits the Structured Authentication
Configuration feature brings in Kubernetes v1.30. To use this feature, you must specify the path to the
authentication configuration using the &lt;code&gt;--authentication-config&lt;/code&gt; command line
argument. From Kubernetes v1.30, the feature is in beta and enabled by default.
If you want to keep using command line arguments instead of a configuration file,
those will continue to work as-is.&lt;/p&gt;
&lt;p&gt;We would love to hear your feedback on this feature. Please reach out to us on the
&lt;a href=&#34;https://kubernetes.slack.com/archives/C04UMAUC4UA&#34;&gt;#sig-auth-authenticators-dev&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;/h2&gt;
&lt;p&gt;If you are interested in getting involved in the development of this feature,
share feedback, or participate in any other ongoing SIG Auth projects, please
reach out on the &lt;a href=&#34;https://kubernetes.slack.com/archives/C0EN96KUY&#34;&gt;#sig-auth&lt;/a&gt;
channel on Kubernetes Slack.&lt;/p&gt;
&lt;p&gt;You are also welcome to join the bi-weekly &lt;a href=&#34;https://github.com/kubernetes/community/blob/master/sig-auth/README.md#meetings&#34;&gt;SIG Auth
meetings&lt;/a&gt;
held every-other Wednesday.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes 1.30: Validating Admission Policy Is Generally Available</title>
      <link>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/04/24/validating-admission-policy-ga/</link>
      <pubDate>Wed, 24 Apr 2024 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/04/24/validating-admission-policy-ga/</guid>
      <description>
        
        
        &lt;p&gt;On behalf of the Kubernetes project, I am excited to announce that ValidatingAdmissionPolicy has reached
&lt;strong&gt;general availability&lt;/strong&gt;
as part of Kubernetes 1.30 release. If you have not yet read about this new declarative alternative to
validating admission webhooks, it may be interesting to read our
&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2022/12/20/validating-admission-policies-alpha/&#34;&gt;previous post&lt;/a&gt; about the new feature.
If you have already heard about ValidatingAdmissionPolicies and you are eager to try them out,
there is no better time to do it than now.&lt;/p&gt;
&lt;p&gt;Let&#39;s have a taste of a ValidatingAdmissionPolicy, by replacing a simple webhook.&lt;/p&gt;
&lt;h2 id=&#34;example-admission-webhook&#34;&gt;Example admission webhook&lt;/h2&gt;
&lt;p&gt;First, let&#39;s take a look at an example of a simple webhook. Here is an excerpt from a webhook that
enforces &lt;code&gt;runAsNonRoot&lt;/code&gt;, &lt;code&gt;readOnlyRootFilesystem&lt;/code&gt;, &lt;code&gt;allowPrivilegeEscalation&lt;/code&gt;, and &lt;code&gt;privileged&lt;/code&gt; to be set to the least permissive values.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#00a000&#34;&gt;verifyDeployment&lt;/span&gt;(deploy &lt;span style=&#34;color:#666&#34;&gt;*&lt;/span&gt;appsv1.Deployment) &lt;span style=&#34;color:#0b0;font-weight:bold&#34;&gt;error&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;var&lt;/span&gt; errs []&lt;span style=&#34;color:#0b0;font-weight:bold&#34;&gt;error&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;for&lt;/span&gt; i, c &lt;span style=&#34;color:#666&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;range&lt;/span&gt; deploy.Spec.Template.Spec.Containers {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;if&lt;/span&gt; c.Name &lt;span style=&#34;color:#666&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;return&lt;/span&gt; fmt.&lt;span style=&#34;color:#00a000&#34;&gt;Errorf&lt;/span&gt;(&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;container %d has no name&amp;#34;&lt;/span&gt;, i)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;if&lt;/span&gt; c.SecurityContext &lt;span style=&#34;color:#666&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;nil&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			errs = &lt;span style=&#34;color:#a2f&#34;&gt;append&lt;/span&gt;(errs, fmt.&lt;span style=&#34;color:#00a000&#34;&gt;Errorf&lt;/span&gt;(&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;container %q does not have SecurityContext&amp;#34;&lt;/span&gt;, c.Name))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;if&lt;/span&gt; c.SecurityContext.RunAsNonRoot &lt;span style=&#34;color:#666&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;nil&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;||&lt;/span&gt; !&lt;span style=&#34;color:#666&#34;&gt;*&lt;/span&gt;c.SecurityContext.RunAsNonRoot {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			errs = &lt;span style=&#34;color:#a2f&#34;&gt;append&lt;/span&gt;(errs, fmt.&lt;span style=&#34;color:#00a000&#34;&gt;Errorf&lt;/span&gt;(&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;container %q must set RunAsNonRoot to true in its SecurityContext&amp;#34;&lt;/span&gt;, c.Name))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;if&lt;/span&gt; c.SecurityContext.ReadOnlyRootFilesystem &lt;span style=&#34;color:#666&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;nil&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;||&lt;/span&gt; !&lt;span style=&#34;color:#666&#34;&gt;*&lt;/span&gt;c.SecurityContext.ReadOnlyRootFilesystem {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			errs = &lt;span style=&#34;color:#a2f&#34;&gt;append&lt;/span&gt;(errs, fmt.&lt;span style=&#34;color:#00a000&#34;&gt;Errorf&lt;/span&gt;(&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;container %q must set ReadOnlyRootFilesystem to true in its SecurityContext&amp;#34;&lt;/span&gt;, c.Name))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;if&lt;/span&gt; c.SecurityContext.AllowPrivilegeEscalation &lt;span style=&#34;color:#666&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;nil&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;*&lt;/span&gt;c.SecurityContext.AllowPrivilegeEscalation {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			errs = &lt;span style=&#34;color:#a2f&#34;&gt;append&lt;/span&gt;(errs, fmt.&lt;span style=&#34;color:#00a000&#34;&gt;Errorf&lt;/span&gt;(&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;container %q must NOT set AllowPrivilegeEscalation to true in its SecurityContext&amp;#34;&lt;/span&gt;, c.Name))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;if&lt;/span&gt; c.SecurityContext.Privileged &lt;span style=&#34;color:#666&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;nil&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;*&lt;/span&gt;c.SecurityContext.Privileged {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			errs = &lt;span style=&#34;color:#a2f&#34;&gt;append&lt;/span&gt;(errs, fmt.&lt;span style=&#34;color:#00a000&#34;&gt;Errorf&lt;/span&gt;(&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;container %q must NOT set Privileged to true in its SecurityContext&amp;#34;&lt;/span&gt;, c.Name))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;return&lt;/span&gt; errors.&lt;span style=&#34;color:#00a000&#34;&gt;NewAggregate&lt;/span&gt;(errs)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Check out &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/reference/access-authn-authz/extensible-admission-controllers/#what-are-admission-webhooks&#34;&gt;What are admission webhooks?&lt;/a&gt;
Or, see the &lt;a href=&#34;webhook.go&#34;&gt;full code&lt;/a&gt; of this webhook to follow along with this walkthrough.&lt;/p&gt;
&lt;h2 id=&#34;the-policy&#34;&gt;The policy&lt;/h2&gt;
&lt;p&gt;Now let&#39;s try to recreate the validation faithfully with a ValidatingAdmissionPolicy.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;admissionregistration.k8s.io/v1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;ValidatingAdmissionPolicy&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;pod-security.policy.example.com&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;spec&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;failurePolicy&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Fail&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;matchConstraints&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;resourceRules&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;apiGroups&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;   &lt;/span&gt;[&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;apps&amp;#34;&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;apiVersions&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;[&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;v1&amp;#34;&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;operations&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;[&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;CREATE&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;UPDATE&amp;#34;&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;resources&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;   &lt;/span&gt;[&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;deployments&amp;#34;&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;validations&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;expression&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;object.spec.template.spec.containers.all(c, has(c.securityContext) &amp;amp;&amp;amp; has(c.securityContext.runAsNonRoot) &amp;amp;&amp;amp; c.securityContext.runAsNonRoot)&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;message&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;all containers must set runAsNonRoot to true&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;expression&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;object.spec.template.spec.containers.all(c, has(c.securityContext) &amp;amp;&amp;amp; has(c.securityContext.readOnlyRootFilesystem) &amp;amp;&amp;amp; c.securityContext.readOnlyRootFilesystem)&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;message&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;all containers must set readOnlyRootFilesystem to true&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;expression&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;object.spec.template.spec.containers.all(c, !has(c.securityContext) || !has(c.securityContext.allowPrivilegeEscalation) || !c.securityContext.allowPrivilegeEscalation)&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;message&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;all containers must NOT set allowPrivilegeEscalation to true&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;expression&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;object.spec.template.spec.containers.all(c, !has(c.securityContext) || !has(c.securityContext.Privileged) || !c.securityContext.Privileged)&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;message&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;all containers must NOT set privileged to true&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Create the policy with &lt;code&gt;kubectl&lt;/code&gt;. Great, no complain so far. But let&#39;s get the policy object back and take a look at its status.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kubectl get -oyaml validatingadmissionpolicies/pod-security.policy.example.com
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;status&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;typeChecking&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;expressionWarnings&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;fieldRef&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;spec.validations[3].expression&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;warning&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;|&lt;span style=&#34;color:#b44;font-style:italic&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44;font-style:italic&#34;&gt;          apps/v1, Kind=Deployment: ERROR: &amp;lt;input&amp;gt;:1:76: undefined field &amp;#39;Privileged&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44;font-style:italic&#34;&gt;           | object.spec.template.spec.containers.all(c, !has(c.securityContext) || !has(c.securityContext.Privileged) || !c.securityContext.Privileged)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44;font-style:italic&#34;&gt;           | ...........................................................................^
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44;font-style:italic&#34;&gt;          ERROR: &amp;lt;input&amp;gt;:1:128: undefined field &amp;#39;Privileged&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44;font-style:italic&#34;&gt;           | object.spec.template.spec.containers.all(c, !has(c.securityContext) || !has(c.securityContext.Privileged) || !c.securityContext.Privileged)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44;font-style:italic&#34;&gt;           | ...............................................................................................................................^&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;          
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The policy was checked against its matched type, which is &lt;code&gt;apps/v1.Deployment&lt;/code&gt;.
Looking at the &lt;code&gt;fieldRef&lt;/code&gt;, the problem was with the 3rd expression (index starts with 0)
The expression in question accessed an undefined &lt;code&gt;Privileged&lt;/code&gt; field.
Ahh, looks like it was a copy-and-paste error. The field name should be in lowercase.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;admissionregistration.k8s.io/v1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;ValidatingAdmissionPolicy&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;pod-security.policy.example.com&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;spec&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;failurePolicy&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Fail&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;matchConstraints&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;resourceRules&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;apiGroups&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;   &lt;/span&gt;[&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;apps&amp;#34;&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;apiVersions&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;[&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;v1&amp;#34;&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;operations&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;[&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;CREATE&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;UPDATE&amp;#34;&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;resources&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;   &lt;/span&gt;[&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;deployments&amp;#34;&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;validations&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;expression&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;object.spec.template.spec.containers.all(c, has(c.securityContext) &amp;amp;&amp;amp; has(c.securityContext.runAsNonRoot) &amp;amp;&amp;amp; c.securityContext.runAsNonRoot)&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;message&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;all containers must set runAsNonRoot to true&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;expression&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;object.spec.template.spec.containers.all(c, has(c.securityContext) &amp;amp;&amp;amp; has(c.securityContext.readOnlyRootFilesystem) &amp;amp;&amp;amp; c.securityContext.readOnlyRootFilesystem)&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;message&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;all containers must set readOnlyRootFilesystem to true&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;expression&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;object.spec.template.spec.containers.all(c, !has(c.securityContext) || !has(c.securityContext.allowPrivilegeEscalation) || !c.securityContext.allowPrivilegeEscalation)&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;message&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;all containers must NOT set allowPrivilegeEscalation to true&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;expression&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;object.spec.template.spec.containers.all(c, !has(c.securityContext) || !has(c.securityContext.privileged) || !c.securityContext.privileged)&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;message&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;all containers must NOT set privileged to true&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Check its status again, and you should see all warnings cleared.&lt;/p&gt;
&lt;p&gt;Next, let&#39;s create a namespace for our tests.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kubectl create namespace policy-test
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then, I bind the policy to the namespace. But at this point, I set the action to &lt;code&gt;Warn&lt;/code&gt;
so that the policy prints out &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2020/09/03/warnings/&#34;&gt;warnings&lt;/a&gt; instead of rejecting the requests.
This is especially useful to collect results from all expressions during development and automated testing.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;admissionregistration.k8s.io/v1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;ValidatingAdmissionPolicyBinding&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;pod-security.policy-binding.example.com&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;spec&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;policyName&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;pod-security.policy.example.com&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;validationActions&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;[&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;Warn&amp;#34;&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;matchResources&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;namespaceSelector&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;matchLabels&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;&amp;#34;kubernetes.io/metadata.name&amp;#34;: &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;policy-test&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Tests out policy enforcement.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kubectl create -n policy-test -f- &lt;span style=&#34;color:#b44&#34;&gt;&amp;lt;&amp;lt;EOF
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;apiVersion: apps/v1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;kind: Deployment
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;metadata:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;  labels:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;    app: nginx
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;  name: nginx
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;spec:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;  selector:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;    matchLabels:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;      app: nginx
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;  template:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;    metadata:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;      labels:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;        app: nginx
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;    spec:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;      containers:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;      - image: nginx
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;        name: nginx
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;        securityContext:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;          privileged: true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;          allowPrivilegeEscalation: true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;EOF&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Warning: Validation failed for ValidatingAdmissionPolicy &amp;#39;pod-security.policy.example.com&amp;#39; with binding &amp;#39;pod-security.policy-binding.example.com&amp;#39;: all containers must set runAsNonRoot to true
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Warning: Validation failed for ValidatingAdmissionPolicy &amp;#39;pod-security.policy.example.com&amp;#39; with binding &amp;#39;pod-security.policy-binding.example.com&amp;#39;: all containers must set readOnlyRootFilesystem to true
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Warning: Validation failed for ValidatingAdmissionPolicy &amp;#39;pod-security.policy.example.com&amp;#39; with binding &amp;#39;pod-security.policy-binding.example.com&amp;#39;: all containers must NOT set allowPrivilegeEscalation to true
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Warning: Validation failed for ValidatingAdmissionPolicy &amp;#39;pod-security.policy.example.com&amp;#39; with binding &amp;#39;pod-security.policy-binding.example.com&amp;#39;: all containers must NOT set privileged to true
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Error from server: error when creating &amp;#34;STDIN&amp;#34;: admission webhook &amp;#34;webhook.example.com&amp;#34; denied the request: [container &amp;#34;nginx&amp;#34; must set RunAsNonRoot to true in its SecurityContext, container &amp;#34;nginx&amp;#34; must set ReadOnlyRootFilesystem to true in its SecurityContext, container &amp;#34;nginx&amp;#34; must NOT set AllowPrivilegeEscalation to true in its SecurityContext, container &amp;#34;nginx&amp;#34; must NOT set Privileged to true in its SecurityContext]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Looks great! The policy and the webhook give equivalent results.
After a few other cases, when we are confident with our policy, maybe it is time to do some cleanup.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;For every expression, we repeat access to &lt;code&gt;object.spec.template.spec.containers&lt;/code&gt; and to each &lt;code&gt;securityContext&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;There is a pattern of checking presence of a field and then accessing it, which looks a bit verbose.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Fortunately, since Kubernetes 1.28, we have new solutions for both issues.
Variable Composition allows us to extract repeated sub-expressions into their own variables.
Kubernetes enables &lt;a href=&#34;https://github.com/google/cel-spec/wiki/proposal-246&#34;&gt;the optional library&lt;/a&gt; for CEL, which are excellent to work with fields that are, you guessed it, optional.&lt;/p&gt;
&lt;p&gt;With both features in mind, let&#39;s refactor the policy a bit.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;admissionregistration.k8s.io/v1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;ValidatingAdmissionPolicy&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;pod-security.policy.example.com&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;spec&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;failurePolicy&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Fail&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;matchConstraints&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;resourceRules&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;apiGroups&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;   &lt;/span&gt;[&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;apps&amp;#34;&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;apiVersions&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;[&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;v1&amp;#34;&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;operations&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;[&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;CREATE&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;UPDATE&amp;#34;&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;resources&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;   &lt;/span&gt;[&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;deployments&amp;#34;&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;variables&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;containers&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;expression&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;object.spec.template.spec.containers&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;securityContexts&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;expression&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;variables.containers.map(c, c.?securityContext)&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;validations&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;expression&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;variables.securityContexts.all(c, c.?runAsNonRoot == optional.of(true))&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;message&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;all containers must set runAsNonRoot to true&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;expression&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;variables.securityContexts.all(c, c.?readOnlyRootFilesystem == optional.of(true))&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;message&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;all containers must set readOnlyRootFilesystem to true&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;expression&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;variables.securityContexts.all(c, c.?allowPrivilegeEscalation != optional.of(true))&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;message&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;all containers must NOT set allowPrivilegeEscalation to true&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;expression&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;variables.securityContexts.all(c, c.?privileged != optional.of(true))&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;message&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;all containers must NOT set privileged to true&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The policy is now much cleaner and more readable. Update the policy, and you should see
it function the same as before.&lt;/p&gt;
&lt;p&gt;Now let&#39;s change the policy binding from warning to actually denying requests that fail validation.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;admissionregistration.k8s.io/v1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;ValidatingAdmissionPolicyBinding&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;pod-security.policy-binding.example.com&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;spec&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;policyName&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;pod-security.policy.example.com&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;validationActions&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;[&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;Deny&amp;#34;&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;matchResources&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;namespaceSelector&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;matchLabels&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;&amp;#34;kubernetes.io/metadata.name&amp;#34;: &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;policy-test&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And finally, remove the webhook. Now the result should include only messages from
the policy.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kubectl create -n policy-test -f- &lt;span style=&#34;color:#b44&#34;&gt;&amp;lt;&amp;lt;EOF
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;apiVersion: apps/v1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;kind: Deployment
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;metadata:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;  labels:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;    app: nginx
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;  name: nginx
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;spec:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;  selector:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;    matchLabels:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;      app: nginx
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;  template:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;    metadata:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;      labels:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;        app: nginx
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;    spec:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;      containers:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;      - image: nginx
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;        name: nginx
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;        securityContext:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;          privileged: true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;          allowPrivilegeEscalation: true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;EOF&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;The deployments &amp;#34;nginx&amp;#34; is invalid: : ValidatingAdmissionPolicy &amp;#39;pod-security.policy.example.com&amp;#39; with binding &amp;#39;pod-security.policy-binding.example.com&amp;#39; denied request: all containers must set runAsNonRoot to true
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Please notice that, by design, the policy will stop evaluation after the first expression that causes the request to be denied.
This is different from what happens when the expressions generate only warnings.&lt;/p&gt;
&lt;h2 id=&#34;set-up-monitoring&#34;&gt;Set up monitoring&lt;/h2&gt;
&lt;p&gt;Unlike a webhook, a policy is not a dedicated process that can expose its own metrics.
Instead, you can use metrics from the API server in their place.&lt;/p&gt;
&lt;p&gt;Here are some examples in Prometheus Query Language of common monitoring tasks.&lt;/p&gt;
&lt;p&gt;To find the 95th percentile execution duration of the policy shown above.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;histogram_quantile(0.95, sum(rate(apiserver_validating_admission_policy_check_duration_seconds_bucket{policy=&amp;#34;pod-security.policy.example.com&amp;#34;}[5m])) by (le)) 
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To find the rate of the policy evaluation.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;rate(apiserver_validating_admission_policy_check_total{policy=&amp;#34;pod-security.policy.example.com&amp;#34;}[5m])
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You can read &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/reference/instrumentation/metrics/&#34;&gt;the metrics reference&lt;/a&gt; to learn more about the metrics above.
The metrics of ValidatingAdmissionPolicy are currently in alpha,
and more and better metrics will come while the stability graduates in the future release.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes 1.30: Read-only volume mounts can be finally literally read-only</title>
      <link>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/04/23/recursive-read-only-mounts/</link>
      <pubDate>Tue, 23 Apr 2024 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/04/23/recursive-read-only-mounts/</guid>
      <description>
        
        
        &lt;p&gt;Read-only volume mounts have been a feature of Kubernetes since the beginning.
Surprisingly, read-only mounts are not completely read-only under certain conditions on Linux.
As of the v1.30 release, they can be made completely read-only,
with alpha support for &lt;em&gt;recursive read-only mounts&lt;/em&gt;.&lt;/p&gt;
&lt;h2 id=&#34;read-only-volume-mounts-are-not-really-read-only-by-default&#34;&gt;Read-only volume mounts are not really read-only by default&lt;/h2&gt;
&lt;p&gt;Volume mounts can be deceptively complicated.&lt;/p&gt;
&lt;p&gt;You might expect that the following manifest makes everything under &lt;code&gt;/mnt&lt;/code&gt; in the containers read-only:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f;font-weight:bold&#34;&gt;---&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;v1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Pod&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;spec&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;volumes&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;mnt&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;hostPath&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;path&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;/mnt&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;containers&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;volumeMounts&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;mnt&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;mountPath&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;/mnt&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;readOnly&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;true&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;However, any sub-mounts beneath &lt;code&gt;/mnt&lt;/code&gt; may still be writable!
For example, consider that &lt;code&gt;/mnt/my-nfs-server&lt;/code&gt; is writeable on the host.
Inside the container, writes to &lt;code&gt;/mnt/*&lt;/code&gt; will be rejected but &lt;code&gt;/mnt/my-nfs-server/*&lt;/code&gt; will still be writeable.&lt;/p&gt;
&lt;h2 id=&#34;new-mount-option-recursivereadonly&#34;&gt;New mount option: recursiveReadOnly&lt;/h2&gt;
&lt;p&gt;Kubernetes 1.30 added a new mount option &lt;code&gt;recursiveReadOnly&lt;/code&gt; so as to make submounts recursively read-only.&lt;/p&gt;
&lt;p&gt;The option can be enabled as follows:
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;display:grid;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f;font-weight:bold&#34;&gt;---&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;v1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Pod&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;spec&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;volumes&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;mnt&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;hostPath&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;path&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;/mnt&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;containers&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;volumeMounts&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;mnt&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;mountPath&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;/mnt&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;readOnly&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;true&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex; background-color:#dfdfdf&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# NEW&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex; background-color:#dfdfdf&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Possible values are `Enabled`, `IfPossible`, and `Disabled`.&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex; background-color:#dfdfdf&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Needs to be specified in conjunction with `readOnly: true`.&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex; background-color:#dfdfdf&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;recursiveReadOnly&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Enabled&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;This is implemented by applying the &lt;code&gt;MOUNT_ATTR_RDONLY&lt;/code&gt; attribute with the &lt;code&gt;AT_RECURSIVE&lt;/code&gt; flag
using &lt;a href=&#34;https://man7.org/linux/man-pages/man2/mount_setattr.2.html&#34;&gt;&lt;code&gt;mount_setattr(2)&lt;/code&gt;&lt;/a&gt; added in
Linux kernel v5.12.&lt;/p&gt;
&lt;p&gt;For backwards compatibility, the &lt;code&gt;recursiveReadOnly&lt;/code&gt; field is not a replacement for &lt;code&gt;readOnly&lt;/code&gt;,
but is used &lt;em&gt;in conjunction&lt;/em&gt; with it.
To get a properly recursive read-only mount, you must set both fields.&lt;/p&gt;
&lt;h2 id=&#34;availability&#34;&gt;Feature availability&lt;/h2&gt;
&lt;p&gt;To enable &lt;code&gt;recursiveReadOnly&lt;/code&gt; mounts, the following components have to be used:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Kubernetes: v1.30 or later, with the &lt;code&gt;RecursiveReadOnlyMounts&lt;/code&gt;
&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/reference/command-line-tools-reference/feature-gates/&#34;&gt;feature gate&lt;/a&gt; enabled.
As of v1.30, the gate is marked as alpha.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;CRI runtime:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;containerd: v2.0 or later&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;OCI runtime:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;runc: v1.1 or later&lt;/li&gt;
&lt;li&gt;crun: v1.8.6 or later&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Linux kernel: v5.12 or later&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;what-s-next&#34;&gt;What&#39;s next?&lt;/h2&gt;
&lt;p&gt;Kubernetes SIG Node hope - and expect - that the feature will be promoted to beta and eventually
general availability (GA) in future releases of Kubernetes, so that users no longer need to enable
the feature gate manually.&lt;/p&gt;
&lt;p&gt;The default value of &lt;code&gt;recursiveReadOnly&lt;/code&gt; will still remain &lt;code&gt;Disabled&lt;/code&gt;, for backwards compatibility.&lt;/p&gt;
&lt;h2 id=&#34;how-can-i-learn-more&#34;&gt;How can I learn more?&lt;/h2&gt;
&lt;!-- https://github.com/kubernetes/website/pull/45159 --&gt;
&lt;p&gt;Please check out the &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/storage/volumes/#read-only-mounts&#34;&gt;documentation&lt;/a&gt;
for the further details of &lt;code&gt;recursiveReadOnly&lt;/code&gt; mounts.&lt;/p&gt;
&lt;h2 id=&#34;how-to-get-involved&#34;&gt;How to get involved?&lt;/h2&gt;
&lt;p&gt;This feature is driven by the SIG Node community. Please join us to connect with
the community and share your ideas and feedback around the above feature and
beyond. We look forward to hearing from you!&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes 1.30: Beta Support For Pods With User Namespaces</title>
      <link>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/04/22/userns-beta/</link>
      <pubDate>Mon, 22 Apr 2024 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/04/22/userns-beta/</guid>
      <description>
        
        
        &lt;p&gt;Linux provides different namespaces to isolate processes from each other. For
example, a typical Kubernetes pod runs within a network namespace to isolate the
network identity and a PID namespace to isolate the processes.&lt;/p&gt;
&lt;p&gt;One Linux namespace that was left behind is the &lt;a href=&#34;https://man7.org/linux/man-pages/man7/user_namespaces.7.html&#34;&gt;user
namespace&lt;/a&gt;. This
namespace allows us to isolate the user and group identifiers (UIDs and GIDs) we
use inside the container from the ones on the host.&lt;/p&gt;
&lt;p&gt;This is a powerful abstraction that allows us to run containers as &amp;quot;root&amp;quot;: we
are root inside the container and can do everything root can inside the pod,
but our interactions with the host are limited to what a non-privileged user can
do. This is great for limiting the impact of a container breakout.&lt;/p&gt;
&lt;p&gt;A container breakout is when a process inside a container can break out
onto the host using some unpatched vulnerability in the container runtime or the
kernel and can access/modify files on the host or other containers. If we
run our pods with user namespaces, the privileges the container has over the
rest of the host are reduced, and the files outside the container it can access
are limited too.&lt;/p&gt;
&lt;p&gt;In Kubernetes v1.25, we introduced support for user namespaces only for stateless
pods. Kubernetes 1.28 lifted that restriction, and now, with Kubernetes 1.30, we
are moving to beta!&lt;/p&gt;
&lt;h2 id=&#34;what-is-a-user-namespace&#34;&gt;What is a user namespace?&lt;/h2&gt;
&lt;p&gt;Note: Linux user namespaces are a different concept from &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/overview/working-with-objects/namespaces/&#34;&gt;Kubernetes
namespaces&lt;/a&gt;.
The former is a Linux kernel feature; the latter is a Kubernetes feature.&lt;/p&gt;
&lt;p&gt;User namespaces are a Linux feature that isolates the UIDs and GIDs of the
containers from the ones on the host. The identifiers in the container can be
mapped to identifiers on the host in a way where the host UID/GIDs used for
different containers never overlap. Furthermore, the identifiers can be mapped
to unprivileged, non-overlapping UIDs and GIDs on the host. This brings two key
benefits:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Prevention of lateral movement&lt;/em&gt;: As the UIDs and GIDs for different
containers are mapped to different UIDs and GIDs on the host, containers have a
harder time attacking each other, even if they escape the container boundaries.
For example, suppose container A runs with different UIDs and GIDs on the host
than container B. In that case, the operations it can do on container B&#39;s files and processes
are limited: only read/write what a file allows to others, as it will never
have permission owner or group permission (the UIDs/GIDs on the host are
guaranteed to be different for different containers).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Increased host isolation&lt;/em&gt;: As the UIDs and GIDs are mapped to unprivileged
users on the host, if a container escapes the container boundaries, even if it
runs as root inside the container, it has no privileges on the host. This
greatly protects what host files it can read/write, which process it can send
signals to, etc. Furthermore, capabilities granted are only valid inside the
user namespace and not on the host, limiting the impact a container
escape can have.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;figure class=&#34;diagram-medium &#34;&gt;
    &lt;img src=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/images/blog/2024-04-22-userns-beta/image.svg&#34;
         alt=&#34;Image showing IDs 0-65535 are reserved to the host, pods use higher IDs&#34;/&gt; &lt;figcaption&gt;
            &lt;h4&gt;User namespace IDs allocation&lt;/h4&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Without using a user namespace, a container running as root in the case of a
container breakout has root privileges on the node. If some capabilities
were granted to the container, the capabilities are valid on the host too. None
of this is true when using user namespaces (modulo bugs, of course 🙂).&lt;/p&gt;
&lt;h2 id=&#34;changes-in-1-30&#34;&gt;Changes in 1.30&lt;/h2&gt;
&lt;p&gt;In Kubernetes 1.30, besides moving user namespaces to beta, the contributors
working on this feature:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Introduced a way for the kubelet to use custom ranges for the UIDs/GIDs mapping&lt;/li&gt;
&lt;li&gt;Have added a way for Kubernetes to enforce that the runtime supports all the features
needed for user namespaces. If they are not supported, Kubernetes will show a
clear error when trying to create a pod with user namespaces. Before 1.30, if
the container runtime didn&#39;t support user namespaces, the pod could be created
without a user namespace.&lt;/li&gt;
&lt;li&gt;Added more tests, including &lt;a href=&#34;https://github.com/kubernetes-sigs/cri-tools/pull/1354&#34;&gt;tests in the
cri-tools&lt;/a&gt;
repository.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can check the
&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/workloads/pods/user-namespaces/#set-up-a-node-to-support-user-namespaces&#34;&gt;documentation&lt;/a&gt;
on user namespaces for how to configure custom ranges for the mapping.&lt;/p&gt;
&lt;h2 id=&#34;demo&#34;&gt;Demo&lt;/h2&gt;
&lt;p&gt;A few months ago, &lt;a href=&#34;https://github.com/opencontainers/runc/security/advisories/GHSA-xr7r-f8xq-vfvv&#34;&gt;CVE-2024-21626&lt;/a&gt; was disclosed. This &lt;strong&gt;vulnerability
score is 8.6 (HIGH)&lt;/strong&gt;. It allows an attacker to escape a container and
&lt;strong&gt;read/write to any path on the node and other pods hosted on the same node&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Rodrigo created a demo that exploits &lt;a href=&#34;https://github.com/opencontainers/runc/security/advisories/GHSA-xr7r-f8xq-vfvv&#34;&gt;CVE 2024-21626&lt;/a&gt; and shows how
the exploit, which works without user namespaces, &lt;strong&gt;is mitigated when user
namespaces are in use.&lt;/strong&gt;&lt;/p&gt;


    
    &lt;div class=&#34;youtube-quote-sm&#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/07y5bl5UDdA?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0&#34; title=&#34;Mitigation of CVE-2024-21626 on Kubernetes by enabling User Namespace support&#34;
      &gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;p&gt;Please note that with user namespaces, an attacker can do on the host file system
what the permission bits for &amp;quot;others&amp;quot; allow. Therefore, the CVE is not
completely prevented, but the impact is greatly reduced.&lt;/p&gt;
&lt;h2 id=&#34;node-system-requirements&#34;&gt;Node system requirements&lt;/h2&gt;
&lt;p&gt;There are requirements on the Linux kernel version and the container
runtime to use this feature.&lt;/p&gt;
&lt;p&gt;On Linux you need Linux 6.3 or greater. This is because the feature relies on a
kernel feature named idmap mounts, and support for using idmap mounts with tmpfs
was merged in Linux 6.3.&lt;/p&gt;
&lt;p&gt;Suppose you are using &lt;a href=&#34;https://cri-o.io/&#34;&gt;CRI-O&lt;/a&gt; with crun; as always, you can expect support for
Kubernetes 1.30 with CRI-O 1.30. Please note you also need &lt;a href=&#34;https://github.com/containers/crun&#34;&gt;crun&lt;/a&gt; 1.9 or
greater. If you are using CRI-O with &lt;a href=&#34;https://github.com/opencontainers/runc/&#34;&gt;runc&lt;/a&gt;, this is still not supported.&lt;/p&gt;
&lt;p&gt;Containerd support is currently targeted for &lt;a href=&#34;https://containerd.io/&#34;&gt;containerd&lt;/a&gt; 2.0, and
the same crun version requirements apply. If you are using containerd with runc,
this is still not supported.&lt;/p&gt;
&lt;p&gt;Please note that containerd 1.7 added &lt;em&gt;experimental&lt;/em&gt; support for user
namespaces, as implemented in Kubernetes 1.25 and 1.26. We did a redesign in
Kubernetes 1.27, which requires changes in the container runtime. Those changes
are not present in containerd 1.7, so it only works with user namespaces
support in Kubernetes 1.25 and 1.26.&lt;/p&gt;
&lt;p&gt;Another limitation of containerd 1.7 is that it needs to change the
ownership of every file and directory inside the container image during Pod
startup. This has a storage overhead and can significantly impact the
container startup latency. Containerd 2.0 will probably include an implementation
that will eliminate the added startup latency and storage overhead. Consider
this if you plan to use containerd 1.7 with user namespaces in
production.&lt;/p&gt;
&lt;p&gt;None of these containerd 1.7 limitations apply to CRI-O.&lt;/p&gt;
&lt;h2 id=&#34;how-do-i-get-involved&#34;&gt;How do I get involved?&lt;/h2&gt;
&lt;p&gt;You can reach SIG Node by several means:&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;
&lt;p&gt;You can also contact us directly:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GitHub: @rata @giuseppe @saschagrunert&lt;/li&gt;
&lt;li&gt;Slack: @rata @giuseppe @sascha&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes v1.30: Uwubernetes</title>
      <link>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/04/17/kubernetes-v1-30-release/</link>
      <pubDate>Wed, 17 Apr 2024 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/04/17/kubernetes-v1-30-release/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Editors:&lt;/strong&gt; Amit Dsouza, Frederick Kautz, Kristin Martin, Abigail McCarthy, Natali Vlatko&lt;/p&gt;
&lt;p&gt;Announcing the release of Kubernetes v1.30: Uwubernetes, the cutest release!&lt;/p&gt;
&lt;p&gt;Similar to previous releases, the release of Kubernetes v1.30 introduces new stable, beta, and alpha
features. The consistent delivery of top-notch 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 45 enhancements. Of those enhancements, 17 have graduated to Stable, 18 are
entering Beta, and 10 have graduated to Alpha.&lt;/p&gt;
&lt;h2 id=&#34;release-theme-and-logo&#34;&gt;Release theme and logo&lt;/h2&gt;
&lt;p&gt;Kubernetes v1.30: &lt;em&gt;Uwubernetes&lt;/em&gt;&lt;/p&gt;


&lt;figure class=&#34;release-logo &#34;&gt;
    &lt;img src=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/images/blog/2024-04-17-kubernetes-1.30-release/k8s-1.30.png&#34;
         alt=&#34;Kubernetes v1.30 Uwubernetes logo&#34;/&gt; 
&lt;/figure&gt;
&lt;p&gt;Kubernetes v1.30 makes your clusters cuter!&lt;/p&gt;
&lt;p&gt;Kubernetes is built and released by thousands of people from all over the world and all walks of
life. Most contributors are not being paid to do this; we build it for fun, to solve a problem, to
learn something, or for the simple love of the community. Many of us found our homes, our friends,
and our careers here. The Release Team is honored to be a part of the continued growth of
Kubernetes.&lt;/p&gt;
&lt;p&gt;For the people who built it, for the people who release it, and for the furries who keep all of our
clusters online, we present to you Kubernetes v1.30: Uwubernetes, the cutest release to date. The
name is a portmanteau of “kubernetes” and “UwU,” an emoticon used to indicate happiness or cuteness.
We’ve found joy here, but we’ve also brought joy from our outside lives that helps to make this
community as weird and wonderful and welcoming as it is. We’re so happy to share our work with you.&lt;/p&gt;
&lt;p&gt;UwU ♥️&lt;/p&gt;
&lt;h2 id=&#34;graduations-to-stable&#34;&gt;Improvements that graduated to stable in Kubernetes v1.30&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.30 release.&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&#34;robust-volumemanager-reconstruction-after-kubelet-restart-sig-storage-https-github-com-kubernetes-community-tree-master-sig-storage&#34;&gt;Robust VolumeManager reconstruction after kubelet restart (&lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-storage&#34;&gt;SIG Storage&lt;/a&gt;)&lt;/h3&gt;
&lt;p&gt;This is a volume manager refactoring that allows the kubelet to populate additional information
about how existing volumes are mounted during the kubelet startup. In general, this makes volume
cleanup after kubelet restart or machine reboot more robust.&lt;/p&gt;
&lt;p&gt;This does not bring any changes for user or cluster administrators. We used the feature process and
feature gate &lt;code&gt;NewVolumeManagerReconstruction&lt;/code&gt; to be able to fall back to the previous behavior in
case something goes wrong. Now that the feature is stable, the feature gate is locked and cannot be
disabled.&lt;/p&gt;
&lt;h3 id=&#34;prevent-unauthorized-volume-mode-conversion-during-volume-restore-sig-storage-https-github-com-kubernetes-community-tree-master-sig-storage&#34;&gt;Prevent unauthorized volume mode conversion during volume restore (&lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-storage&#34;&gt;SIG Storage&lt;/a&gt;)&lt;/h3&gt;
&lt;p&gt;For Kubernetes v1.30, the control plane always prevents unauthorized changes to volume modes when
restoring a snapshot into a PersistentVolume. As a cluster administrator, you&#39;ll need to grant
permissions to the appropriate identity principals (for example: ServiceAccounts representing a
storage integration) if you need to allow that kind of change at restore time.&lt;/p&gt;
&lt;div class=&#34;alert alert-danger&#34; role=&#34;alert&#34;&gt;&lt;h4 class=&#34;alert-heading&#34;&gt;Warning:&lt;/h4&gt;Action required before upgrading. The &lt;code&gt;prevent-volume-mode-conversion&lt;/code&gt; feature flag is enabled by
default in the external-provisioner &lt;code&gt;v4.0.0&lt;/code&gt; and external-snapshotter &lt;code&gt;v7.0.0&lt;/code&gt;. Volume mode change
will be rejected when creating a PVC from a VolumeSnapshot unless you perform the steps described in
the &amp;quot;Urgent Upgrade Notes&amp;quot; sections for the &lt;a href=&#34;https://github.com/kubernetes-csi/external-provisioner/releases/tag/v4.0.0&#34;&gt;external-provisioner
4.0.0&lt;/a&gt; and the
&lt;a href=&#34;https://github.com/kubernetes-csi/external-snapshotter/releases/tag/v7.0.0&#34;&gt;external-snapshotter
v7.0.0&lt;/a&gt;.&lt;/div&gt;

&lt;p&gt;For more information on this feature also read &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/storage/volume-snapshots/#convert-volume-mode&#34;&gt;converting the volume mode of a
Snapshot&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;pod-scheduling-readiness-sig-scheduling-https-github-com-kubernetes-community-tree-master-sig-scheduling&#34;&gt;Pod Scheduling Readiness (&lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-scheduling&#34;&gt;SIG Scheduling&lt;/a&gt;)&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Pod scheduling readiness&lt;/em&gt; graduates to stable this release, after being promoted to beta in
Kubernetes v1.27.&lt;/p&gt;
&lt;p&gt;This now-stable feature lets Kubernetes avoid trying to schedule a Pod that has been defined, when
the cluster doesn&#39;t yet have the resources provisioned to allow actually binding that Pod to a node.
That&#39;s not the only use case; the custom control on whether a Pod can be allowed to schedule also
lets you implement quota mechanisms, security controls, and more.&lt;/p&gt;
&lt;p&gt;Crucially, marking these Pods as exempt from scheduling cuts the work that the scheduler would
otherwise do, churning through Pods that can&#39;t or won&#39;t schedule onto the nodes your cluster
currently has. If you have &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/cluster-administration/cluster-autoscaling/&#34;&gt;cluster
autoscaling&lt;/a&gt; active, using scheduling
gates doesn&#39;t just cut the load on the scheduler, it can also save money. Without scheduling gates,
the autoscaler might otherwise launch a node that doesn&#39;t need to be started.&lt;/p&gt;
&lt;p&gt;In Kubernetes v1.30, by specifying (or removing) a Pod&#39;s &lt;code&gt;.spec.schedulingGates&lt;/code&gt;, you can control
when a Pod is ready to be considered for scheduling. This is a stable feature and is now formally
part of the Kubernetes API definition for Pod.&lt;/p&gt;
&lt;h3 id=&#34;min-domains-in-podtopologyspread-sig-scheduling-https-github-com-kubernetes-community-tree-master-sig-scheduling&#34;&gt;Min domains in PodTopologySpread (&lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-scheduling&#34;&gt;SIG Scheduling&lt;/a&gt;)&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;minDomains&lt;/code&gt; parameter for PodTopologySpread constraints graduates to stable this release, which
allows you to define the minimum number of domains. This feature is designed to be used with Cluster
Autoscaler.&lt;/p&gt;
&lt;p&gt;If you previously attempted use and there weren&#39;t enough domains already present, Pods would be
marked as unschedulable. The Cluster Autoscaler would then provision node(s) in new domain(s), and
you&#39;d eventually get Pods spreading over enough domains.&lt;/p&gt;
&lt;h3 id=&#34;go-workspaces-for-k-k-sig-architecture-https-github-com-kubernetes-community-tree-master-sig-architecture&#34;&gt;Go workspaces for k/k (&lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-architecture&#34;&gt;SIG Architecture&lt;/a&gt;)&lt;/h3&gt;
&lt;p&gt;The Kubernetes repo now uses Go workspaces. This should not impact end users at all, but does have a
impact for developers of downstream projects. Switching to workspaces caused some breaking changes
in the flags to the various &lt;a href=&#34;https://github.com/kubernetes/code-generator&#34;&gt;k8s.io/code-generator&lt;/a&gt;
tools. Downstream consumers should look at
&lt;a href=&#34;https://github.com/kubernetes/code-generator/blob/master/kube_codegen.sh&#34;&gt;&lt;code&gt;staging/src/k8s.io/code-generator/kube_codegen.sh&lt;/code&gt;&lt;/a&gt;
to see the changes.&lt;/p&gt;
&lt;p&gt;For full details on the changes and reasons why Go workspaces was introduced, read &lt;a href=&#34;https://www.kubernetes.dev/blog/2024/03/19/go-workspaces-in-kubernetes/&#34;&gt;Using Go
workspaces in Kubernetes&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;graduations-to-beta&#34;&gt;Improvements that graduated to beta in Kubernetes v1.30&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.30 release.&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&#34;node-log-query-sig-windows-https-github-com-kubernetes-community-tree-master-sig-windows&#34;&gt;Node log query (&lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-windows&#34;&gt;SIG Windows&lt;/a&gt;)&lt;/h3&gt;
&lt;p&gt;To help with debugging issues on nodes, Kubernetes v1.27 introduced a feature that allows fetching
logs of services running on the node. To use the feature, ensure that the &lt;code&gt;NodeLogQuery&lt;/code&gt; feature
gate is enabled for that node, and that the kubelet configuration options &lt;code&gt;enableSystemLogHandler&lt;/code&gt;
and &lt;code&gt;enableSystemLogQuery&lt;/code&gt; are both set to true.&lt;/p&gt;
&lt;p&gt;Following the v1.30 release, this is now beta (you still need to enable the feature to use it,
though).&lt;/p&gt;
&lt;p&gt;On Linux the assumption is that service logs are available via journald. On Windows the assumption
is that service logs are available in the application log provider. Logs are also available by
reading files within &lt;code&gt;/var/log/&lt;/code&gt; (Linux) or &lt;code&gt;C:\var\log\&lt;/code&gt; (Windows). For more information, see the
&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/cluster-administration/system-logs/#log-query&#34;&gt;log query&lt;/a&gt; documentation.&lt;/p&gt;
&lt;h3 id=&#34;crd-validation-ratcheting-sig-api-machinery-https-github-com-kubernetes-community-tree-master-sig-api-machinery&#34;&gt;CRD validation ratcheting (&lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-api-machinery&#34;&gt;SIG API Machinery&lt;/a&gt;)&lt;/h3&gt;
&lt;p&gt;You need to enable the &lt;code&gt;CRDValidationRatcheting&lt;/code&gt; &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/reference/command-line-tools-reference/feature-gates/&#34;&gt;feature
gate&lt;/a&gt; to use this behavior, which then
applies to all CustomResourceDefinitions in your cluster.&lt;/p&gt;
&lt;p&gt;Provided you enabled the feature gate, Kubernetes implements &lt;em&gt;validation ratcheting&lt;/em&gt; for
CustomResourceDefinitions. The API server is willing to accept updates to resources that are not valid
after the update, provided that each part of the resource that failed to validate was not changed by
the update operation. In other words, any invalid part of the resource that remains invalid must
have already been wrong. You cannot use this mechanism to update a valid resource so that it becomes
invalid.&lt;/p&gt;
&lt;p&gt;This feature allows authors of CRDs to confidently add new validations to the OpenAPIV3 schema under
certain conditions. Users can update to the new schema safely without bumping the version of the
object or breaking workflows.&lt;/p&gt;
&lt;h3 id=&#34;contextual-logging-sig-instrumentation-https-github-com-kubernetes-community-tree-master-sig-instrumentation&#34;&gt;Contextual logging (&lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-instrumentation&#34;&gt;SIG Instrumentation&lt;/a&gt;)&lt;/h3&gt;
&lt;p&gt;Contextual Logging advances to beta in this release, empowering developers and operators to inject
customizable, correlatable contextual details like service names and transaction IDs into logs
through &lt;code&gt;WithValues&lt;/code&gt; and &lt;code&gt;WithName&lt;/code&gt;. This enhancement simplifies the correlation and analysis of log
data across distributed systems, significantly improving the efficiency of troubleshooting efforts.
By offering a clearer insight into the workings of your Kubernetes environments, Contextual Logging
ensures that operational challenges are more manageable, marking a notable step forward in
Kubernetes observability.&lt;/p&gt;
&lt;h3 id=&#34;make-kubernetes-aware-of-the-loadbalancer-behaviour-sig-network-https-github-com-kubernetes-community-tree-master-sig-network&#34;&gt;Make Kubernetes aware of the LoadBalancer behaviour (&lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-network&#34;&gt;SIG Network&lt;/a&gt;)&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;LoadBalancerIPMode&lt;/code&gt; feature gate is now beta and is now enabled by default. This feature allows
you to set the &lt;code&gt;.status.loadBalancer.ingress.ipMode&lt;/code&gt; for a Service with &lt;code&gt;type&lt;/code&gt; set to
&lt;code&gt;LoadBalancer&lt;/code&gt;. The &lt;code&gt;.status.loadBalancer.ingress.ipMode&lt;/code&gt; specifies how the load-balancer IP
behaves. It may be specified only when the &lt;code&gt;.status.loadBalancer.ingress.ip&lt;/code&gt; field is also
specified. See more details about &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/services-networking/service/#load-balancer-ip-mode&#34;&gt;specifying IPMode of load balancer
status&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;structured-authentication-configuration-sig-auth-https-github-com-kubernetes-community-tree-master-sig-auth&#34;&gt;Structured Authentication Configuration (&lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-auth&#34;&gt;SIG Auth&lt;/a&gt;)&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Structured Authentication Configuration&lt;/em&gt; graduates to beta in this release.&lt;/p&gt;
&lt;p&gt;Kubernetes has had a long-standing need for a more flexible and extensible
authentication system. The current system, while powerful, has some limitations
that make it difficult to use in certain scenarios. For example, it is not
possible to use multiple authenticators of the same type (e.g., multiple JWT
authenticators) or to change the configuration without restarting the API server. The
Structured Authentication Configuration feature is the first step towards
addressing these limitations and providing a more flexible and extensible way
to configure authentication in Kubernetes. See more details about &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/reference/access-authn-authz/authentication/#using-authentication-configuration&#34;&gt;structured
authentication configuration&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;structured-authorization-configuration-sig-auth-https-github-com-kubernetes-community-tree-master-sig-auth&#34;&gt;Structured Authorization Configuration (&lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-auth&#34;&gt;SIG Auth&lt;/a&gt;)&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Structured Authorization Configuration&lt;/em&gt; graduates to beta in this release.&lt;/p&gt;
&lt;p&gt;Kubernetes continues to evolve to meet the intricate requirements of system
administrators and developers alike. A critical aspect of Kubernetes that
ensures the security and integrity of the cluster is the API server
authorization. Until recently, the configuration of the authorization chain in
kube-apiserver was somewhat rigid, limited to a set of command-line flags and
allowing only a single webhook in the authorization chain. This approach, while
functional, restricted the flexibility needed by cluster administrators to
define complex, fine-grained authorization policies. The latest Structured
Authorization Configuration feature aims to revolutionize this aspect by introducing
a more structured and versatile way to configure the authorization chain, focusing
on enabling multiple webhooks and providing explicit control mechanisms. See more
details about &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/reference/access-authn-authz/authorization/#configuring-the-api-server-using-an-authorization-config-file&#34;&gt;structured authorization configuration&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;new-alpha-features&#34;&gt;New alpha features&lt;/h2&gt;
&lt;h3 id=&#34;speed-up-recursive-selinux-label-change-sig-storage-https-github-com-kubernetes-community-tree-master-sig-storage&#34;&gt;Speed up recursive SELinux label change (&lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-storage&#34;&gt;SIG Storage&lt;/a&gt;)&lt;/h3&gt;
&lt;p&gt;From the v1.27 release, Kubernetes already included an optimization that sets SELinux labels on the
contents of volumes, using only constant time. Kubernetes achieves that speed up using a mount
option. The slower legacy behavior requires the container runtime to recursively walk through the
whole volumes and apply SELinux labelling individually to each file and directory; this is
especially noticable for volumes with large amount of files and directories.&lt;/p&gt;
&lt;p&gt;Kubernetes v1.27 graduated this feature as beta, but limited it to ReadWriteOncePod volumes. The
corresponding feature gate is &lt;code&gt;SELinuxMountReadWriteOncePod&lt;/code&gt;. It&#39;s still enabled by default and
remains beta in v1.30.&lt;/p&gt;
&lt;p&gt;Kubernetes v1.30 extends support for SELinux mount option to &lt;strong&gt;all&lt;/strong&gt; volumes as alpha, with a
separate feature gate: &lt;code&gt;SELinuxMount&lt;/code&gt;. This feature gate introduces a behavioral change when
multiple Pods with different SELinux labels share the same volume. See
&lt;a href=&#34;https://github.com/kubernetes/enhancements/tree/master/keps/sig-storage/1710-selinux-relabeling#behavioral-changes&#34;&gt;KEP&lt;/a&gt;
for details.&lt;/p&gt;
&lt;p&gt;We strongly encourage users that run Kubernetes with SELinux enabled to test this feature and
provide any feedback on the &lt;a href=&#34;https://kep.k8s.io/1710&#34;&gt;KEP issue&lt;/a&gt;.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature gate&lt;/th&gt;
&lt;th&gt;Stage in v1.30&lt;/th&gt;
&lt;th&gt;Behavior change&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SELinuxMountReadWriteOncePod&lt;/td&gt;
&lt;td&gt;Beta&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SELinuxMount&lt;/td&gt;
&lt;td&gt;Alpha&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Both feature gates &lt;code&gt;SELinuxMountReadWriteOncePod&lt;/code&gt; and &lt;code&gt;SELinuxMount&lt;/code&gt; must be enabled to test this
feature on all volumes.&lt;/p&gt;
&lt;p&gt;This feature has no effect on Windows nodes or on Linux nodes without SELinux support.&lt;/p&gt;
&lt;h3 id=&#34;recursive-read-only-rro-mounts-sig-node-https-github-com-kubernetes-community-tree-master-sig-node&#34;&gt;Recursive Read-only (RRO) mounts (&lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-node&#34;&gt;SIG Node&lt;/a&gt;)&lt;/h3&gt;
&lt;p&gt;Introducing Recursive Read-Only (RRO) Mounts in alpha this release, you&#39;ll find a new layer of
security for your data. This feature lets you set volumes and their submounts as read-only,
preventing accidental modifications. Imagine deploying a critical application where data integrity
is key—RRO Mounts ensure that your data stays untouched, reinforcing your cluster&#39;s security with an
extra safeguard. This is especially crucial in tightly controlled environments, where even the
slightest change can have significant implications.&lt;/p&gt;
&lt;h3 id=&#34;job-success-completion-policy-sig-apps-https-github-com-kubernetes-community-tree-master-sig-apps&#34;&gt;Job success/completion policy (&lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-apps&#34;&gt;SIG Apps&lt;/a&gt;)&lt;/h3&gt;
&lt;p&gt;From Kubernetes v1.30, indexed Jobs support &lt;code&gt;.spec.successPolicy&lt;/code&gt; to define when a Job can be
declared succeeded based on succeeded Pods. This allows you to define two types of criteria:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;succeededIndexes&lt;/code&gt; indicates that the Job can be declared succeeded when these indexes succeeded,
even if other indexes failed.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;succeededCount&lt;/code&gt; indicates that the Job can be declared succeeded when the number of succeeded
Indexes reaches this criterion.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After the Job meets the success policy, the Job controller terminates the lingering Pods.&lt;/p&gt;
&lt;h3 id=&#34;traffic-distribution-for-services-sig-network-https-github-com-kubernetes-community-tree-master-sig-network&#34;&gt;Traffic distribution for services (&lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-network&#34;&gt;SIG Network&lt;/a&gt;)&lt;/h3&gt;
&lt;p&gt;Kubernetes v1.30 introduces the &lt;code&gt;spec.trafficDistribution&lt;/code&gt; field within a Kubernetes Service as
alpha. This allows you to express preferences for how traffic should be routed to Service endpoints.
While &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/reference/networking/virtual-ips/#traffic-policies&#34;&gt;traffic policies&lt;/a&gt; focus on strict
semantic guarantees, traffic distribution allows you to express &lt;em&gt;preferences&lt;/em&gt; (such as routing to
topologically closer endpoints). This can help optimize for performance, cost, or reliability. You
can use this field by enabling the &lt;code&gt;ServiceTrafficDistribution&lt;/code&gt; feature gate for your cluster and
all of its nodes. In Kubernetes v1.30, the following field value is supported:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;PreferClose&lt;/code&gt;: Indicates a preference for routing traffic to endpoints that are topologically
proximate to the client. The interpretation of &amp;quot;topologically proximate&amp;quot; may vary across
implementations and could encompass endpoints within the same node, rack, zone, or even region.
Setting this value gives implementations permission to make different tradeoffs, for example
optimizing for proximity rather than equal distribution of load. You should not set this value if
such tradeoffs are not acceptable.&lt;/p&gt;
&lt;p&gt;If the field is not set, the implementation (like kube-proxy) will apply its default routing
strategy.&lt;/p&gt;
&lt;p&gt;See &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/reference/networking/virtual-ips/#traffic-distribution&#34;&gt;Traffic Distribution&lt;/a&gt; for more
details.&lt;/p&gt;
&lt;h3 id=&#34;storage-version-migration-sig-api-machinery-https-github-com-kubernetes-community-tree-master-sig-api-machinery&#34;&gt;Storage Version Migration (&lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-api-machinery&#34;&gt;SIG API Machinery&lt;/a&gt;)&lt;/h3&gt;
&lt;p&gt;Kubernetes v1.30 introduces a new built-in API for &lt;em&gt;StorageVersionMigration&lt;/em&gt;.
Kubernetes relies on API data being actively re-written, to support some
maintenance activities related to at rest storage. Two prominent examples are
the versioned schema of stored resources (that is, the preferred storage schema
changing from v1 to v2 for a given resource) and encryption at rest (that is,
rewriting stale data based on a change in how the data should be encrypted).&lt;/p&gt;
&lt;p&gt;StorageVersionMigration is alpha API which was available &lt;a href=&#34;https://github.com/kubernetes-sigs/kube-storage-version-migrator&#34;&gt;out of tree&lt;/a&gt; before.&lt;/p&gt;
&lt;p&gt;See &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/tasks/manage-kubernetes-objects/storage-version-migration/&#34;&gt;storage version migration&lt;/a&gt; for more details.&lt;/p&gt;
&lt;h2 id=&#34;graduations-deprecations-and-removals-for-kubernetes-v1-30&#34;&gt;Graduations, deprecations and removals for Kubernetes v1.30&lt;/h2&gt;
&lt;h3 id=&#34;graduated-to-stable&#34;&gt;Graduated to stable&lt;/h3&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 &lt;a href=&#34;https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.30.md&#34;&gt;release
notes&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This release includes a total of 17 enhancements promoted to Stable:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/1610&#34;&gt;Container Resource based Pod Autoscaling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/3458&#34;&gt;Remove transient node predicates from KCCM&#39;s service controller&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/4402&#34;&gt;Go workspaces for k/k&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/2799&#34;&gt;Reduction of Secret-based Service Account Tokens&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/3488&#34;&gt;CEL for Admission Control&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/3716&#34;&gt;CEL-based admission webhook match conditions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/3521&#34;&gt;Pod Scheduling Readiness&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/3022&#34;&gt;Min domains in PodTopologySpread&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/3141&#34;&gt;Prevent unauthorised volume mode conversion during volume restore&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/647&#34;&gt;API Server Tracing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/3705&#34;&gt;Cloud Dual-Stack --node-ip Handling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/24&#34;&gt;AppArmor support&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/3756&#34;&gt;Robust VolumeManager reconstruction after kubelet restart&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/3895&#34;&gt;kubectl delete: Add interactive(-i) flag&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/2305&#34;&gt;Metric cardinality enforcement&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/2681&#34;&gt;Field &lt;code&gt;status.hostIPs&lt;/code&gt; added for Pod&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/3352&#34;&gt;Aggregated Discovery&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;deprecations-and-removals&#34;&gt;Deprecations and removals&lt;/h3&gt;
&lt;h4 id=&#34;removed-the-securitycontextdeny-admission-plugin-deprecated-since-v1-27&#34;&gt;Removed the SecurityContextDeny admission plugin, deprecated since v1.27&lt;/h4&gt;
&lt;p&gt;(&lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-auth&#34;&gt;SIG Auth&lt;/a&gt;, &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-security&#34;&gt;SIG Security&lt;/a&gt;, and &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-testing&#34;&gt;SIG Testing&lt;/a&gt;)
With the removal of the SecurityContextDeny admission plugin, the Pod Security Admission plugin,
available since v1.25, is recommended instead.&lt;/p&gt;
&lt;h2 id=&#34;release-notes&#34;&gt;Release notes&lt;/h2&gt;
&lt;p&gt;Check out the full details of the Kubernetes v1.30 release in our &lt;a href=&#34;https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.30.md&#34;&gt;release
notes&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;availability&#34;&gt;Availability&lt;/h2&gt;
&lt;p&gt;Kubernetes v1.30 is available for download on
&lt;a href=&#34;https://github.com/kubernetes/kubernetes/releases/tag/v1.30.0&#34;&gt;GitHub&lt;/a&gt;. To get started with
Kubernetes, check out these &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/tutorials/&#34;&gt;interactive 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.30 using &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/setup/independent/create-cluster-kubeadm/&#34;&gt;kubeadm&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;release-team&#34;&gt;Release team&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.30/release-team.md&#34;&gt;release team&lt;/a&gt;
for the hours spent hard at work to deliver the Kubernetes v1.30 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 our release lead, Kat Cosgrove,
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;h2 id=&#34;project-velocity&#34;&gt;Project velocity&lt;/h2&gt;
&lt;p&gt;The CNCF K8s DevStats 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;In the v1.30 release cycle, which ran for 14 weeks (January 8 to April 17), we saw contributions
from &lt;a href=&#34;https://k8s.devstats.cncf.io/d/9/companies-table?orgId=1&amp;var-period_name=v1.29.0%20-%20now&amp;var-metric=contributions&#34;&gt;863 companies&lt;/a&gt; and &lt;a href=&#34;https://k8s.devstats.cncf.io/d/66/developer-activity-counts-by-companies?orgId=1&amp;var-period_name=v1.29.0%20-%20now&amp;var-metric=contributions&amp;var-repogroup_name=Kubernetes&amp;var-repo_name=kubernetes%2Fkubernetes&amp;var-country_name=All&amp;var-companies=All&#34;&gt;1391 individuals&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;event-update&#34;&gt;Event update&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;KubeCon + CloudNativeCon China 2024 will take place in Hong Kong, from 21 – 23 August 2024! You
can find more information about the conference and registration on the &lt;a href=&#34;https://events.linuxfoundation.org/kubecon-cloudnativecon-open-source-summit-ai-dev-china/&#34;&gt;event
site&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;KubeCon + CloudNativeCon North America 2024 will take place in Salt Lake City, Utah, The United
States of America, from 12 – 15 November 2024! You can find more information about the conference
and registration on the &lt;a href=&#34;https://events.linuxfoundation.org/kubecon-cloudnativecon-north-america/&#34;&gt;eventsite&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;upcoming-release-webinar&#34;&gt;Upcoming release webinar&lt;/h2&gt;
&lt;p&gt;Join members of the Kubernetes v1.30 release team on Thursday, May 23rd, 2024, at 9 A.M. PT to learn
about the major features of this release, as well as deprecations and removals to help plan for
upgrades. For more information and registration, visit the &lt;a href=&#34;https://community.cncf.io/events/details/cncf-cncf-online-programs-presents-cncf-live-webinar-kubernetes-130-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;/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 𝕏 &lt;a href=&#34;https://twitter.com/kubernetesio&#34;&gt;@Kubernetesio&lt;/a&gt; for 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;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;
&lt;p&gt;&lt;em&gt;This blog was updated on April 19th, 2024 to highlight two additional changes not originally included in the release blog.&lt;/em&gt;&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Spotlight on SIG Architecture: Code Organization</title>
      <link>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/04/11/sig-architecture-code-spotlight-2024/</link>
      <pubDate>Thu, 11 Apr 2024 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/04/11/sig-architecture-code-spotlight-2024/</guid>
      <description>
        
        
        &lt;p&gt;&lt;em&gt;This is the third interview of a SIG Architecture Spotlight series that will cover the different
subprojects. We will cover &lt;a href=&#34;https://github.com/kubernetes/community/blob/e44c2c9d0d3023e7111d8b01ac93d54c8624ee91/sig-architecture/README.md#code-organization&#34;&gt;SIG Architecture: Code Organization&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;In this SIG Architecture spotlight I talked with &lt;a href=&#34;https://github.com/MadhavJivrajani&#34;&gt;Madhav Jivrajani&lt;/a&gt;
(VMware), a member of the Code Organization subproject.&lt;/p&gt;
&lt;h2 id=&#34;introducing-the-code-organization-subproject&#34;&gt;Introducing the Code Organization subproject&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Frederico (FSM)&lt;/strong&gt;: Hello Madhav, thank you for your availability. Could you start by telling us a
bit about yourself, your role and how you got involved in Kubernetes?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Madhav Jivrajani (MJ)&lt;/strong&gt;: Hello! My name is Madhav Jivrajani, I serve as a technical lead for SIG
Contributor Experience and a GitHub Admin for the Kubernetes project. Apart from that I also
contribute to SIG API Machinery and SIG Etcd, but more recently, I’ve been helping out with the work
that is needed to help Kubernetes &lt;a href=&#34;https://github.com/kubernetes/enhancements/tree/cf6ee34e37f00d838872d368ec66d7a0b40ee4e6/keps/sig-release/3744-stay-on-supported-go-versions&#34;&gt;stay on supported versions of
Go&lt;/a&gt;,
and it is through this that I am involved with the Code Organization subproject of SIG Architecture.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;FSM&lt;/strong&gt;: A project the size of Kubernetes must have unique challenges in terms of code organization
-- is this a fair assumption?  If so, what would you pick as some of the main challenges that are
specific to Kubernetes?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;MJ&lt;/strong&gt;: That’s a fair assumption! The first interesting challenge comes from the sheer size of the
Kubernetes codebase. We have ≅2.2 million lines of Go code (which is steadily decreasing thanks to
&lt;a href=&#34;https://github.com/dims&#34;&gt;dims&lt;/a&gt; and other folks in this sub-project!), and a little over 240
dependencies that we rely on either directly or indirectly, which is why having a sub-project
dedicated to helping out with dependency management is crucial: we need to know what dependencies
we’re pulling in, what versions these dependencies are at, and tooling to help make sure we are
managing these dependencies across different parts of the codebase in a consistent manner.&lt;/p&gt;
&lt;p&gt;Another interesting challenge with Kubernetes is that we publish a lot of Go modules as part of the
Kubernetes release cycles, one example of this is
&lt;a href=&#34;https://github.com/kubernetes/client-go&#34;&gt;&lt;code&gt;client-go&lt;/code&gt;&lt;/a&gt;.However, we as a project would also like the
benefits of having everything in one repository to get the advantages of using a monorepo, like
atomic commits... so, because of this, code organization works with other SIGs (like SIG Release) to
automate the process of publishing code from the monorepo to downstream individual repositories
which are much easier to consume, and this way you won’t have to import the entire Kubernetes
codebase!&lt;/p&gt;
&lt;h2 id=&#34;code-organization-and-kubernetes&#34;&gt;Code organization and Kubernetes&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;FSM&lt;/strong&gt;: For someone just starting contributing to Kubernetes code-wise, what are the main things
they should consider in terms of code organization? How would you sum up the key concepts?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;MJ&lt;/strong&gt;: I think one of the key things to keep in mind at least as you’re starting off is the concept
of staging directories. In the &lt;a href=&#34;https://github.com/kubernetes/kubernetes&#34;&gt;&lt;code&gt;kubernetes/kubernetes&lt;/code&gt;&lt;/a&gt;
repository, you will come across a directory called
&lt;a href=&#34;https://github.com/kubernetes/kubernetes/tree/master/staging&#34;&gt;&lt;code&gt;staging/&lt;/code&gt;&lt;/a&gt;. The sub-folders in this
directory serve as a bunch of pseudo-repositories. For example, the
&lt;a href=&#34;https://github.com/kubernetes/client-go&#34;&gt;&lt;code&gt;kubernetes/client-go&lt;/code&gt;&lt;/a&gt; repository that publishes releases
for &lt;code&gt;client-go&lt;/code&gt; is actually a &lt;a href=&#34;https://github.com/kubernetes/kubernetes/tree/master/staging/src/k8s.io/client-go&#34;&gt;staging
repo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;FSM&lt;/strong&gt;: So the concept of staging directories fundamentally impact contributions?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;MJ&lt;/strong&gt;: Precisely, because if you’d like to contribute to any of the staging repos, you will need to
send in a PR to its corresponding staging directory in &lt;code&gt;kubernetes/kubernetes&lt;/code&gt;. Once the code merges
there, we have a bot called the &lt;a href=&#34;https://github.com/kubernetes/publishing-bot&#34;&gt;&lt;code&gt;publishing-bot&lt;/code&gt;&lt;/a&gt;
that will sync the merged commits to the required staging repositories (like
&lt;code&gt;kubernetes/client-go&lt;/code&gt;). This way we get the benefits of a monorepo but we also can modularly
publish code for downstream consumption. PS: The &lt;code&gt;publishing-bot&lt;/code&gt; needs more folks to help out!&lt;/p&gt;
&lt;p&gt;For more information on staging repositories, please see the &lt;a href=&#34;https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/staging.md&#34;&gt;contributor
documentation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;FSM&lt;/strong&gt;: Speaking of contributions, the very high number of contributors, both individuals and
companies, must also be a challenge: how does the subproject operate in terms of making sure that
standards are being followed?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;MJ&lt;/strong&gt;: When it comes to dependency management in the project, there is a &lt;a href=&#34;https://github.com/kubernetes/org/blob/a106af09b8c345c301d072bfb7106b309c0ad8e9/config/kubernetes/org.yaml#L1329&#34;&gt;dedicated
team&lt;/a&gt;
that helps review and approve dependency changes. These are folks who have helped lay the foundation
of much of the
&lt;a href=&#34;https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/vendor.md&#34;&gt;tooling&lt;/a&gt;
that Kubernetes uses today for dependency management. This tooling helps ensure there is a
consistent way that contributors can make changes to dependencies. The project has also worked on
additional tooling to signal statistics of dependencies that is being added or removed:
&lt;a href=&#34;https://github.com/kubernetes-sigs/depstat&#34;&gt;&lt;code&gt;depstat&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Apart from dependency management, another crucial task that the project does is management of the
staging repositories. The tooling for achieving this (&lt;code&gt;publishing-bot&lt;/code&gt;) is completely transparent to
contributors and helps ensure that the staging repos get a consistent view of contributions that are
submitted to &lt;code&gt;kubernetes/kubernetes&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Code Organization also works towards making sure that Kubernetes &lt;a href=&#34;https://github.com/kubernetes/enhancements/tree/cf6ee34e37f00d838872d368ec66d7a0b40ee4e6/keps/sig-release/3744-stay-on-supported-go-versions&#34;&gt;stays on supported versions of
Go&lt;/a&gt;. The
linked KEP provides more context on why we need to do this. We collaborate with SIG Release to
ensure that we are testing Kubernetes as rigorously and as early as we can on Go releases and
working on changes that break our CI as a part of this. An example of how we track this process can
be found &lt;a href=&#34;https://github.com/kubernetes/release/issues/3076&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;release-cycle-and-current-priorities&#34;&gt;Release cycle and current priorities&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;FSM&lt;/strong&gt;: Is there anything that changes during the release cycle?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;MJ&lt;/strong&gt; During the release cycle, specifically before code freeze, there are often changes that go in
that add/update/delete dependencies, fix code that needs fixing as part of our effort to stay on
supported versions of Go.&lt;/p&gt;
&lt;p&gt;Furthermore, some of these changes are also candidates for
&lt;a href=&#34;https://github.com/kubernetes/community/blob/master/contributors/devel/sig-release/cherry-picks.md&#34;&gt;backporting&lt;/a&gt;
to our supported release branches.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;FSM&lt;/strong&gt;: Is there any major project or theme the subproject is working on right now that you would
like to highlight?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;MJ&lt;/strong&gt;: I think one very interesting and immensely useful change that
has been recently added (and I take the opportunity to specifically
highlight the work of &lt;a href=&#34;https://github.com/thockin&#34;&gt;Tim Hockin&lt;/a&gt; on
this) is the introduction of &lt;a href=&#34;https://www.kubernetes.dev/blog/2024/03/19/go-workspaces-in-kubernetes/&#34;&gt;Go workspaces to the Kubernetes
repo&lt;/a&gt;. A lot of our
current tooling for dependency management and code publishing, as well
as the experience of editing code in the Kubernetes repo, can be
significantly improved by this change.&lt;/p&gt;
&lt;h2 id=&#34;wrapping-up&#34;&gt;Wrapping up&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;FSM&lt;/strong&gt;: How would someone interested in the topic start helping the subproject?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;MJ&lt;/strong&gt;: The first step, as is the first step with any project in Kubernetes, is to join our slack:
&lt;a href=&#34;https://slack.k8s.io&#34;&gt;slack.k8s.io&lt;/a&gt;, and after that join the &lt;code&gt;#k8s-code-organization&lt;/code&gt; channel. There is also a
&lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-architecture#meetings&#34;&gt;code-organization office
hours&lt;/a&gt; that takes
place that you can choose to attend. Timezones are hard, so feel free to also look at the recordings
or meeting notes and follow up on slack!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;FSM&lt;/strong&gt;: Excellent, thank you! Any final comments you would like to share?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;MJ&lt;/strong&gt;: The Code Organization subproject always needs help! Especially areas like the publishing
bot, so don’t hesitate to get involved in the &lt;code&gt;#k8s-code-organization&lt;/code&gt; Slack channel.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>DIY: Create Your Own Cloud with Kubernetes (Part 3)</title>
      <link>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/04/05/diy-create-your-own-cloud-with-kubernetes-part-3/</link>
      <pubDate>Fri, 05 Apr 2024 07:40:00 +0000</pubDate>
      
      <guid>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/04/05/diy-create-your-own-cloud-with-kubernetes-part-3/</guid>
      <description>
        
        
        &lt;p&gt;Approaching the most interesting phase, this article delves into running Kubernetes within
Kubernetes. Technologies such as Kamaji and Cluster API are highlighted, along with their
integration with KubeVirt.&lt;/p&gt;
&lt;p&gt;Previous discussions have covered
&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/04/05/diy-create-your-own-cloud-with-kubernetes-part-1/&#34;&gt;preparing Kubernetes on bare metal&lt;/a&gt;
and
&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/04/05/diy-create-your-own-cloud-with-kubernetes-part-2&#34;&gt;how to turn Kubernetes into virtual machines management system&lt;/a&gt;.
This article concludes the series by explaining how, using all of the above, you can build a
full-fledged managed Kubernetes and run virtual Kubernetes clusters with just a click.&lt;/p&gt;
&lt;p&gt;First up, let&#39;s dive into the Cluster API.&lt;/p&gt;
&lt;h2 id=&#34;cluster-api&#34;&gt;Cluster API&lt;/h2&gt;
&lt;p&gt;Cluster API is an extension for Kubernetes that allows the management of Kubernetes clusters as
custom resources within another Kubernetes cluster.&lt;/p&gt;
&lt;p&gt;The main goal of the Cluster API is to provide a unified interface for describing the basic
entities of a Kubernetes cluster and managing their lifecycle. This enables the automation of
processes for creating, updating, and deleting clusters, simplifying scaling, and infrastructure
management.&lt;/p&gt;
&lt;p&gt;Within the context of Cluster API, there are two terms: &lt;strong&gt;management cluster&lt;/strong&gt; and
&lt;strong&gt;tenant clusters&lt;/strong&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Management cluster&lt;/strong&gt; is a Kubernetes cluster used to deploy and manage other clusters.
This cluster contains all the necessary Cluster API components and is responsible for describing,
creating, and updating tenant clusters. It is often used just for this purpose.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tenant clusters&lt;/strong&gt; are the user clusters or clusters deployed using the Cluster API. They are
created by describing the relevant resources in the management cluster. They are then used for
deploying applications and services by end-users.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It&#39;s important to understand that physically, tenant clusters do not necessarily have to run on
the same infrastructure with the management cluster; more often, they are running elsewhere.&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/04/05/diy-create-your-own-cloud-with-kubernetes-part-3/clusterapi1.svg&#34;
         alt=&#34;A diagram showing interaction of management Kubernetes cluster and tenant Kubernetes clusters using Cluster API&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;A diagram showing interaction of management Kubernetes cluster and tenant Kubernetes clusters using Cluster API&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;For its operation, Cluster API utilizes the concept of &lt;em&gt;providers&lt;/em&gt; which are separate controllers
responsible for specific components of the cluster being created. Within Cluster API, there are
several types of providers. The major ones are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Infrastructure Provider&lt;/strong&gt;, which is responsible for providing the computing infrastructure, such as virtual machines or physical servers.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Control Plane Provider&lt;/strong&gt;, which provides the Kubernetes control plane, namely the components kube-apiserver, kube-scheduler, and kube-controller-manager.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bootstrap Provider&lt;/strong&gt;, which is used for generating cloud-init configuration for the virtual machines and servers being created.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To get started, you will need to install the Cluster API itself and one provider of each type.
You can find a complete list of supported providers in the project&#39;s
&lt;a href=&#34;https://cluster-api.sigs.k8s.io/reference/providers.html&#34;&gt;documentation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For installation, you can use the &lt;code&gt;clusterctl&lt;/code&gt; utility, or
&lt;a href=&#34;https://github.com/kubernetes-sigs/cluster-api-operator&#34;&gt;Cluster API Operator&lt;/a&gt;
as the more declarative method.&lt;/p&gt;
&lt;h2 id=&#34;choosing-providers&#34;&gt;Choosing providers&lt;/h2&gt;
&lt;h3 id=&#34;infrastructure-provider&#34;&gt;Infrastructure provider&lt;/h3&gt;
&lt;p&gt;To run Kubernetes clusters using KubeVirt, the
&lt;a href=&#34;https://github.com/kubernetes-sigs/cluster-api-provider-kubevirt&#34;&gt;KubeVirt Infrastructure Provider&lt;/a&gt;
must be installed.
It enables the deployment of virtual machines for worker nodes in the same management cluster, where
the Cluster API operates.&lt;/p&gt;
&lt;h3 id=&#34;control-plane-provider&#34;&gt;Control plane provider&lt;/h3&gt;
&lt;p&gt;The &lt;a href=&#34;https://github.com/clastix/kamaji&#34;&gt;Kamaji&lt;/a&gt; project offers a ready solution for running the
Kubernetes control plane for tenant clusters as containers within the management cluster.
This approach has several significant advantages:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Cost-effectiveness&lt;/strong&gt;: Running the control plane in containers avoids the use of separate control
plane nodes for each cluster, thereby significantly reducing infrastructure costs.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Stability&lt;/strong&gt;: Simplifying architecture by eliminating complex multi-layered deployment schemes.
Instead of sequentially launching a virtual machine and then installing etcd and Kubernetes components
inside it, there&#39;s a simple control plane that is deployed and run as a regular application inside
Kubernetes and managed by an operator.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Security&lt;/strong&gt;: The cluster&#39;s control plane is hidden from the end user, reducing the possibility
of its components being compromised, and also eliminates user access to the cluster&#39;s certificate
store. This approach to organizing a control plane invisible to the user is often used by cloud providers.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;bootstrap-provider&#34;&gt;Bootstrap provider&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/kubernetes-sigs/cluster-api/tree/main/bootstrap&#34;&gt;Kubeadm&lt;/a&gt; as the Bootstrap
Provider - as the standard method for preparing clusters in Cluster API. This provider is developed
as part of the Cluster API itself. It requires only a prepared system image with kubelet and kubeadm
installed and allows generating configs in the cloud-init and ignition formats.&lt;/p&gt;
&lt;p&gt;It&#39;s worth noting that Talos Linux also supports provisioning via the Cluster API and
&lt;a href=&#34;https://github.com/siderolabs/cluster-api-bootstrap-provider-talos&#34;&gt;has&lt;/a&gt;
&lt;a href=&#34;https://github.com/siderolabs/cluster-api-bootstrap-provider-talos&#34;&gt;providers&lt;/a&gt; for this.
Although &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/04/05/diy-create-your-own-cloud-with-kubernetes-part-1/&#34;&gt;previous articles&lt;/a&gt;
discussed using Talos Linux to set up a management cluster on bare-metal nodes, to provision tenant
clusters the Kamaji+Kubeadm approach has more advantages.
It facilitates the deployment of Kubernetes control planes in containers, thus removing the need for
separate virtual machines for control plane instances. This simplifies the management and reduces costs.&lt;/p&gt;
&lt;h2 id=&#34;how-it-works&#34;&gt;How it works&lt;/h2&gt;
&lt;p&gt;The primary object in Cluster API is the Cluster resource, which acts as the parent for all the others.
Typically, this resource references two others: a resource describing the &lt;strong&gt;control plane&lt;/strong&gt; and a
resource describing the &lt;strong&gt;infrastructure&lt;/strong&gt;, each managed by a separate provider.&lt;/p&gt;
&lt;p&gt;Unlike the Cluster, these two resources are not standardized, and their kind depends on the specific
provider you are using:&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/04/05/diy-create-your-own-cloud-with-kubernetes-part-3/clusterapi2.svg&#34;
         alt=&#34;A diagram showing the relationship of a Cluster resource and the resources it links to in Cluster API&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;A diagram showing the relationship of a Cluster resource and the resources it links to in Cluster API&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Within Cluster API, there is also a resource named MachineDeployment, which describes a group of nodes,
whether they are physical servers or virtual machines. This resource functions similarly to standard
Kubernetes resources such as Deployment, ReplicaSet, and Pod, providing a mechanism for the
declarative description of a group of nodes and automatic scaling.&lt;/p&gt;
&lt;p&gt;In other words, the MachineDeployment resource allows you to declaratively describe nodes for your
cluster, automating their creation, deletion, and updating according to specified parameters and
the requested number of replicas.&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/04/05/diy-create-your-own-cloud-with-kubernetes-part-3/machinedeploymentres.svg&#34;
         alt=&#34;A diagram showing the relationship of a Cluster resource and its children in Cluster API&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;A diagram showing the relationship of a MachineDeployment resource and its children in Cluster API&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;To create machines, MachineDeployment refers to a template for generating the machine itself and a
template for generating its cloud-init config:&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/04/05/diy-create-your-own-cloud-with-kubernetes-part-3/clusterapi3.svg&#34;
         alt=&#34;A diagram showing the relationship of a Cluster resource and the resources it links to in Cluster API&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;A diagram showing the relationship of a MachineDeployment resource and the resources it links to in Cluster API&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;To deploy a new Kubernetes cluster using Cluster API, you will need to prepare the following set of resources:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A general Cluster resource&lt;/li&gt;
&lt;li&gt;A KamajiControlPlane resource, responsible for the control plane operated by Kamaji&lt;/li&gt;
&lt;li&gt;A KubevirtCluster resource, describing the cluster configuration in KubeVirt&lt;/li&gt;
&lt;li&gt;A KubevirtMachineTemplate resource, responsible for the virtual machine template&lt;/li&gt;
&lt;li&gt;A KubeadmConfigTemplate resource, responsible for generating tokens and cloud-init&lt;/li&gt;
&lt;li&gt;At least one MachineDeployment to create some workers&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;polishing-the-cluster&#34;&gt;Polishing the cluster&lt;/h2&gt;
&lt;p&gt;In most cases, this is sufficient, but depending on the providers used, you may need other resources
as well. You can find examples of the resources created for each type of provider in the
&lt;a href=&#34;https://github.com/clastix/cluster-api-control-plane-provider-kamaji?tab=readme-ov-file#-supported-capi-infrastructure-providers&#34;&gt;Kamaji project documentation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;At this stage, you already have a ready tenant Kubernetes cluster, but so far, it contains nothing
but API workers and a few core plugins that are standardly included in the installation of any
Kubernetes cluster: &lt;strong&gt;kube-proxy&lt;/strong&gt; and &lt;strong&gt;CoreDNS&lt;/strong&gt;. For full integration, you will need to install
several more components:&lt;/p&gt;
&lt;p&gt;To install additional components, you can use a separate
&lt;a href=&#34;https://github.com/kubernetes-sigs/cluster-api-addon-provider-helm&#34;&gt;Cluster API Add-on Provider for Helm&lt;/a&gt;,
or the same &lt;a href=&#34;https://fluxcd.io/&#34;&gt;FluxCD&lt;/a&gt; discussed in
&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/04/05/diy-create-your-own-cloud-with-kubernetes-part-1/&#34;&gt;previous articles&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;When creating resources in FluxCD, it&#39;s possible to specify the target cluster by referring to the
kubeconfig generated by Cluster API. Then, the installation will be performed directly into it.
Thus, FluxCD becomes a universal tool for managing resources both in the management cluster and
in the user tenant clusters.&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/04/05/diy-create-your-own-cloud-with-kubernetes-part-3/fluxcd.svg&#34;
         alt=&#34;A diagram showing the interaction scheme of fluxcd, which can install components in both management and tenant Kubernetes clusters&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;A diagram showing the interaction scheme of fluxcd, which can install components in both management and tenant Kubernetes clusters&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;What components are being discussed here? Generally, the set includes the following:&lt;/p&gt;
&lt;h3 id=&#34;cni-plugin&#34;&gt;CNI Plugin&lt;/h3&gt;
&lt;p&gt;To ensure communication between pods in a tenant Kubernetes cluster, it&#39;s necessary to deploy a
CNI plugin. This plugin creates a virtual network that allows pods to interact with each other
and is traditionally deployed as a Daemonset on the cluster&#39;s worker nodes. You can choose and
install any CNI plugin that you find suitable.&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/04/05/diy-create-your-own-cloud-with-kubernetes-part-3/components1.svg&#34;
         alt=&#34;A diagram showing a CNI plugin installed inside the tenant Kubernetes cluster on a scheme of nested Kubernetes clusters&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;A diagram showing a CNI plugin installed inside the tenant Kubernetes cluster on a scheme of nested Kubernetes clusters&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h3 id=&#34;cloud-controller-manager&#34;&gt;Cloud Controller Manager&lt;/h3&gt;
&lt;p&gt;The main task of the Cloud Controller Manager (CCM) is to integrate Kubernetes with the cloud
infrastructure provider&#39;s environment (in your case, it is the management Kubernetes cluster
in which all worksers of tenant Kubernetes are provisioned). Here are some tasks it performs:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;When a service of type LoadBalancer is created, the CCM initiates the process of creating a cloud load balancer, which directs traffic to your Kubernetes cluster.&lt;/li&gt;
&lt;li&gt;If a node is removed from the cloud infrastructure, the CCM ensures its removal from your cluster as well, maintaining the cluster&#39;s current state.&lt;/li&gt;
&lt;li&gt;When using the CCM, nodes are added to the cluster with a special taint, &lt;code&gt;node.cloudprovider.kubernetes.io/uninitialized&lt;/code&gt;,
which allows for the processing of additional business logic if necessary. After successful initialization, this taint is removed from the node.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Depending on the cloud provider, the CCM can operate both inside and outside the tenant cluster.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/kubevirt/cloud-provider-kubevirt&#34;&gt;The KubeVirt Cloud Provider&lt;/a&gt; is designed
to be installed in the external parent management cluster. Thus, creating services of type
LoadBalancer in the tenant cluster initiates the creation of LoadBalancer services in the parent
cluster, which direct traffic into the tenant cluster.&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/04/05/diy-create-your-own-cloud-with-kubernetes-part-3/components2.svg&#34;
         alt=&#34;A diagram showing a Cloud Controller Manager installed outside of a tenant Kubernetes cluster on a scheme of nested Kubernetes clusters and the mapping of services it manages from the parent to the child Kubernetes cluster&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;A diagram showing a Cloud Controller Manager installed outside of a tenant Kubernetes cluster on a scheme of nested Kubernetes clusters and the mapping of services it manages from the parent to the child Kubernetes cluster&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h3 id=&#34;csi-driver&#34;&gt;CSI Driver&lt;/h3&gt;
&lt;p&gt;The Container Storage Interface (CSI) is divided into two main parts for interacting with storage
in Kubernetes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;csi-controller&lt;/strong&gt;: This component is responsible for interacting with the cloud provider&#39;s API
to create, delete, attach, detach, and resize volumes.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;csi-node&lt;/strong&gt;: This component runs on each node and facilitates the mounting of volumes to pods
as requested by kubelet.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the context of using the &lt;a href=&#34;https://github.com/kubevirt/csi-driver&#34;&gt;KubeVirt CSI Driver&lt;/a&gt;, a unique
opportunity arises. Since virtual machines in KubeVirt runs within the management Kubernetes cluster,
where a full-fledged Kubernetes API is available, this opens the path for running the csi-controller
outside of the user&#39;s tenant cluster. This approach is popular in the KubeVirt community and offers
several key advantages:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Security&lt;/strong&gt;: This method hides the internal cloud API from the end-user, providing access to
resources exclusively through the Kubernetes interface. Thus, it reduces the risk of direct access
to the management cluster from user clusters.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Simplicity and Convenience&lt;/strong&gt;: Users don&#39;t need to manage additional controllers in their clusters,
simplifying the architecture and reducing the management burden.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;However, the CSI-node must necessarily run inside the tenant cluster, as it directly interacts with
kubelet on each node. This component is responsible for the mounting and unmounting of volumes into pods,
requiring close integration with processes occurring directly on the cluster nodes.&lt;/p&gt;
&lt;p&gt;The KubeVirt CSI Driver acts as a proxy for ordering volumes. When a PVC is created inside the tenant
cluster, a PVC is created in the management cluster, and then the created PV is connected to the
virtual machine.&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/04/05/diy-create-your-own-cloud-with-kubernetes-part-3/components3.svg&#34;
         alt=&#34;A diagram showing a CSI plugin components installed on both inside and outside of a tenant Kubernetes cluster on a scheme of nested Kubernetes clusters and the mapping of persistent volumes it manages from the parent to the child Kubernetes cluster&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;A diagram showing a CSI plugin components installed on both inside and outside of a tenant Kubernetes cluster on a scheme of nested Kubernetes clusters and the mapping of persistent volumes it manages from the parent to the child Kubernetes cluster&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h3 id=&#34;cluster-autoscaler&#34;&gt;Cluster Autoscaler&lt;/h3&gt;
&lt;p&gt;The &lt;a href=&#34;https://github.com/kubernetes/autoscaler&#34;&gt;Cluster Autoscaler&lt;/a&gt; is a versatile component that
can work with various cloud APIs, and its integration with Cluster-API is just one of the available
functions. For proper configuration, it requires access to two clusters: the tenant cluster, to
track pods and determine the need for adding new nodes, and the managing Kubernetes cluster
(management kubernetes cluster), where it interacts with the MachineDeployment resource and adjusts
the number of replicas.&lt;/p&gt;
&lt;p&gt;Although Cluster Autoscaler usually runs inside the tenant Kubernetes cluster, in this situation,
it is suggested to install it outside for the same reasons described before. This approach is
simpler to maintain and more secure as it prevents users of tenant clusters from accessing the
management API of the management cluster.&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/04/05/diy-create-your-own-cloud-with-kubernetes-part-3/components4.svg&#34;
         alt=&#34;A diagram showing a Cloud Controller Manager installed outside of a tenant Kubernetes cluster on a scheme of nested Kubernetes clusters&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;A diagram showing a Cluster Autoscaler installed outside of a tenant Kubernetes cluster on a scheme of nested Kubernetes clusters&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h3 id=&#34;konnectivity&#34;&gt;Konnectivity&lt;/h3&gt;
&lt;p&gt;There&#39;s another additional component I&#39;d like to mention -
&lt;a href=&#34;https://kubernetes.io/docs/tasks/extend-kubernetes/setup-konnectivity/&#34;&gt;Konnectivity&lt;/a&gt;.
You will likely need it later on to get webhooks and the API aggregation layer working in your
tenant Kubernetes cluster. This topic is covered in detail in one of my
&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2021/12/22/kubernetes-in-kubernetes-and-pxe-bootable-server-farm/#webhooks-and-api-aggregation-layer&#34;&gt;previous article&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Unlike the components presented above, Kamaji allows you to easily enable Konnectivity and manage
it as one of the core components of your tenant cluster, alongside kube-proxy and CoreDNS.&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Now you have a fully functional Kubernetes cluster with the capability for dynamic scaling, automatic
provisioning of volumes, and load balancers.&lt;/p&gt;
&lt;p&gt;Going forward, you might consider metrics and logs collection from your tenant clusters, but that
goes beyond the scope of this article.&lt;/p&gt;
&lt;p&gt;Of course, all the components necessary for deploying a Kubernetes cluster can be packaged into a
single Helm chart and deployed as a unified application. This is precisely how we organize the
deployment of managed Kubernetes clusters with the click of a button on our open PaaS platform,
&lt;a href=&#34;https://cozystack.io/&#34;&gt;Cozystack&lt;/a&gt;, where you can try all the technologies described in the article
for free.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>DIY: Create Your Own Cloud with Kubernetes (Part 2)</title>
      <link>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/04/05/diy-create-your-own-cloud-with-kubernetes-part-2/</link>
      <pubDate>Fri, 05 Apr 2024 07:35:00 +0000</pubDate>
      
      <guid>https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/04/05/diy-create-your-own-cloud-with-kubernetes-part-2/</guid>
      <description>
        
        
        &lt;p&gt;Continuing our series of posts on how to build your own cloud using just the Kubernetes ecosystem.
In the &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/04/05/diy-create-your-own-cloud-with-kubernetes-part-1/&#34;&gt;previous article&lt;/a&gt;, we
explained how we prepare a basic Kubernetes distribution based on Talos Linux and Flux CD.
In this article, we&#39;ll show you a few various virtualization technologies in Kubernetes and prepare
everything need to run virtual machines in Kubernetes, primarily storage and networking.&lt;/p&gt;
&lt;p&gt;We will talk about technologies such as KubeVirt, LINSTOR, and Kube-OVN.&lt;/p&gt;
&lt;p&gt;But first, let&#39;s explain what virtual machines are needed for, and why can&#39;t you just use docker
containers for building cloud?
The reason is that containers do not provide a sufficient level of isolation.
Although the situation improves year by year, we often encounter vulnerabilities that allow
escaping the container sandbox and elevating privileges in the system.&lt;/p&gt;
&lt;p&gt;On the other hand, Kubernetes was not originally designed to be a multi-tenant system, meaning
the basic usage pattern involves creating a separate Kubernetes cluster for every independent
project and development team.&lt;/p&gt;
&lt;p&gt;Virtual machines are the primary means of isolating tenants from each other in a cloud environment.
In virtual machines, users can execute code and programs with administrative privilege, but this
doesn&#39;t affect other tenants or the environment itself. In other words, virtual machines allow to
achieve &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/docs/concepts/security/multi-tenancy/#isolation&#34;&gt;hard multi-tenancy isolation&lt;/a&gt;, and run
in environments where tenants do not trust each other.&lt;/p&gt;
&lt;h2 id=&#34;virtualization-technologies-in-kubernetes&#34;&gt;Virtualization technologies in Kubernetes&lt;/h2&gt;
&lt;p&gt;There are several different technologies that bring virtualization into the Kubernetes world:
&lt;a href=&#34;https://kubevirt.io/&#34;&gt;KubeVirt&lt;/a&gt; and &lt;a href=&#34;https://katacontainers.io/&#34;&gt;Kata Containers&lt;/a&gt;
are the most popular ones. But you should know that they work differently.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Kata Containers&lt;/strong&gt; implements the CRI (Container Runtime Interface) and provides an additional
level of isolation for standard containers by running them in virtual machines.
But they work in a same single Kubernetes-cluster.&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/04/05/diy-create-your-own-cloud-with-kubernetes-part-2/kata-containers.svg&#34;
         alt=&#34;A diagram showing how container isolation is ensured by running containers in virtual machines with Kata Containers&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;A diagram showing how container isolation is ensured by running containers in virtual machines with Kata Containers&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;strong&gt;KubeVirt&lt;/strong&gt; allows running traditional virtual machines using the Kubernetes API. KubeVirt virtual
machines are run as regular linux processes in containers. In other words, in KubeVirt, a container
is used as a sandbox for running virtual machine (QEMU) processes.
This can be clearly seen in the figure below, by looking at how live migration of virtual machines
is implemented in KubeVirt. When migration is needed, the virtual machine moves from one container
to another.&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/04/05/diy-create-your-own-cloud-with-kubernetes-part-2/kubevirt-migration.svg&#34;
         alt=&#34;A diagram showing live migration of a virtual machine from one container to another in KubeVirt&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;A diagram showing live migration of a virtual machine from one container to another in KubeVirt&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;There is also an alternative project - &lt;a href=&#34;https://github.com/smartxworks/virtink&#34;&gt;Virtink&lt;/a&gt;, which
implements lightweight virtualization using
&lt;a href=&#34;https://github.com/cloud-hypervisor/cloud-hypervisor&#34;&gt;Cloud-Hypervisor&lt;/a&gt; and is initially focused
on running virtual Kubernetes clusters using the Cluster API.&lt;/p&gt;
&lt;p&gt;Considering our goals, we decided to use KubeVirt as the most popular project in this area.
Besides we have extensive expertise and already made a lot of contributions to KubeVirt.&lt;/p&gt;
&lt;p&gt;KubeVirt is &lt;a href=&#34;https://kubevirt.io/user-guide/operations/installation/&#34;&gt;easy to install&lt;/a&gt; and allows
you to run virtual machines  out-of-the-box using
&lt;a href=&#34;https://kubevirt.io/user-guide/virtual_machines/disks_and_volumes/#containerdisk&#34;&gt;containerDisk&lt;/a&gt;
feature - this allows you to store and distribute VM images directly as OCI images from container
image registry.
Virtual machines with containerDisk are well suited for creating Kubernetes worker nodes and other
VMs that do not require state persistence.&lt;/p&gt;
&lt;p&gt;For managing persistent data, KubeVirt offers a separate tool, Containerized Data Importer (CDI).
It allows for cloning PVCs and populating them with data from base images. The CDI is necessary
if you want to automatically provision persistent volumes for your virtual machines, and it is
also required for the KubeVirt CSI Driver, which is used to handle persistent volumes claims
from tenant Kubernetes clusters.&lt;/p&gt;
&lt;p&gt;But at first, you have to decide where and how you will store these data.&lt;/p&gt;
&lt;h2 id=&#34;storage-for-kubernetes-vms&#34;&gt;Storage for Kubernetes VMs&lt;/h2&gt;
&lt;p&gt;With the introduction of the CSI (Container Storage Interface), a wide range of technologies that
integrate with Kubernetes has become available.
In fact, KubeVirt fully utilizes the CSI interface, aligning the choice of storage for
virtualization closely with the choice of storage for Kubernetes itself.
However, there are nuances, which you need to consider. Unlike containers, which typically use a
standard filesystem, block devices are more efficient for virtual machine.&lt;/p&gt;
&lt;p&gt;Although the CSI interface in Kubernetes allows the request of both types of volumes: filesystems
and block devices, it&#39;s important to verify that your storage backend supports this.&lt;/p&gt;
&lt;p&gt;Using block devices for virtual machines eliminates the need for an additional abstraction layer,
such as a filesystem, that makes it more performant and in most cases enables the use of the
&lt;em&gt;ReadWriteMany&lt;/em&gt; mode. This mode allows concurrent access to the volume from multiple nodes, which
is a critical feature for enabling the live migration of virtual machines in KubeVirt.&lt;/p&gt;
&lt;p&gt;The storage system can be external or internal (in the case of hyper-converged infrastructure).
Using external storage in many cases makes the whole system more stable, as your data is stored
separately from compute nodes.&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/04/05/diy-create-your-own-cloud-with-kubernetes-part-2/storage-external.svg&#34;
         alt=&#34;A diagram showing external data storage communication with the compute nodes&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;A diagram showing external data storage communication with the compute nodes&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;External storage solutions are often popular in enterprise systems because such storage is
frequently provided by an external vendor, that takes care of its operations. The integration with
Kubernetes involves only a small component installed in the cluster - the CSI driver. This driver
is responsible for provisioning volumes in this storage and attaching them to pods run by Kubernetes.
However, such storage solutions can also be implemented using purely open-source technologies.
One of the popular solutions is &lt;a href=&#34;https://www.truenas.com/&#34;&gt;TrueNAS&lt;/a&gt; powered by
&lt;a href=&#34;https://github.com/democratic-csi/democratic-csi&#34;&gt;democratic-csi&lt;/a&gt; driver.&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/04/05/diy-create-your-own-cloud-with-kubernetes-part-2/storage-local.svg&#34;
         alt=&#34;A diagram showing local data storage running on the compute nodes&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;A diagram showing local data storage running on the compute nodes&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;On the other hand, hyper-converged systems are often implemented using local storage (when you do
not need replication) and with software-defined storages, often installed directly in Kubernetes,
such as &lt;a href=&#34;https://rook.io/&#34;&gt;Rook/Ceph&lt;/a&gt;, &lt;a href=&#34;https://openebs.io/&#34;&gt;OpenEBS&lt;/a&gt;,
&lt;a href=&#34;https://longhorn.io/&#34;&gt;Longhorn&lt;/a&gt;, &lt;a href=&#34;https://linbit.com/linstor/&#34;&gt;LINSTOR&lt;/a&gt;, and others.&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/04/05/diy-create-your-own-cloud-with-kubernetes-part-2/storage-clustered.svg&#34;
         alt=&#34;A diagram showing clustered data storage running on the compute nodes&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;A diagram showing clustered data storage running on the compute nodes&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;A hyper-converged system has its advantages. For example, data locality: when your data is stored
locally, access to such data is faster. But there are disadvantages as such a system is usually
more difficult to manage and maintain.&lt;/p&gt;
&lt;p&gt;At Ænix, we wanted to provide a ready-to-use solution that could be used without the need to
purchase and setup an additional external storage, and that was optimal in terms of speed and
resource utilization. LINSTOR became that solution.
The time-tested and industry-popular technologies such as LVM and ZFS as backend gives confidence
that data is securely stored. DRBD-based replication is incredible fast and consumes a small amount
of computing resources.&lt;/p&gt;
&lt;p&gt;For installing LINSTOR in Kubernetes, there is the Piraeus project, which already provides a
ready-made block storage to use with KubeVirt.&lt;/p&gt;

&lt;div class=&#34;alert alert-info&#34; role=&#34;alert&#34;&gt;&lt;h4 class=&#34;alert-heading&#34;&gt;Note:&lt;/h4&gt;In case you are using Talos Linux, as we described in the
&lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/04/05/diy-create-your-own-cloud-with-kubernetes-part-1/&#34;&gt;previous article&lt;/a&gt;, you will
need to enable the necessary kernel modules in advance, and configure piraeus as described in the
&lt;a href=&#34;https://github.com/piraeusdatastore/piraeus-operator/blob/v2/docs/how-to/talos.md&#34;&gt;instruction&lt;/a&gt;.&lt;/div&gt;

&lt;h2 id=&#34;networking-for-kubernetes-vms&#34;&gt;Networking for Kubernetes VMs&lt;/h2&gt;
&lt;p&gt;Despite having the similar interface - CNI, The network architecture in Kubernetes is actually more
complex and typically consists of many independent components that are not directly connected to
each other. In fact, you can split Kubernetes networking into four layers, which are described below.&lt;/p&gt;
&lt;h3 id=&#34;node-network-data-center-network&#34;&gt;Node Network (Data Center Network)&lt;/h3&gt;
&lt;p&gt;The network through which nodes are interconnected with each other. This network is usually not
managed by Kubernetes, but it is an important one because, without it, nothing would work.
In practice, the bare metal infrastructure usually has more than one of such networks e.g.
one for node-to-node communication, second for storage replication, third for external access, etc.&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/04/05/diy-create-your-own-cloud-with-kubernetes-part-2/net-nodes.svg&#34;
         alt=&#34;A diagram showing the role of the node network (data center network) on the Kubernetes networking scheme&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;A diagram showing the role of the node network (data center network) on the Kubernetes networking scheme&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Configuring the physical network interaction between nodes goes beyond the scope of this article,
as in most situations, Kubernetes utilizes already existing network infrastructure.&lt;/p&gt;
&lt;h3 id=&#34;pod-network&#34;&gt;Pod Network&lt;/h3&gt;
&lt;p&gt;This is the network provided by your CNI plugin. The task of the CNI plugin is to ensure transparent
connectivity between all containers and nodes in the cluster. Most CNI plugins implement a flat
network from which separate blocks of IP addresses are allocated for use on each node.&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/04/05/diy-create-your-own-cloud-with-kubernetes-part-2/net-pods.svg&#34;
         alt=&#34;A diagram showing the role of the pod network (CNI-plugin) on the Kubernetes network scheme&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;A diagram showing the role of the pod network (CNI-plugin) on the Kubernetes network scheme&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;In practice, your cluster can have several CNI plugins managed by
&lt;a href=&#34;https://github.com/k8snetworkplumbingwg/multus-cni&#34;&gt;Multus&lt;/a&gt;. This approach is often used in
virtualization solutions based on KubeVirt - &lt;a href=&#34;https://www.rancher.com/&#34;&gt;Rancher&lt;/a&gt; and
&lt;a href=&#34;https://www.redhat.com/en/technologies/cloud-computing/openshift/virtualization&#34;&gt;OpenShift&lt;/a&gt;.
The primary CNI plugin is used for integration with Kubernetes services, while additional CNI
plugins are used to implement private networks (VPC) and integration with the physical networks
of your data center.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&#34;https://github.com/containernetworking/plugins/tree/main/plugins&#34;&gt;default CNI-plugins&lt;/a&gt; can
be used to connect bridges or physical interfaces. Additionally, there are specialized plugins
such as &lt;a href=&#34;https://github.com/kubevirt/macvtap-cni&#34;&gt;macvtap-cni&lt;/a&gt; which are designed to provide
more performance.&lt;/p&gt;
&lt;p&gt;One additional aspect to keep in mind when running virtual machines in Kubernetes is the need for
IPAM (IP Address Management), especially for secondary interfaces provided by Multus. This is
commonly managed by a DHCP server operating within your infrastructure. Additionally, the allocation
of MAC addresses for virtual machines can be managed by
&lt;a href=&#34;https://github.com/k8snetworkplumbingwg/kubemacpool&#34;&gt;Kubemacpool&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Although in our platform, we decided to go another way and fully rely on
&lt;a href=&#34;https://www.kube-ovn.io/&#34;&gt;Kube-OVN&lt;/a&gt;. This CNI plugin is based on OVN (Open Virtual Network) which
was originally developed for OpenStack and it provides a complete network solution for virtual
machines in Kubernetes, features Custom Resources for managing IPs and MAC addresses, supports
live migration with preserving IP addresses between the nodes, and enables the creation of VPCs
for physical network separation between tenants.&lt;/p&gt;
&lt;p&gt;In Kube-OVN you can assign separate subnets to an entire namespace or connect them as additional
network interfaces using Multus.&lt;/p&gt;
&lt;h3 id=&#34;services-network&#34;&gt;Services Network&lt;/h3&gt;
&lt;p&gt;In addition to the CNI plugin, Kubernetes also has a services network, which is primarily needed
for service discovery.
Contrary to traditional virtual machines, Kubernetes is originally designed to run pods with a
random address.
And the services network provides a convenient abstraction (stable IP addresses and DNS names)
that will always direct traffic to the correct pod.
The same approach is also commonly used with virtual machines in clouds despite the fact that
their IPs are usually static.&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/04/05/diy-create-your-own-cloud-with-kubernetes-part-2/net-services.svg&#34;
         alt=&#34;A diagram showing the role of the services network (services network plugin) on the Kubernetes network scheme&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;A diagram showing the role of the services network (services network plugin) on the Kubernetes network scheme&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The implementation of the services network in Kubernetes is handled by the services network plugin,
The standard implementation is called &lt;strong&gt;kube-proxy&lt;/strong&gt; and is used in most clusters.
But nowadays, this functionality might be provided as part of the CNI plugin. The most advanced
implementation is offered by the &lt;a href=&#34;https://cilium.io/&#34;&gt;Cilium&lt;/a&gt; project, which can be run in kube-proxy replacement mode.&lt;/p&gt;
&lt;p&gt;Cilium is based on the eBPF technology, which allows for efficient offloading of the Linux
networking stack, thereby improving performance and security compared to traditional methods based
on iptables.&lt;/p&gt;
&lt;p&gt;In practice, Cilium and Kube-OVN can be easily
&lt;a href=&#34;https://kube-ovn.readthedocs.io/zh-cn/stable/en/advance/with-cilium/&#34;&gt;integrated&lt;/a&gt; to provide a
unified solution that offers seamless, multi-tenant networking for virtual machines, as well as
advanced network policies and combined services network functionality.&lt;/p&gt;
&lt;h3 id=&#34;external-traffic-load-balancer&#34;&gt;External Traffic Load Balancer&lt;/h3&gt;
&lt;p&gt;At this stage, you already have everything needed to run virtual machines in Kubernetes.
But there is actually one more thing.
You still need to access your services from outside your cluster, and an external load balancer
will help you with organizing this.&lt;/p&gt;
&lt;p&gt;For bare metal Kubernetes clusters, there are several load balancers available:
&lt;a href=&#34;https://metallb.universe.tf/&#34;&gt;MetalLB&lt;/a&gt;, &lt;a href=&#34;https://kube-vip.io/&#34;&gt;kube-vip&lt;/a&gt;,
&lt;a href=&#34;https://www.loxilb.io/&#34;&gt;LoxiLB&lt;/a&gt;, also &lt;a href=&#34;https://docs.cilium.io/en/latest/network/lb-ipam/&#34;&gt;Cilium&lt;/a&gt; and
&lt;a href=&#34;https://kube-ovn.readthedocs.io/zh-cn/latest/en/guide/loadbalancer-service/&#34;&gt;Kube-OVN&lt;/a&gt;
provides built-in implementation.&lt;/p&gt;
&lt;p&gt;The role of a external load balancer is to provide a stable address available externally and direct
external traffic to the services network.
The services network plugin will direct it to your pods and virtual machines as usual.&lt;/p&gt;


&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/04/05/diy-create-your-own-cloud-with-kubernetes-part-2/net-loadbalancer.svg&#34;
         alt=&#34;The role of the external load balancer on the Kubernetes network scheme&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;A diagram showing the role of the external load balancer on the Kubernetes network scheme&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;In most cases, setting up a load balancer on bare metal is achieved by creating floating IP address
on the nodes within the cluster, and announce it externally using ARP/NDP or BGP protocols.&lt;/p&gt;
&lt;p&gt;After exploring various options, we decided that MetalLB is the simplest and most reliable solution,
although we do not strictly enforce the use of only it.&lt;/p&gt;
&lt;p&gt;Another benefit is that in L2 mode, MetalLB speakers continuously check their neighbour&#39;s state by
sending preforming liveness checks using a memberlist protocol.
This enables failover that works independently of Kubernetes control-plane.&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;This concludes our overview of virtualization, storage, and networking in Kubernetes.
The technologies mentioned here are available and already pre-configured on the
&lt;a href=&#34;https://github.com/aenix-io/cozystack&#34;&gt;Cozystack&lt;/a&gt; platform, where you can try them with no limitations.&lt;/p&gt;
&lt;p&gt;In the &lt;a href=&#34;https://deploy-preview-50011--kubernetes-io-main-staging.netlify.app/blog/2024/04/05/diy-create-your-own-cloud-with-kubernetes-part-3/&#34;&gt;next article&lt;/a&gt;,
I&#39;ll detail how, on top of this, you can implement the provisioning of fully functional Kubernetes
clusters with just the click of a button.&lt;/p&gt;

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