<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Kubernetes Blog</title>
    <link>https://deploy-preview-57407--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-57407--kubernetes-io-main-staging.netlify.app/</link>
    </image>
    
    <atom:link href="https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/feed.xml" rel="self" type="application/rss+xml" />
    
    
    <item>
      <title>Contextual logging in Kubernetes 1.29: Better troubleshooting and enhanced logging</title>
      <link>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/12/20/contextual-logging-in-kubernetes-1-29/</link>
      <pubDate>Wed, 20 Dec 2023 09:30:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/12/20/contextual-logging-in-kubernetes-1-29/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Authors&lt;/strong&gt;: &lt;a href=&#34;https://github.com/mengjiao-liu/&#34;&gt;Mengjiao Liu&lt;/a&gt; (DaoCloud), &lt;a href=&#34;https://github.com/pohly&#34;&gt;Patrick Ohly&lt;/a&gt; (Intel)&lt;/p&gt;
&lt;p&gt;On behalf of the &lt;a href=&#34;https://github.com/kubernetes/community/blob/master/wg-structured-logging/README.md&#34;&gt;Structured Logging Working Group&lt;/a&gt;
and &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-instrumentation#readme&#34;&gt;SIG Instrumentation&lt;/a&gt;,
we are pleased to announce that the contextual logging feature
introduced in Kubernetes v1.24 has now been successfully migrated to
two components (kube-scheduler and kube-controller-manager)
as well as some directories. This feature aims to provide more useful logs
for better troubleshooting of Kubernetes and to empower developers to enhance Kubernetes.&lt;/p&gt;
&lt;h2 id=&#34;what-is-contextual-logging&#34;&gt;What is contextual logging?&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/kubernetes/enhancements/tree/master/keps/sig-instrumentation/3077-contextual-logging&#34;&gt;Contextual logging&lt;/a&gt;
is based on the &lt;a href=&#34;https://github.com/go-logr/logr#a-minimal-logging-api-for-go&#34;&gt;go-logr&lt;/a&gt; API.
The key idea is that libraries are passed a logger instance by their caller
and use that for logging instead of accessing a global logger.
The binary decides the logging implementation, not the libraries.
The go-logr API is designed around structured logging and supports attaching
additional information to a logger.&lt;/p&gt;
&lt;p&gt;This enables additional use cases:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The caller can attach additional information to a logger:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://pkg.go.dev/github.com/go-logr/logr#Logger.WithName&#34;&gt;WithName&lt;/a&gt; adds a &amp;quot;logger&amp;quot; key with the names concatenated by a dot as value&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://pkg.go.dev/github.com/go-logr/logr#Logger.WithValues&#34;&gt;WithValues&lt;/a&gt; adds key/value pairs&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When passing this extended logger into a function, and the function uses it
instead of the global logger, the additional information is then included
in all log entries, without having to modify the code that generates the log entries.
This is useful in highly parallel applications where it can become hard to identify
all log entries for a certain operation, because the output from different operations gets interleaved.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;When running unit tests, log output can be associated with the current test.
Then, when a test fails, only the log output of the failed test gets shown by go test.
That output can also be more verbose by default because it will not get shown for successful tests.
Tests can be run in parallel without interleaving their output.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;One of the design decisions for contextual logging was to allow attaching a logger as value to a &lt;code&gt;context.Context&lt;/code&gt;.
Since the logger encapsulates all aspects of the intended logging for the call,
it is &lt;em&gt;part&lt;/em&gt; of the context, and not just &lt;em&gt;using&lt;/em&gt; it. A practical advantage is that many APIs
already have a &lt;code&gt;ctx&lt;/code&gt; parameter or can add one. This provides additional advantages, like being able to
get rid of &lt;code&gt;context.TODO()&lt;/code&gt; calls inside the functions.&lt;/p&gt;
&lt;h2 id=&#34;how-to-use-it&#34;&gt;How to use it&lt;/h2&gt;
&lt;p&gt;The contextual logging feature is alpha starting from Kubernetes v1.24,
so it requires the &lt;code&gt;ContextualLogging&lt;/code&gt; &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/reference/command-line-tools-reference/feature-gates/&#34;&gt;feature gate&lt;/a&gt; to be enabled.
If you want to test the feature while it is alpha, you need to enable this feature gate
on the &lt;code&gt;kube-controller-manager&lt;/code&gt; and the &lt;code&gt;kube-scheduler&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For the &lt;code&gt;kube-scheduler&lt;/code&gt;, there is one thing to note, in addition to enabling
the &lt;code&gt;ContextualLogging&lt;/code&gt; feature gate, instrumentation also depends on log verbosity.
To avoid slowing down the scheduler with the logging instrumentation for contextual logging added for 1.29,
it is important to choose carefully when to add additional information:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;At &lt;code&gt;-v3&lt;/code&gt; or lower, only &lt;code&gt;WithValues(&amp;quot;pod&amp;quot;)&lt;/code&gt; is used once per scheduling cycle.
This has the intended effect that all log messages for the cycle include the pod information.
Once contextual logging is GA, &amp;quot;pod&amp;quot; key/value pairs can be removed from all log calls.&lt;/li&gt;
&lt;li&gt;At &lt;code&gt;-v4&lt;/code&gt; or higher, richer log entries get produced where &lt;code&gt;WithValues&lt;/code&gt; is also used for the node (when applicable)
and &lt;code&gt;WithName&lt;/code&gt; is used for the current operation and plugin.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here is an example that demonstrates the effect:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I1113 08:43:37.029524   87144 default_binder.go:53] &amp;quot;Attempting to bind pod to node&amp;quot; &lt;strong&gt;logger=&amp;quot;Bind.DefaultBinder&amp;quot;&lt;/strong&gt; &lt;strong&gt;pod&lt;/strong&gt;=&amp;quot;kube-system/coredns-69cbfb9798-ms4pq&amp;quot; &lt;strong&gt;node&lt;/strong&gt;=&amp;quot;127.0.0.1&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The immediate benefit is that the operation and plugin name are visible in &lt;code&gt;logger&lt;/code&gt;.
&lt;code&gt;pod&lt;/code&gt; and &lt;code&gt;node&lt;/code&gt; are already logged as parameters in individual log calls in &lt;code&gt;kube-scheduler&lt;/code&gt; code.
Once contextual logging is supported by more packages outside of &lt;code&gt;kube-scheduler&lt;/code&gt;,
they will also be visible there (for example, client-go). Once it is GA,
log calls can be simplified to avoid repeating those values.&lt;/p&gt;
&lt;p&gt;In &lt;code&gt;kube-controller-manager&lt;/code&gt;, &lt;code&gt;WithName&lt;/code&gt; is used to add the user-visible controller name to log output,
for example:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I1113 08:43:29.284360   87141 graph_builder.go:285] &amp;quot;garbage controller monitor not synced: no monitors&amp;quot; &lt;strong&gt;logger=&amp;quot;garbage-collector-controller&amp;quot;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The &lt;code&gt;logger=”garbage-collector-controller”&lt;/code&gt; was added by the &lt;code&gt;kube-controller-manager&lt;/code&gt; core
when instantiating that controller and appears in all of its log entries - at least as long as the code
that it calls supports contextual logging. Further work is needed to convert shared packages like client-go.&lt;/p&gt;
&lt;h2 id=&#34;performance-impact&#34;&gt;Performance impact&lt;/h2&gt;
&lt;p&gt;Supporting contextual logging in a package, i.e. accepting a logger from a caller, is cheap.
No performance impact was observed for the &lt;code&gt;kube-scheduler&lt;/code&gt;. As noted above,
adding &lt;code&gt;WithName&lt;/code&gt; and &lt;code&gt;WithValues&lt;/code&gt; needs to be done more carefully.&lt;/p&gt;
&lt;p&gt;In Kubernetes 1.29, enabling contextual logging at production verbosity (&lt;code&gt;-v3&lt;/code&gt; or lower)
caused no measurable slowdown for the &lt;code&gt;kube-scheduler&lt;/code&gt; and is not expected for the &lt;code&gt;kube-controller-manager&lt;/code&gt; either.
At debug levels, a 28% slowdown for some test cases is still reasonable given that the resulting logs make debugging easier.
For details, see the &lt;a href=&#34;https://github.com/kubernetes/enhancements/pull/4219#issuecomment-1807811995&#34;&gt;discussion around promoting the feature to beta&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;impact-on-downstream-users&#34;&gt;Impact on downstream users&lt;/h2&gt;
&lt;p&gt;Log output is not part of the Kubernetes API and changes regularly in each release,
whether it is because developers work on the code or because of the ongoing conversion
to structured and contextual logging.&lt;/p&gt;
&lt;p&gt;If downstream users have dependencies on specific logs,
they need to be aware of how this change affects them.&lt;/p&gt;
&lt;h2 id=&#34;further-reading&#34;&gt;Further reading&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Read the &lt;a href=&#34;https://www.kubernetes.dev/blog/2022/05/25/contextual-logging/&#34;&gt;Contextual Logging in Kubernetes 1.24&lt;/a&gt; article.&lt;/li&gt;
&lt;li&gt;Read the &lt;a href=&#34;https://github.com/kubernetes/enhancements/tree/master/keps/sig-instrumentation/3077-contextual-logging&#34;&gt;KEP-3077: contextual logging&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;If you&#39;re interested in getting involved, we always welcome new contributors to join us.
Contextual logging provides a fantastic opportunity for you to contribute to Kubernetes development and make a meaningful impact.
By joining &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/wg-structured-logging&#34;&gt;Structured Logging WG&lt;/a&gt;,
you can actively participate in the development of Kubernetes and make your first contribution.
It&#39;s a great way to learn and engage with the community while gaining valuable experience.&lt;/p&gt;
&lt;p&gt;We encourage you to explore the repository and familiarize yourself with the ongoing discussions and projects.
It&#39;s a collaborative environment where you can exchange ideas, ask questions, and work together with other contributors.&lt;/p&gt;
&lt;p&gt;If you have any questions or need guidance, don&#39;t hesitate to reach out to us
and you can do so on our &lt;a href=&#34;https://kubernetes.slack.com/messages/wg-structured-logging&#34;&gt;public Slack channel&lt;/a&gt;.
If you&#39;re not already part of that Slack workspace, you can visit &lt;a href=&#34;https://slack.k8s.io/&#34;&gt;https://slack.k8s.io/&lt;/a&gt;
for an invitation.&lt;/p&gt;
&lt;p&gt;We would like to express our gratitude to all the contributors who provided excellent reviews,
shared valuable insights, and assisted in the implementation of this feature (in alphabetical order):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Aldo Culquicondor (&lt;a href=&#34;https://github.com/alculquicondor&#34;&gt;alculquicondor&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Andy Goldstein (&lt;a href=&#34;https://github.com/ncdc&#34;&gt;ncdc&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Feruzjon Muyassarov (&lt;a href=&#34;https://github.com/fmuyassarov&#34;&gt;fmuyassarov&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Freddie (&lt;a href=&#34;https://github.com/freddie400&#34;&gt;freddie400&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;JUN YANG (&lt;a href=&#34;https://github.com/yangjunmyfm192085&#34;&gt;yangjunmyfm192085&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Kante Yin (&lt;a href=&#34;https://github.com/kerthcet&#34;&gt;kerthcet&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Kiki (&lt;a href=&#34;https://github.com/carlory&#34;&gt;carlory&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Lucas Severo Alve (&lt;a href=&#34;https://github.com/knelasevero&#34;&gt;knelasevero&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Maciej Szulik (&lt;a href=&#34;https://github.com/soltysh&#34;&gt;soltysh&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Mengjiao Liu (&lt;a href=&#34;https://github.com/mengjiao-liu&#34;&gt;mengjiao-liu&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Naman Lakhwani (&lt;a href=&#34;https://github.com/Namanl2001&#34;&gt;Namanl2001&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Oksana Baranova (&lt;a href=&#34;https://github.com/oxxenix&#34;&gt;oxxenix&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Patrick Ohly (&lt;a href=&#34;https://github.com/pohly&#34;&gt;pohly&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;songxiao-wang87 (&lt;a href=&#34;https://github.com/songxiao-wang87&#34;&gt;songxiao-wang87&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Tim Allclai (&lt;a href=&#34;https://github.com/tallclair&#34;&gt;tallclair&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;ZhangYu (&lt;a href=&#34;https://github.com/Octopusjust&#34;&gt;Octopusjust&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Ziqi Zhao (&lt;a href=&#34;https://github.com/fatsheep9146&#34;&gt;fatsheep9146&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Zac (&lt;a href=&#34;https://github.com/249043822&#34;&gt;249043822&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes 1.29: Decoupling taint-manager from node-lifecycle-controller</title>
      <link>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/12/19/kubernetes-1-29-taint-eviction-controller/</link>
      <pubDate>Tue, 19 Dec 2023 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/12/19/kubernetes-1-29-taint-eviction-controller/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Authors:&lt;/strong&gt; Yuan Chen (Apple), Andrea Tosatto (Apple)&lt;/p&gt;
&lt;p&gt;This blog discusses a new feature in Kubernetes 1.29 to improve the handling of taint-based pod eviction.&lt;/p&gt;
&lt;h2 id=&#34;background&#34;&gt;Background&lt;/h2&gt;
&lt;p&gt;In Kubernetes 1.29, an improvement has been introduced to enhance the taint-based pod eviction handling on nodes.
This blog discusses the changes made to node-lifecycle-controller
to separate its responsibilities and improve overall code maintainability.&lt;/p&gt;
&lt;h2 id=&#34;summary-of-changes&#34;&gt;Summary of changes&lt;/h2&gt;
&lt;p&gt;node-lifecycle-controller previously combined two independent functions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Adding a pre-defined set of &lt;code&gt;NoExecute&lt;/code&gt; taints to Node based on Node&#39;s condition.&lt;/li&gt;
&lt;li&gt;Performing pod eviction on &lt;code&gt;NoExecute&lt;/code&gt; taint.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With the Kubernetes 1.29 release, the taint-based eviction implementation has been
moved out of node-lifecycle-controller into a separate and independent component called taint-eviction-controller.
This separation aims to disentangle code, enhance code maintainability,
and facilitate future extensions to either component.&lt;/p&gt;
&lt;p&gt;As part of the change, additional metrics were introduced to help you monitor taint-based pod evictions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;pod_deletion_duration_seconds&lt;/code&gt; measures the latency between the time when a taint effect
has been activated for the Pod and its deletion via taint-eviction-controller.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pod_deletions_total&lt;/code&gt; reports the total number of Pods deleted by taint-eviction-controller since its start.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;how-to-use-the-new-feature&#34;&gt;How to use the new feature?&lt;/h2&gt;
&lt;p&gt;A new feature gate, &lt;code&gt;SeparateTaintEvictionController&lt;/code&gt;, has been added. The feature is enabled by default as Beta in Kubernetes 1.29.
Please refer to the &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/reference/command-line-tools-reference/feature-gates/&#34;&gt;feature gate document&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;When this feature is enabled, users can optionally disable taint-based eviction by setting &lt;code&gt;--controllers=-taint-eviction-controller&lt;/code&gt;
in kube-controller-manager.&lt;/p&gt;
&lt;p&gt;To disable the new feature and use the old taint-manager within node-lifecylecycle-controller , users can set the feature gate &lt;code&gt;SeparateTaintEvictionController=false&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;use-cases&#34;&gt;Use cases&lt;/h2&gt;
&lt;p&gt;This new feature will allow cluster administrators to extend and enhance the default
taint-eviction-controller and even replace the default taint-eviction-controller with a
custom implementation to meet different needs. An example is to better support
stateful workloads that use PersistentVolume on local disks.&lt;/p&gt;
&lt;h2 id=&#34;faq&#34;&gt;FAQ&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Does this feature change the existing behavior of taint-based pod evictions?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;No, the taint-based pod eviction behavior remains unchanged. If the feature gate
&lt;code&gt;SeparateTaintEvictionController&lt;/code&gt; is turned off, the legacy node-lifecycle-controller with taint-manager will continue to be used.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Will enabling/using this feature result in an increase in the time taken by any operations covered by existing SLIs/SLOs?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Will enabling/using this feature result in an increase in resource usage (CPU, RAM, disk, IO, ...)?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The increase in resource usage by running a separate &lt;code&gt;taint-eviction-controller&lt;/code&gt; will be negligible.&lt;/p&gt;
&lt;h2 id=&#34;learn-more&#34;&gt;Learn more&lt;/h2&gt;
&lt;p&gt;For more details, refer to the &lt;a href=&#34;http://kep.k8s.io/3902&#34;&gt;KEP&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;acknowledgments&#34;&gt;Acknowledgments&lt;/h2&gt;
&lt;p&gt;As with any Kubernetes feature, multiple community members have contributed, from
writing the KEP to implementing the new controller and reviewing the KEP and code. Special thanks to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Aldo Culquicondor (@alculquicondor)&lt;/li&gt;
&lt;li&gt;Maciej Szulik (@soltysh)&lt;/li&gt;
&lt;li&gt;Filip Křepinský (@atiratree)&lt;/li&gt;
&lt;li&gt;Han Kang (@logicalhan)&lt;/li&gt;
&lt;li&gt;Wei Huang (@Huang-Wei)&lt;/li&gt;
&lt;li&gt;Sergey Kanzhelevi (@SergeyKanzhelev)&lt;/li&gt;
&lt;li&gt;Ravi Gudimetla (@ravisantoshgudimetla)&lt;/li&gt;
&lt;li&gt;Deep Debroy (@ddebroy)&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes 1.29: PodReadyToStartContainers Condition Moves to Beta</title>
      <link>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/12/19/pod-ready-to-start-containers-condition-now-in-beta/</link>
      <pubDate>Tue, 19 Dec 2023 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/12/19/pod-ready-to-start-containers-condition-now-in-beta/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Authors&lt;/strong&gt;: Zefeng Chen (independent), Kevin Hannon (Red Hat)&lt;/p&gt;
&lt;p&gt;With the recent release of Kubernetes 1.29, the &lt;code&gt;PodReadyToStartContainers&lt;/code&gt;
&lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/concepts/workloads/pods/pod-lifecycle/#pod-conditions&#34;&gt;condition&lt;/a&gt; is
available by default.
The kubelet manages the value for that condition throughout a Pod&#39;s lifecycle,
in the status field of a Pod. The kubelet will use the &lt;code&gt;PodReadyToStartContainers&lt;/code&gt;
condition to accurately surface the initialization state of a Pod,
from the perspective of Pod sandbox creation and network configuration by a container runtime.&lt;/p&gt;
&lt;h2 id=&#34;what-s-the-motivation-for-this-feature&#34;&gt;What&#39;s the motivation for this feature?&lt;/h2&gt;
&lt;p&gt;Cluster administrators did not have a clear and easily accessible way to view the completion of Pod&#39;s sandbox creation
and initialization. As of 1.28, the &lt;code&gt;Initialized&lt;/code&gt; condition in Pods tracks the execution of init containers.
However, it has limitations in accurately reflecting the completion of sandbox creation and readiness to start containers for all Pods in a cluster.
This distinction is particularly important in multi-tenant clusters where tenants own the Pod specifications, including the set of init containers,
while cluster administrators manage storage plugins, networking plugins, and container runtime handlers.
Therefore, there is a need for an improved mechanism to provide cluster administrators with a clear and
comprehensive view of Pod sandbox creation completion and container readiness.&lt;/p&gt;
&lt;h2 id=&#34;what-s-the-benefit&#34;&gt;What&#39;s the benefit?&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Improved Visibility: Cluster administrators gain a clearer and more comprehensive view of Pod sandbox
creation completion and container readiness.
This enhanced visibility allows them to make better-informed decisions and troubleshoot issues more effectively.&lt;/li&gt;
&lt;li&gt;Metric Collection and Monitoring: Monitoring services can leverage the fields associated with
the &lt;code&gt;PodReadyToStartContainers&lt;/code&gt; condition to report sandbox creation state and latency.
Metrics can be collected at per-Pod cardinality or aggregated based on various
properties of the Pod, such as &lt;code&gt;volumes&lt;/code&gt;, &lt;code&gt;runtimeClassName&lt;/code&gt;, custom annotations for CNI
and IPAM plugins or arbitrary labels and annotations, and &lt;code&gt;storageClassName&lt;/code&gt; of
PersistentVolumeClaims.
This enables comprehensive monitoring and analysis of Pod readiness across the cluster.&lt;/li&gt;
&lt;li&gt;Enhanced Troubleshooting: With a more accurate representation of Pod sandbox creation and container readiness,
cluster administrators can quickly identify and address any issues that may arise during the initialization process.
This leads to improved troubleshooting capabilities and reduced downtime.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;what-s-next&#34;&gt;What’s next?&lt;/h3&gt;
&lt;p&gt;Due to feedback and adoption, the Kubernetes team promoted &lt;code&gt;PodReadyToStartContainersCondition&lt;/code&gt; to Beta in 1.29.
Your comments will help determine if this condition continues forward to get promoted to GA,
so please submit additional feedback on this feature!&lt;/p&gt;
&lt;h3 id=&#34;how-can-i-learn-more&#34;&gt;How can I learn more?&lt;/h3&gt;
&lt;p&gt;Please check out the
&lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/concepts/workloads/pods/pod-lifecycle/&#34;&gt;documentation&lt;/a&gt; for the
&lt;code&gt;PodReadyToStartContainersCondition&lt;/code&gt; to learn more about it and how it fits in relation to
other Pod conditions.&lt;/p&gt;
&lt;h3 id=&#34;how-to-get-involved&#34;&gt;How to get involved?&lt;/h3&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.29: New (alpha) Feature, Load Balancer IP Mode for Services</title>
      <link>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/12/18/kubernetes-1-29-feature-loadbalancer-ip-mode-alpha/</link>
      <pubDate>Mon, 18 Dec 2023 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/12/18/kubernetes-1-29-feature-loadbalancer-ip-mode-alpha/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Author:&lt;/strong&gt; &lt;a href=&#34;https://github.com/RyanAoh&#34;&gt;Aohan Yang&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This blog introduces a new alpha feature in Kubernetes 1.29.
It provides a configurable approach to define how Service implementations,
exemplified in this blog by kube-proxy,
handle traffic from pods to the Service, within the cluster.&lt;/p&gt;
&lt;h2 id=&#34;background&#34;&gt;Background&lt;/h2&gt;
&lt;p&gt;In older Kubernetes releases, the kube-proxy would intercept traffic that was destined for the IP
address associated with a Service of &lt;code&gt;type: LoadBalancer&lt;/code&gt;. This happened whatever mode you used
for &lt;code&gt;kube-proxy&lt;/code&gt;.
The interception implemented the expected behavior (traffic eventually reaching the expected
endpoints behind the Service). The mechanism to make that work depended on the mode for kube-proxy;
on Linux, kube-proxy in iptables mode would redirecting packets directly to the endpoint; in ipvs mode,
kube-proxy would configure the load balancer&#39;s IP address to one interface on the node.
The motivation for implementing that interception was for two reasons:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Traffic path optimization:&lt;/strong&gt; Efficiently redirecting pod traffic - when a container in a pod sends an outbound
packet that is destined for the load balancer&#39;s IP address -
directly to the backend service by bypassing the load balancer.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Handling load balancer packets:&lt;/strong&gt; Some load balancers send packets with the destination IP set to
the load balancer&#39;s IP address. As a result, these packets need to be routed directly to the correct backend (which
might not be local to that node), in order to avoid loops.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;problems&#34;&gt;Problems&lt;/h2&gt;
&lt;p&gt;However, there are several problems with the aforementioned behavior:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/kubernetes/kubernetes/issues/79783&#34;&gt;Source IP&lt;/a&gt;:&lt;/strong&gt;
Some cloud providers use the load balancer&#39;s IP as the source IP when
transmitting packets to the node. In the ipvs mode of kube-proxy,
there is a problem that health checks from the load balancer never return. This occurs because the reply packets
would be forward to the local interface &lt;code&gt;kube-ipvs0&lt;/code&gt;(where the load balancer&#39;s IP is bound to)
and be subsequently ignored.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/kubernetes/kubernetes/issues/66607&#34;&gt;Feature loss at load balancer level&lt;/a&gt;:&lt;/strong&gt;
Certain cloud providers offer features(such as TLS termination, proxy protocol, etc.) at the
load balancer level.
Bypassing the load balancer results in the loss of these features when the packet reaches the service
(leading to protocol errors).&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Even with the new alpha behaviour disabled (the default), there is a
&lt;a href=&#34;https://github.com/kubernetes/kubernetes/issues/66607#issuecomment-474513060&#34;&gt;workaround&lt;/a&gt;
that involves setting &lt;code&gt;.status.loadBalancer.ingress.hostname&lt;/code&gt; for the Service, in order
to bypass kube-proxy binding.
But this is just a makeshift solution.&lt;/p&gt;
&lt;h2 id=&#34;solution&#34;&gt;Solution&lt;/h2&gt;
&lt;p&gt;In summary, providing an option for cloud providers to disable the current behavior would be highly beneficial.&lt;/p&gt;
&lt;p&gt;To address this, Kubernetes v1.29 introduces a new (alpha) &lt;code&gt;.status.loadBalancer.ingress.ipMode&lt;/code&gt;
field for a Service.
This field specifies how the load balancer IP behaves and can be specified only when
the &lt;code&gt;.status.loadBalancer.ingress.ip&lt;/code&gt; field is also specified.&lt;/p&gt;
&lt;p&gt;Two values are possible for &lt;code&gt;.status.loadBalancer.ingress.ipMode&lt;/code&gt;: &lt;code&gt;&amp;quot;VIP&amp;quot;&lt;/code&gt; and &lt;code&gt;&amp;quot;Proxy&amp;quot;&lt;/code&gt;.
The default value is &amp;quot;VIP&amp;quot;, meaning that traffic delivered to the node
with the destination set to the load balancer&#39;s IP and port will be redirected to the backend service by kube-proxy.
This preserves the existing behavior of kube-proxy.
The &amp;quot;Proxy&amp;quot; value is intended to prevent kube-proxy from binding the load balancer&#39;s IP address
to the node in both ipvs and iptables modes.
Consequently, traffic is sent directly to the load balancer and then forwarded to the destination node.
The destination setting for forwarded packets varies depending on how the cloud provider&#39;s load balancer delivers traffic:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If the traffic is delivered to the node then DNATed to the pod, the destination would be set to the node&#39;s IP and node port;&lt;/li&gt;
&lt;li&gt;If the traffic is delivered directly to the pod, the destination would be set to the pod&#39;s IP and port.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;usage&#34;&gt;Usage&lt;/h2&gt;
&lt;p&gt;Here are the necessary steps to enable this feature:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Download the &lt;a href=&#34;https://kubernetes.io/releases/download/&#34;&gt;latest Kubernetes project&lt;/a&gt; (version &lt;code&gt;v1.29.0&lt;/code&gt; or later).&lt;/li&gt;
&lt;li&gt;Enable the feature gate with the command line flag &lt;code&gt;--feature-gates=LoadBalancerIPMode=true&lt;/code&gt;
on kube-proxy, kube-apiserver, and cloud-controller-manager.&lt;/li&gt;
&lt;li&gt;For Services with &lt;code&gt;type: LoadBalancer&lt;/code&gt;, set &lt;code&gt;ipMode&lt;/code&gt; to the appropriate value.
This step is likely handled by your chosen cloud-controller-manager during the &lt;code&gt;EnsureLoadBalancer&lt;/code&gt; process.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;more-information&#34;&gt;More information&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Read &lt;a href=&#34;https://deploy-preview-57407--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;/li&gt;
&lt;li&gt;Read &lt;a href=&#34;https://kep.k8s.io/1860&#34;&gt;KEP-1860&lt;/a&gt; - &lt;a href=&#34;https://github.com/kubernetes/enhancements/tree/b103a6b0992439f996be4314caf3bf7b75652366/keps/sig-network/1860-kube-proxy-IP-node-binding#kep-1860-make-kubernetes-aware-of-the-loadbalancer-behaviour&#34;&gt;Make Kubernetes aware of the LoadBalancer behaviour&lt;/a&gt; &lt;em&gt;(sic)&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;getting-involved&#34;&gt;Getting involved&lt;/h2&gt;
&lt;p&gt;Reach us on &lt;a href=&#34;https://slack.k8s.io/&#34;&gt;Slack&lt;/a&gt;: &lt;a href=&#34;https://kubernetes.slack.com/messages/sig-network&#34;&gt;#sig-network&lt;/a&gt;,
or through the &lt;a href=&#34;https://groups.google.com/forum/#!forum/kubernetes-sig-network&#34;&gt;mailing list&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;acknowledgments&#34;&gt;Acknowledgments&lt;/h2&gt;
&lt;p&gt;Huge thanks to &lt;a href=&#34;https://github.com/Sh4d1&#34;&gt;@Sh4d1&lt;/a&gt; for the original KEP and initial implementation code.
I took over midway and completed the work. Similarly, immense gratitude to other contributors
who have assisted in the design, implementation, and review of this feature (alphabetical order):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/aojea&#34;&gt;@aojea&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/danwinship&#34;&gt;@danwinship&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/sftim&#34;&gt;@sftim&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/tengqm&#34;&gt;@tengqm&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/thockin&#34;&gt;@thockin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/wojtek-t&#34;&gt;@wojtek-t&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes 1.29: Single Pod Access Mode for PersistentVolumes Graduates to Stable</title>
      <link>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/12/18/read-write-once-pod-access-mode-ga/</link>
      <pubDate>Mon, 18 Dec 2023 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/12/18/read-write-once-pod-access-mode-ga/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Author:&lt;/strong&gt; Chris Henzie (Google)&lt;/p&gt;
&lt;p&gt;With the release of Kubernetes v1.29, the &lt;code&gt;ReadWriteOncePod&lt;/code&gt; volume access mode
has graduated to general availability: it&#39;s part of Kubernetes&#39; stable API. In
this blog post, I&#39;ll take a closer look at this access mode and what it does.&lt;/p&gt;
&lt;h2 id=&#34;what-is-readwriteoncepod&#34;&gt;What is &lt;code&gt;ReadWriteOncePod&lt;/code&gt;?&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;ReadWriteOncePod&lt;/code&gt; is an access mode for
&lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/concepts/storage/persistent-volumes/#persistent-volumes&#34;&gt;PersistentVolumes&lt;/a&gt; (PVs)
and &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims&#34;&gt;PersistentVolumeClaims&lt;/a&gt; (PVCs)
introduced in Kubernetes v1.22. This access mode enables you to restrict volume
access to a single pod in the cluster, ensuring that only one pod can write to
the volume at a time. This can be particularly useful for stateful workloads
that require single-writer access to storage.&lt;/p&gt;
&lt;p&gt;For more context on access modes and how &lt;code&gt;ReadWriteOncePod&lt;/code&gt; works read
&lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2021/09/13/read-write-once-pod-access-mode-alpha/#what-are-access-modes-and-why-are-they-important&#34;&gt;What are access modes and why are they important?&lt;/a&gt;
in the &lt;em&gt;Introducing Single Pod Access Mode for PersistentVolumes&lt;/em&gt; article from 2021.&lt;/p&gt;
&lt;h2 id=&#34;how-can-i-start-using-readwriteoncepod&#34;&gt;How can I start using &lt;code&gt;ReadWriteOncePod&lt;/code&gt;?&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;ReadWriteOncePod&lt;/code&gt; volume access mode is available by default in Kubernetes
versions v1.27 and beyond. In Kubernetes v1.29 and later, the Kubernetes API
always recognizes this access mode.&lt;/p&gt;
&lt;p&gt;Note that &lt;code&gt;ReadWriteOncePod&lt;/code&gt; is
&lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/concepts/storage/persistent-volumes/#access-modes&#34;&gt;only supported for CSI volumes&lt;/a&gt;,
and before using this feature, you will need to update the following
&lt;a href=&#34;https://kubernetes-csi.github.io/docs/sidecar-containers.html&#34;&gt;CSI sidecars&lt;/a&gt;
to these versions or greater:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes-csi/external-provisioner/releases/tag/v3.0.0&#34;&gt;csi-provisioner:v3.0.0+&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes-csi/external-attacher/releases/tag/v3.3.0&#34;&gt;csi-attacher:v3.3.0+&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes-csi/external-resizer/releases/tag/v1.3.0&#34;&gt;csi-resizer:v1.3.0+&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To start using &lt;code&gt;ReadWriteOncePod&lt;/code&gt;, you need to create a PVC with the
&lt;code&gt;ReadWriteOncePod&lt;/code&gt; access mode:&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;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;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;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;single-writer-only&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;- ReadWriteOncePod&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Allows only a single pod to access single-writer-only.&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;1Gi&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;If your storage plugin supports
&lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/concepts/storage/dynamic-provisioning/&#34;&gt;Dynamic provisioning&lt;/a&gt;, then
new PersistentVolumes will be created with the &lt;code&gt;ReadWriteOncePod&lt;/code&gt; access mode
applied.&lt;/p&gt;
&lt;p&gt;Read &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2021/09/13/read-write-once-pod-access-mode-alpha/#migrating-existing-persistentvolumes&#34;&gt;Migrating existing PersistentVolumes&lt;/a&gt;
for details on migrating existing volumes to use &lt;code&gt;ReadWriteOncePod&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;how-can-i-learn-more&#34;&gt;How can I learn more?&lt;/h2&gt;
&lt;p&gt;Please see the blog posts &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2021/09/13/read-write-once-pod-access-mode-alpha&#34;&gt;alpha&lt;/a&gt;,
&lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/04/20/read-write-once-pod-access-mode-beta&#34;&gt;beta&lt;/a&gt;, and
&lt;a href=&#34;https://github.com/kubernetes/enhancements/blob/master/keps/sig-storage/2485-read-write-once-pod-pv-access-mode/README.md&#34;&gt;KEP-2485&lt;/a&gt;
for more details on the &lt;code&gt;ReadWriteOncePod&lt;/code&gt; access mode and motivations for CSI
spec changes.&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;The &lt;a href=&#34;https://kubernetes.slack.com/messages/csi&#34;&gt;Kubernetes #csi Slack channel&lt;/a&gt;
and any of the standard
&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 methods to reach out to the SIG Storage and the CSI teams.&lt;/p&gt;
&lt;p&gt;Special thanks to the following people whose thoughtful reviews and feedback helped shape this feature:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Abdullah Gharaibeh (ahg-g)&lt;/li&gt;
&lt;li&gt;Aldo Culquicondor (alculquicondor)&lt;/li&gt;
&lt;li&gt;Antonio Ojea (aojea)&lt;/li&gt;
&lt;li&gt;David Eads (deads2k)&lt;/li&gt;
&lt;li&gt;Jan Šafránek (jsafrane)&lt;/li&gt;
&lt;li&gt;Joe Betz (jpbetz)&lt;/li&gt;
&lt;li&gt;Kante Yin (kerthcet)&lt;/li&gt;
&lt;li&gt;Michelle Au (msau42)&lt;/li&gt;
&lt;li&gt;Tim Bannister (sftim)&lt;/li&gt;
&lt;li&gt;Xing Yang (xing-yang)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you’re 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’re rapidly growing and always welcome new contributors.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes 1.29: CSI Storage Resizing Authenticated and Generally Available in v1.29</title>
      <link>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/12/15/csi-node-expand-secret-support-ga/</link>
      <pubDate>Fri, 15 Dec 2023 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/12/15/csi-node-expand-secret-support-ga/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Authors:&lt;/strong&gt; Humble Chirammal (Vmware), Louis Koo (deeproute.ai)&lt;/p&gt;
&lt;p&gt;Kubernetes version v1.29 brings generally available support for authentication
during CSI (Container Storage Interface) storage resize operations.&lt;/p&gt;
&lt;p&gt;Let&#39;s embark on the evolution of this feature, initially introduced in alpha in
Kubernetes v1.25, and unravel the changes accompanying its transition to GA.&lt;/p&gt;
&lt;h2 id=&#34;authenticated-csi-storage-resizing-unveiled&#34;&gt;Authenticated CSI storage resizing unveiled&lt;/h2&gt;
&lt;p&gt;Kubernetes harnesses the capabilities of CSI to seamlessly integrate with third-party
storage systems, empowering your cluster to seamlessly expand storage volumes
managed by the CSI driver. The recent elevation of authentication secret support
for resizes from Beta to GA ushers in new horizons, enabling volume expansion in
scenarios where the underlying storage operation demands credentials for backend
cluster operations – such as accessing a SAN/NAS fabric. This enhancement addresses
a critical limitation for CSI drivers, allowing volume expansion at the node level,
especially in cases necessitating authentication for resize operations.&lt;/p&gt;
&lt;p&gt;The challenges extend beyond node-level expansion. Within the Special Interest
Group (SIG) Storage, use cases have surfaced, including scenarios where the
CSI driver needs to validate the actual size of backend block storage before
initiating a node-level filesystem expand operation. This validation prevents
false positive returns from the backend storage cluster during file system expansion.
Additionally, for PersistentVolumes representing encrypted block storage (e.g., using LUKS),
a passphrase is mandated to expand the device and grow the filesystem, underscoring
the necessity for authenticated resizing.&lt;/p&gt;
&lt;h2 id=&#34;what-s-new-for-kubernetes-v1-29&#34;&gt;What&#39;s new for Kubernetes v1.29&lt;/h2&gt;
&lt;p&gt;With the graduation to GA, the feature remains enabled by default. Support for
node-level volume expansion secrets has been seamlessly integrated into the CSI
external-provisioner sidecar controller. To take advantage, ensure your external
CSI storage provisioner sidecar controller is operating at v3.3.0 or above.&lt;/p&gt;
&lt;h2 id=&#34;navigating-authenticated-csi-storage-resizing&#34;&gt;Navigating Authenticated CSI Storage Resizing&lt;/h2&gt;
&lt;p&gt;Assuming all requisite components, including the CSI driver, are deployed and operational
on your cluster, and you have a CSI driver supporting resizing, you can initiate a
&lt;code&gt;NodeExpand&lt;/code&gt; operation on a CSI volume. Credentials for the CSI &lt;code&gt;NodeExpand&lt;/code&gt; operation
can be conveniently provided as a Kubernetes Secret, specifying the Secret via the
StorageClass. Here&#39;s an illustrative manifest for a Secret holding credentials:&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;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;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-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;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;data&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;stringData&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;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;password&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;t0p-Secret&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 here&#39;s an example manifest for a StorageClass referencing those credentials:&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;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;StorageClass&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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-blockstorage-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;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;csi.storage.k8s.io/node-expand-secret-name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;test-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;csi.storage.k8s.io/node-expand-secret-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;provisioner&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;blockstorage.cloudprovider.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;reclaimPolicy&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;volumeBindingMode&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Immediate&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;allowVolumeExpansion&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;Upon successful creation of the PersistentVolumeClaim (PVC), you can verify the
configuration within the .spec.csi field of the PersistentVolume. To confirm,
execute &lt;code&gt;kubectl get persistentvolume &amp;lt;pv_name&amp;gt; -o yaml&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;engage-with-the-evolution&#34;&gt;Engage with the Evolution!&lt;/h2&gt;
&lt;p&gt;For those enthusiastic about contributing or delving deeper into the technical
intricacies, the enhancement proposal comprises exhaustive details about the
feature&#39;s history and implementation. Explore the realms of StorageClass-based
dynamic provisioning in Kubernetes by referring to the [storage class documentation]
(&lt;a href=&#34;https://kubernetes.io/docs/concepts/storage/persistent-volumes/#class&#34;&gt;https://kubernetes.io/docs/concepts/storage/persistent-volumes/#class&lt;/a&gt;)
and the overarching &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/concepts/storage/persistent-volumes/&#34;&gt;PersistentVolumes&lt;/a&gt; documentation.&lt;/p&gt;
&lt;p&gt;Join the Kubernetes Storage SIG (Special Interest Group) to actively participate
in elevating this feature. Your insights are invaluable, and we eagerly anticipate
welcoming more contributors to shape the future of Kubernetes storage!&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes 1.29: VolumeAttributesClass for Volume Modification</title>
      <link>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/12/15/kubernetes-1-29-volume-attributes-class/</link>
      <pubDate>Fri, 15 Dec 2023 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/12/15/kubernetes-1-29-volume-attributes-class/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Author&lt;/strong&gt;: Sunny Song (Google)&lt;/p&gt;
&lt;p&gt;The v1.29 release of Kubernetes introduced an alpha feature to support modifying a volume
by changing the &lt;code&gt;volumeAttributesClassName&lt;/code&gt; that was specified for a PersistentVolumeClaim (PVC).
With the feature enabled, Kubernetes can handle updates of volume attributes other than capacity.
Allowing volume attributes to be changed without managing it through different
provider&#39;s APIs directly simplifies the current flow.&lt;/p&gt;
&lt;p&gt;You can read about VolumeAttributesClass usage details in the Kubernetes documentation
or you can read on to learn about why the Kubernetes project is supporting this feature.&lt;/p&gt;
&lt;h2 id=&#34;volumeattributesclass&#34;&gt;VolumeAttributesClass&lt;/h2&gt;
&lt;p&gt;The new &lt;code&gt;storage.k8s.io/v1alpha1&lt;/code&gt; API group provides two new types:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;VolumeAttributesClass&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Represents a specification of mutable volume attributes defined by the CSI driver.
The class can be specified during dynamic provisioning of PersistentVolumeClaims,
and changed in the PersistentVolumeClaim spec after provisioning.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ModifyVolumeStatus&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Represents the status object of &lt;code&gt;ControllerModifyVolume&lt;/code&gt; operation.&lt;/p&gt;
&lt;p&gt;With this alpha feature enabled, the spec of PersistentVolumeClaim defines VolumeAttributesClassName
that is used in the PVC. At volume provisioning, the &lt;code&gt;CreateVolume&lt;/code&gt; operation will apply the parameters in the
VolumeAttributesClass along with the parameters in the StorageClass.&lt;/p&gt;
&lt;p&gt;When there is a change of volumeAttributesClassName in the PVC spec,
the external-resizer sidecar will get an informer event. Based on the current state of the configuration,
the resizer will trigger a CSI ControllerModifyVolume.
More details can be found in &lt;a href=&#34;https://github.com/kubernetes/enhancements/blob/master/keps/sig-storage/3751-volume-attributes-class/README.md&#34;&gt;KEP-3751&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;how-to-use-it&#34;&gt;How to use it&lt;/h2&gt;
&lt;p&gt;If you want to test the feature whilst it&#39;s alpha, you need to enable the relevant feature gate
in the &lt;code&gt;kube-controller-manager&lt;/code&gt; and the &lt;code&gt;kube-apiserver&lt;/code&gt;. Use the &lt;code&gt;--feature-gates&lt;/code&gt; command line argument:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;--feature-gates=&amp;#34;...,VolumeAttributesClass=true&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It also requires that the CSI driver has implemented the ModifyVolume API.&lt;/p&gt;
&lt;h3 id=&#34;user-flow&#34;&gt;User flow&lt;/h3&gt;
&lt;p&gt;If you would like to see the feature in action and verify it works fine in your cluster, here&#39;s what you can try:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Define a StorageClass and VolumeAttributesClass&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/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;StorageClass&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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-sc-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;provisioner&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;pd.csi.storage.gke.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;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;disk-type&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;hyperdisk-balanced&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;volumeBindingMode&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;WaitForFirstConsumer&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;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;pd.csi.storage.gke.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;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;3000&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;50&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;/li&gt;
&lt;li&gt;
&lt;p&gt;Define and create the PersistentVolumeClaim&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;csi-sc-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;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;/li&gt;
&lt;li&gt;
&lt;p&gt;Verify that the PersistentVolumeClaim is now provisioned correctly with:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;kubectl get pvc
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a new VolumeAttributesClass gold:&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;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;pd.csi.storage.gke.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;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;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;4000&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;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;60&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;/li&gt;
&lt;li&gt;
&lt;p&gt;Update the PVC with the new VolumeAttributesClass and apply:&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;csi-sc-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;volumeAttributesClassName&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;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;/li&gt;
&lt;li&gt;
&lt;p&gt;Verify that PersistentVolumeClaims has the updated VolumeAttributesClass parameters with:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;kubectl describe pvc &amp;lt;PVC_NAME&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;next-steps&#34;&gt;Next steps&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;See the &lt;a href=&#34;https://kep.k8s.io/3751&#34;&gt;VolumeAttributesClass KEP&lt;/a&gt; for more information on the design&lt;/li&gt;
&lt;li&gt;You can view or comment on the &lt;a href=&#34;https://github.com/orgs/kubernetes-csi/projects/72&#34;&gt;project board&lt;/a&gt; for VolumeAttributesClass&lt;/li&gt;
&lt;li&gt;In order to move this feature towards beta, we need feedback from the community,
so here&#39;s a call to action: add support to the CSI drivers, try out this feature,
consider how it can help with problems that your users are having…&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;getting-involved&#34;&gt;Getting involved&lt;/h2&gt;
&lt;p&gt;We always welcome new contributors. So, if you would like to get involved, you can 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).&lt;/p&gt;
&lt;p&gt;If you would like to share feedback, you can do so on our &lt;a href=&#34;https://app.slack.com/client/T09NY5SBT/C09QZFCE5&#34;&gt;public Slack channel&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Special thanks to all the contributors that provided great reviews, shared valuable insight and helped implement this feature (alphabetical order):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Baofa Fan (calory)&lt;/li&gt;
&lt;li&gt;Ben Swartzlander (bswartz)&lt;/li&gt;
&lt;li&gt;Connor Catlett (ConnorJC3)&lt;/li&gt;
&lt;li&gt;Hemant Kumar (gnufied)&lt;/li&gt;
&lt;li&gt;Jan Šafránek (jsafrane)&lt;/li&gt;
&lt;li&gt;Joe Betz (jpbetz)&lt;/li&gt;
&lt;li&gt;Jordan Liggitt (liggitt)&lt;/li&gt;
&lt;li&gt;Matthew Cary (mattcary)&lt;/li&gt;
&lt;li&gt;Michelle Au (msau42)&lt;/li&gt;
&lt;li&gt;Xing Yang (xing-yang)&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes 1.29: Cloud Provider Integrations Are Now Separate Components</title>
      <link>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/12/14/cloud-provider-integration-changes/</link>
      <pubDate>Thu, 14 Dec 2023 09:30:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/12/14/cloud-provider-integration-changes/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Authors:&lt;/strong&gt; Michael McCune (Red Hat), Andrew Sy Kim (Google)&lt;/p&gt;
&lt;p&gt;For Kubernetes v1.29, you need to use additional components to integrate your
Kubernetes cluster with a cloud infrastructure provider. By default, Kubernetes
v1.29 components &lt;strong&gt;abort&lt;/strong&gt; if you try to specify integration with any cloud provider using
one of the legacy compiled-in cloud provider integrations. If you want to use a legacy
integration, you have to opt back in - and a future release will remove even that option.&lt;/p&gt;
&lt;p&gt;In 2018, the &lt;a href=&#34;https://kubernetes.io/blog/2019/04/17/the-future-of-cloud-providers-in-kubernetes/&#34;&gt;Kubernetes community agreed to form the Cloud Provider Special
Interest Group (SIG)&lt;/a&gt;, with a mission to externalize all cloud provider
integrations and remove all the existing in-tree cloud provider integrations.
In January 2019, the Kubernetes community approved the initial draft of
&lt;a href=&#34;https://github.com/kubernetes/enhancements/tree/master/keps/sig-cloud-provider/2395-removing-in-tree-cloud-providers&#34;&gt;KEP-2395: Removing In-Tree Cloud Provider Code&lt;/a&gt;. This KEP defines a
process by which we can remove cloud provider specific code from the core
Kubernetes source tree. From the KEP:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Motiviation [sic] behind this effort is to allow cloud providers to develop and
make releases independent from the core Kubernetes release cycle. The
de-coupling of cloud provider code allows for separation of concern between
&amp;quot;Kubernetes core&amp;quot; and the cloud providers within the ecosystem. In addition,
this ensures all cloud providers in the ecosystem are integrating with
Kubernetes in a consistent and extendable way.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;After many years of development and collaboration across many contributors,
the default behavior for legacy cloud provider integrations is changing.
This means that users will need to confirm their Kubernetes configurations,
and in some cases run external cloud controller managers. These changes are
taking effect in Kubernetes version 1.29; read on to learn if you are affected
and what changes you will need to make.&lt;/p&gt;
&lt;p&gt;These updated default settings affect a large proportion of Kubernetes users,
and &lt;strong&gt;will require changes&lt;/strong&gt; for users who were previously using the in-tree
provider integrations. The legacy integrations offered compatibility with
Azure, AWS, GCE, OpenStack, and vSphere; however for AWS and OpenStack the
compiled-in integrations were removed in Kubernetes versions 1.26 and 1.27,
respectively.&lt;/p&gt;
&lt;h2 id=&#34;what-has-changed&#34;&gt;What has changed?&lt;/h2&gt;
&lt;p&gt;At the most basic level, two &lt;a href=&#34;https://kubernetes.io/docs/reference/command-line-tools-reference/feature-gates/&#34;&gt;feature gates&lt;/a&gt; are changing their default
value from false to true. Those feature gates, &lt;code&gt;DisableCloudProviders&lt;/code&gt; and
&lt;code&gt;DisableKubeletCloudCredentialProviders&lt;/code&gt;, control the way that the
&lt;a href=&#34;https://kubernetes.io/docs/reference/command-line-tools-reference/kube-apiserver/&#34;&gt;kube-apiserver&lt;/a&gt;, &lt;a href=&#34;https://kubernetes.io/docs/reference/command-line-tools-reference/kube-controller-manager/&#34;&gt;kube-controller-manager&lt;/a&gt;, and &lt;a href=&#34;https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet/&#34;&gt;kubelet&lt;/a&gt;
invoke the cloud provider related code that is included in those components.
When these feature gates are true (the default), the only recognized value for
the &lt;code&gt;--cloud-provider&lt;/code&gt; command line argument is &lt;code&gt;external&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Let&#39;s see what the &lt;a href=&#34;https://kubernetes.io/docs/reference/command-line-tools-reference/feature-gates/&#34;&gt;official Kubernetes documentation&lt;/a&gt; says about these
feature gates:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;DisableCloudProviders&lt;/code&gt;: Disables any functionality in &lt;code&gt;kube-apiserver&lt;/code&gt;,
&lt;code&gt;kube-controller-manager&lt;/code&gt; and &lt;code&gt;kubelet&lt;/code&gt; related to the &lt;code&gt;--cloud-provider&lt;/code&gt;
component flag.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;DisableKubeletCloudCredentialProviders&lt;/code&gt;: Disable the in-tree functionality
in kubelet to authenticate to a cloud provider container registry for image
pull credentials.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The next stage beyond beta will be full removal; for that release onwards, you
won&#39;t be able to override those feature gates back to false.&lt;/p&gt;
&lt;h2 id=&#34;what-do-you-need-to-do&#34;&gt;What do you need to do?&lt;/h2&gt;
&lt;p&gt;If you are upgrading from Kubernetes 1.28+ and are not on Azure, GCE, or
vSphere then there are no changes you will need to make. If
you &lt;strong&gt;are&lt;/strong&gt; on Azure, GCE, or vSphere, or you are upgrading from a version
older than 1.28, then read on.&lt;/p&gt;
&lt;p&gt;Historically, Kubernetes has included code for a set of cloud providers that
included AWS, Azure, GCE, OpenStack, and vSphere. Since the inception of
&lt;a href=&#34;https://github.com/kubernetes/enhancements/tree/master/keps/sig-cloud-provider/2395-removing-in-tree-cloud-providers&#34;&gt;KEP-2395&lt;/a&gt; the community has been moving towards removal of that
cloud provider code. The OpenStack provider code was removed in version 1.26,
and the AWS provider code was removed in version 1.27. This means that users
who are upgrading from one of the affected cloud providers and versions will
need to modify their deployments.&lt;/p&gt;
&lt;h3 id=&#34;upgrading-on-azure-gce-or-vsphere&#34;&gt;Upgrading on Azure, GCE, or vSphere&lt;/h3&gt;
&lt;p&gt;There are two options for upgrading in this configuration: migrate to external
cloud controller managers, or continue using the in-tree provider code.
Although migrating to external cloud controller managers is recommended,
there are scenarios where continuing with the current behavior is desired.
Please choose the best option for your needs.&lt;/p&gt;
&lt;h4 id=&#34;migrate-to-external-cloud-controller-managers&#34;&gt;Migrate to external cloud controller managers&lt;/h4&gt;
&lt;p&gt;Migrating to use external cloud controller managers is the recommended upgrade
path, when possible in your situation. To do this you will need to
enable the &lt;code&gt;--cloud-provider=external&lt;/code&gt; command line flag for the
&lt;code&gt;kube-apiserver&lt;/code&gt;, &lt;code&gt;kube-controller-manager&lt;/code&gt;, and &lt;code&gt;kubelet&lt;/code&gt; components. In
addition you will need to deploy a cloud controller manager for your provider.&lt;/p&gt;
&lt;p&gt;Installing and running cloud controller managers is a larger topic than this
post can address; if you would like more information on this process please
read the documentation for &lt;a href=&#34;https://kubernetes.io/docs/tasks/administer-cluster/running-cloud-controller/&#34;&gt;Cloud Controller Manager Administration&lt;/a&gt;
and &lt;a href=&#34;https://kubernetes.io/docs/tasks/administer-cluster/controller-manager-leader-migration/&#34;&gt;Migrate Replicated Control Plane To Use Cloud Controller Manager&lt;/a&gt;.
See &lt;a href=&#34;#cloud-provider-integrations&#34;&gt;below&lt;/a&gt; for links to specific cloud provider
implementations.&lt;/p&gt;
&lt;h4 id=&#34;continue-using-in-tree-provider-code&#34;&gt;Continue using in-tree provider code&lt;/h4&gt;
&lt;p&gt;If you wish to continue using Kubernetes with the in-tree cloud provider code,
you will need to modify the command line parameters for &lt;code&gt;kube-apiserver&lt;/code&gt;,
&lt;code&gt;kube-controller-manager&lt;/code&gt;, and &lt;code&gt;kubelet&lt;/code&gt; to disable the feature gates for
&lt;code&gt;DisableCloudProviders&lt;/code&gt; and &lt;code&gt;DisableKubeletCloudCredentialProviders&lt;/code&gt;. To do
this, add the following command line flag to the arguments for the previously
listed commands:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;--feature-gates=DisableCloudProviders=false,DisableKubeletCloudCredentialProviders=false
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;Please note that if you have other feature gate modifications on the command
line, they will need to include these 2 feature gates.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: These feature gates will be locked to &lt;code&gt;true&lt;/code&gt; in an upcoming
release. Setting these feature gates to &lt;code&gt;false&lt;/code&gt; should be used as a last
resort. It is highly recommended to migrate to an external cloud controller
manager as the in-tree providers are planned for removal as early as Kubernetes
version 1.31.&lt;/p&gt;
&lt;h3 id=&#34;upgrading-on-other-providers&#34;&gt;Upgrading on other providers&lt;/h3&gt;
&lt;p&gt;For providers other than Azure, GCE, or vSphere, good news, the external cloud
controller manager should already be in use. You can confirm this by inspecting
the &lt;code&gt;--cloud-provider&lt;/code&gt; flag for the kubelets in your cluster, they will have
the value &lt;code&gt;external&lt;/code&gt; if using external providers. The code for AWS and OpenStack
providers was removed from Kubernetes before version 1.27 was released.
Other providers beyond the AWS, Azure, GCE, OpenStack, and vSphere were never
included in Kubernetes and as such they began their life as external cloud
controller managers.&lt;/p&gt;
&lt;h3 id=&#34;upgrading-from-older-kubernetes-versions&#34;&gt;Upgrading from older Kubernetes versions&lt;/h3&gt;
&lt;p&gt;If you are upgrading from a Kubernetes release older than 1.26, and you are on
AWS, Azure, GCE, OpenStack, or vSphere then you will need to enable the
&lt;code&gt;--cloud-provider=external&lt;/code&gt; flag, and follow the advice for installing and
running a cloud controller manager for your provider.&lt;/p&gt;
&lt;p&gt;Please read the documentation for
&lt;a href=&#34;https://kubernetes.io/docs/tasks/administer-cluster/running-cloud-controller/&#34;&gt;Cloud Controller Manager Administration&lt;/a&gt; and
&lt;a href=&#34;https://kubernetes.io/docs/tasks/administer-cluster/controller-manager-leader-migration/&#34;&gt;Migrate Replicated Control Plane To Use Cloud Controller Manager&lt;/a&gt;. See
below for links to specific cloud provider implementations.&lt;/p&gt;
&lt;h2 id=&#34;where-to-find-a-cloud-controller-manager&#34;&gt;Where to find a cloud controller manager?&lt;/h2&gt;
&lt;p&gt;At its core, this announcement is about the cloud provider integrations that
were previously included in Kubernetes. As these components move out of the
core Kubernetes code and into their own repositories, it is important to note
a few things:&lt;/p&gt;
&lt;p&gt;First, SIG Cloud Provider offers a reference framework for developers who
wish to create cloud controller managers for any provider. See the
&lt;a href=&#34;https://github.com/kubernetes/cloud-provider&#34;&gt;cloud-provider repository&lt;/a&gt; for more information about how
these controllers work and how to get started creating your own.&lt;/p&gt;
&lt;p&gt;Second, there are many cloud controller managers available for Kubernetes.
This post is addressing the provider integrations that have been historically
included with Kubernetes but are now in the process of being removed. If you
need a cloud controller manager for your provider and do not see it listed here,
please reach out to the cloud provider you are integrating with or the
&lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-cloud-provider&#34;&gt;Kubernetes SIG Cloud Provider community&lt;/a&gt; for help and advice. It is
worth noting that while most cloud controller managers are open source today,
this may not always be the case. Users should always contact their cloud
provider to learn if there are preferred solutions to utilize on their
infrastructure.&lt;/p&gt;
&lt;h3 id=&#34;cloud-provider-integrations&#34;&gt;Cloud provider integrations provided by the Kubernetes project&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;AWS - &lt;a href=&#34;https://github.com/kubernetes/cloud-provider-aws&#34;&gt;https://github.com/kubernetes/cloud-provider-aws&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Azure - &lt;a href=&#34;https://github.com/kubernetes-sigs/cloud-provider-azure&#34;&gt;https://github.com/kubernetes-sigs/cloud-provider-azure&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;GCE - &lt;a href=&#34;https://github.com/kubernetes/cloud-provider-gcp&#34;&gt;https://github.com/kubernetes/cloud-provider-gcp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;OpenStack - &lt;a href=&#34;https://github.com/kubernetes/cloud-provider-openstack&#34;&gt;https://github.com/kubernetes/cloud-provider-openstack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;vSphere - &lt;a href=&#34;https://github.com/kubernetes/cloud-provider-vsphere&#34;&gt;https://github.com/kubernetes/cloud-provider-vsphere&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you are looking for an automated approach to installing cloud controller
managers in your clusters, the &lt;a href=&#34;https://github.com/kubernetes/kops&#34;&gt;kOps&lt;/a&gt; project provides a convenient
solution for managing production-ready clusters.&lt;/p&gt;
&lt;h2 id=&#34;want-to-learn-more&#34;&gt;Want to learn more?&lt;/h2&gt;
&lt;p&gt;Cloud providers and cloud controller managers serve a core function in
Kubernetes. Cloud providers are often the substrate upon which Kubernetes is
operated, and the cloud controller managers supply the essential lifeline
between Kubernetes clusters and their physical infrastructure.&lt;/p&gt;
&lt;p&gt;This post covers one aspect of how the Kubernetes community interacts with
the world of cloud infrastructure providers. If you are curious about this
topic and want to learn more, the Cloud Provider Special Interest Group (SIG)
is the place to go. SIG Cloud Provider hosts bi-weekly meetings to discuss all
manner of topics related to cloud providers and cloud controller managers in
Kubernetes.&lt;/p&gt;
&lt;h3 id=&#34;sig-cloud-provider&#34;&gt;SIG Cloud Provider&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Regular SIG Meeting: &lt;a href=&#34;https://zoom.us/j/508079177?pwd=ZmEvMksxdTFTc0N1eXFLRm91QUlyUT09&#34;&gt;Wednesdays at 9:00 PT (Pacific Time)&lt;/a&gt; (biweekly). &lt;a href=&#34;http://www.thetimezoneconverter.com/?t=9:00&amp;amp;tz=PT%20%28Pacific%20Time%29&#34;&gt;Convert to your timezone&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kubernetes.slack.com&#34;&gt;Kubernetes slack&lt;/a&gt; channel &lt;code&gt;#sig-cloud-provider&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-cloud-provider&#34;&gt;SIG Community page&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes v1.29: Mandala</title>
      <link>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/12/13/kubernetes-v1-29-release/</link>
      <pubDate>Wed, 13 Dec 2023 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/12/13/kubernetes-v1-29-release/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Authors:&lt;/strong&gt; &lt;a href=&#34;https://github.com/kubernetes/sig-release/blob/master/releases/release-1.29/release-team.md&#34;&gt;Kubernetes v1.29 Release Team&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Editors:&lt;/strong&gt; Carol Valencia, Kristin Martin, Abigail McCarthy, James Quigley&lt;/p&gt;
&lt;p&gt;Announcing the release of Kubernetes v1.29: Mandala (The Universe), the last release of 2023!&lt;/p&gt;
&lt;p&gt;Similar to previous releases, the release of Kubernetes v1.29 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 49 enhancements. Of those enhancements, 11 have graduated to Stable, 19 are entering Beta and 19 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.29: &lt;em&gt;Mandala (The Universe)&lt;/em&gt; ✨🌌&lt;/p&gt;

&lt;figure class=&#34;release-logo&#34;&gt;
    &lt;img src=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/images/blog/2023-12-13-kubernetes-1.29-release/k8s-1.29.png&#34;
         alt=&#34;Kubernetes 1.29 Mandala logo&#34;/&gt; 
&lt;/figure&gt;

&lt;p&gt;Join us on a cosmic journey with Kubernetes v1.29!&lt;/p&gt;
&lt;p&gt;This release is inspired by the beautiful art form that is Mandala—a symbol of the universe in its perfection. Our tight-knit universe of around 40 Release Team members, backed by hundreds of community contributors, has worked tirelessly to turn challenges into joy for millions worldwide.&lt;/p&gt;
&lt;p&gt;The Mandala theme reflects our community’s interconnectedness—a vibrant tapestry woven by enthusiasts and experts alike. Each contributor is a crucial part, adding their unique energy, much like the diverse patterns in Mandala art. Kubernetes thrives on collaboration, echoing the harmony in Mandala creations.&lt;/p&gt;
&lt;p&gt;The release logo, made by &lt;a href=&#34;https://janusworx.com&#34;&gt;Mario Jason Braganza&lt;/a&gt; (base Mandala art, courtesy - &lt;a href=&#34;https://pixabay.com/users/fibrel-3502541/&#34;&gt;Fibrel Ojalá&lt;/a&gt;), symbolizes the little universe that is the Kubernetes project and all its people.&lt;/p&gt;
&lt;p&gt;In the spirit of Mandala’s transformative symbolism, Kubernetes v1.29 celebrates our project’s evolution. Like stars in the Kubernetes universe, each contributor, user, and supporter lights the way. Together, we create a universe of possibilities—one release at a time.&lt;/p&gt;
&lt;h2 id=&#34;graduations-to-stable&#34;&gt;Improvements that graduated to stable in Kubernetes v1.29&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.29 release.&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&#34;readwriteoncepod-pv-access-mode&#34;&gt;ReadWriteOncePod PersistentVolume access mode (&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;In Kubernetes, volume &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/concepts/storage/persistent-volumes/#access-modes&#34;&gt;access modes&lt;/a&gt;
are the way you can define how durable storage is consumed. These access modes are a part of the spec for PersistentVolumes (PVs) and PersistentVolumeClaims (PVCs). When using storage, there are different ways to model how that storage is consumed. For example, a storage system like a network file share can have many users all reading and writing data simultaneously. In other cases maybe everyone is allowed to read data but not write it. For highly sensitive data, maybe only one user is allowed to read and write data but nobody else.&lt;/p&gt;
&lt;p&gt;Before v1.22, Kubernetes offered three access modes for PVs and PVCs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ReadWriteOnce – the volume can be mounted as read-write by a single node&lt;/li&gt;
&lt;li&gt;ReadOnlyMany – the volume can be mounted read-only by many nodes&lt;/li&gt;
&lt;li&gt;ReadWriteMany – the volume can be mounted as read-write by many nodes&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The ReadWriteOnce access mode restricts volume access to a single node, which means it is possible for multiple pods on the same node to read from and write to the same volume. This could potentially be a major problem for some applications, especially if they require at most one writer for data safety guarantees.&lt;/p&gt;
&lt;p&gt;To address this problem, a fourth access mode ReadWriteOncePod was introduced as an Alpha feature in v1.22 for CSI volumes. If you create a pod with a PVC that uses the ReadWriteOncePod access mode, Kubernetes ensures that pod is the only pod across your whole cluster that can read that PVC or write to it. In v1.29, this feature became Generally Available.&lt;/p&gt;
&lt;h3 id=&#34;csi-node-volume-expansion-secrets&#34;&gt;Node volume expansion Secret support for CSI drivers (&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;In Kubernetes, a volume expansion operation may include the expansion of the volume on the node, which involves filesystem resize. Some CSI drivers require secrets, for example a credential for accessing a SAN fabric, during the node expansion for the following use cases:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When a PersistentVolume represents encrypted block storage, for example using LUKS, you may need to provide a passphrase in order to expand the device.&lt;/li&gt;
&lt;li&gt;For various validations, the CSI driver needs to have credentials to communicate with the backend storage system at time of node expansion.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To meet this requirement, the CSI Node Expand Secret feature was introduced in Kubernetes v1.25. This allows an optional secret field to be sent as part of the NodeExpandVolumeRequest by the CSI drivers so that node volume expansion operation can be performed with the underlying storage system. In Kubernetes v1.29, this feature became generally available.&lt;/p&gt;
&lt;h3 id=&#34;kms-v2-api-encryption&#34;&gt;KMS v2 encryption at rest generally available (&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;One of the first things to consider when securing a Kubernetes cluster is encrypting persisted
API data at rest. KMS provides an interface for a provider to utilize a key stored in an external
key service to perform this encryption. With the Kubernetes v1.29, KMS v2 has become
a stable feature bringing numerous improvements in performance, key rotation,
health check &amp;amp; status, and observability.
These enhancements provide users with a reliable solution to encrypt all resources in their Kubernetes clusters. You can read more about this in &lt;a href=&#34;https://kep.k8s.io/3299&#34;&gt;KEP-3299&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It is recommended to use KMS v2. KMS v1 feature gate is disabled by default. You will have to opt in to continue to use it.&lt;/p&gt;
&lt;h2 id=&#34;graduations-to-beta&#34;&gt;Improvements that graduated to beta in Kubernetes v1.29&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.29 release.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The throughput of the scheduler is our eternal challenge. This QueueingHint feature brings a new possibility to optimize the efficiency of requeueing, which could reduce useless scheduling retries significantly.&lt;/p&gt;
&lt;h3 id=&#34;node-lifecycle-separated-from-taint-management-sig-scheduling-https-github-com-kubernetes-community-tree-master-sig-scheduling&#34;&gt;Node lifecycle separated from taint management (&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;As title describes, it&#39;s to decouple &lt;code&gt;TaintManager&lt;/code&gt; that performs taint-based pod eviction from &lt;code&gt;NodeLifecycleController&lt;/code&gt; and make them two separate controllers: &lt;code&gt;NodeLifecycleController&lt;/code&gt; to add taints to unhealthy nodes and &lt;code&gt;TaintManager&lt;/code&gt; to perform pod deletion on nodes tainted with NoExecute effect.&lt;/p&gt;
&lt;h3 id=&#34;serviceaccount-token-clean-up&#34;&gt;Clean up for legacy Secret-based ServiceAccount tokens (&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;Kubernetes switched to using more secure service account tokens, which were time-limited and bound to specific pods by 1.22. Stopped auto-generating legacy secret-based service account tokens in 1.24. Then started labeling remaining auto-generated secret-based tokens still in use with their last-used date in 1.27.&lt;/p&gt;
&lt;p&gt;In v1.29, to reduce potential attack surface, the LegacyServiceAccountTokenCleanUp feature labels legacy auto-generated secret-based tokens as invalid if they have not been used for a long time (1 year by default), and automatically removes them if use is not attempted for a long time after being marked as invalid (1 additional year by default). &lt;a href=&#34;https://kep.k8s.io/2799&#34;&gt;KEP-2799&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;match-label-keys-pod-affinity&#34;&gt;Define Pod affinity or anti-affinity using &lt;code&gt;matchLabelKeys&lt;/code&gt; (&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;One enhancement will be introduced in PodAffinity/PodAntiAffinity as alpha. It will increase the accuracy of calculation during rolling updates.&lt;/p&gt;
&lt;h3 id=&#34;kube-proxy-nftables&#34;&gt;nftables backend for kube-proxy (&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 default kube-proxy implementation on Linux is currently based on iptables. This was the preferred packet filtering and processing system in the Linux kernel for many years (starting with the 2.4 kernel in 2001). However, unsolvable problems with iptables led to the development of a successor, nftables. Development on iptables has mostly stopped, with new features and performance improvements primarily going into nftables instead.&lt;/p&gt;
&lt;p&gt;This feature adds a new backend to kube-proxy based on nftables, since some Linux distributions already started to deprecate and remove iptables, and nftables claims to solve the main performance problems of iptables.&lt;/p&gt;
&lt;h3 id=&#34;ip-address-range-apis&#34;&gt;APIs to manage IP address ranges 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;Services are an abstract way to expose an application running on a set of Pods. Services can have a cluster-scoped virtual IP address, that is allocated from a predefined CIDR defined in the kube-apiserver flags. However, users may want to add, remove, or resize existing IP ranges allocated for Services without having to restart the kube-apiserver.&lt;/p&gt;
&lt;p&gt;This feature implements a new allocator logic that uses 2 new API Objects: ServiceCIDR and IPAddress, allowing users to dynamically increase the number of Services IPs available by creating new ServiceCIDRs. This helps to resolve problems like IP exhaustion or IP renumbering.&lt;/p&gt;
&lt;h3 id=&#34;image-pull-per-runtimeclass&#34;&gt;Add support to containerd/kubelet/CRI to support image pull per runtime class (&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;Kubernetes v1.29 adds support to pull container images based on the RuntimeClass of the Pod that uses them.
This feature is off by default in v1.29 under a feature gate called &lt;code&gt;RuntimeClassInImageCriApi&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Container images can either be a manifest or an index. When the image being pulled is an index (image index has a list of image manifests ordered by platform), platform matching logic in the container runtime is used to pull an appropriate image manifest from the index. By default, the platform matching logic picks a manifest that matches the host that the image pull is being executed from. This can be limiting for VM-based containers where a user could pull an image with the intention of running it as a VM-based container, for example, Windows Hyper-V containers.&lt;/p&gt;
&lt;p&gt;The image pull per runtime class feature adds support to pull different images based the runtime class specified. This is achieved by referencing an image by a tuple of (&lt;code&gt;imageID&lt;/code&gt;, &lt;code&gt;runtimeClass&lt;/code&gt;), instead of just the &lt;code&gt;imageName&lt;/code&gt; or &lt;code&gt;imageID&lt;/code&gt;. Container runtimes could choose to add support for this feature if they&#39;d like. If they do not, the default behavior of kubelet that existed prior to Kubernetes v1.29 will be retained.&lt;/p&gt;
&lt;h3 id=&#34;in-place-updates-for-pod-resources-for-windows-pods-sig-windows-https-github-com-kubernetes-community-tree-master-sig-windows&#34;&gt;In-place updates for Pod resources, for Windows Pods (&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;As an alpha feature, Kubernetes Pods can be mutable with respect to their &lt;code&gt;resources&lt;/code&gt;, allowing users to change the &lt;em&gt;desired&lt;/em&gt; resource requests and limits for a Pod without the need to restart the Pod. With v1.29, this feature is now supported for Windows containers.&lt;/p&gt;
&lt;h2 id=&#34;graduations-deprecations-and-removals-for-kubernetes-v1-29&#34;&gt;Graduations, deprecations and removals for Kubernetes v1.29&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.29.md&#34;&gt;release notes&lt;/a&gt;.&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://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/3668&#34;&gt;Reserve nodeport ranges for dynamic and static allocation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/1040&#34;&gt;Priority and Fairness for API Server Requests&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/3299&#34;&gt;KMS v2 Improvements&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/365&#34;&gt;Support paged LIST queries from the Kubernetes API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/2485&#34;&gt;ReadWriteOncePod PersistentVolume Access Mode&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/3466&#34;&gt;Kubernetes Component Health SLIs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/2876&#34;&gt;CRD Validation Expression Language&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/3107&#34;&gt;Introduce nodeExpandSecret in CSI PV source&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/2879&#34;&gt;Track Ready Pods in Job status&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kep.k8s.io/727&#34;&gt;Kubelet Resource Metrics Endpoint&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;in-tree-cloud-provider-integration-removal&#34;&gt;Removal of in-tree integrations with cloud providers (&lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-cloud-provider&#34;&gt;SIG Cloud Provider&lt;/a&gt;)&lt;/h4&gt;
&lt;p&gt;Kubernetes v1.29 defaults to operating &lt;em&gt;without&lt;/em&gt; a built-in integration to any cloud provider.
If you have previously been relying on in-tree cloud provider integrations (with Azure, GCE, or vSphere) then you can either:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;enable an equivalent external &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/concepts/architecture/cloud-controller/&#34;&gt;cloud controller manager&lt;/a&gt;
integration &lt;em&gt;(recommended)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;opt back in to the legacy integration by setting the associated feature gates to &lt;code&gt;false&lt;/code&gt;; the feature
gates to change are &lt;code&gt;DisableCloudProviders&lt;/code&gt; and &lt;code&gt;DisableKubeletCloudCredentialProviders&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Enabling external cloud controller managers means you must run a suitable cloud controller manager within your cluster&#39;s control plane; it also requires setting the command line argument &lt;code&gt;--cloud-provider=external&lt;/code&gt; for the kubelet (on every relevant node), and across the control plane (kube-apiserver and kube-controller-manager).&lt;/p&gt;
&lt;p&gt;For more information about how to enable and run external cloud controller managers, read &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/tasks/administer-cluster/running-cloud-controller/&#34;&gt;Cloud Controller Manager Administration&lt;/a&gt; and &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/tasks/administer-cluster/controller-manager-leader-migration/&#34;&gt;Migrate Replicated Control Plane To Use Cloud Controller Manager&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you need a cloud controller manager for one of the legacy in-tree providers, please see the following links:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/cloud-provider-aws&#34;&gt;Cloud provider AWS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes-sigs/cloud-provider-azure&#34;&gt;Cloud provider Azure&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/cloud-provider-gcp&#34;&gt;Cloud provider GCE&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/cloud-provider-openstack&#34;&gt;Cloud provider OpenStack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/cloud-provider-vsphere&#34;&gt;Cloud provider vSphere&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are more details in &lt;a href=&#34;https://kep.k8s.io/2395&#34;&gt;KEP-2395&lt;/a&gt;.&lt;/p&gt;
&lt;h4 id=&#34;removal-of-the-v1beta2-flow-control-api-group&#34;&gt;Removal of the &lt;code&gt;v1beta2&lt;/code&gt; flow control API group&lt;/h4&gt;
&lt;p&gt;The deprecated &lt;em&gt;flowcontrol.apiserver.k8s.io/v1beta2&lt;/em&gt; API version of FlowSchema and
PriorityLevelConfiguration are no longer served in Kubernetes v1.29.&lt;/p&gt;
&lt;p&gt;If you have manifests or client software that uses the deprecated beta API group, you should change
these before you upgrade to v1.29.
See the &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/reference/using-api/deprecation-guide/#v1-29&#34;&gt;deprecated API migration guide&lt;/a&gt;
for details and advice.&lt;/p&gt;
&lt;h4 id=&#34;deprecation-of-the-status-nodeinfo-kubeproxyversion-field-for-node&#34;&gt;Deprecation of the &lt;code&gt;status.nodeInfo.kubeProxyVersion&lt;/code&gt; field for Node&lt;/h4&gt;
&lt;p&gt;The &lt;code&gt;.status.kubeProxyVersion&lt;/code&gt; field for Node objects is now deprecated, and the Kubernetes project
is proposing to remove that field in a future release. The deprecated field is not accurate and has historically
been managed by kubelet - which does not actually know the kube-proxy version, or even whether kube-proxy
is running.&lt;/p&gt;
&lt;p&gt;If you&#39;ve been using this field in client software, stop - the information isn&#39;t reliable and the field is now
deprecated.&lt;/p&gt;
&lt;h4 id=&#34;legacy-linux-package-repositories&#34;&gt;Legacy Linux package repositories&lt;/h4&gt;
&lt;p&gt;Please note that in August of 2023, the legacy package repositories (&lt;code&gt;apt.kubernetes.io&lt;/code&gt; and
&lt;code&gt;yum.kubernetes.io&lt;/code&gt;) were formally deprecated and the Kubernetes project announced the
general availability of the community-owned package repositories for Debian and RPM packages,
available at &lt;code&gt;https://pkgs.k8s.io&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;These legacy repositories were frozen in September of 2023, and
will go away entirely in January of 2024. If you are currently relying on them, you &lt;strong&gt;must&lt;/strong&gt; migrate.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This deprecation is not directly related to the v1.29 release.&lt;/em&gt; For more details, including how these changes may affect you and what to do if you are affected, please read the &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/08/31/legacy-package-repository-deprecation/&#34;&gt;legacy package repository deprecation announcement&lt;/a&gt;.&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.29 release in our &lt;a href=&#34;https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.29.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.29 is available for download on &lt;a href=&#34;https://github.com/kubernetes/kubernetes/releases/tag/v1.29.0&#34;&gt;GitHub&lt;/a&gt;. To get started with Kubernetes, check out these &lt;a href=&#34;https://deploy-preview-57407--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.29 using &lt;a href=&#34;https://deploy-preview-57407--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.29/release-team.md&#34;&gt;release team&lt;/a&gt; for the hours spent hard at work to deliver the Kubernetes v1.29 release for our community. A very special thanks is in order for our release lead, &lt;a href=&#34;https://github.com/Priyankasaggu11929&#34;&gt;Priyanka Saggu&lt;/a&gt;, for supporting and guiding us through a successful release cycle, 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.29 release cycle, which &lt;a href=&#34;https://github.com/kubernetes/sig-release/tree/master/releases/release-1.29&#34;&gt;ran for 14 weeks&lt;/a&gt; (September 6 to December 13), we saw contributions from &lt;a href=&#34;https://k8s.devstats.cncf.io/d/9/companies-table?orgId=1&amp;amp;var-period_name=v1.28.0%20-%20now&amp;amp;var-metric=contributions&#34;&gt;888 companies&lt;/a&gt; and &lt;a href=&#34;https://k8s.devstats.cncf.io/d/66/developer-activity-counts-by-companies?orgId=1&amp;amp;var-period_name=v1.28.0%20-%20now&amp;amp;var-metric=contributions&amp;amp;var-repogroup_name=Kubernetes&amp;amp;var-repo_name=kubernetes%2Fkubernetes&amp;amp;var-country_name=All&amp;amp;var-companies=All&#34;&gt;1422 individuals&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;ecosystem-updates&#34;&gt;Ecosystem updates&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;KubeCon + CloudNativeCon Europe 2024 will take in Paris, France, from &lt;strong&gt;19 – 22 March 2024&lt;/strong&gt;! You can find more information about the conference and registration on the &lt;a href=&#34;https://events.linuxfoundation.org/kubecon-cloudnativecon-europe/&#34;&gt;event site&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;release-webinar&#34;&gt;Upcoming release webinar&lt;/h2&gt;
&lt;p&gt;Join members of the Kubernetes v1.29 release team on Friday, December 15th, 2023, at 11am PT (2pm eastern) 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-129-release/&#34;&gt;event page&lt;/a&gt; on the CNCF Online Programs site.&lt;/p&gt;
&lt;h3 id=&#34;get-involved&#34;&gt;Get involved&lt;/h3&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 Twitter &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;

      </description>
    </item>
    
    <item>
      <title>New Experimental Features in Gateway API v1.0</title>
      <link>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/11/28/gateway-api-ga/</link>
      <pubDate>Tue, 28 Nov 2023 10:00:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/11/28/gateway-api-ga/</guid>
      <description>
        
        
        &lt;p&gt;&lt;em&gt;&lt;strong&gt;Authors:&lt;/strong&gt;&lt;/em&gt; Candace Holman (Red Hat), Dave Protasowski (VMware), Gaurav K Ghildiyal (Google), John Howard (Google), Simone Rodigari (IBM)&lt;/p&gt;
&lt;p&gt;Recently, the &lt;a href=&#34;https://gateway-api.sigs.k8s.io/&#34;&gt;Gateway API&lt;/a&gt; &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/10/31/gateway-api-ga/&#34;&gt;announced its v1.0 GA release&lt;/a&gt;, marking a huge milestone for the project.&lt;/p&gt;
&lt;p&gt;Along with stabilizing some of the core functionality in the API, a number of exciting new &lt;em&gt;experimental&lt;/em&gt; features have been added.&lt;/p&gt;
&lt;h2 id=&#34;backend-tls-policy&#34;&gt;Backend TLS Policy&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;BackendTLSPolicy&lt;/code&gt; is a new Gateway API type used for specifying the TLS configuration of the connection from the Gateway to backend Pods via the Service API object.
It is specified as a &lt;a href=&#34;https://gateway-api.sigs.k8s.io/geps/gep-713/#direct-policy-attachment&#34;&gt;Direct PolicyAttachment&lt;/a&gt; without defaults or overrides, applied to a Service that accesses a backend, where the BackendTLSPolicy resides in the same namespace as the Service to which it is applied.
All Gateway API Routes that point to a referenced Service should respect a configured &lt;code&gt;BackendTLSPolicy&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;While there were existing ways provided for &lt;a href=&#34;https://gateway-api.sigs.k8s.io/guides/tls/#tls-configuration&#34;&gt;TLS to be configured for edge and passthrough termination&lt;/a&gt;, this new API object specifically addresses the configuration of TLS in order to convey HTTPS from the Gateway dataplane to the backend.
This is referred to as &amp;quot;backend TLS termination&amp;quot; and enables the Gateway to know how to connect to a backend Pod that has its own certificate.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://gateway-api.sigs.k8s.io/geps/images/1897-TLStermtypes.png&#34; alt=&#34;Termination Types&#34;&gt;&lt;/p&gt;
&lt;p&gt;The specification of a &lt;code&gt;BackendTLSPolicy&lt;/code&gt; consists of:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;targetRef&lt;/code&gt; - Defines the targeted API object of the policy.  Only Service is allowed.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tls&lt;/code&gt; - Defines the configuration for TLS, including &lt;code&gt;hostname&lt;/code&gt;, &lt;code&gt;caCertRefs&lt;/code&gt;, and &lt;code&gt;wellKnownCACerts&lt;/code&gt;. Either &lt;code&gt;caCertRefs&lt;/code&gt; or &lt;code&gt;wellKnownCACerts&lt;/code&gt; may be specified, but not both.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hostname&lt;/code&gt; - Defines the Server Name Indication (SNI) that the Gateway uses to connect to the backend. The certificate served by the backend must match this SNI.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;caCertRefs&lt;/code&gt; - Defines one or more references to objects that contain PEM-encoded TLS certificates, which are used to establish a TLS handshake between the Gateway and backend.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;wellKnownCACerts&lt;/code&gt; - Specifies whether or not system CA certificates may be used in the TLS handshake between the Gateway and backend.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;examples&#34;&gt;Examples&lt;/h3&gt;
&lt;h4 id=&#34;using-system-certificates&#34;&gt;Using System Certificates&lt;/h4&gt;
&lt;p&gt;In this example, the &lt;code&gt;BackendTLSPolicy&lt;/code&gt; is configured to use system certificates to connect with a TLS-encrypted upstream connection where Pods backing the &lt;code&gt;dev&lt;/code&gt; Service are expected to serve a valid certificate for &lt;code&gt;dev.example.com&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;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;BackendTLSPolicy&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;tls-upstream-dev&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;targetRef&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;dev-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;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;wellKnownCACerts&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;System&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;hostname&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;dev.example.com&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;using-explicit-ca-certificates&#34;&gt;Using Explicit CA Certificates&lt;/h4&gt;
&lt;p&gt;In this example, the &lt;code&gt;BackendTLSPolicy&lt;/code&gt; is configured to use certificates defined in the configuration map &lt;code&gt;auth-cert&lt;/code&gt; to connect with a TLS-encrypted upstream connection where Pods backing the &lt;code&gt;auth&lt;/code&gt; Service are expected to serve a valid certificate for &lt;code&gt;auth.example.com&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;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;BackendTLSPolicy&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;tls-upstream-auth&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;targetRef&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;auth-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;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;caCertRefs&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;ConfigMapReference&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;auth-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;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;hostname&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;auth.example.com&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 illustrates a BackendTLSPolicy that configures TLS for a Service serving a backend:&lt;/p&gt;
&lt;figure&gt;
&lt;div class=&#34;mermaid&#34;&gt;
    
flowchart LR
    client([&#34;client&#34;])
    gateway[&#34;Gateway&#34;]
    style gateway fill:#02f,color:#fff
    httproute[&#34;HTTP&lt;BR&gt;Route&#34;]
    style httproute fill:#02f,color:#fff
    service[&#34;Service&#34;]
    style service fill:#02f,color:#fff
    pod1[&#34;Pod&#34;]
    style pod1 fill:#02f,color:#fff
    pod2[&#34;Pod&#34;]
    style pod2 fill:#02f,color:#fff
    client -.-&gt;|HTTP &lt;br&gt; request| gateway
    gateway --&gt; httproute
    httproute -.-&gt;|BackendTLSPolicy|service
    service --&gt; pod1 &amp; pod2

&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;For more information, refer to the &lt;a href=&#34;https://gateway-api.sigs.k8s.io/guides/tls&#34;&gt;documentation for TLS&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;httproute-timeouts&#34;&gt;HTTPRoute Timeouts&lt;/h2&gt;
&lt;p&gt;A key enhancement in Gateway API&#39;s latest release (v1.0) is the introduction of the &lt;code&gt;timeouts&lt;/code&gt; field within HTTPRoute Rules. This feature offers a dynamic way to manage timeouts for incoming HTTP requests, adding precision and reliability to your gateway setups.&lt;/p&gt;
&lt;p&gt;With Timeouts, developers can fine-tune their Gateway API&#39;s behavior in two fundamental ways:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Request Timeout&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;The request timeout is the duration within which the Gateway API implementation must send a response to a client&#39;s HTTP request.
It allows flexibility in specifying when this timeout starts, either before or after the entire client request stream is received, making it implementation-specific.
This timeout efficiently covers the entire request-response transaction, enhancing the responsiveness of your services.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Backend Request Timeout&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;The backendRequest timeout is a game-changer for those dealing with backends.
It sets a timeout for a single request sent from the Gateway to a backend service.
This timeout spans from the initiation of the request to the reception of the full response from the backend.
This feature is particularly helpful in scenarios where the Gateway needs to retry connections to a backend, ensuring smooth communication under various conditions.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Notably, the &lt;code&gt;request&lt;/code&gt; timeout encompasses the &lt;code&gt;backendRequest&lt;/code&gt; timeout. Hence, the value of &lt;code&gt;backendRequest&lt;/code&gt; should never exceed the value of the &lt;code&gt;request&lt;/code&gt; timeout.&lt;/p&gt;
&lt;p&gt;The ability to configure these timeouts adds a new layer of reliability to your Kubernetes services.
Whether it&#39;s ensuring client requests are processed within a specified timeframe or managing backend service communications, Gateway API&#39;s Timeouts offer the control and predictability you need.&lt;/p&gt;
&lt;p&gt;To get started, you can define timeouts in your HTTPRoute Rules using the Timeouts field, specifying their type as Duration.
A zero-valued timeout (&lt;code&gt;0s&lt;/code&gt;) disables the timeout, while a valid non-zero-valued timeout should be at least 1ms.&lt;/p&gt;
&lt;p&gt;Here&#39;s an example of setting request and backendRequest timeouts in an HTTPRoute:&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;timeout-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;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;example-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;/timeout&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;10s&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;backendRequest&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;2s&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;timeout-svc&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;8080&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, a &lt;code&gt;request&lt;/code&gt; timeout of 10 seconds is defined, ensuring that client requests are processed within that timeframe.
Additionally, a 2-second &lt;code&gt;backendRequest&lt;/code&gt; timeout is set for individual requests from the Gateway to a backend service called timeout-svc.&lt;/p&gt;
&lt;p&gt;These new HTTPRoute Timeouts provide Kubernetes users with more control and flexibility in managing network communications, helping ensure a smoother and more predictable experience for both clients and backends.
For additional details and examples, refer to the &lt;a href=&#34;https://gateway-api.sigs.k8s.io/api-types/httproute/#timeouts-optional&#34;&gt;official timeouts API documentation&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;gateway-infrastructure-labels&#34;&gt;Gateway Infrastructure Labels&lt;/h2&gt;
&lt;p&gt;While Gateway API providers a common API for different implementations, each implementation will have different resources created under-the-hood to apply users&#39; intent.
This could be configuring cloud load balancers, creating in-cluster Pods and Services, or more.&lt;/p&gt;
&lt;p&gt;While the API has always provided an extension point -- &lt;code&gt;parametersRef&lt;/code&gt; in &lt;code&gt;GatewayClass&lt;/code&gt; -- to customize implementation specific things, there was no common core way to express common infrastructure customizations.&lt;/p&gt;
&lt;p&gt;Gateway API v1.0 paves the way for this with a new &lt;code&gt;infrastructure&lt;/code&gt; field on the &lt;code&gt;Gateway&lt;/code&gt; object, allowing customization of the underlying infrastructure.
For now, this starts small with two critical fields: labels and annotations.
When these are set, any generated infrastructure will have the provided labels and annotations set on them.&lt;/p&gt;
&lt;p&gt;For example, I may want to group all my resources for one application 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;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;hello-world&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;infrastructure&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;app.kubernetes.io/name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;hello-world&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 future, we are looking into more common infrastructure configurations, such as resource sizing.&lt;/p&gt;
&lt;p&gt;For more information, refer to the &lt;a href=&#34;https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.GatewayInfrastructure&#34;&gt;documentation&lt;/a&gt; for this feature.&lt;/p&gt;
&lt;h2 id=&#34;support-for-websockets-http-2-and-more&#34;&gt;Support for Websockets, HTTP/2 and more!&lt;/h2&gt;
&lt;p&gt;Not all implementations of Gateway API support automatic protocol selection.
In some cases protocols are disabled without an explicit opt-in.&lt;/p&gt;
&lt;p&gt;When a Route&#39;s backend references a Kubernetes Service, application developers can specify the protocol using &lt;code&gt;ServicePort&lt;/code&gt; &lt;a href=&#34;https://kubernetes.io/docs/concepts/services-networking/service/#application-protocol&#34;&gt;&lt;code&gt;appProtocol&lt;/code&gt;&lt;/a&gt; field.&lt;/p&gt;
&lt;p&gt;For example the following &lt;code&gt;store&lt;/code&gt; Kubernetes Service is indicating the port &lt;code&gt;8080&lt;/code&gt; supports HTTP/2 Prior Knowledge.&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;store&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;store&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;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/h2c&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;8080&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;8080&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, Gateway API has conformance testing for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;kubernetes.io/h2c&lt;/code&gt; - HTTP/2 Prior Knowledge&lt;/li&gt;
&lt;li&gt;&lt;code&gt;kubernetes.io/ws&lt;/code&gt; - WebSocket over HTTP&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For more information, refer to the documentation for &lt;a href=&#34;https://gateway-api.sigs.k8s.io/guides/backend-protocol&#34;&gt;Backend Protocol Selection&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;gwctl-our-new-gateway-api-command-line-tool&#34;&gt;&lt;code&gt;gwctl&lt;/code&gt;, our new Gateway API command line tool&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;gwctl&lt;/code&gt; is a command line tool that aims to be a &lt;code&gt;kubectl&lt;/code&gt; replacement for viewing Gateway API resources.&lt;/p&gt;
&lt;p&gt;The initial release of &lt;code&gt;gwctl&lt;/code&gt; that comes bundled with Gateway v1.0 release includes helpful features for managing Gateway API Policies.
Gateway API Policies serve as powerful extension mechanisms for modifying the behavior of Gateway resources.
One challenge with using policies is that it may be hard to discover which policies are affecting which Gateway resources.
&lt;code&gt;gwctl&lt;/code&gt; helps bridge this gap by answering questions like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Which policies are available for use in the Kubernetes cluster?&lt;/li&gt;
&lt;li&gt;Which policies are attached to a particular Gateway, HTTPRoute, etc?&lt;/li&gt;
&lt;li&gt;If policies are applied to multiple resources in the Gateway resource hierarchy, what is the effective policy that is affecting a particular resource? (For example, if an HTTP request timeout policy is applied to both an HTTPRoute and its parent Gateway, what is the effective timeout for the HTTPRoute?)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;gwctl&lt;/code&gt; is still in the very early phases of development and hence may be a bit rough around the edges.
Follow the instructions in &lt;a href=&#34;https://github.com/kubernetes-sigs/gateway-api/tree/main/gwctl#try-it-out&#34;&gt;the repository&lt;/a&gt; to install and try out &lt;code&gt;gwctl&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&#34;examples-1&#34;&gt;Examples&lt;/h3&gt;
&lt;p&gt;Here are some examples of how &lt;code&gt;gwctl&lt;/code&gt; can be used:&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# List all policies in the cluster. This will also give the resource they bind&lt;/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;# to.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;gwctl get policies -A
&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;# List all available policy types.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;gwctl get policycrds
&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;# Describe all HTTPRoutes in namespace ns2. (Output includes effective policies)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;gwctl describe httproutes -n ns2
&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;# Describe a single HTTPRoute in the default namespace. (Output includes&lt;/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;# effective policies)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;gwctl describe httproutes my-httproute-1
&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;# Describe all Gateways across all namespaces. (Output includes effective&lt;/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;# policies)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;gwctl describe gateways -A
&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;# Describe a single GatewayClass. (Output includes effective policies)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;gwctl describe gatewayclasses foo-com-external-gateway-class
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;get-involved&#34;&gt;Get involved&lt;/h2&gt;
&lt;p&gt;These projects, and many more, continue to be improved in Gateway API.
There are lots of opportunities to get involved and help define the future of Kubernetes routing APIs for both Ingress and Mesh.&lt;/p&gt;
&lt;p&gt;If this is interesting to you, please &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;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Spotlight on SIG Testing</title>
      <link>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/11/24/sig-testing-spotlight-2023/</link>
      <pubDate>Fri, 24 Nov 2023 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/11/24/sig-testing-spotlight-2023/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Author:&lt;/strong&gt; Sandipan Panda&lt;/p&gt;
&lt;p&gt;Welcome to another edition of the &lt;em&gt;SIG spotlight&lt;/em&gt; blog series, where we
highlight the incredible work being done by various Special Interest
Groups (SIGs) within the Kubernetes project. In this edition, we turn
our attention to &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-testing#readme&#34;&gt;SIG Testing&lt;/a&gt;,
a group interested in effective testing of Kubernetes and automating
away project toil. SIG Testing focus on creating and running tools and
infrastructure that make it easier for the community to write and run
tests, and to contribute, analyze and act upon test results.&lt;/p&gt;
&lt;p&gt;To gain some insights into SIG Testing, &lt;a href=&#34;https://github.com/sandipanpanda&#34;&gt;Sandipan
Panda&lt;/a&gt; spoke with &lt;a href=&#34;https://github.com/michelle192837&#34;&gt;Michelle Shepardson&lt;/a&gt;,
a senior software engineer at Google and a chair of SIG Testing, and
&lt;a href=&#34;https://github.com/pohly&#34;&gt;Patrick Ohly&lt;/a&gt;, a software engineer and architect at
Intel and a SIG Testing Tech Lead.&lt;/p&gt;
&lt;h2 id=&#34;meet-the-contributors&#34;&gt;Meet the contributors&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Sandipan:&lt;/strong&gt; Could you tell us a bit about yourself, your role, and
how you got involved in the Kubernetes project and SIG Testing?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Michelle:&lt;/strong&gt; Hi! I&#39;m Michelle, a senior software engineer at
Google. I first got involved in Kubernetes through working on tooling
for SIG Testing, like the external instance of TestGrid. I&#39;m part of
oncall for TestGrid and Prow, and am now a chair for the SIG.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Patrick:&lt;/strong&gt; Hello! I work as a software engineer and architect in a
team at Intel which focuses on open source Cloud Native projects. When
I ramped up on Kubernetes to develop a storage driver, my very first
question was &amp;quot;how do I test it in a cluster and how do I log
information?&amp;quot; That interest led to various enhancement proposals until
I had (re)written enough code that also took over official roles as
SIG Testing Tech Lead (for the &lt;a href=&#34;https://github.com/kubernetes-sigs/e2e-framework&#34;&gt;E2E framework&lt;/a&gt;) and
structured logging WG lead.&lt;/p&gt;
&lt;h2 id=&#34;testing-practices-and-tools&#34;&gt;Testing practices and tools&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Sandipan:&lt;/strong&gt; Testing is a field in which multiple approaches and
tools exist; how did you arrive at the existing practices?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Patrick:&lt;/strong&gt; I can’t speak about the early days because I wasn’t
around yet 😆, but looking back at some of the commit history it’s
pretty obvious that developers just took what was available and
started using it. For E2E testing, that was
&lt;a href=&#34;https://github.com/onsi/ginkgo&#34;&gt;Ginkgo+Gomega&lt;/a&gt;. Some hacks were
necessary, for example around cleanup after a test run and for
categorising tests. Eventually this led to Ginkgo v2 and &lt;a href=&#34;https://www.kubernetes.dev/blog/2023/04/12/e2e-testing-best-practices-reloaded/&#34;&gt;revised best
practices for E2E testing&lt;/a&gt;.
Regarding unit testing opinions are pretty diverse: some maintainers
prefer to use just the Go standard library with hand-written
checks. Others use helper packages like stretchr/testify. That
diversity is okay because unit tests are self-contained - contributors
just have to be flexible when working on many different areas.
Integration testing falls somewhere in the middle. It’s based on Go
unit tests, but needs complex helper packages to bring up an apiserver
and other components, then runs tests that are more like E2E tests.&lt;/p&gt;
&lt;h2 id=&#34;subprojects-owned-by-sig-testing&#34;&gt;Subprojects owned by SIG Testing&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Sandipan:&lt;/strong&gt; SIG Testing is pretty diverse. Can you give a brief
overview of the various subprojects owned by SIG Testing?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Michelle:&lt;/strong&gt; Broadly, we have subprojects related to testing
frameworks, and infrastructure, though they definitely overlap.  So
for the former, there&#39;s
&lt;a href=&#34;https://pkg.go.dev/sigs.k8s.io/e2e-framework&#34;&gt;e2e-framework&lt;/a&gt; (used
externally),
&lt;a href=&#34;https://pkg.go.dev/k8s.io/kubernetes/test/e2e/framework&#34;&gt;test/e2e/framework&lt;/a&gt;
(used for Kubernetes itself) and kubetest2 for end-to-end testing,
as well as boskos (resource rental for e2e tests),
&lt;a href=&#34;https://kind.sigs.k8s.io/&#34;&gt;KIND&lt;/a&gt; (Kubernetes-in-Docker, for local
testing and development), and the cloud provider for KIND.  For the
latter, there&#39;s &lt;a href=&#34;https://docs.prow.k8s.io/&#34;&gt;Prow&lt;/a&gt; (K8s-based CI/CD and
chatops), and a litany of other tools and utilities for triage,
analysis, coverage, Prow/TestGrid config generation, and more in the
test-infra repo.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;If you are willing to learn more and get involved with any of the SIG
Testing subprojects, check out the &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-testing#subprojects&#34;&gt;SIG Testing README&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&#34;key-challenges-and-accomplishments&#34;&gt;Key challenges and accomplishments&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Sandipan:&lt;/strong&gt; What are some of the key challenges you face?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Michelle:&lt;/strong&gt; Kubernetes is a gigantic project in every aspect, from
contributors to code to users and more. Testing and infrastructure
have to meet that scale, keeping up with every change from every repo
under Kubernetes while facilitating developing, improving, and
releasing the project as much as possible, though of course, we&#39;re not
the only SIG involved in that.  I think another other challenge is
staffing subprojects. SIG Testing has a number of subprojects that
have existed for years, but many of the original maintainers for them
have moved on to other areas or no longer have the time to maintain
them. We need to grow long-term expertise and owners in those
subprojects.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Patrick:&lt;/strong&gt; As Michelle said, the sheer size can be a challenge. It’s
not just the infrastructure, also our processes must scale with the
number of contributors. It’s good to document best practices, but not
good enough: we have many new contributors, which is good, but having
reviewers explain best practices doesn’t scale - assuming that the
reviewers even know about them! It also doesn’t help that existing
code cannot get updated immediately because there is so much of it, in
particular for E2E testing. The initiative to &lt;a href=&#34;https://groups.google.com/a/kubernetes.io/g/dev/c/myGiml72IbM/m/QdO5bgQiAQAJ&#34;&gt;apply stricter linting to new or modified code&lt;/a&gt;
while accepting that existing code doesn’t pass those same linter
checks helps a bit.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Sandipan:&lt;/strong&gt; Any SIG accomplishments that you are proud of and would
like to highlight?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Patrick:&lt;/strong&gt; I am biased because I have been driving this, but I think
that the &lt;a href=&#34;https://github.com/kubernetes-sigs/e2e-framework&#34;&gt;E2E framework&lt;/a&gt; and linting are now in a much better shape than
they used to be. We may soon be able to run integration tests with
race detection enabled, which is important because we currently only
have that for unit tests and those tend to be less complex.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Sandipan:&lt;/strong&gt; Testing is always important, but is there anything
specific to your work in terms of the Kubernetes release process?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Patrick:&lt;/strong&gt; &lt;a href=&#34;https://github.com/kubernetes/community/blob/master/contributors/devel/sig-testing/flaky-tests.md&#34;&gt;test flakes&lt;/a&gt;…
if we have too many of those, development velocity goes down because
PRs cannot be merged without clean test runs and those become less
likely. Developers also lose trust in testing and just &amp;quot;retest&amp;quot; until
they have a clean run, without checking whether failures might indeed
be related to a regression in their current change.&lt;/p&gt;
&lt;h2 id=&#34;the-people-and-the-scope&#34;&gt;The people and the scope&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Sandipan:&lt;/strong&gt; What are some of your favourite things about this SIG?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Michelle:&lt;/strong&gt; The people, of course 🙂. Aside from that, I like the
broad scope SIG Testing has. I feel like even small changes can make a
big difference for fellow contributors, and even if my interests
change over time, I&#39;ll never run out of projects to work on.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Patrick:&lt;/strong&gt; I can work on things that make my life and the life of my
fellow developers better, like the tooling that we have to use every
day while working on some new feature elsewhere.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Sandipan:&lt;/strong&gt; Are there any funny / cool / TIL anecdotes that you
could tell us?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Patrick:&lt;/strong&gt; I started working on E2E framework enhancements five
years ago, then was less active there for a while. When I came back
and wanted to test some new enhancement, I asked about how to write
unit tests for the new code and was pointed to some existing tests
which looked vaguely familiar, as if I had &lt;em&gt;seen&lt;/em&gt; them before. I
looked at the commit history and found that I had &lt;em&gt;written&lt;/em&gt; them! I’ll
let you decide whether that says something about my failing long-term
memory or simply is normal… Anyway, folks, remember to write good
commit messages and comments; someone will need them at some point -
it might even be yourself!&lt;/p&gt;
&lt;h2 id=&#34;looking-ahead&#34;&gt;Looking ahead&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Sandipan:&lt;/strong&gt; What areas and/or subprojects does your SIG need help with?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Michelle:&lt;/strong&gt; Some subprojects aren&#39;t staffed at the moment and could
use folks willing to learn more about
them. &lt;a href=&#34;https://github.com/kubernetes-sigs/boskos#boskos&#34;&gt;boskos&lt;/a&gt; and
&lt;a href=&#34;https://github.com/kubernetes-sigs/kubetest2#kubetest2&#34;&gt;kubetest2&lt;/a&gt;
especially stand out to me, since both are important for testing but
lack dedicated owners.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Sandipan:&lt;/strong&gt; Are there any useful skills that new contributors to SIG
Testing can bring to the table? What are some things that people can
do to help this SIG if they come from a background that isn’t directly
linked to programming?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Michelle:&lt;/strong&gt; I think user empathy, writing clear feedback, and
recognizing patterns are really useful. Someone who uses the test
framework or tooling and can outline pain points with clear examples,
or who can recognize a wider issue in the project and pull data to
inform solutions for it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Sandipan:&lt;/strong&gt; What’s next for SIG Testing?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Patrick:&lt;/strong&gt; Stricter linting will soon become mandatory for new
code. There are several E2E framework sub-packages that could be
modernised, if someone wants to take on that work. I also see an
opportunity to unify some of our helper code for E2E and integration
testing, but that needs more thought and discussion.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Michelle:&lt;/strong&gt; I&#39;m looking forward to making some usability
improvements for some of our tools and infra, and to supporting more
long-term contributions and growth of contributors into long-term
roles within the SIG. If you&#39;re interested, hit us up!&lt;/p&gt;
&lt;p&gt;Looking ahead, SIG Testing has exciting plans in store. You can get in
touch with the folks at SIG Testing in their &lt;a href=&#34;https://kubernetes.slack.com/messages/sig-testing&#34;&gt;Slack channel&lt;/a&gt; or attend
one of their regular &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-testing#meetings&#34;&gt;bi-weekly meetings on Tuesdays&lt;/a&gt;. If
you are interested in making it easier for the community to run tests
and contribute test results, to ensure Kubernetes is stable across a
variety of cluster configurations and cloud providers, join the SIG
Testing community today!&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes Removals, Deprecations, and Major Changes in Kubernetes 1.29</title>
      <link>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/11/16/kubernetes-1-29-upcoming-changes/</link>
      <pubDate>Thu, 16 Nov 2023 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/11/16/kubernetes-1-29-upcoming-changes/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Authors:&lt;/strong&gt; Carol Valencia, Kristin Martin, Abigail McCarthy, James Quigley, Hosam Kamel&lt;/p&gt;
&lt;p&gt;As with every release, Kubernetes v1.29 will introduce feature deprecations and removals. Our continued ability to produce high-quality releases is a testament to our robust development cycle and healthy community. The following are some of the deprecations and removals coming in the Kubernetes 1.29 release.&lt;/p&gt;
&lt;h2 id=&#34;the-kubernetes-api-removal-and-deprecation-process&#34;&gt;The Kubernetes API removal and deprecation process&lt;/h2&gt;
&lt;p&gt;The Kubernetes project has a well-documented deprecation policy for features. This policy states that stable APIs may only be deprecated when a newer, stable version of that same API is available and that APIs have a minimum lifetime for each stability level. A deprecated API is one that has been marked for removal in a future Kubernetes release; it will continue to function until removal (at least one year from the deprecation), but usage will result in a warning being displayed. Removed APIs are no longer available in the current version, at which point you must migrate to using the replacement.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Generally available (GA) or stable API versions may be marked as deprecated, but must not be removed within a major version of Kubernetes.&lt;/li&gt;
&lt;li&gt;Beta or pre-release API versions must be supported for 3 releases after deprecation.&lt;/li&gt;
&lt;li&gt;Alpha or experimental API versions may be removed in any release without prior deprecation notice.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Whether an API is removed as a result of a feature graduating from beta to stable or because that API simply did not succeed, all removals comply with this deprecation policy. Whenever an API is removed, migration options are communicated in the documentation.&lt;/p&gt;
&lt;h2 id=&#34;a-note-about-the-k8s-gcr-io-redirect-to-registry-k8s-io&#34;&gt;A note about the k8s.gcr.io redirect to registry.k8s.io&lt;/h2&gt;
&lt;p&gt;To host its container images, the Kubernetes project uses a community-owned image registry called registry.k8s.io. Starting last March traffic to the old k8s.gcr.io registry began being redirected to registry.k8s.io. The deprecated k8s.gcr.io registry will eventually be phased out. For more details on this change or to see if you are impacted, please read &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/03/10/image-registry-redirect/&#34;&gt;k8s.gcr.io Redirect to registry.k8s.io - What You Need to Know&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;a-note-about-the-kubernetes-community-owned-package-repositories&#34;&gt;A note about the Kubernetes community-owned package repositories&lt;/h2&gt;
&lt;p&gt;Earlier in 2023, the Kubernetes project &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/08/15/pkgs-k8s-io-introduction/&#34;&gt;introduced&lt;/a&gt; &lt;code&gt;pkgs.k8s.io&lt;/code&gt;, community-owned software repositories for Debian and RPM packages. The community-owned repositories replaced the legacy Google-owned repositories (&lt;code&gt;apt.kubernetes.io&lt;/code&gt; and &lt;code&gt;yum.kubernetes.io&lt;/code&gt;).
On September 13, 2023, those legacy repositories were formally deprecated and their contents frozen.&lt;/p&gt;
&lt;p&gt;For more information on this change or to see if you are impacted, please read the &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/08/31/legacy-package-repository-deprecation/&#34;&gt;deprecation announcement&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;deprecations-and-removals-for-kubernetes-v1-29&#34;&gt;Deprecations and removals for Kubernetes v1.29&lt;/h2&gt;
&lt;p&gt;See the official list of &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/reference/using-api/deprecation-guide/#v1-29&#34;&gt;API removals&lt;/a&gt; for a full list of planned deprecations for Kubernetes v1.29.&lt;/p&gt;
&lt;h3 id=&#34;removal-of-in-tree-integrations-with-cloud-providers-kep-2395-https-kep-k8s-io-2395&#34;&gt;Removal of in-tree integrations with cloud providers (&lt;a href=&#34;https://kep.k8s.io/2395&#34;&gt;KEP-2395&lt;/a&gt;)&lt;/h3&gt;
&lt;p&gt;The &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/reference/command-line-tools-reference/feature-gates/&#34;&gt;feature gates&lt;/a&gt; &lt;code&gt;DisableCloudProviders&lt;/code&gt; and &lt;code&gt;DisableKubeletCloudCredentialProviders&lt;/code&gt; will both be set to &lt;code&gt;true&lt;/code&gt; by default for Kubernetes v1.29. This change will require that users who are currently using in-tree cloud provider integrations (Azure, GCE, or vSphere) enable external cloud controller managers, or opt in to the legacy integration by setting the associated feature gates to &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Enabling external cloud controller managers means you must run a suitable cloud controller manager within your cluster&#39;s control plane; it also requires setting the command line argument &lt;code&gt;--cloud-provider=external&lt;/code&gt; for the kubelet (on every relevant node), and across the control plane (kube-apiserver and kube-controller-manager).&lt;/p&gt;
&lt;p&gt;For more information about how to enable and run external cloud controller managers, read &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/tasks/administer-cluster/running-cloud-controller/&#34;&gt;Cloud Controller Manager Administration&lt;/a&gt; and &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/tasks/administer-cluster/controller-manager-leader-migration/&#34;&gt;Migrate Replicated Control Plane To Use Cloud Controller Manager&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For general information about cloud controller managers, please see
&lt;a href=&#34;https://deploy-preview-57407--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;removal-of-the-v1beta2-flow-control-api-group&#34;&gt;Removal of the &lt;code&gt;v1beta2&lt;/code&gt; flow control API group&lt;/h3&gt;
&lt;p&gt;The &lt;em&gt;flowcontrol.apiserver.k8s.io/v1beta2&lt;/em&gt; API version of FlowSchema and PriorityLevelConfiguration will &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/reference/using-api/deprecation-guide/#v1-29&#34;&gt;no longer be served&lt;/a&gt; in Kubernetes v1.29.&lt;/p&gt;
&lt;p&gt;To prepare for this, you can edit your existing manifests and rewrite client software to use the &lt;code&gt;flowcontrol.apiserver.k8s.io/v1beta3&lt;/code&gt; API version, available since v1.26. 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.assuredConcurrencyShares&lt;/code&gt; field was renamed to &lt;code&gt;spec.limited.nominalConcurrencyShares&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&#34;deprecation-of-the-status-nodeinfo-kubeproxyversion-field-for-node&#34;&gt;Deprecation of the &lt;code&gt;status.nodeInfo.kubeProxyVersion&lt;/code&gt; field for Node&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;.status.kubeProxyVersion&lt;/code&gt; field for Node objects will be &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/4004&#34;&gt;marked as deprecated&lt;/a&gt; in v1.29 in preparation for its removal in a future release. This field is not accurate and is set by kubelet, which does not actually know the kube-proxy version, or even if kube-proxy is running.&lt;/p&gt;
&lt;h2 id=&#34;want-to-know-more&#34;&gt;Want to know more?&lt;/h2&gt;
&lt;p&gt;Deprecations are announced in the Kubernetes release notes. You can see the announcements of pending deprecations in the release notes for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.25.md#deprecation&#34;&gt;Kubernetes v1.25&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.26.md#deprecation&#34;&gt;Kubernetes v1.26&lt;/a&gt;&lt;/li&gt;
&lt;li&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;/li&gt;
&lt;li&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;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We will formally announce the deprecations that come with &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; as part of the CHANGELOG for that release.&lt;/p&gt;
&lt;p&gt;For information on the deprecation and removal process, refer to the official Kubernetes &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/reference/using-api/deprecation-policy/#deprecating-parts-of-the-api&#34;&gt;deprecation policy&lt;/a&gt; document.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>The Case for Kubernetes Resource Limits: Predictability vs. Efficiency</title>
      <link>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/11/16/the-case-for-kubernetes-resource-limits/</link>
      <pubDate>Thu, 16 Nov 2023 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/11/16/the-case-for-kubernetes-resource-limits/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Author:&lt;/strong&gt; Milan Plžík (Grafana Labs)&lt;/p&gt;
&lt;p&gt;There’s been quite a lot of posts suggesting that not using Kubernetes resource limits might be a fairly useful thing (for example, &lt;a href=&#34;https://home.robusta.dev/blog/stop-using-cpu-limits/&#34;&gt;For the Love of God, Stop Using CPU Limits on Kubernetes&lt;/a&gt; or &lt;a href=&#34;https://erickhun.com/posts/kubernetes-faster-services-no-cpu-limits/&#34;&gt;Kubernetes: Make your services faster by removing CPU limits&lt;/a&gt; ). The points made there are totally valid – it doesn’t make much sense to pay for compute power that will not be used due to limits, nor to artificially increase latency. This post strives to argue that limits have their legitimate use as well.&lt;/p&gt;
&lt;p&gt;As a Site Reliability Engineer on the &lt;a href=&#34;https://grafana.com/&#34;&gt;Grafana Labs&lt;/a&gt; platform team, which maintains and improves internal infrastructure and tooling used by the product teams, I primarily try to make Kubernetes upgrades as smooth as possible. But I also spend a lot of time going down the rabbit hole of various interesting Kubernetes issues. This article reflects my personal opinion, and others in the community may disagree.&lt;/p&gt;
&lt;p&gt;Let’s flip the problem upside down. Every pod in a Kubernetes cluster has inherent resource limits – the actual CPU, memory, and other resources of the machine it’s running on. If those physical limits are reached by a pod, it will experience throttling similar to what is caused by reaching Kubernetes limits.&lt;/p&gt;
&lt;h2 id=&#34;the-problem&#34;&gt;The problem&lt;/h2&gt;
&lt;p&gt;Pods without (or with generous) limits can easily consume the extra resources on the node. This, however, has a hidden cost – the amount of extra resources available often heavily depends on pods scheduled on the particular node and their actual load. These extra resources make each pod a special snowflake when it comes to real resource allocation. Even worse, it’s fairly hard to figure out the resources that the pod had at its disposal at any given moment – certainly not without unwieldy data mining of pods running on a particular node, their resource consumption, and similar. And finally, even if we pass this obstacle, we can only have data sampled up to a certain rate and get profiles only for a certain fraction of our calls. This can be scaled up, but the amount of observability data generated might easily reach diminishing returns. Thus, there’s no easy way to tell if a pod had a quick spike and for a short period of time used twice as much memory as usual to handle a request burst.&lt;/p&gt;
&lt;p&gt;Now, with Black Friday and Cyber Monday approaching, businesses expect a surge in traffic. Good performance data/benchmarks of the past performance allow businesses to plan for some extra capacity. But is data about pods without limits reliable? With memory or CPU instant spikes handled by the extra resources, everything might look good according to past data. But once the pod bin-packing changes and the extra resources get more scarce, everything might start looking different – ranging from request latencies rising negligibly to requests slowly snowballing and causing pod OOM kills. While almost no one actually cares about the former, the latter is a serious issue that requires instant capacity increase.&lt;/p&gt;
&lt;h2 id=&#34;configuring-the-limits&#34;&gt;Configuring the limits&lt;/h2&gt;
&lt;p&gt;Not using limits takes a tradeoff – it opportunistically improves the performance if there are extra resources available, but lowers predictability of the performance, which might strike back in the future. There are a few approaches that can be used to increase the predictability again. Let’s pick two of them to analyze:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Configure workload limits to be a fixed (and small) percentage more than the requests&lt;/strong&gt; – I&#39;ll call it &lt;em&gt;fixed-fraction headroom&lt;/em&gt;. This allows the use of some extra shared resources, but keeps the per-node overcommit bound and can be taken to guide worst-case estimates for the workload. Note that the bigger the limits percentage is, the bigger the variance in the performance that might happen across the workloads.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Configure workloads with &lt;code&gt;requests&lt;/code&gt; = &lt;code&gt;limits&lt;/code&gt;&lt;/strong&gt;. From some point of view, this is equivalent to giving each pod its own tiny machine with constrained resources; the performance is fairly predictable. This also puts the pod into the &lt;em&gt;Guaranteed&lt;/em&gt; QoS class, which makes it get evicted only after &lt;em&gt;BestEffort&lt;/em&gt; and &lt;em&gt;Burstable&lt;/em&gt; pods have been evicted by a node under resource pressure (see &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/concepts/workloads/pods/pod-qos/&#34;&gt;Quality of Service for Pods&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Some other cases might also be considered, but these are probably the two simplest ones to discuss.&lt;/p&gt;
&lt;h2 id=&#34;cluster-resource-economy&#34;&gt;Cluster resource economy&lt;/h2&gt;
&lt;p&gt;Note that in both cases discussed above, we’re effectively preventing the workloads from using some cluster resources it has at the cost of getting more predictability – which might sound like a steep price to pay for a bit more stable performance. Let’s try to quantify the impact there.&lt;/p&gt;
&lt;h3 id=&#34;bin-packing-and-cluster-resource-allocation&#34;&gt;Bin-packing and cluster resource allocation&lt;/h3&gt;
&lt;p&gt;Firstly, let’s discuss bin-packing and cluster resource allocation. There’s some inherent cluster inefficiency that comes to play – it’s hard to achieve 100% resource allocation in a Kubernetes cluster. Thus, some percentage will be left unallocated.&lt;/p&gt;
&lt;p&gt;When configuring fixed-fraction headroom limits, a proportional amount of this will be available to the pods. If the percentage of unallocated resources in the cluster is lower than the constant we use for setting fixed-fraction headroom limits (see the figure, line 2), all the pods together are able to theoretically use up all the node’s resources; otherwise there are some resources that will inevitably be wasted (see the figure, line 1). In order to eliminate the inevitable resource waste, the percentage for fixed-fraction headroom limits should be configured so that it’s at least equal to the expected percentage of unallocated resources.&lt;/p&gt;

&lt;figure class=&#34;diagram-medium&#34;&gt;
    &lt;img src=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/11/16/the-case-for-kubernetes-resource-limits/requests-limits-configurations.svg&#34;
         alt=&#34;Chart displaying various requests/limits configurations&#34;/&gt; 
&lt;/figure&gt;

&lt;p&gt;For requests = limits (see the figure, line 3), this does not hold: Unless we’re able to allocate all node’s resources, there’s going to be some inevitably wasted resources. Without any knobs to turn on the requests/limits side, the only suitable approach here is to ensure efficient bin-packing on the nodes by configuring correct machine profiles. This can be done either manually or by using a variety of cloud service provider tooling – for example &lt;a href=&#34;https://karpenter.sh/&#34;&gt;Karpenter&lt;/a&gt; for EKS or &lt;a href=&#34;https://cloud.google.com/kubernetes-engine/docs/how-to/node-auto-provisioning&#34;&gt;GKE Node auto provisioning&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;optimizing-actual-resource-utilization&#34;&gt;Optimizing actual resource utilization&lt;/h3&gt;
&lt;p&gt;Free resources also come in the form of unused resources of other pods (reserved vs. actual CPU utilization, etc.), and their availability can’t be predicted in any reasonable way. Configuring limits makes it next to impossible to utilize these. Looking at this from a different perspective, if a workload wastes a significant amount of resources it has requested, re-visiting its own resource requests might be a fair thing to do. Looking at past data and picking more fitting resource requests might help to make the packing more tight (although at the price of worsening its performance – for example increasing long tail latencies).&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Optimizing resource requests and limits is hard. Although it’s much easier to break things when setting limits, those breakages might help prevent a catastrophe later by giving more insights into how the workload behaves in bordering conditions. There are cases where setting limits makes less sense: batch workloads (which are not latency-sensitive – for example non-live video encoding), best-effort services (don’t need that level of availability and can be preempted), clusters that have a lot of spare resources by design (various cases of specialty workloads – for example services that handle spikes by design).&lt;/p&gt;
&lt;p&gt;On the other hand, setting limits shouldn’t be avoided at all costs – even though figuring out the &amp;quot;right” value for limits is harder and configuring a wrong value yields less forgiving situations. Configuring limits helps you learn about a workload’s behavior in corner cases, and there are simple strategies that can help when reasoning about the right value. It’s a tradeoff between efficient resource usage and performance predictability and should be considered as such.&lt;/p&gt;
&lt;p&gt;There’s also an economic aspect of workloads with spiky resource usage. Having “freebie” resources always at hand does not serve as an incentive to improve performance for the product team. Big enough spikes might easily trigger efficiency issues or even problems when trying to defend a product’s SLA – and thus, might be a good candidate to mention when assessing any risks.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Introducing SIG etcd</title>
      <link>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/11/07/introducing-sig-etcd/</link>
      <pubDate>Tue, 07 Nov 2023 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/11/07/introducing-sig-etcd/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Authors&lt;/strong&gt;:  Han Kang (Google), Marek Siarkowicz (Google), Frederico Muñoz (SAS Institute)&lt;/p&gt;
&lt;p&gt;Special Interest Groups (SIGs) are a fundamental part of the Kubernetes project, with a substantial share of the community activity happening within them. When the need arises, &lt;a href=&#34;https://github.com/kubernetes/community/blob/master/sig-wg-lifecycle.md&#34;&gt;new SIGs can be created&lt;/a&gt;, and that was precisely what happened recently.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/kubernetes/community/blob/master/sig-etcd/README.md&#34;&gt;SIG etcd&lt;/a&gt; is the most recent addition to the list of Kubernetes SIGs. In this article we will get to know it a bit better, understand its origins, scope, and plans.&lt;/p&gt;
&lt;h2 id=&#34;the-critical-role-of-etcd&#34;&gt;The critical role of etcd&lt;/h2&gt;
&lt;p&gt;If we look inside the control plane of a Kubernetes cluster, we will find &lt;a href=&#34;https://kubernetes.io/docs/concepts/overview/components/#etcd&#34;&gt;etcd&lt;/a&gt;, a consistent and highly-available key value store used as Kubernetes&#39; backing store for all cluster data -- this description alone highlights the critical role that etcd plays, and the importance of it within the Kubernetes ecosystem.&lt;/p&gt;
&lt;p&gt;This critical role makes the health of the etcd project and community an important consideration, and &lt;a href=&#34;https://groups.google.com/a/kubernetes.io/g/steering/c/e-O-tVSCJOk/m/N9IkiWLEAgAJ&#34;&gt;concerns about the state of the project&lt;/a&gt; in early 2022 did not go unnoticed. The changes in the maintainer team, amongst other factors, contributed to a situation that needed to be addressed.&lt;/p&gt;
&lt;h2 id=&#34;why-a-special-interest-group&#34;&gt;Why a special interest group&lt;/h2&gt;
&lt;p&gt;With the critical role of etcd in mind, it was proposed that the way forward would be to create a new special interest group. If etcd was already at the heart of Kubernetes, creating a dedicated SIG not only recognises that role, it would make etcd a first-class citizen of the Kubernetes community.&lt;/p&gt;
&lt;p&gt;Establishing SIG etcd creates a dedicated space to make explicit the contract between etcd and Kubernetes api machinery and to prevent, on the etcd level, changes which violate this contract. Additionally, etcd will be able to adopt the processes that Kubernetes offers its SIGs (&lt;a href=&#34;https://www.kubernetes.dev/resources/keps/&#34;&gt;KEPs&lt;/a&gt;, &lt;a href=&#34;https://github.com/kubernetes/community/blob/master/sig-architecture/production-readiness.md&#34;&gt;PRR&lt;/a&gt;, &lt;a href=&#34;https://kubernetes.io/docs/reference/command-line-tools-reference/feature-gates/&#34;&gt;phased feature gates&lt;/a&gt;, amongst others) in order to improve the consistency and reliability of the codebase. Being able to use these processes will be a substantial benefit to the etcd community.&lt;/p&gt;
&lt;p&gt;As a SIG, etcd will also be able to draw contributor support from Kubernetes proper: active contributions to etcd from Kubernetes maintainers would decrease the likelihood of breaking Kubernetes changes, through the increased number of potential reviewers and the integration with existing testing framework. This will not only benefit Kubernetes, which will be able to better participate and shape the direction of etcd in terms of the critical role it plays, but also etcd as a whole.&lt;/p&gt;
&lt;h2 id=&#34;about-sig-etcd&#34;&gt;About SIG etcd&lt;/h2&gt;
&lt;p&gt;The recently created SIG is already working towards its goals, defined in its &lt;a href=&#34;https://github.com/kubernetes/community/blob/master/sig-etcd/charter.md&#34;&gt;Charter&lt;/a&gt; and &lt;a href=&#34;https://github.com/kubernetes/community/blob/master/sig-etcd/vision.md&#34;&gt;Vision&lt;/a&gt;. The purpose is clear: to ensure etcd is a reliable, simple, and scalable production-ready store for building cloud-native distributed systems and managing cloud-native infrastructure via orchestrators like Kubernetes.&lt;/p&gt;
&lt;p&gt;The scope of SIG etcd is not exclusively about etcd as a Kubernetes component, it also covers etcd as a standard solution. Our goal is to make etcd the most reliable key-value storage to be used anywhere, unconstrained by any Kubernetes-specific limits and scaling to meet the requirements of many diverse use-cases.&lt;/p&gt;
&lt;p&gt;We are confident that the creation of SIG etcd constitutes an important milestone in the lifecycle of the project, simultaneously improving etcd itself, and also the integration of etcd with Kubernetes. We invite everyone interested in etcd to &lt;a href=&#34;https://github.com/kubernetes/community/blob/master/sig-etcd/README.md&#34;&gt;visit our page&lt;/a&gt;, &lt;a href=&#34;https://kubernetes.slack.com/messages/etcd&#34;&gt;join us at our Slack channel&lt;/a&gt;, and get involved in this new stage of etcd&#39;s life.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes Contributor Summit: Behind-the-scenes</title>
      <link>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/11/03/k8s-contributor-summit-behind-the-scenes/</link>
      <pubDate>Fri, 03 Nov 2023 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/11/03/k8s-contributor-summit-behind-the-scenes/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Author&lt;/strong&gt; : Frederico Muñoz (SAS Institute)&lt;/p&gt;
&lt;p&gt;Every year, just before the official start of KubeCon+CloudNativeCon, there&#39;s a special event that
has a very special place in the hearts of those organizing and participating in it: the Kubernetes
Contributor Summit. To find out why, and to provide a behind-the-scenes perspective, we interview
Noah Abrahams, whom amongst other roles was the co-lead for the Kubernetes Contributor Summit in
2023.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Frederico Muñoz (FSM)&lt;/strong&gt;: Hello Noah, and welcome. Could you start by introducing yourself and
telling us how you got involved in Kubernetes?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Noah Abrahams (NA)&lt;/strong&gt;: I’ve been in this space for quite a while.  I got started in IT in the mid
90&#39;s, and I’ve been working in the &amp;quot;Cloud&amp;quot; space for about 15 years.  It was, frankly, through a
combination of sheer luck (being in the right place at the right time) and having good mentors to
pull me into those places (thanks, Tim!), that I ended up at a startup called Apprenda in 2016.
While I was there, they pivoted into Kubernetes, and it was the best thing that could have happened
to my career.  It was around v1.2 and someone asked me if I could give a presentation on Kubernetes
concepts at &amp;quot;my local meetup&amp;quot; in Las Vegas.  The meetup didn’t exist yet, so I created it, and got
involved in the wider community.  One thing led to another, and soon I was involved in ContribEx,
joined the release team, was doing booth duty for the CNCF, became an ambassador, and here we are
today.&lt;/p&gt;
&lt;h2 id=&#34;the-contributor-summit&#34;&gt;The Contributor Summit&lt;/h2&gt;
&lt;p&gt;&lt;img src=&#34;kcseu2023-group.jpg&#34; alt=&#34;KCSEU 2023 group photo&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;FM&lt;/strong&gt;: Before leading the organisation of the KCSEU 2023, how many other Contributor Summits were
you a part of?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NA&lt;/strong&gt;: I was involved in four or five before taking the lead.  If I&#39;m recalling correctly, I
attended the summit in Copenhagen, then sometime in 2018 I joined the wrong meeting, because the
summit staff meeting was listed on the ContribEx calendar.  Instead of dropping out of the call, I
listened a bit, then volunteered to take on some work that didn&#39;t look like it had anybody yet
dedicated to it.  I ended up running Ops in Seattle and helping run the New Contributor Workshop in
Shanghai, that year.  Since then, I’ve been involved in all but two, since I missed both Barcelona
and Valencia.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;FM&lt;/strong&gt;: Have you noticed any major changes in terms of how the conference is organized throughout
the years? Namely in terms of number of participants, venues, speakers, themes...&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NA&lt;/strong&gt;: The summit changes over the years with the ebb and flow of the desires of the contributors
that attend.  While we can typically expect about the same number of attendees, depending on the
region that the event is held in, we adapt the style and content greatly based on the feedback that
we receive at the end of each event.  Some years, contributors ask for more free-style or
unconference type sessions, and we plan on having more of those, but some years, people ask for more
planned sessions or workshops, so that&#39;s what we facilitate.  We also have to continually adapt to
the venue that we have, the number of rooms we&#39;re allotted, how we&#39;re going to share the space with
other events and so forth.  That all goes into the planning ahead of time, from how many talk tracks
we’ll have, to what types of tables and how many microphones we want in a room.&lt;/p&gt;
&lt;p&gt;There has been one very significant change over the years, though, and that is that we no longer run
the New Contributor Workshop.  While the content was valuable, running the session during the summit
never led to any people who weren’t already contributing to the project becoming dedicated
contributors to the project, so we removed it from the schedule.  We&#39;ll deliver that content another
way, while we’ll keep the summit focused on existing contributors.&lt;/p&gt;
&lt;h2 id=&#34;what-makes-it-special&#34;&gt;What makes it special&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;FM&lt;/strong&gt;: Going back to the introduction I made, I’ve heard several participants saying that KubeCon
is great, but that the Contributor Summit is for them the main event. In your opinion, why do you
think that makes it so?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NA&lt;/strong&gt;: I think part of it ties into what I mentioned a moment ago, the flexibility in our content
types.  For many contributors, I think the summit is basically &amp;quot;How Kubecon used to be&amp;quot;, back when
it was primarily a gathering of the contributors to talk about the health of the project and the
work that needed to be done.  So, in that context, if the contributors want to discuss, say, a new
Working Group, then they have dedicated space to do so in the summit.  They also have the space to
sit down and hack on a tough problem, discuss architectural philosophy, bring potential problems to
more people’s attention, refine our methods, and so forth.  Plus, the unconference aspect allows for
some malleability on the day-of, for whatever is most important right then and there.  Whatever
folks want to get out of this environment is what we’ll provide, and having a space and time
specifically to address your particular needs is always going to be well received.&lt;/p&gt;
&lt;p&gt;Let&#39;s not forget the social aspect, too.  Despite the fact that we&#39;re a global community and work
together remotely and asynchronously, it&#39;s still easier to work together when you have a personal
connection, and can put a face to a Github handle.  Zoom meetings are a good start, but even a
single instance of in-person time makes a big difference in how people work together.  So, getting
folks together a couple times a year makes the project run more smoothly.&lt;/p&gt;
&lt;h2 id=&#34;organizing-the-summit&#34;&gt;Organizing the Summit&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;FM&lt;/strong&gt;: In terms of the organization team itself, could you share with us a general overview of the
staffing process? Who are the people that make it happen? How many different teams are involved?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NA&lt;/strong&gt;: There&#39;s a bit of the &amp;quot;usual suspects&amp;quot; involved in making this happen, many of whom you&#39;ll
find in the ContribEx meetings, but really it comes down to whoever is going to step up and do the
work.  We start with a general call out for volunteers from the org.  There&#39;s a Github issue where
we&#39;ll track the staffing and that will get shouted out to all the usual comms channels: slack,
k-dev, etc.&lt;/p&gt;
&lt;p&gt;From there, there&#39;s a handful of different teams, overseeing content/program committee,
registration, communications, day-of operations, the awards the SIGs present to their members, the
after-summit social event, and so on.  The leads for each team/role are generally picked from folks
who have stepped up and worked the event before, either as a shadow, or a previous lead, so we know
we can rely on them, which is a recurring theme.  The leads pick their shadows from whoever pipes up
on the issue, and the teams move forward, operating according to their role books, which we try to
update at the end of each summit, with what we&#39;ve learned over the past few months.  It&#39;s expected
that a shadow will be in line to lead that role at some point in a future summit, so we always have
a good bench of folks available to make this event happen.  A couple of the roles also have some
non-shadow volunteers where people can step in to help a bit, like as an on-site room monitor, and
get a feel for how things are put together without having to give a serious up-front commitment, but
most of the folks working the event are dedicated to both making the summit successful, and coming
back to do so in the future.  Of course, the roster can change over time, or even suddenly, as
people gain or lose travel budget, get new jobs, only attend Europe or North America or Asia, etc.
It&#39;s a constant dance, relying 100% on the people who want to make this project successful.&lt;/p&gt;
&lt;p&gt;Last, but not least, is the Summit lead.  They have to keep the entire process moving forward, be
willing to step in to keep bike-shedding from derailing our deadlines, make sure the right people
are talking to one another, lead all our meetings to make sure everyone gets a voice, etc.  In some
cases, the lead has to even be willing to take over an entirely separate role, in case someone gets
sick or has any other extenuating circumstances, to make sure absolutely nothing falls through the
cracks.  The lead is only allowed to volunteer after they’ve been through this a few times and know
what the event entails.  Event planning is not for the faint of heart.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;FM&lt;/strong&gt;: The participation of volunteers is essential, but there&#39;s also the topic of CNCF support:
how does this dynamic play out in practice?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NA&lt;/strong&gt;: This event would not happen in its current form without our CNCF liaison.  They provide us
with space, make sure we are fed and caffeinated and cared for, bring us outside spaces to evaluate,
so we have somewhere to hold the social gathering, get us the budget so we have t-shirts and patches
and the like, and generally make it possible for us to put this event together.  They&#39;re even
responsible for the signage and arrows, so the attendees know where to go.  They&#39;re the ones sitting
at the front desk, keeping an eye on everything and answering people&#39;s questions.  At the same time,
they&#39;re along to facilitate, and try to avoid influencing our planning.&lt;/p&gt;
&lt;p&gt;There&#39;s a ton of work that goes into making the summit happen that is easy to overlook, as an
attendee, because people tend to expect things to just work.  It is not exaggerating to say this
event would not have happened like it has over the years, without the help from our liaisons, like
Brienne and Deb.  They are an integral part of the team.&lt;/p&gt;
&lt;h2 id=&#34;a-look-ahead&#34;&gt;A look ahead&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;FM&lt;/strong&gt;: Currently, we’re preparing the NA 2023 summit, how is it going? Any changes in format
compared with previous ones?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NA&lt;/strong&gt;: I would say it&#39;s going great, though I&#39;m sort of emeritus lead for this event, mostly
picking up the things that I see need to be done and don&#39;t have someone assigned to it.  We&#39;re
always learning from our past experiences and making small changes to continually be better, from
how many people need to be on a particular rotation to how far in advance we open and close the CFP.
There&#39;s no major changes right now, just continually providing the content that the contributors
want.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;FM&lt;/strong&gt;: For our readers that might be interested in joining in the Kubernetes Contributor Summit, is
there anything they should know?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NA&lt;/strong&gt;: First of all, the summit is an event by and for Org members.  If you&#39;re not already an org
member, you should be getting involved before trying to attend the summit, as the content is curated
specifically towards the contributors and maintainers of the project.  That applies to the staff, as
well, as all the decisions should be made with the interests and health of kubernetes contributors
being the end goal.  We get a lot of people who show interest in helping out, but then aren&#39;t ready
to make any sort of commitment, and that just makes more work for us.  If you&#39;re not already a
proven and committed member of this community, it’s difficult for us to place you in a position that
requires reliability.  We have made some rare exceptions when we need someone local to help us out,
but those are few and far between.&lt;/p&gt;
&lt;p&gt;If you are, however, already a member, we&#39;d love to have you.  The more people that are involved,
the better the event becomes.  That applies to both dedicated staff, and those in attendance
bringing CFPs, unconference topics, and just contributing to the discussions.  If you&#39;re part of
this community and you&#39;re going to be at KubeCon, I would highly urge you to attend, and if you&#39;re
not yet an org member, let&#39;s make that happen!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;FM&lt;/strong&gt;: Indeed! Any final comments you would like to share?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NA&lt;/strong&gt;: Just that the Contributor Summit is, for me, the ultimate manifestation of the Hallway
Track.  By being here, you&#39;re part of the conversations that move this project forward.  It&#39;s good
for you, and it&#39;s good for Kubernetes.  I hope to see you all in Chicago!&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Spotlight on SIG Architecture: Production Readiness</title>
      <link>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/11/02/sig-architecture-production-readiness-spotlight-2023/</link>
      <pubDate>Thu, 02 Nov 2023 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/11/02/sig-architecture-production-readiness-spotlight-2023/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Author&lt;/strong&gt;: Frederico Muñoz (SAS Institute)&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This is the second interview of a SIG Architecture Spotlight series that will cover the different
subprojects. In this blog, we will cover the &lt;a href=&#34;https://github.com/kubernetes/community/blob/master/sig-architecture/README.md#production-readiness-1&#34;&gt;SIG Architecture: Production Readiness
subproject&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/wojtek-t&#34;&gt;Wojciech Tyczynski&lt;/a&gt;
(Google), lead of the Production Readiness subproject.&lt;/p&gt;
&lt;h2 id=&#34;about-sig-architecture-and-the-production-readiness-subproject&#34;&gt;About SIG Architecture and the Production Readiness subproject&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Frederico (FSM)&lt;/strong&gt;: Hello Wojciech, could you tell us a bit about yourself, your role and how you
got involved in Kubernetes?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Wojciech Tyczynski (WT)&lt;/strong&gt;: I started contributing to Kubernetes in January 2015. At that time,
Google (where I was and still am working) decided to start a Kubernetes team in the Warsaw office
(in addition to already existing teams in California and Seattle). I was lucky enough to be one of
the seeding engineers for that team.&lt;/p&gt;
&lt;p&gt;After two months of onboarding and helping with different tasks across the project towards 1.0
launch, I took ownership of the scalability area and I was leading Kubernetes to support clusters
with 5000 nodes. I’m still involved in &lt;a href=&#34;https://github.com/kubernetes/community/blob/master/sig-scalability/README.md&#34;&gt;SIG Scalability&lt;/a&gt;
as its Technical Lead. That was the start of a journey since scalability is such a cross-cutting topic,
and I started contributing to many other areas including, over time, to SIG Architecture.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;FSM&lt;/strong&gt;: In SIG Architecture, why specifically the Production Readiness subproject? Was it something
you had in mind from the start, or was it an unexpected consequence of your initial involvement in
scalability?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;WT&lt;/strong&gt;: After reaching that milestone of &lt;a href=&#34;https://kubernetes.io/blog/2017/03/scalability-updates-in-kubernetes-1-6/&#34;&gt;Kubernetes supporting 5000-node clusters&lt;/a&gt;,
one of the goals was to ensure that Kubernetes would not degrade its scalability properties over time. While
non-scalable implementation is always fixable, designing non-scalable APIs or contracts is
problematic. I was looking for a way to ensure that people are thinking about
scalability when they create new features and capabilities without introducing too much overhead.&lt;/p&gt;
&lt;p&gt;This is when I joined forces with &lt;a href=&#34;https://github.com/johnbelamaric&#34;&gt;John Belamaric&lt;/a&gt; and
&lt;a href=&#34;https://github.com/deads2k&#34;&gt;David Eads&lt;/a&gt; and created a Production Readiness subproject within SIG
Architecture. While setting the bar for scalability was only one of a few motivations for it, it
ended up fitting quite well. At the same time, I was already involved in the overall reliability of
the system internally, so other goals of Production Readiness were also close to my heart.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;FSM&lt;/strong&gt;: To anyone new to how SIG Architecture works, how would you describe the main goals and
areas of intervention of the Production Readiness subproject?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;WT&lt;/strong&gt;: The goal of the Production Readiness subproject is to ensure that any feature that is added
to Kubernetes can be reliably used in production clusters. This primarily means that those features
are observable, scalable, supportable, can always be safely enabled and in case of production issues
also disabled.&lt;/p&gt;
&lt;h2 id=&#34;production-readiness-and-the-kubernetes-project&#34;&gt;Production readiness and the Kubernetes project&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;FSM&lt;/strong&gt;: Architectural consistency being one of the goals of the SIG, is this made more challenging
by the &lt;a href=&#34;https://www.cncf.io/reports/kubernetes-project-journey-report/&#34;&gt;distributed and open nature of Kubernetes&lt;/a&gt;?
Do you feel this impacts the approach that Production Readiness has to take?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;WT&lt;/strong&gt;: The distributed nature of Kubernetes certainly impacts Production Readiness, because it
makes thinking about aspects like enablement/disablement or scalability more challenging. To be more
precise, when enabling or disabling features that span multiple components you need to think about
version skew between them and design for it. For scalability, changes in one component may actually
result in problems for a completely different one, so it requires a good understanding of the whole
system, not just individual components. But it’s also what makes this project so interesting.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;FSM&lt;/strong&gt;: Those running Kubernetes in production will have their own perspective on things, how do
you capture this feedback?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;WT&lt;/strong&gt;: Fortunately, we aren’t talking about &lt;em&gt;&amp;quot;them&amp;quot;&lt;/em&gt; here, we’re talking about &lt;em&gt;&amp;quot;us&amp;quot;&lt;/em&gt;: all of us are
working for companies that are managing large fleets of Kubernetes clusters and we’re involved in
that too, so we suffer from those problems ourselves.&lt;/p&gt;
&lt;p&gt;So while we’re trying to get feedback (our annual PRR survey is very important for us), it rarely
reveals completely new problems - it rather shows the scale of them. And we try to react to it -
changes like &amp;quot;Beta APIs off by default&amp;quot; happen in reaction to the data that we observe.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;FSM&lt;/strong&gt;: On the topic of reaction, that made me think of how the &lt;a href=&#34;https://github.com/kubernetes/enhancements/blob/master/keps/NNNN-kep-template/README.md&#34;&gt;Kubernetes Enhancement Proposal (KEP)&lt;/a&gt;
template has a Production Readiness Review (PRR) section, which is tied to the graduation
process. Was this something born out of identified insufficiencies? How would you describe the
results?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;WT&lt;/strong&gt;: As mentioned above, the overall goal of the Production Readiness subproject is to ensure
that every newly added feature can be reliably used in production. It’s not possible to enforce that
by a central team - we need to make it everyone&#39;s problem.&lt;/p&gt;
&lt;p&gt;To achieve it, we wanted to ensure that everyone designing their new feature is thinking about safe
enablement, scalability, observability, supportability, etc. from the very beginning. Which means
not when the implementation starts, but rather during the design. Given that KEPs are effectively
Kubernetes design docs, making it part of the KEP template was the way to achieve the goal.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;FSM&lt;/strong&gt;: So, in a way making sure that feature owners have thought about the implications of their
proposal.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;WT&lt;/strong&gt;: Exactly. We already observed that just by forcing feature owners to think through the PRR
aspects (via forcing them to fill in the PRR questionnaire) many of the original issues are going
away. Sure - as PRR approvers we’re still catching gaps, but even the initial versions of KEPs are
better now than they used to be a couple of years ago in what concerns thinking about
productionisation aspects, which is exactly what we wanted to achieve - spreading the culture of
thinking about reliability in its widest possible meaning.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;FSM&lt;/strong&gt;: We&#39;ve been talking about the PRR process, could you describe it for our readers?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;WT&lt;/strong&gt;: The &lt;a href=&#34;https://github.com/kubernetes/community/blob/master/sig-architecture/production-readiness.md&#34;&gt;PRR process&lt;/a&gt;
is fairly simple - we just want to ensure that you think through the productionisation aspects of
your feature early enough. If you do your job, it’s just a matter of answering some questions in the
KEP template and getting approval from a PRR approver (in addition to regular SIG approval). If you
didn’t think about those aspects earlier, it may require spending more time and potentially revising
some decisions, but that’s exactly what we need to make the Kubernetes project reliable.&lt;/p&gt;
&lt;h2 id=&#34;helping-with-production-readiness&#34;&gt;Helping with Production Readiness&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;FSM&lt;/strong&gt;: Production Readiness seems to be one area where a good deal of prior exposure is required
in order to be an effective contributor. Are there also ways for someone newer to the project to
contribute?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;WT&lt;/strong&gt;: PRR approvers have to have a deep understanding of the whole Kubernetes project to catch
potential issues. Kubernetes is such a large project now with so many nuances that people who are
new to the project can simply miss the context, no matter how senior they are.&lt;/p&gt;
&lt;p&gt;That said, there are many ways that you may implicitly help. Increasing the reliability of
particular areas of the project by improving its observability and debuggability, increasing test
coverage, and building new kinds of tests (upgrade, downgrade, chaos, etc.) will help us a lot. Note
that the PRR subproject is focused on keeping the bar at the design level, but we should also care
equally about the implementation. For that, we’re relying on individual SIGs and code approvers, so
having people there who are aware of productionisation aspects, and who deeply care about it, will
help the project a lot.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;FSM&lt;/strong&gt;: Thank you! Any final comments you would like to share with our readers?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;WT&lt;/strong&gt;: I would like to highlight and thank all contributors for their cooperation. While the PRR
adds some additional work for them, we see that people care about it, and what’s even more
encouraging is that with every release the quality of the answers improves, and questions &amp;quot;do I
really need a metric reflecting if my feature works&amp;quot; or &amp;quot;is downgrade really that important&amp;quot; don’t
really appear anymore.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Gateway API v1.0: GA Release</title>
      <link>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/10/31/gateway-api-ga/</link>
      <pubDate>Tue, 31 Oct 2023 10:00:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/10/31/gateway-api-ga/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Authors:&lt;/strong&gt; Shane Utt (Kong), Nick Young (Isovalent), Rob Scott (Google)&lt;/p&gt;
&lt;p&gt;On behalf of Kubernetes SIG Network, we are pleased to announce the v1.0 release of &lt;a href=&#34;https://gateway-api.sigs.k8s.io/&#34;&gt;Gateway
API&lt;/a&gt;! This release marks a huge milestone for
this project. Several key APIs are graduating to GA (generally available), while
other significant features have been added to the Experimental channel.&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-v1&#34;&gt;Graduation to v1&lt;/h3&gt;
&lt;p&gt;This release includes the graduation of
&lt;a href=&#34;https://gateway-api.sigs.k8s.io/api-types/gateway/&#34;&gt;Gateway&lt;/a&gt;,
&lt;a href=&#34;https://gateway-api.sigs.k8s.io/api-types/gatewayclass/&#34;&gt;GatewayClass&lt;/a&gt;, and
&lt;a href=&#34;https://gateway-api.sigs.k8s.io/api-types/httproute/&#34;&gt;HTTPRoute&lt;/a&gt; to v1, which
means they are now generally available (GA). This API version denotes a high
level of confidence in the API surface and provides guarantees of backwards
compatibility. Note that although, the version of these APIs included in the
Standard channel are now considered stable, that does not mean that they are
complete. These APIs will continue to receive new features via the Experimental
channel as they meet graduation criteria. 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;logo&#34;&gt;Logo&lt;/h3&gt;
&lt;p&gt;Gateway API now has a logo! This logo was designed through a collaborative
process, and is intended to represent the idea that this is a set of Kubernetes
APIs for routing traffic both north-south and east-west:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;gateway-api-logo.png&#34; alt=&#34;Gateway API Logo&#34; title=&#34;Gateway API Logo&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;cel-validation&#34;&gt;CEL Validation&lt;/h3&gt;
&lt;p&gt;Historically, Gateway API has bundled a validating webhook as part of installing
the API. Starting in v1.0, webhook installation is optional and only recommended
for Kubernetes 1.24. Gateway API now includes
&lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/reference/using-api/cel/&#34;&gt;CEL&lt;/a&gt; validation rules as
part of the
&lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/concepts/extend-kubernetes/api-extension/custom-resources/&#34;&gt;CRDs&lt;/a&gt;.
This new form of validation is supported in Kubernetes 1.25+, and thus the
validating webhook is no longer required in most installations.&lt;/p&gt;
&lt;h3 id=&#34;standard-channel&#34;&gt;Standard channel&lt;/h3&gt;
&lt;p&gt;This release was primarily focused on ensuring that the existing beta APIs were
well defined and sufficiently stable to graduate to GA. That led to a variety of
spec clarifications, as well as some improvements to status to improve the
overall UX when interacting with Gateway API.&lt;/p&gt;
&lt;h3 id=&#34;experimental-channel&#34;&gt;Experimental channel&lt;/h3&gt;
&lt;p&gt;Most of the changes included in this release were limited to the experimental
channel. These include HTTPRoute timeouts, TLS config from Gateways to backends,
WebSocket support, Gateway infrastructure labels, and more. Stay tuned for a
follow up blog post that will cover each of these new features in detail.&lt;/p&gt;
&lt;h3 id=&#34;everything-else&#34;&gt;Everything else&lt;/h3&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.0.0&#34;&gt;v1.0.0 release
notes&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;how-we-got-here&#34;&gt;How we got here&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;
4 years ago at KubeCon San Diego as the next generation
of Ingress API. Since then, an incredible community has formed to develop what
has likely become the most collaborative API in Kubernetes history. Over 170
people have contributed to this API so far, and that number continues to grow.&lt;/p&gt;
&lt;p&gt;A special thank you to the 20+ &lt;a href=&#34;https://github.com/kubernetes-sigs/gateway-api/blob/main/OWNERS_ALIASES&#34;&gt;community members who agreed to take on an
official role in the
project&lt;/a&gt;,
providing some time for reviews and sharing the load of maintaining the project!&lt;/p&gt;
&lt;p&gt;We especially want to highlight the emeritus maintainers that played a pivotal
role in the early development of this project:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/bowei&#34;&gt;Bowei Du&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/danehans&#34;&gt;Daneyon Hansen&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/hbagdi&#34;&gt;Harry Bagdi&lt;/a&gt;&lt;/li&gt;
&lt;/ul&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
one of the 5 most recent minor versions of Kubernetes (1.24+), you&#39;ll be able to
get up and running with the latest 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;what-s-next&#34;&gt;What&#39;s next&lt;/h2&gt;
&lt;p&gt;This release is just the beginning of a much larger journey for Gateway API, and
there are still plenty of new features and new ideas in flight for future
releases of the API.&lt;/p&gt;
&lt;p&gt;One of our key goals going forward is to work to stabilize and graduate other
experimental features of the API. These include &lt;a href=&#34;https://gateway-api.sigs.k8s.io/concepts/gamma/&#34;&gt;support for service
mesh&lt;/a&gt;, additional route types
(&lt;a href=&#34;https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1alpha2.GRPCRoute&#34;&gt;GRPCRoute&lt;/a&gt;,
&lt;a href=&#34;https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1alpha2.TCPRoute&#34;&gt;TCPRoute&lt;/a&gt;,
&lt;a href=&#34;https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1alpha2.TLSRoute&#34;&gt;TLSRoute&lt;/a&gt;,
&lt;a href=&#34;https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1alpha2.UDPRoute&#34;&gt;UDPRoute&lt;/a&gt;),
and a variety of experimental features.&lt;/p&gt;
&lt;p&gt;We&#39;ve also been working towards moving
&lt;a href=&#34;https://gateway-api.sigs.k8s.io/api-types/referencegrant/&#34;&gt;ReferenceGrant&lt;/a&gt; into
a built-in Kubernetes API that can be used for more than just Gateway API.
Within Gateway API, we&#39;ve used this resource to safely enable cross-namespace
references, and that concept is now being adopted by other SIGs. The new version
of this API will be owned by SIG Auth and will likely include at least some
modifications as it migrates to a built-in Kubernetes API.&lt;/p&gt;
&lt;h3 id=&#34;gateway-api-at-kubecon-cloudnativecon&#34;&gt;Gateway API at KubeCon + CloudNativeCon&lt;/h3&gt;
&lt;p&gt;At &lt;a href=&#34;https://events.linuxfoundation.org/kubecon-cloudnativecon-north-america/&#34;&gt;KubeCon North America
(Chicago)&lt;/a&gt;
and the adjacent &lt;a href=&#34;https://www.kubernetes.dev/events/2023/kcsna/&#34;&gt;Contributor
Summit&lt;/a&gt; there are several talks
related to Gateway API that will go into more detail on these topics. If you&#39;re
attending either of these events this year, considering adding these to your
schedule.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Contributor Summit:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://sched.co/1Sp9u&#34;&gt;Lessons Learned Building a GA API with CRDs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://sched.co/1Sp9l&#34;&gt;Conformance Profiles: Building a generic conformance test reporting framework&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://sched.co/1SpA9&#34;&gt;Gateway API: Beyond GA&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;KubeCon Main Event:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://sched.co/1R2qM&#34;&gt;Gateway API: The Most Collaborative API in Kubernetes History Is GA&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;KubeCon Office Hours:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Gateway API maintainers will be holding office hours sessions at KubeCon if
you&#39;d like to discuss or brainstorm any related topics. To get the latest
updates on these sessions, join the &lt;code&gt;#sig-network-gateway-api&lt;/code&gt; channel on
&lt;a href=&#34;https://slack.kubernetes.io/&#34;&gt;Kubernetes Slack&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;get-involved&#34;&gt;Get involved&lt;/h2&gt;
&lt;p&gt;We&#39;ve only barely scratched the surface of what&#39;s in flight with Gateway API.
There are lots of opportunities to get involved and help define the future of
Kubernetes routing APIs for both Ingress and Mesh.&lt;/p&gt;
&lt;p&gt;If this is interesting to you, please &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;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Introducing ingress2gateway; Simplifying Upgrades to Gateway API</title>
      <link>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/10/25/introducing-ingress2gateway/</link>
      <pubDate>Wed, 25 Oct 2023 10:00:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/10/25/introducing-ingress2gateway/</guid>
      <description>
        
        
        &lt;p&gt;&lt;em&gt;&lt;strong&gt;Authors:&lt;/strong&gt;&lt;/em&gt; Lior Lieberman (Google), Kobi Levi (independent)&lt;/p&gt;
&lt;p&gt;Today we are releasing &lt;a href=&#34;https://github.com/kubernetes-sigs/ingress2gateway&#34;&gt;ingress2gateway&lt;/a&gt;, a tool
that can help you migrate from &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/concepts/services-networking/ingress/&#34;&gt;Ingress&lt;/a&gt; to &lt;a href=&#34;https://gateway-api.sigs.k8s.io&#34;&gt;Gateway
API&lt;/a&gt;. Gateway API is just weeks away from graduating to GA, if you
haven&#39;t upgraded yet, now&#39;s the time to think about it!&lt;/p&gt;
&lt;h2 id=&#34;background&#34;&gt;Background&lt;/h2&gt;
&lt;p&gt;In the ever-evolving world of Kubernetes, networking plays a pivotal role. As more applications are
deployed in Kubernetes clusters, effective exposure of these services to clients becomes a critical
concern. If you&#39;ve been working with Kubernetes, you&#39;re likely familiar with the &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/concepts/services-networking/ingress/&#34;&gt;Ingress API&lt;/a&gt;,
which has been the go-to solution for managing external access to services.&lt;/p&gt;
&lt;p&gt;The Ingress API provides a way to route external traffic to your applications within the cluster,
making it an indispensable tool for many Kubernetes users. Ingress has its limitations however, and
as applications become more complex and the demands on your Kubernetes clusters increase, these
limitations can become bottlenecks.&lt;/p&gt;
&lt;p&gt;Some of the limitations are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Insufficient common denominator&lt;/strong&gt; - by attempting to establish a common denominator for various
HTTP proxies, Ingress can only accommodate basic HTTP routing, forcing more features of
contemporary proxies like traffic splitting and header matching into provider-specific,
non-transferable annotations.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Inadequate permission model&lt;/strong&gt; - Ingress spec configures both infrastructure and application
configuration in one object. With Ingress, the cluster operator and application developer operate
on the same Ingress object without being aware of each other’s roles. This creates an insufficient
role-based access control and has high potential for setup errors.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Lack of protocol diversity&lt;/strong&gt; - Ingress primarily focuses on HTTP(S) routing and does not provide
native support for other protocols, such as TCP, UDP and gRPC. This limitation makes it less
suitable for handling non-HTTP workloads.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;gateway-api&#34;&gt;Gateway API&lt;/h2&gt;
&lt;p&gt;To overcome this, Gateway API is designed to provide a more flexible, extensible, and powerful way
to manage traffic to your services.&lt;/p&gt;
&lt;p&gt;Gateway API is just weeks away from a GA (General Availability) release. It provides a standard
Kubernetes API for ingress traffic control. It offers extended functionality, improved
customization, and greater flexibility. By focusing on modular and expressive API resources, Gateway
API makes it possible to describe a wider array of routing configurations and models.&lt;/p&gt;
&lt;p&gt;The transition from Ingress API to Gateway API in Kubernetes is driven by advantages and advanced
functionalities that Gateway API offers, with its foundation built on four core principles: a
role-oriented approach, portability, expressiveness and extensibility.&lt;/p&gt;
&lt;h3 id=&#34;a-role-oriented-approach&#34;&gt;A role-oriented approach&lt;/h3&gt;
&lt;p&gt;Gateway API employs a role-oriented approach that aligns with the conventional roles within
organizations involved in configuring Kubernetes service networking. This approach enables
infrastructure engineers, cluster operators, and application developers to collectively address
different aspects of Gateway API.&lt;/p&gt;
&lt;p&gt;For instance, infrastructure engineers play a pivotal role in deploying GatewayClasses,
cluster-scoped resources that act as templates to explicitly define behavior for Gateways derived
from them, laying the groundwork for robust service networking.&lt;/p&gt;
&lt;p&gt;Subsequently, cluster operators utilize these GatewayClasses to deploy gateways. A Gateway in
Kubernetes&#39; Gateway API defines how external traffic can be directed to Services within the cluster,
essentially bridging non-Kubernetes sources to Kubernetes-aware destinations. It represents a
request for a load balancer configuration aligned with a GatewayClass’ specification. The Gateway
spec may not be exhaustive as some details can be supplied by the GatewayClass controller, ensuring
portability. Additionally, a Gateway can be linked to multiple Route references to channel specific
traffic subsets to designated services.&lt;/p&gt;
&lt;p&gt;Lastly, application developers configure route resources (such as HTTPRoutes), to manage
configuration (e.g. timeouts, request matching/filter) and Service composition (e.g. path routing to
backends) Route resources define protocol-specific rules for mapping requests from a Gateway to
Kubernetes Services. HTTPRoute is for multiplexing HTTP or terminated HTTPS connections. It&#39;s
intended for use in cases where you want to inspect the HTTP stream and use HTTP request data for
either routing or modification, for example using HTTP Headers for routing, or modifying them
in-flight.&lt;/p&gt;

&lt;figure class=&#34;diagram-medium&#34;&gt;
    &lt;img src=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/10/25/introducing-ingress2gateway/gateway-api-resources.svg&#34;
         alt=&#34;Diagram showing the key resources that make up Gateway API and how they relate to each other. The resources shown are GatewayClass, Gateway, and HTTPRoute; the Service API is also shown&#34;/&gt; 
&lt;/figure&gt;

&lt;h3 id=&#34;portability&#34;&gt;Portability&lt;/h3&gt;
&lt;p&gt;With more than 20 &lt;a href=&#34;https://gateway-api.sigs.k8s.io/implementations/#implementations&#34;&gt;API
implementations&lt;/a&gt;, Gateway API is
designed to be more portable across different implementations, clusters and environments. It helps
reduce Ingress&#39; reliance on non-portable, provider-specific annotations, making your configurations
more consistent and easier to manage across multiple clusters.&lt;/p&gt;
&lt;p&gt;Gateway API commits to supporting the 5 latest Kubernetes minor versions. That means that Gateway
API currently supports Kubernetes 1.24+.&lt;/p&gt;
&lt;h3 id=&#34;expressiveness&#34;&gt;Expressiveness&lt;/h3&gt;
&lt;p&gt;Gateway API provides standard, Kubernetes-backed support for a wide range of features, such as
header-based matching, traffic splitting, weight-based routing, request mirroring and more. With
Ingress, these features need custom provider-specific annotations.&lt;/p&gt;
&lt;h3 id=&#34;extensibility&#34;&gt;Extensibility&lt;/h3&gt;
&lt;p&gt;Gateway API is designed with extensibility as a core feature. Rather than enforcing a
one-size-fits-all model, it offers the flexibility to link custom resources at multiple layers
within the API&#39;s framework. This layered approach to customization ensures that users can tailor
configurations to their specific needs without overwhelming the main structure. By doing so, Gateway
API facilitates more granular and context-sensitive adjustments, allowing for a fine-tuned balance
between standardization and adaptability. This becomes particularly valuable in complex cloud-native
environments where specific use cases require nuanced configurations. A critical difference is that
Gateway API has a much broader base set of features and a standard pattern for extensions that can
be more expressive than annotations were on Ingress.&lt;/p&gt;
&lt;h2 id=&#34;upgrading-to-gateway&#34;&gt;Upgrading to Gateway&lt;/h2&gt;
&lt;p&gt;Migrating from Ingress to Gateway API may seem intimidating, but luckily Kubernetes just released a
tool to simplify the process. &lt;a href=&#34;https://github.com/kubernetes-sigs/ingress2gateway&#34;&gt;ingress2gateway&lt;/a&gt;
assists in the migration by converting your existing Ingress resources into Gateway API resources.
Here is how you can get started with Gateway API and using ingress2gateway:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://gateway-api.sigs.k8s.io/guides/#installing-a-gateway-controller&#34;&gt;Install a Gateway
controller&lt;/a&gt; OR &lt;a href=&#34;https://gateway-api.sigs.k8s.io/guides/#installing-gateway-api&#34;&gt;install
the Gateway API CRDs manually&lt;/a&gt; .&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Install &lt;a href=&#34;https://github.com/kubernetes-sigs/ingress2gateway&#34;&gt;ingress2gateway&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you have a Go development environment locally, you can install &lt;code&gt;ingress2gateway&lt;/code&gt; with:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;go install github.com/kubernetes-sigs/ingress2gateway@v0.1.0
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This installs &lt;code&gt;ingress2gateway&lt;/code&gt; to &lt;code&gt;$(go env GOPATH)/bin/ingress2gateway&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Alternatively, follow the installation guide
&lt;a href=&#34;https://github.com/kubernetes-sigs/ingress2gateway#installation&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Once the tool is installed, you can use it to convert the ingress resources in your cluster to
Gateway API resources.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;ingress2gateway print
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This above command will:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Load your current Kubernetes client config including the active context, namespace and
authentication details.&lt;/li&gt;
&lt;li&gt;Search for ingresses and provider-specific resources in that namespace.&lt;/li&gt;
&lt;li&gt;Convert them to Gateway API resources (Currently only Gateways and HTTPRoutes). For other
options you can  run the tool with &lt;code&gt;-h&lt;/code&gt;, or refer to
&lt;a href=&#34;https://github.com/kubernetes-sigs/ingress2gateway#options&#34;&gt;https://github.com/kubernetes-sigs/ingress2gateway#options&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Review the converted Gateway API resources, validate them, and then apply them to your cluster.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Send test requests to your Gateway to check that it is working. You could get your gateway
address using &lt;code&gt;kubectl get gateway &amp;lt;gateway-name&amp;gt; -n &amp;lt;namespace&amp;gt; -o jsonpath=&#39;{.status.addresses}{&amp;quot;\n&amp;quot;}&#39;&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Update your DNS to point to the new Gateway.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Once you&#39;ve confirmed that no more traffic is going through your Ingress configuration, you can
safely delete it.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;wrapping-up&#34;&gt;Wrapping up&lt;/h2&gt;
&lt;p&gt;Achieving reliable, scalable and extensible networking has always been a challenging objective. The
Gateway API is designed to improve the current Kubernetes networking standards like ingress and
reduce the need for implementation specific annotations and CRDs.&lt;/p&gt;
&lt;p&gt;It is a Kubernetes standard API, consistent across different platforms and implementations and most
importantly it is future proof. Gateway API is the next generation of the Ingress API, but has a
larger scope than that, expanding to tackle mesh and layer 4 routing as well. Gateway API and
ingress2gateway are supported by a dedicated team under SIG Network that actively work on it and
manage the ecosystem. It is also likely to receive more updates and community support.&lt;/p&gt;
&lt;h3 id=&#34;the-road-ahead&#34;&gt;The Road Ahead&lt;/h3&gt;
&lt;p&gt;ingress2gateway is just getting started. We&#39;re planning to onboard more providers, introduce support
for more types of Gateway API routes, and make sure everything syncs up smoothly with the ongoing
development of Gateway API.&lt;/p&gt;
&lt;p&gt;Excitingly, Gateway API is also making significant strides. While v1.0 is about to launching,
there&#39;s still a lot of work ahead. This release incorporates many new experimental features, with
additional functionalities currently in the early stages of planning and development.&lt;/p&gt;
&lt;p&gt;If you&#39;re interested in helping to contribute, we would love to have you! Please check out the
&lt;a href=&#34;https://gateway-api.sigs.k8s.io/contributing/community/&#34;&gt;community page&lt;/a&gt; which includes links to
the Slack channel and community meetings. We look forward to seeing you!!&lt;/p&gt;
&lt;h3 id=&#34;useful-links&#34;&gt;Useful Links&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Get involved with the Ingress2Gateway project on
&lt;a href=&#34;https://github.com/kubernetes-sigs/ingress2gateway&#34;&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Open a new issue -
&lt;a href=&#34;https://github.com/kubernetes-sigs/ingress2gateway/issues/new/choose&#34;&gt;ingress2gateway&lt;/a&gt;, &lt;a href=&#34;https://github.com/kubernetes-sigs/gateway-api/issues/new/choose&#34;&gt;Gateway
API&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Join our &lt;a href=&#34;https://github.com/kubernetes-sigs/gateway-api/discussions&#34;&gt;discussions&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gateway-api.sigs.k8s.io/guides/&#34;&gt;Gateway API Getting Started&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gateway-api.sigs.k8s.io/implementations/#gateways&#34;&gt;Gateway API Implementations&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Plants, process and parties: the Kubernetes 1.28 release interview</title>
      <link>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/10/24/plants-process-and-parties-the-kubernetes-1.28-release-interview/</link>
      <pubDate>Tue, 24 Oct 2023 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/10/24/plants-process-and-parties-the-kubernetes-1.28-release-interview/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Author&lt;/strong&gt;: Craig Box&lt;/p&gt;
&lt;p&gt;Since 2018, one of my favourite contributions to the Kubernetes community has been to &lt;a href=&#34;https://www.google.com/search?q=%22release+interview%22+site%3Akubernetes.io%2Fblog&#34;&gt;share the story of each release&lt;/a&gt;. Many of these stories were told on behalf of a past employer; by popular demand, I&#39;ve brought them back, now under my own name. If you were a fan of the old show, I would be delighted if you would &lt;a href=&#34;https://craigbox.substack.com/about&#34;&gt;subscribe&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Back in August, &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/08/15/kubernetes-v1-28-release/&#34;&gt;we welcomed the release of Kubernetes 1.28&lt;/a&gt;. That release was led by &lt;a href=&#34;https://twitter.com/gracenng&#34;&gt;Grace Nguyen&lt;/a&gt;, a CS student at the University of Waterloo. Grace joined me for the traditional release interview, and while you can read her story below, &lt;a href=&#34;https://craigbox.substack.com/p/the-kubernetes-128-release-interview&#34;&gt;I encourage you to listen to it if you can&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This transcript has been lightly edited and condensed for clarity.&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;You&#39;re a student at the University of Waterloo, so I want to spend the first two minutes of this interview talking about the Greater Kitchener-Waterloo region. It&#39;s August, so this is one of the four months of the year when there&#39;s no snow visible on the ground?&lt;/strong&gt;&lt;br&gt;
Well, it&#39;s not that bad. I think the East Coast has it kind of good. I grew up in Calgary, but I do love summer here in Waterloo. We have a &lt;a href=&#34;https://goo.gl/maps/W1nM7LjNZPv&#34;&gt;petting zoo&lt;/a&gt; close to our university campus, so I go and see the llamas sometimes.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Is that a new thing?&lt;/strong&gt;&lt;br&gt;
I&#39;m not sure, it seems like it&#39;s been around five-ish years, the Waterloo Park?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;I lived there in 2007, for a couple of years, just to set the scene for why we&#39;re talking about this. I think they were building a lot of the park then. I do remember, of course, that &lt;a href=&#34;https://www.oktoberfest.ca/&#34;&gt;Kitchener holds the second largest Oktoberfest in the world&lt;/a&gt;. Is that something you&#39;ve had a chance to check out?&lt;/strong&gt;&lt;br&gt;
I have not. I actually didn&#39;t know that was a fact.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The local civic organization is going to have to do a bit more work, I feel. Do you like ribs?&lt;/strong&gt;&lt;br&gt;
I have mixed feelings about ribs. It&#39;s kind of a hit or miss situation for me so far.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Again, that might be something that&#39;s changed over the last few years. The Ribfests used to have a lot of trophies with little pigs on top of them, but I feel that the shifting dining habits of the world might mean they have to offer some vegan or vegetarian options, to please the modern palette.&lt;/strong&gt;&lt;br&gt;
[LAUGHS] For sure. Do you recommend the Oktoberfest here? Have you been?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;I went a couple of times.  It was a lot of fun.&lt;/strong&gt;&lt;br&gt;
Okay.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;It&#39;s basically just drinking. I would have recommended it back then; I&#39;m not sure it would be quite what I&#39;d be doing today.&lt;/strong&gt;&lt;br&gt;
All right, good to know.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Ribfest, however, I would go back just for that.&lt;/strong&gt;&lt;br&gt;
Oh, ok.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;And the great thing about Ribfests as a concept is that they have one in every little town. &lt;a href=&#34;https://kitchenerribandbeerfest.com/&#34;&gt;The Kitchener Ribfest&lt;/a&gt;, I looked it up, it&#39;s in July; you&#39;ve just missed that. But, you could go to the &lt;a href=&#34;https://northernheatribseries.ca/waterloo/&#34;&gt;Waterloo Ribfest&lt;/a&gt; in September.&lt;/strong&gt;&lt;br&gt;
Oh, it is in September? They have their own Ribfest?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;They do. I think Guelph has one, and Cambridge has one. That&#39;s the advantage of the region — there are lots of little cities. Kitchener and Waterloo are two cities that grew into each other — they do call them the Twin Cities. I hear that they finally built the light rail link between the two of them?&lt;/strong&gt;&lt;br&gt;
It is fantastic, and makes the city so much more walkable.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Yes, you can go from one mall to the other. That&#39;s Canada for you.&lt;/strong&gt;&lt;br&gt;
Well, Uptown is really nice. I quite like it. It&#39;s quite cozy.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Do you ever cross the border over into Kitchener? Or only when you&#39;ve lost a bet?&lt;/strong&gt;&lt;br&gt;
Yeah, not a lot. Only for farmer&#39;s market, I say.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;It&#39;s worthwhile. There&#39;s a lot of good food there, I remember.&lt;/strong&gt;&lt;br&gt;
Yeah. Quite lovely.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Now we&#39;ve got all that out of the way, let&#39;s travel back in time a little bit. You mentioned there that you went to high school in Calgary?&lt;/strong&gt;&lt;br&gt;
I did. I had not been to Ontario before I went to university. Calgary was frankly too cold and not walkable enough for me.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;I basically say the same thing about Waterloo and that&#39;s why I moved to England.&lt;/strong&gt;&lt;br&gt;
Fascinating. Gets better.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How did you get into tech?&lt;/strong&gt;&lt;br&gt;
I took a computer science class in high school. I was one of maybe only three women in the class, and I kind of stuck with it since.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Was the gender distribution part of your thought process at the time?&lt;/strong&gt;&lt;br&gt;
Yeah, I think I was drawn to it partially because I didn&#39;t see a lot of people who looked like me in the class.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;You followed it through to university. What is it that you&#39;re studying?&lt;/strong&gt;&lt;br&gt;
I am studying computer engineering, so a lot of hardware stuff.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;You&#39;re involved in the &lt;a href=&#34;https://www.facebook.com/groups/uwcyber/&#34;&gt;UW Cybersecurity Club&lt;/a&gt;. What can you tell me about that without having to kill me?&lt;/strong&gt;&lt;br&gt;
Oh, we are very nice and friendly people! I told myself I&#39;m going to have a nice and chill summer and then I got chosen to lead the release and also ended up running the Waterloo Cybersecurity Club. The club kind of died out during the pandemic, because we weren&#39;t on campus, but we have so many smart and amazing people who are in cybersecurity, so it&#39;s great to get them together and I learned so many things.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Is that like the modern equivalent of the &lt;a href=&#34;https://en.wikipedia.org/wiki/LAN_party&#34;&gt;LAN party&lt;/a&gt;? You&#39;re all getting into a dark room and trying to hack the Gibson?&lt;/strong&gt;&lt;br&gt;
[LAUGHS] Well, you&#39;ll have to explain to me again what a LAN party is. Do you bring your own PC?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;You used to. Back in the day it was incomprehensible that you could communicate with a different person in a different place at a fast enough speed, so you had to physically sit next to somebody and plug a cable in between you.&lt;/strong&gt;&lt;br&gt;
Okay, well kind of the same, I guess. We bring our own laptop and we go to CTF competitions together.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;They didn&#39;t have laptops back in the days of LAN parties. You&#39;d bring a giant 19-inch square monitor, and everything. It was a badge of honor what you could carry.&lt;/strong&gt;&lt;br&gt;
Okay. Can&#39;t relate, but good to know. [LAUGHS]&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;One of the more unique aspects of UW is its &lt;a href=&#34;https://uwaterloo.ca/future-students/co-op&#34;&gt;co-op system&lt;/a&gt;. Tell us a little bit about that?&lt;/strong&gt;&lt;br&gt;
As part of my degree, I am required to do minimum five and maximum six co-ops. I&#39;ve done all six of them. Two of them were in Kubernetes and that&#39;s how I got started.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A co-op is a placement, as opposed to something you do on campus?&lt;/strong&gt;&lt;br&gt;
Right, so co-op is basically an internship. My first one was at the Canada Revenue Agency. We didn&#39;t have wifi and I had my own cubicle, which is interesting. They don&#39;t do that anymore, they have open office space. But my second was at Ericsson, where I learned about Kubernetes. It was during the pandemic. KubeCon offered virtual attendance for students and I signed up and I poked around and I have been around since.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What was it like going through university during the COVID years? What did that mean in terms of the fact you would previously have traveled to these internships? Did you do them all from home?&lt;/strong&gt;&lt;br&gt;
I&#39;m not totally sure what I missed out on. For sure, a lot of relationship building, but also that we do have to move a lot as part of the co-op experience. Last fall I was in San Francisco, I was in Palo Alto earlier this year. A lot of that dynamic has already been the case.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Definitely different weather systems, Palo Alto versus Waterloo.&lt;/strong&gt;&lt;br&gt;
Oh, for sure. Yes, yes. Really glad I was there over the winter.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The first snow would fall in Ontario about the end of October and it would pile up over the next few months. There were still piles that hadn&#39;t melted by June. That&#39;s why I say, there were only four months of the year, July through September, where there was no snow on the ground.&lt;/strong&gt;&lt;br&gt;
That&#39;s true. Didn&#39;t catch any snow in Palo Alto, and honestly, that&#39;s great. [CHUCKLES]&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Thank you, global warming, I guess.&lt;/strong&gt;&lt;br&gt;
Oh no! [LAUGHS]&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tell me about the co-op term that you did working with Kubernetes at Ericsson?&lt;/strong&gt;&lt;br&gt;
This was such a long time ago, but we were trying to build some sort of pipeline to deploy testing. It was running inside a cluster, and I learned Helm charts and all that good stuff. And then, for the co-op after that, I worked at a Canadian startup in FinTech. It was 24/7 Kubernetes, &lt;a href=&#34;https://medium.com/@nng.grace/automated-kubernetes-secret-injection-with-1password-secret-automation-and-hashicorp-vault-8db826c50c1d&#34;&gt;building their secret injection system, using ArgoCD to automatically pull secrets from 1Password&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How did that lead you on to involvement with the release team?&lt;/strong&gt;&lt;br&gt;
It was over the pandemic, so I didn&#39;t have a lot to do, I went to the conference, saw so many cool talks. One that really stuck out to me was &lt;a href=&#34;https://www.youtube.com/watch?v=-4W3ChRVeLI&#34;&gt;a Kubernetes hacking talk by Tabitha Sable and V Korbes&lt;/a&gt;. I thought it was the most amazing thing and it was so cool. One of my friends was on the release team at the time, and she showed me what she does. I applied and thankfully got in. I didn&#39;t have any open source experience. It was fully like one of those things where someone took a chance on me.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How would you characterize the experience that you&#39;ve had to date? You have had involvement with pretty much every release since then.&lt;/strong&gt;&lt;br&gt;
Yeah, I think it was a really formative experience, and the community has been such a big part of it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;You started as an enhancement shadow with Kubernetes 1.22, eventually moving up to enhancements lead, then you moved on to be the release lead shadow. Obviously, you are the lead for 1.28, but for 1.27 you did something a bit different. What was that, and why did you do it?&lt;/strong&gt;&lt;br&gt;
For 1.25 and 1.26, I was release lead shadow, so I had an understanding of what that role was like. I wanted to shadow another team, and at that time I thought CI Signal was a big black box to me. I joined the team, but I also had capacity for other things, I joined as a branch manager associate as well.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What is the difference between that role and the traditional release team roles we think about?&lt;/strong&gt;&lt;br&gt;
Yeah, that&#39;s a great question. So the branch management role is a more constant role. They don&#39;t necessarily get swapped out every release. You shadow as an associate, so you do things like cut releases, distribute them, update distros, things like that. It&#39;s a really important role, and the folks that are in there are more technical. So if you have been on the release team for a long time and are looking for more permanent role, I recommend looking into that.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Congratulations again on &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/08/15/kubernetes-v1-28-release/&#34;&gt;the release of 1.28 today&lt;/a&gt;.&lt;/strong&gt;&lt;br&gt;
Yeah, thank you.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What is the best new feature in Kubernetes 1.28, and why is it &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/08/25/native-sidecar-containers/&#34;&gt;sidecar container support&lt;/a&gt;?&lt;/strong&gt;&lt;br&gt;
Great question. I am as excited as you. In 1.28, we have a new feature in alpha, which is sidecar container support. We introduced a new field called restartPolicy for init containers, that allows the containers to live throughout the life cycle of the pod and not block the pod from terminating. Craig, you know a lot about this, but there are so many use cases for this. It is a very common pattern. You use it for logging, monitoring, metrics; also configs and secrets as well.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;And the service mesh!&lt;/strong&gt;&lt;br&gt;
And the service mesh.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Very popular. I will say that the Sidecar pattern was called out very early on, in &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2015/06/the-distributed-system-toolkit-patterns/&#34;&gt;a blog post Brendan Burns wrote&lt;/a&gt;, talking about how you can achieve some of the things you just mentioned. Support for it in Kubernetes has been— it&#39;s been a while, shall we say. I&#39;ve been doing these interviews since 2018, and September 2019 was when &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2019/12/06/when-youre-in-the-release-team-youre-family-the-kubernetes-1.16-release-interview/&#34;&gt;I first had a conversation with a release manager&lt;/a&gt; who felt they had to apologize for Sidecar containers not shipping in that release.&lt;/strong&gt;&lt;br&gt;
Well, here we are!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Thank you for not letting the side down.&lt;/strong&gt;&lt;br&gt;
[LAUGHS]&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;There are a bunch of other features that are going to GA in 1.28. Tell me about what&#39;s new with &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/1440&#34;&gt;kubectl events&lt;/a&gt;?&lt;/strong&gt;&lt;br&gt;
It got a new CLI and now it is separate from kubectl get. I think that changes in the CLI are always a little bit more apparent because they are user-facing.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Are there a lot of other user-facing changes, or are most of the things in the release very much behind the scenes?&lt;/strong&gt;&lt;br&gt;
I would say it&#39;s a good mix of both; it depends on what you&#39;re interested in.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;I am interested, of course, in &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/2268&#34;&gt;non-graceful node shutdown support&lt;/a&gt;. What can you tell us about that?&lt;/strong&gt;&lt;br&gt;
Right, so for situations where you have a hardware failure or a broken OS, we have added additional support for a better graceful shutdown.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;If someone trips over the power cord at your LAN party and your cluster goes offline as a result?&lt;/strong&gt;&lt;br&gt;
Right, exactly. More availability! That&#39;s always good.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;And if it&#39;s not someone tripping over your power cord, it&#39;s probably DNS that broke your cluster. What&#39;s changed in terms of DNS configuration?&lt;/strong&gt;&lt;br&gt;
Oh, we introduced &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/2595&#34;&gt;a new feature gate to allow more DNS search path&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Is that all there is to it?&lt;/strong&gt;&lt;br&gt;
That&#39;s pretty much it. [LAUGHING] Yeah, you can have more and longer DNS search path.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;It can never be long enough. Just search everything! If .com doesn&#39;t work, try .net and try .io after that.&lt;/strong&gt;&lt;br&gt;
Surely.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Those are a few of the big features that are moving to stable. Obviously, over the course of the last few releases, features come in, moving from Alpha to Beta and so on. New features coming in today might not be available to people for a while. As you mentioned, there are feature gates that you can enable to allow people to have access to these. What are some of the newest features that have been introduced that are in Alpha, that are particularly interesting to you personally?&lt;/strong&gt;&lt;br&gt;
I have two. The first one is &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/3895&#34;&gt;&lt;code&gt;kubectl delete --interactive&lt;/code&gt;&lt;/a&gt;. I&#39;m always nervous when I delete something, you know, it&#39;s going to be a typo or it&#39;s going to be on the wrong tab. So we have an &lt;code&gt;--interactive&lt;/code&gt; flag for that now.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;So you can get feedback on what you&#39;re about to delete before you do it?&lt;/strong&gt;&lt;br&gt;
Right; confirmation is good!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;You mentioned two there, what was the second one?&lt;/strong&gt;&lt;br&gt;
Right; this one is close to my heart. It is a SIG Release KEP, &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/1731&#34;&gt;publishing on community infrastructure&lt;/a&gt;. I&#39;m not sure if you know, but as part of my branch management associate role in 1.27, I had the opportunity to cut a few releases. It takes up to 12 hours sometimes. And now, we are hoping that the process only includes release managers, so we don&#39;t have to call up the folks at Google and, you know, lengthen that process anymore.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Is 12 hours the expected length for software of this size, or is there work in place to try and bring that down?&lt;/strong&gt;&lt;br&gt;
There&#39;s so much work in place to bring that down. I think 12 hours is on the shorter end of it. Unfortunately, we have had a situation where we have to, you know, switch the release manager because it&#39;s just so late at night for them.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;They&#39;ve fallen asleep halfway through?&lt;/strong&gt;&lt;br&gt;
Exactly, yeah. 6 to 12 hours, I think, is our status quo.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The theme for this release is &amp;quot;&lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/08/15/kubernetes-v1-28-release/#release-theme-and-logo&#34;&gt;Planternetes&lt;/a&gt;&amp;quot;. That&#39;s going to need some explanation, I feel.&lt;/strong&gt;&lt;br&gt;
Okay. I had full creative control over this. It is summer in the northern hemisphere, and I am a big house plant fanatic. It&#39;s always a little sad when I have to move cities for co-op and can&#39;t take my plants with me.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Is that a border control thing? They don&#39;t let you take them over the border?&lt;/strong&gt;&lt;br&gt;
It&#39;s not even that; they&#39;re just so clunky and fragile. It&#39;s usually not worth the effort. But I think our community is very much like a garden. We have very critical roles in the ecosystem and we all have to work together.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Will you be posting seeds out to contributors and growing something together all around the world?&lt;/strong&gt;&lt;br&gt;
That would be so cool if we had merch, like a little card with seeds embedded in it. I don&#39;t think we have the budget for that though. [LAUGHS]&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;You say that. There are people who are inspired in many different areas. I love talking to the release managers and hearing the things that they&#39;re interested in. You should think about taking some seeds off one of your plants, and just spreading them around the world. People can take pictures, and tag you in them on Instagram.&lt;/strong&gt;&lt;br&gt;
That&#39;s cool. You know how we have a SIG Beard? We can have a SIG Plant.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;You worked for a long time with the release lead for 1.27. Xander Grzywinski. One of the benefits of having &lt;a href=&#34;https://craigbox.substack.com/p/kubernetes-and-chill&#34;&gt;done my interview with him in writing&lt;/a&gt; and not as a podcast is I didn&#39;t have to try and butcher pronouncing his surname. Can you help me out here?&lt;/strong&gt;&lt;br&gt;
I unfortunately cannot. I don&#39;t want to butcher it either!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Anyway, Xander told me that he suspected that in this release you would have to deal with some very last-minute PRs, as is tradition. Was that the case?&lt;/strong&gt;&lt;br&gt;
I vividly remember the last minute PRs from last release because I was trying to cut the releases, as part of the branch management team. Thankfully, that was not the case this release. We have had other challenges, of course.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Can you tell me some of those challenges?&lt;/strong&gt;&lt;br&gt;
I think improvement on documentation is always a big part. The KEP process can be very daunting to new contributors. How do you get people to review your KEPs? How do you opt in? All that stuff. We&#39;re improving documentations for that.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;As someone who has been through a lot of releases, I&#39;ve been feeling, like you&#39;ve said, that the last minute nature has slowed down a little. The process is perhaps improving. Do you see that, or do you think there&#39;s still a long way to go for the leads to improve it?&lt;/strong&gt;&lt;br&gt;
I think we&#39;ve come very far. When I started in 1.22, we were using spreadsheets to track a hundred enhancements. It was a monster; I was terrified to touch it. Now, we&#39;re on GitHub boards. As a result of that, we are actually merging the bug triage and CI Signal team in 1.29.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What&#39;s the impact of that?&lt;/strong&gt;&lt;br&gt;
The bug triage team is now using the GitHub board to track issues, which is much more efficient. We are able to merge the two teams together.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;I have heard a rumor that GitHub boards are powered by spreadsheets underneath.&lt;/strong&gt;&lt;br&gt;
Honestly, even if that&#39;s true, the fact that it&#39;s on the same platform and it has better version control is just magical.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;At this time, the next release lead has not yet been announced, but tradition dictates that you write down your feelings, best wishes and instructions to them in an envelope, which you&#39;ll leave in their desk drawer. What are you going to put inside that envelope?&lt;/strong&gt;&lt;br&gt;
Our 1.28 release lead is fantastic and they&#39;re so capable of handling the release—&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;That&#39;s you, isn&#39;t it?&lt;/strong&gt;&lt;br&gt;
1.29? [LAUGHS] No, I&#39;m too tired. I need to catch up on my sleep. My advice for them? It&#39;s going to be okay. It&#39;s all going to be okay. I was going to echo Leo&#39;s and Cici&#39;s words, to overcommunicate, but I think that has been said enough times already.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;You&#39;ve communicated enough. Stop! No more communication!&lt;/strong&gt;&lt;br&gt;
Yeah, no more communication. [LAUGHS] It&#39;s going to be okay. And honestly, shout out to my emeritus advisor, Leo, for reminding me that. Sometimes there are a lot of fires and it can be overwhelming, but it will be okay.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;As we&#39;ve alluded to a little bit throughout our conversation, there are a lot of people in the Kubernetes community who, for want of a better term, have had &amp;quot;a lot of experience&amp;quot; at running these systems. Then there are, of course, a lot of people who are just at the beginning of their careers; like yourself, at university. How do you see the difference between how those groups interact? Is there one team throughout, or what do you think that each can learn from the other?&lt;/strong&gt;&lt;br&gt;
I think the diversity of the team is one of its strengths and I really enjoy it. I learn so much from folks who have been doing this for 20 years or folks who are new to the industry like I am.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;I know the CNCF goes to a lot of effort to enable new people to take part. Is there anything that you can say about how people might get involved?&lt;/strong&gt;&lt;br&gt;
Firstly, I think SIG Release has started a wonderful tradition, or system, of &lt;a href=&#34;https://github.com/kubernetes/sig-release/blob/master/release-team/shadows.md&#34;&gt;helping new folks join the release team as a shadow&lt;/a&gt;, and helping them grow into bigger positions, like leads. I think other SIGs are also following that template as well. But a big part of me joining and sticking with the community has been the ability to go to conferences. As I said, my first conference was KubeCon, when I was not involved in the community at all. And so a big shout-out to the CNCF and the companies that sponsor the Dan Kohn and the speaker scholarships. They have been the sole reason that I was able to attend KubeCon, meet people, and feel the power of the community.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Last year&#39;s KubeCon in North America was in Detroit?&lt;/strong&gt;&lt;br&gt;
Detroit, &lt;a href=&#34;https://medium.com/@nng.grace/kubecon-in-the-motor-city-4e23e0446751&#34;&gt;I was there, yeah&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;That&#39;s quite a long drive?&lt;/strong&gt;&lt;br&gt;
I was in SF, so I flew over.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;You live right next door! If only you&#39;d been in Waterloo.&lt;/strong&gt;&lt;br&gt;
Yeah, but who knows? Maybe I&#39;ll do a road trip from Waterloo to Chicago this year.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;&lt;a href=&#34;https://twitter.com/GraceNNG&#34;&gt;Grace Nguyen&lt;/a&gt; is a student at the University of Waterloo, and was the release team lead for Kubernetes 1.28. Subscribe to &lt;a href=&#34;https://craigbox.substack.com/about#%C2%A7follow-the-podcast&#34;&gt;Let&#39;s Get To The News&lt;/a&gt;, or search for it wherever you get your podcasts.&lt;/em&gt;&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>PersistentVolume Last Phase Transition Time in Kubernetes</title>
      <link>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/10/23/persistent-volume-last-phase-transition-time/</link>
      <pubDate>Mon, 23 Oct 2023 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/10/23/persistent-volume-last-phase-transition-time/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Author:&lt;/strong&gt; Roman Bednář (Red Hat)&lt;/p&gt;
&lt;p&gt;In the recent Kubernetes v1.28 release, we (SIG Storage) introduced a new alpha feature that aims to improve PersistentVolume (PV)
storage management and help cluster administrators gain better insights into the lifecycle of PVs.
With the addition of the &lt;code&gt;lastPhaseTransitionTime&lt;/code&gt; field into the status of a PV,
cluster administrators are now able to track the last time a PV transitioned to a different
&lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/concepts/storage/persistent-volumes/#phase&#34;&gt;phase&lt;/a&gt;, allowing for more efficient
and informed resource management.&lt;/p&gt;
&lt;h2 id=&#34;why-new-field&#34;&gt;Why do we need new PV field?&lt;/h2&gt;
&lt;p&gt;PersistentVolumes in Kubernetes play a crucial role in providing storage resources to workloads running in the cluster.
However, managing these PVs effectively can be challenging, especially when it comes
to determining the last time a PV transitioned between different phases, such as
&lt;code&gt;Pending&lt;/code&gt;, &lt;code&gt;Bound&lt;/code&gt; or &lt;code&gt;Released&lt;/code&gt;.
Administrators often need to know when a PV was last used or transitioned to certain
phases; for instance, to implement retention policies, perform cleanup, or monitor storage health.&lt;/p&gt;
&lt;p&gt;In the past, Kubernetes users have faced data loss issues when using the &lt;code&gt;Delete&lt;/code&gt; retain policy and had to resort to the safer &lt;code&gt;Retain&lt;/code&gt; policy.
When we planned the work to introduce the new &lt;code&gt;lastPhaseTransitionTime&lt;/code&gt; field, we
wanted to provide a more generic solution that can be used for various use cases,
including manual cleanup based on the time a volume was last used or producing alerts based on phase transition times.&lt;/p&gt;
&lt;h2 id=&#34;how-lastphasetransitiontime-helps&#34;&gt;How lastPhaseTransitionTime helps&lt;/h2&gt;
&lt;p&gt;Provided you&#39;ve enabled the feature gate (see &lt;a href=&#34;#how-to-use-it&#34;&gt;How to use it&lt;/a&gt;, the new &lt;code&gt;.status.lastPhaseTransitionTime&lt;/code&gt; field of a PersistentVolume (PV)
is updated every time that PV transitions from one phase to another.
Whether it&#39;s transitioning from &lt;code&gt;Pending&lt;/code&gt; to &lt;code&gt;Bound&lt;/code&gt;, &lt;code&gt;Bound&lt;/code&gt; to &lt;code&gt;Released&lt;/code&gt;, or any other phase transition, the &lt;code&gt;lastPhaseTransitionTime&lt;/code&gt; will be recorded.
For newly created PVs the phase will be set to &lt;code&gt;Pending&lt;/code&gt; and the &lt;code&gt;lastPhaseTransitionTime&lt;/code&gt; will be recorded as well.&lt;/p&gt;
&lt;p&gt;This feature allows cluster administrators to:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Implement Retention Policies&lt;/p&gt;
&lt;p&gt;With the &lt;code&gt;lastPhaseTransitionTime&lt;/code&gt;, administrators can now track when a PV was last used or transitioned to the &lt;code&gt;Released&lt;/code&gt; phase.
This information can be crucial for implementing retention policies to clean up resources that have been in the &lt;code&gt;Released&lt;/code&gt; phase for a specific duration.
For example, it is now trivial to write a script or a policy that deletes all PVs that have been in the &lt;code&gt;Released&lt;/code&gt; phase for a week.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Monitor Storage Health&lt;/p&gt;
&lt;p&gt;By analyzing the phase transition times of PVs, administrators can monitor storage health more effectively.
For example, they can identify PVs that have been in the &lt;code&gt;Pending&lt;/code&gt; phase for an unusually long time, which may indicate underlying issues with the storage provisioner.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;how-to-use-it&#34;&gt;How to use it&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;lastPhaseTransitionTime&lt;/code&gt; field is alpha starting from Kubernetes v1.28, so it requires
the &lt;code&gt;PersistentVolumeLastPhaseTransitionTime&lt;/code&gt; feature gate to be enabled.&lt;/p&gt;
&lt;p&gt;If you want to test the feature whilst it&#39;s alpha, you need to enable this feature gate on the &lt;code&gt;kube-controller-manager&lt;/code&gt; and the &lt;code&gt;kube-apiserver&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Use the &lt;code&gt;--feature-gates&lt;/code&gt; command line argument:&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;--feature-gates&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;...,PersistentVolumeLastPhaseTransitionTime=true&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Keep in mind that the feature enablement does not have immediate effect; the new field will be populated whenever a PV is updated and transitions between phases.
Administrators can then access the new field through the PV status, which can be retrieved using standard Kubernetes API calls or through Kubernetes client libraries.&lt;/p&gt;
&lt;p&gt;Here is an example of how to retrieve the &lt;code&gt;lastPhaseTransitionTime&lt;/code&gt; for a specific PV using the &lt;code&gt;kubectl&lt;/code&gt; command-line tool:&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 pv &amp;lt;pv-name&amp;gt; -o &lt;span style=&#34;color:#b8860b&#34;&gt;jsonpath&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;{.status.lastPhaseTransitionTime}&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;going-forward&#34;&gt;Going forward&lt;/h2&gt;
&lt;p&gt;This feature was initially introduced as an alpha feature, behind a feature gate that is disabled by default.
During the alpha phase, we (Kubernetes SIG Storage) will collect feedback from the end user community and address any issues or improvements identified.&lt;/p&gt;
&lt;p&gt;Once sufficient feedback has been received, or no complaints are received the feature can move to beta.
The beta phase will allow us to further validate the implementation and ensure its stability.&lt;/p&gt;
&lt;p&gt;At least two Kubernetes releases will happen between the release where this field graduates
to beta and the release that graduates the field to general availability (GA). That means that
the earliest release where this field could be generally available is Kubernetes 1.32,
likely to be scheduled for early 2025.&lt;/p&gt;
&lt;h2 id=&#34;getting-involved&#34;&gt;Getting involved&lt;/h2&gt;
&lt;p&gt;We always welcome new contributors so if you would like to get involved you can
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).&lt;/p&gt;
&lt;p&gt;If you would like to share feedback, you can do so on our
&lt;a href=&#34;https://app.slack.com/client/T09NY5SBT/C09QZFCE5&#34;&gt;public Slack channel&lt;/a&gt;.
If you&#39;re not already part of that Slack workspace, you can visit &lt;a href=&#34;https://slack.k8s.io/&#34;&gt;https://slack.k8s.io/&lt;/a&gt; for an invitation.&lt;/p&gt;
&lt;p&gt;Special thanks to all the contributors that provided great reviews, shared valuable insight and helped implement this feature (alphabetical order):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Han Kang (&lt;a href=&#34;https://github.com/logicalhan&#34;&gt;logicalhan&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;Jordan Liggitt (&lt;a href=&#34;https://github.com/liggitt&#34;&gt;liggitt&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Kiki (&lt;a href=&#34;https://github.com/carlory&#34;&gt;carlory&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;Tim Bannister (&lt;a href=&#34;https://github.com/sftim&#34;&gt;sftim&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Wojciech Tyczynski (&lt;a href=&#34;https://github.com/wojtek-t&#34;&gt;wojtek-t&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Xing Yang (&lt;a href=&#34;https://github.com/xing-yang&#34;&gt;xing-yang&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>A Quick Recap of 2023 China Kubernetes Contributor Summit</title>
      <link>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/10/20/kcs-shanghai/</link>
      <pubDate>Fri, 20 Oct 2023 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/10/20/kcs-shanghai/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Author:&lt;/strong&gt; Paco Xu and Michael Yao (DaoCloud)&lt;/p&gt;
&lt;p&gt;On September 26, 2023, the first day of
&lt;a href=&#34;https://www.lfasiallc.com/kubecon-cloudnativecon-open-source-summit-china/&#34;&gt;KubeCon + CloudNativeCon + Open Source Summit China 2023&lt;/a&gt;,
nearly 50 contributors gathered in Shanghai for the Kubernetes Contributor Summit.&lt;/p&gt;

&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/10/20/kcs-shanghai/kcs04.jpeg&#34;
         alt=&#34;All participants in the 2023 Kubernetes Contributor Summit&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;All participants in the 2023 Kubernetes Contributor Summit&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;This marked the first in-person offline gathering held in China after three years of the pandemic.&lt;/p&gt;
&lt;h2 id=&#34;a-joyful-meetup&#34;&gt;A joyful meetup&lt;/h2&gt;
&lt;p&gt;The event began with welcome speeches from &lt;a href=&#34;https://github.com/kevin-wangzefeng&#34;&gt;Kevin Wang&lt;/a&gt; from Huawei Cloud,
one of the co-chairs of KubeCon, and &lt;a href=&#34;https://github.com/puja108&#34;&gt;Puja&lt;/a&gt; from Giant Swarm.&lt;/p&gt;
&lt;p&gt;Following the opening remarks, the contributors introduced themselves briefly. Most attendees were from China,
while some contributors had made the journey from Europe and the United States specifically for the conference.
Technical experts from companies such as Microsoft, Intel, Huawei, as well as emerging forces like DaoCloud,
were present. Laughter and cheerful voices filled the room, regardless of whether English was spoken with
European or American accents or if conversations were carried out in authentic Chinese language. This created
an atmosphere of comfort, joy, respect, and anticipation. Past contributions brought everyone closer, and
mutual recognition and accomplishments made this offline gathering possible.&lt;/p&gt;

&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/10/20/kcs-shanghai/kcs06.jpeg&#34;
         alt=&#34;Face to face meeting in Shanghai&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;Face to face meeting in Shanghai&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;The attending contributors were no longer just GitHub IDs; they transformed into vivid faces.
From sitting together and capturing group photos to attempting to identify &amp;quot;Who is who,&amp;quot;
a loosely connected collective emerged. This team structure, although loosely knit and free-spirited,
was established to pursue shared dreams.&lt;/p&gt;
&lt;p&gt;As the saying goes, &amp;quot;You reap what you sow.&amp;quot; Each effort has been diligently documented within
the Kubernetes community contributions. Regardless of the passage of time, the community will
not erase those shining traces. Brilliance can be found in your PRs, issues, or comments.
It can also be seen in the smiling faces captured in meetup photos or heard through stories
passed down among contributors.&lt;/p&gt;
&lt;h2 id=&#34;technical-sharing-and-discussions&#34;&gt;Technical sharing and discussions&lt;/h2&gt;
&lt;p&gt;Next, there were three technical sharing sessions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/kubernetes/community/blob/master/sig-multicluster/README.md&#34;&gt;sig-multi-cluster&lt;/a&gt;:
&lt;a href=&#34;https://github.com/RainbowMango&#34;&gt;Hongcai Ren&lt;/a&gt;, a maintainer of Karmada, provided an introduction to
the responsibilities and roles of this SIG. Their focus is on designing, discussing, implementing,
and maintaining APIs, tools, and documentation related to multi-cluster management.
Cluster Federation, one of Karmada&#39;s core concepts, is also part of their work.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/helmfile/helmfile&#34;&gt;helmfile&lt;/a&gt;: &lt;a href=&#34;https://github.com/yxxhero&#34;&gt;yxxhero&lt;/a&gt;
from &lt;a href=&#34;https://gitlab.cn/&#34;&gt;GitLab&lt;/a&gt; presented how to deploy Kubernetes manifests declaratively,
customize configurations, and leverage the latest features of Helm, including Helmfile.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/kubernetes/community/blob/master/sig-scheduling/README.md&#34;&gt;sig-scheduling&lt;/a&gt;:
&lt;a href=&#34;https://github.com/william-wang&#34;&gt;william-wang&lt;/a&gt; from Huawei Cloud shared the recent updates and
future plans of SIG Scheduling. This SIG is responsible for designing, developing, and testing
components related to Pod scheduling.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/10/20/kcs-shanghai/kcs03.jpeg&#34;
         alt=&#34;A technical session about sig-multi-cluster&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;A technical session about sig-multi-cluster&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Following the sessions, a video featuring a call for contributors by &lt;a href=&#34;https://github.com/SergeyKanzhelev&#34;&gt;Sergey Kanzhelev&lt;/a&gt;,
the SIG-Node Chair, was played. The purpose was to encourage more contributors to join the Kubernetes community,
with a special emphasis on the popular SIG-Node.&lt;/p&gt;
&lt;p&gt;Lastly, Kevin hosted an Unconference collective discussion session covering topics such as
multi-cluster management, scheduling, elasticity, AI, and more. For detailed minutes of
the Unconference meeting, please refer to &lt;a href=&#34;https://docs.qq.com/doc/DY3pLWklzQkhjWHNT&#34;&gt;https://docs.qq.com/doc/DY3pLWklzQkhjWHNT&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;china-s-contributor-statistics&#34;&gt;China&#39;s contributor statistics&lt;/h2&gt;
&lt;p&gt;The contributor summit took place in Shanghai, with 90% of the attendees being Chinese.
Within the Cloud Native Computing Foundation (CNCF) ecosystem, contributions from China have been steadily increasing. Currently:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Chinese contributors account for 9% of the total.&lt;/li&gt;
&lt;li&gt;Contributions from China make up 11.7% of the overall volume.&lt;/li&gt;
&lt;li&gt;China ranks second globally in terms of contributions.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;alert alert-info note callout&#34; role=&#34;alert&#34;&gt;
  &lt;strong&gt;Note:&lt;/strong&gt; The data is from KubeCon keynotes by Chris Aniszczyk, CTO of Cloud Native Computing Foundation,
on September 26, 2023. This probably understates Chinese contributions. A lot of Chinese contributors
use VPNs and may not show up as being from China in the stats accurately.
&lt;/div&gt;
&lt;p&gt;The Kubernetes Contributor Summit is an inclusive meetup that welcomes all community contributors, including:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;New Contributors&lt;/li&gt;
&lt;li&gt;Current Contributors
&lt;ul&gt;
&lt;li&gt;docs&lt;/li&gt;
&lt;li&gt;code&lt;/li&gt;
&lt;li&gt;community management&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Subproject members&lt;/li&gt;
&lt;li&gt;Members of Special Interest Group (SIG) / Working Group (WG)&lt;/li&gt;
&lt;li&gt;Active Contributors&lt;/li&gt;
&lt;li&gt;Casual Contributors&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;acknowledgments&#34;&gt;Acknowledgments&lt;/h2&gt;
&lt;p&gt;We would like to express our gratitude to the organizers of this event:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kevin-wangzefeng&#34;&gt;Kevin Wang&lt;/a&gt;, the co-chair of KubeCon and the lead of the kubernetes contributor summit.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/pacoxu&#34;&gt;Paco Xu&lt;/a&gt;, who actively coordinated the venue, meals, invited contributors from both China and
international sources, and established WeChat groups to collect agenda topics. They also shared details of the event
before and after its occurrence through &lt;a href=&#34;https://github.com/kubernetes/community/issues/7510&#34;&gt;pre and post announcements&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/mengjiao-liu&#34;&gt;Mengjiao Liu&lt;/a&gt;, who was responsible for organizing, coordinating,
and facilitating various matters related to the summit.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We extend our appreciation to all the contributors who attended the China Kubernetes Contributor Summit in Shanghai.
Your dedication and commitment to the Kubernetes community are invaluable.
Together, we continue to push the boundaries of cloud native technology and shape the future of this ecosystem.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Bootstrap an Air Gapped Cluster With Kubeadm</title>
      <link>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/10/12/bootstrap-an-air-gapped-cluster-with-kubeadm/</link>
      <pubDate>Thu, 12 Oct 2023 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/10/12/bootstrap-an-air-gapped-cluster-with-kubeadm/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Author:&lt;/strong&gt; Rob Mengert (Defense Unicorns)&lt;/p&gt;
&lt;p&gt;Ever wonder how software gets deployed onto a system that is deliberately disconnected from the Internet and other networks? These systems are typically disconnected due to their sensitive nature. Sensitive as in utilities (power/water), banking, healthcare, weapons systems, other government use cases, etc. Sometimes it&#39;s technically a water gap, if you&#39;re running Kubernetes on an underwater vessel. Still, these environments need software to operate. This concept of deployment in a disconnected state is what it means to deploy to the other side of an &lt;a href=&#34;https://en.wikipedia.org/wiki/Air_gap_(networking)&#34;&gt;air gap&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Again, despite this posture, software still needs to run in these environments. Traditionally, software artifacts are physically carried across the air gap on hard drives, USB sticks, CDs, or floppy disks (for ancient systems, it still happens). Kubernetes lends itself particularly well to running software behind an air gap for several reasons, largely due to its declarative nature.&lt;/p&gt;
&lt;p&gt;In this blog article, I will walk through the process of bootstrapping a Kubernetes
cluster in an air-gapped lab environment using Fedora Linux and kubeadm.&lt;/p&gt;
&lt;h2 id=&#34;the-air-gap-vm-setup&#34;&gt;The Air Gap VM Setup&lt;/h2&gt;
&lt;p&gt;A real air-gapped network can take some effort to set up, so for this post, I will use an example VM on a laptop and do some network modifications. Below is the topology:&lt;/p&gt;

&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/10/12/bootstrap-an-air-gapped-cluster-with-kubeadm/airgap-vm.svg&#34;
         alt=&#34;Topology on the host/laptop which shows that connectivity to the internet from the air gap VM is not possible. However, connectivity between the host/laptop and the VM is possible&#34;/&gt; 
&lt;/figure&gt;

&lt;h3 id=&#34;local-topology&#34;&gt;Local topology&lt;/h3&gt;
&lt;p&gt;This VM will have its network connectivity disabled but in a way that doesn&#39;t shut down the VM&#39;s virtual NIC. Instead, its network will be downed by injecting a default route to a dummy interface, making anything internet-hosted unreachable. However, the VM still has a connected route to the bridge interface on the host, which means that network connectivity to the host is still working. This posture means that data can be transferred from the host/laptop to the VM via &lt;code&gt;scp&lt;/code&gt;, even with the default route on the VM black-holing all traffic that isn&#39;t destined for the local bridge subnet. This type of transfer is analogous to carrying data across the air gap and will be used throughout this post.&lt;/p&gt;
&lt;p&gt;Other details about the lab setup:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;VM OS:&lt;/strong&gt; Fedora 37&lt;br&gt;
&lt;strong&gt;Kubernetes Version:&lt;/strong&gt; v1.27.3&lt;br&gt;
&lt;strong&gt;CNI Plugins Version:&lt;/strong&gt; v1.3.0&lt;br&gt;
&lt;strong&gt;CNI Provider and Version:&lt;/strong&gt; Flannel v0.22.0&lt;/p&gt;
&lt;p&gt;While this single VM lab is a simplified example, the below diagram more approximately shows what a real air-gapped environment could look like:&lt;/p&gt;

&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/10/12/bootstrap-an-air-gapped-cluster-with-kubeadm/example_production_topology.svg&#34;
         alt=&#34;Example production topology which shows 3 control plane Kubernetes nodes and &amp;#39;n&amp;#39; worker nodes along with a Docker registry in an air-gapped environment.  Additionally shows two workstations, one on each side of the air gap and an IT admin which physically carries the artifacts across.&#34;/&gt; 
&lt;/figure&gt;

&lt;p&gt;Note, there is still intentional isolation between the environment and the internet.  There are also some things that are not shown in order to keep the diagram simple, for example malware scanning on the secure side of the air gap.&lt;/p&gt;
&lt;p&gt;Back to the single VM lab environment.&lt;/p&gt;
&lt;h2 id=&#34;identifying-the-required-software-artifacts&#34;&gt;Identifying the required software artifacts&lt;/h2&gt;
&lt;p&gt;I have gone through the trouble of identifying all of the required software components that need to be carried across the air gap in order for this cluster to be stood up:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Docker (to host an internal container image registry)&lt;/li&gt;
&lt;li&gt;Containerd&lt;/li&gt;
&lt;li&gt;libcgroup&lt;/li&gt;
&lt;li&gt;socat&lt;/li&gt;
&lt;li&gt;conntrack-tools&lt;/li&gt;
&lt;li&gt;CNI plugins&lt;/li&gt;
&lt;li&gt;crictl&lt;/li&gt;
&lt;li&gt;kubeadm&lt;/li&gt;
&lt;li&gt;kubelet&lt;/li&gt;
&lt;li&gt;kubectl and k9s (strictly speaking, these aren&#39;t required to bootstrap a cluster but they are handy to interact with one)&lt;/li&gt;
&lt;li&gt;kubelet.service systemd file&lt;/li&gt;
&lt;li&gt;kubeadm configuration file&lt;/li&gt;
&lt;li&gt;Docker registry container image&lt;/li&gt;
&lt;li&gt;Kubernetes component container images&lt;/li&gt;
&lt;li&gt;CNI network plugin container images (&lt;a href=&#34;https://github.com/flannel-io/flannel&#34;&gt;Flannel&lt;/a&gt; will be used for this lab)&lt;/li&gt;
&lt;li&gt;CNI network plugin manifests&lt;/li&gt;
&lt;li&gt;CNI tooling container images&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The way I identified these was by trying to do the installation and working through all of the errors that are thrown around an additional dependency being required. In a real air-gapped scenario, each transport of artifacts across the air gap could represent anywhere from 20 minutes to several weeks of time spent by the installer. That is to say that the target system could be located in a data center on the same floor as your desk, at a satellite downlink facility in the middle of nowhere, or on a submarine that&#39;s out to sea. Knowing what is on that system at any given time is important so you know what you have to bring.&lt;/p&gt;
&lt;h2 id=&#34;prepare-the-node-for-k8s&#34;&gt;Prepare the Node for K8s&lt;/h2&gt;
&lt;p&gt;Before downloading and moving the artifacts to the VM, let&#39;s first prep that VM to run Kubernetes.&lt;/p&gt;
&lt;h3 id=&#34;vm-preparation&#34;&gt;VM preparation&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Run these steps as a normal user&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Make destination directory for software artifacts&lt;/strong&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mkdir ~/tmp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;em&gt;Run the following steps as the superuser&lt;/em&gt; (&lt;code&gt;root&lt;/code&gt;)&lt;/p&gt;
&lt;p&gt;Write to &lt;code&gt;/etc/sysctl.d/99-k8s-cri.conf&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cat &amp;gt; /etc/sysctl.d/99-k8s-cri.conf &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;net.bridge.bridge-nf-call-iptables=1
&lt;/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;net.ipv4.ip_forward=1
&lt;/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;net.bridge.bridge-nf-call-ip6tables=1
&lt;/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;p&gt;Write to &lt;code&gt;/etc/modules-load.d/k8s.conf&lt;/code&gt; (enable &lt;code&gt;overlay&lt;/code&gt; and &lt;code&gt;nbr_netfilter&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f&#34;&gt;echo&lt;/span&gt; -e overlay&lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;\\&lt;/span&gt;nbr_netfilter &amp;gt; /etc/modules-load.d/k8s.conf
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Install iptables:&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;dnf -y install iptables-legacy
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Set iptables to use legacy mode (not &lt;code&gt;nft&lt;/code&gt; emulating &lt;code&gt;iptables&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;update-alternatives --set iptables /usr/sbin/iptables-legacy
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Turn off swap:&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;touch /etc/systemd/zram-generator.conf
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;systemctl mask systemd-zram-setup@.service
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sed -i &lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;/ swap / s/^\(.*\)$/#\1/g&amp;#39;&lt;/span&gt; /etc/fstab
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Disable &lt;code&gt;firewalld&lt;/code&gt; (this is OK in a demo context):&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;systemctl disable --now firewalld
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Disable &lt;code&gt;systemd-resolved&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;systemctl disable --now systemd-resolved
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Configure DNS defaults for NetworkManager:&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sed -i &lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;/\[main\]/a dns=default&amp;#39;&lt;/span&gt; /etc/NetworkManager/NetworkManager.conf
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Blank the system-level DNS resolver 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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;unlink /etc/resolv.conf &lt;span style=&#34;color:#666&#34;&gt;||&lt;/span&gt; &lt;span style=&#34;color:#a2f&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;touch /etc/resolv.conf
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Disable SELinux &lt;em&gt;(just for a demo - check before doing this in production!)&lt;/em&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;setenforce &lt;span style=&#34;color:#666&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Make sure all changes survive a reboot&lt;/strong&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;reboot
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;download-all-the-artifacts&#34;&gt;Download all the artifacts&lt;/h2&gt;
&lt;p&gt;On the laptop/host machine, download all of the artifacts enumerated in the previous section.  Since the air gapped VM is running Fedora 37, all of the dependencies shown in this part are for Fedora 37.  Note, this procedure will only work on AArch64 or AMD64 CPU architectures as they are the most popular and widely available..  You can execute this procedure anywhere you have write permissions; your home directory is a perfectly suitable choice.&lt;/p&gt;
&lt;p&gt;Note, operating system packages for the Kubernetes artifacts that need to be carried across can now be found at &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/08/15/pkgs-k8s-io-introduction/&#34;&gt;pkgs.k8s.io&lt;/a&gt;. This blog post will use a combination of Fedora repositories and GitHub in order to download all of the required artifacts. When you’re doing this on your own cluster, you should decide whether to use the official Kubernetes packages, or the official packages from your operating system distribution - both are valid choices.&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Set architecture variables&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;UARCH&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;$(&lt;/span&gt;uname -m&lt;span style=&#34;color:#a2f;font-weight:bold&#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;if&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;[[&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;$UARCH&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;arm64&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;||&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;$UARCH&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;aarch64&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;]]&lt;/span&gt;; &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;then&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:#b8860b&#34;&gt;ARCH&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;aarch64&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:#b8860b&#34;&gt;K8s_ARCH&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;arm64&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:#a2f;font-weight:bold&#34;&gt;else&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:#b8860b&#34;&gt;ARCH&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;x86_64&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:#b8860b&#34;&gt;K8s_ARCH&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;amd64&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:#a2f;font-weight:bold&#34;&gt;fi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Set environment variables for software versions to 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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;CNI_PLUGINS_VERSION&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;v1.3.0&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:#b8860b&#34;&gt;CRICTL_VERSION&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;v1.27.0&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:#b8860b&#34;&gt;KUBE_RELEASE&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;v1.27.3&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:#b8860b&#34;&gt;RELEASE_VERSION&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;v0.15.1&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:#b8860b&#34;&gt;K9S_VERSION&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;v0.27.4&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Create a &lt;code&gt;download&lt;/code&gt; directory, change into it, and download all of the RPMs and configuration files&lt;/strong&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mkdir download &lt;span style=&#34;color:#666&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style=&#34;color:#a2f&#34;&gt;cd&lt;/span&gt; download
&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;curl -O https://download.docker.com/linux/fedora/37/&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;ARCH&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;/stable/Packages/docker-ce-cli-23.0.2-1.fc37.&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;ARCH&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;.rpm
&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;curl -O https://download.docker.com/linux/fedora/37/&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;ARCH&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;/stable/Packages/containerd.io-1.6.19-3.1.fc37.&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;ARCH&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;.rpm
&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;curl -O https://download.docker.com/linux/fedora/37/&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;ARCH&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;/stable/Packages/docker-compose-plugin-2.17.2-1.fc37.&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;ARCH&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;.rpm
&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;curl -O https://download.docker.com/linux/fedora/37/&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;ARCH&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;/stable/Packages/docker-ce-rootless-extras-23.0.2-1.fc37.&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;ARCH&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;.rpm
&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;curl -O https://download.docker.com/linux/fedora/37/&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;ARCH&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;/stable/Packages/docker-ce-23.0.2-1.fc37.&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;ARCH&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;.rpm
&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;curl -O https://download-ib01.fedoraproject.org/pub/fedora/linux/releases/37/Everything/&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;ARCH&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;/os/Packages/l/libcgroup-3.0-1.fc37.&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;ARCH&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;.rpm
&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&#34;&gt;echo&lt;/span&gt; -e &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;\nDownload Kubernetes Binaries&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;curl -L -O &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;https://github.com/containernetworking/plugins/releases/download/&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;CNI_PLUGINS_VERSION&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;/cni-plugins-linux-&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;K8s_ARCH&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;CNI_PLUGINS_VERSION&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;.tgz&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;curl -L -O &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;https://github.com/kubernetes-sigs/cri-tools/releases/download/&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;CRICTL_VERSION&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;/crictl-&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;CRICTL_VERSION&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;-linux-&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;K8s_ARCH&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;.tar.gz&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;curl -L --remote-name-all https://dl.k8s.io/release/&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;KUBE_RELEASE&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;/bin/linux/&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;K8s_ARCH&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;/&lt;span style=&#34;color:#666&#34;&gt;{&lt;/span&gt;kubeadm,kubelet&lt;span style=&#34;color:#666&#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;curl -L -O &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;https://raw.githubusercontent.com/kubernetes/release/&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;RELEASE_VERSION&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;/cmd/kubepkg/templates/latest/deb/kubelet/lib/systemd/system/kubelet.service&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;curl -L -O &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;https://raw.githubusercontent.com/kubernetes/release/&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;RELEASE_VERSION&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;/cmd/kubepkg/templates/latest/deb/kubeadm/10-kubeadm.conf&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;curl -L -O &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;https://dl.k8s.io/release/&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;KUBE_RELEASE&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;/bin/linux/&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;K8s_ARCH&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;/kubectl&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:#a2f&#34;&gt;echo&lt;/span&gt; -e &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;\nDownload dependencies&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;curl -O &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;https://dl.fedoraproject.org/pub/fedora/linux/releases/37/Everything/&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;ARCH&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;/os/Packages/s/socat-1.7.4.2-3.fc37.&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;ARCH&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;.rpm&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;curl -O &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;https://dl.fedoraproject.org/pub/fedora/linux/releases/37/Everything/&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;ARCH&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;/os/Packages/l/libcgroup-3.0-1.fc37.&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;ARCH&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;.rpm&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;curl -O &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;https://dl.fedoraproject.org/pub/fedora/linux/releases/37/Everything/&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;ARCH&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;/os/Packages/c/conntrack-tools-1.4.6-4.fc37.&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;ARCH&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;.rpm&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;curl -LO &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;https://github.com/derailed/k9s/releases/download/&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;K9S_VERSION&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;/k9s_Linux_&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;K8s_ARCH&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;.tar.gz&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;curl -LO &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Download all of the necessary container images:&lt;/strong&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;images&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=(&lt;/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;&amp;#34;registry.k8s.io/kube-apiserver:&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;KUBE_RELEASE&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&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&#34;&gt;&amp;#34;registry.k8s.io/kube-controller-manager:&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;KUBE_RELEASE&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&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&#34;&gt;&amp;#34;registry.k8s.io/kube-scheduler:&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;KUBE_RELEASE&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&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&#34;&gt;&amp;#34;registry.k8s.io/kube-proxy:&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;KUBE_RELEASE&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&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&#34;&gt;&amp;#34;registry.k8s.io/pause:3.9&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&#34;&gt;&amp;#34;registry.k8s.io/etcd:3.5.7-0&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&#34;&gt;&amp;#34;registry.k8s.io/coredns/coredns:v1.10.1&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&#34;&gt;&amp;#34;registry:2.8.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:#b44&#34;&gt;&amp;#34;flannel/flannel:v0.22.0&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&#34;&gt;&amp;#34;flannel/flannel-cni-plugin:v1.1.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:#666&#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;for&lt;/span&gt; image in &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;images&lt;/span&gt;[@]&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt;; &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;do&lt;/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;# Pull the image from the registry&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    docker pull &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;$image&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&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:#080;font-style:italic&#34;&gt;# Save the image to a tar file on the local disk&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#b8860b&#34;&gt;image_name&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;$(&lt;/span&gt;&lt;span style=&#34;color:#a2f&#34;&gt;echo&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;$image&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt; | sed &lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;s|/|_|g&amp;#39;&lt;/span&gt; | sed &lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;s/:/_/g&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    docker save -o &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;image_name&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;.tar&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;$image&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&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:#a2f;font-weight:bold&#34;&gt;done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The above commands will take a look at the CPU architecture for the current host/laptop, create and change into a directory called download, and finally download all of the dependencies. Each of these files must then be transported over the air gap via scp. The exact syntax of the command will vary depending on the user on the VM, if you created an SSH key, and the IP of your air gap VM. The rough syntax 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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;scp -i &lt;span style=&#34;color:#b44&#34;&gt;&amp;lt;&amp;lt;SSH_KEY&amp;gt;&amp;gt; &amp;lt;&amp;lt;FILE&amp;gt;&amp;gt; &amp;lt;&amp;lt;AIRGAP_VM_US&lt;/span&gt;ER&amp;gt;&amp;gt;@&lt;span style=&#34;color:#b44&#34;&gt;&amp;lt;&amp;lt;AIRGA&lt;/span&gt;P_VM_IP&amp;gt;&amp;gt;:~/tmp/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Once all of the files have been transported to the air gapped VM, the rest of the blog post will take place from the VM. Open a terminal session to that system.&lt;/p&gt;
&lt;h3 id=&#34;put-the-artifacts-in-place&#34;&gt;Put the artifacts in place&lt;/h3&gt;
&lt;p&gt;Everything that is needed in order to bootstrap a Kubernetes cluster now exists on the air-gapped VM. This section is a lot more complicated since various types of artifacts are now on disk on the air-gapped VM. Get a root shell on the air gap VM as the rest of this section will be executed from there. Let&#39;s start by setting the same architecture variables and environmental as were set on the host/laptop and then install all of the RPM packages:&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;UARCH&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;$(&lt;/span&gt;uname -m&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;)&lt;/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;# Set architecture variables&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;if&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;[[&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;$UARCH&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;arm64&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;||&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;$UARCH&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;aarch64&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;]]&lt;/span&gt;; &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;then&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:#b8860b&#34;&gt;ARCH&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;aarch64&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:#b8860b&#34;&gt;K8s_ARCH&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;arm64&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:#a2f;font-weight:bold&#34;&gt;else&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:#b8860b&#34;&gt;ARCH&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;x86_64&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:#b8860b&#34;&gt;K8s_ARCH&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;amd64&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:#a2f;font-weight:bold&#34;&gt;fi&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:#080;font-style:italic&#34;&gt;# Set environment variables&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;CNI_PLUGINS_VERSION&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;v1.3.0&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:#b8860b&#34;&gt;CRICTL_VERSION&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;v1.27.0&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:#b8860b&#34;&gt;KUBE_RELEASE&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;v1.27.3&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:#b8860b&#34;&gt;RELEASE_VERSION&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;v0.15.1&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:#b8860b&#34;&gt;K9S_VERSION&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;v0.27.4&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:#a2f&#34;&gt;cd&lt;/span&gt; ~/tmp/
&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;dnf -y install ./*.rpm
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Next, install the CNI plugins and &lt;code&gt;crictl&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mkdir -p /opt/cni/bin
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;tar -C /opt/cni/bin -xz -f &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;cni-plugins-linux-&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;K8s_ARCH&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;-v1.3.0.tgz&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;tar -C /usr/local/bin-xz -f &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;crictl-v1.27.0-linux-&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;K8s_ARCH&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;.tar.gz&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Make kubeadm, kubelet and kubectl executable and move them from the &lt;code&gt;/tmp&lt;/code&gt;
directory to &lt;code&gt;/usr/local/bin&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;chmod +x kubeadm kubelet kubectl
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mv kubeadm kubelet kubectl /usr/local/bin
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Define an override for the systemd kubelet service file, and move it to the proper location:&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mkdir -p /etc/systemd/system/kubelet.service.d
&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;sed &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;s:/usr/bin:/usr/local/bin:g&amp;#34;&lt;/span&gt; 10-kubeadm.conf &amp;gt; /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The CRI plugin for containerd is disabled by default; enable 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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sed -i &lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;s/^disabled_plugins = \[&amp;#34;cri&amp;#34;\]/#&amp;amp;/&amp;#39;&lt;/span&gt; /etc/containerd/config.toml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Put a custom &lt;code&gt;/etc/docker/daemon.json&lt;/code&gt; file in place:&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f&#34;&gt;echo&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&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&#34;&gt;
&lt;/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;&amp;#34;exec-opts&amp;#34;: [&amp;#34;native.cgroupdriver=systemd&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&#34;&gt;
&lt;/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;&amp;#34;insecure-registries&amp;#34; : [&amp;#34;localhost:5000&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&#34;&gt;
&lt;/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;&amp;#34;allow-nondistributable-artifacts&amp;#34;: [&amp;#34;localhost:5000&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&#34;&gt;
&lt;/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;&amp;#34;log-driver&amp;#34;: &amp;#34;json-file&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&#34;&gt;
&lt;/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;&amp;#34;log-opts&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&#34;&gt;
&lt;/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;&amp;#34;max-size&amp;#34;: &amp;#34;100m&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&#34;&gt;
&lt;/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;},
&lt;/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;
&lt;/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;&amp;#34;group&amp;#34;: &amp;#34;rnd&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&#34;&gt;
&lt;/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;&amp;#34;storage-driver&amp;#34;: &amp;#34;overlay2&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&#34;&gt;
&lt;/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;&amp;#34;storage-opts&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&#34;&gt;
&lt;/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;&amp;#34;overlay2.override_kernel_check=true&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&#34;&gt;
&lt;/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;]
&lt;/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;
&lt;/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;}&amp;#39;&lt;/span&gt; &amp;gt; /etc/docker/daemon.json
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Two important items to highlight in the Docker &lt;code&gt;daemon.json&lt;/code&gt; configuration file. The insecure-registries line means that the registry in brackets does not support TLS. Even inside an air gapped environment, this isn&#39;t a good practice but is fine for the purposes of this lab. The allow-nondistributable-artifacts line tells Docker to permit pushing nondistributable artifacts to this registry. Docker by default does not push these layers to avoid potential issues around licensing or distribution rights. A good example of this is the Windows base container image. This line will allow layers that Docker marks as &amp;quot;foreign&amp;quot; to be pushed to the registry. While not a big deal for this article, that line could be required for some air gapped environments. All layers have to exist locally since nothing inside the air gapped environment can reach out to a public container image registry to get what it needs.&lt;/p&gt;
&lt;p&gt;(Re)start Docker and enable it so it starts at system boot:&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;systemctl restart docker
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;systemctl &lt;span style=&#34;color:#a2f&#34;&gt;enable&lt;/span&gt; docker
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Start, and enable, containerd and the kubelet:&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;systemctl &lt;span style=&#34;color:#a2f&#34;&gt;enable&lt;/span&gt; --now containerd
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;systemctl &lt;span style=&#34;color:#a2f&#34;&gt;enable&lt;/span&gt; --now kubelet
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The container image registry that runs in Docker is only required for any CNI related containers and subsequent workload containers. This registry is &lt;strong&gt;not&lt;/strong&gt; used to house the Kubernetes component containers. Note, nerdctl would have also worked here as an alternative to Docker and would have allowed for direct interaction with containerd. Docker was chosen for its familiarity.&lt;/p&gt;
&lt;p&gt;Start a container image registry inside Docker:&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker load -i registry_2.8.2.tar
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker run -d -p 5000:5000 --restart&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;always --name registry registry:2.8.2
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;load-flannel-containers-into-the-docker-registry&#34;&gt;Load Flannel containers into the Docker registry&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: &lt;em&gt;Flannel was chosen for this lab due to familiarity.  Chose whatever CNI works best in your environment.&lt;/em&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker load -i flannel_flannel_v0.22.0.tar
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker load -i flannel_flannel-cni-plugin_v1.1.2.tar
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker tag flannel/flannel:v0.22.0 localhost:5000/flannel/flannel:v0.22.0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker tag flannel/flannel-cni-plugin:v1.1.1 localhost:5000/flannel/flannel-cni-plugin:v1.1.1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker push localhost:5000/flannel/flannel:v0.22.0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker push localhost:5000/flannel/flannel-cni-plugin:v1.1.1
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Load container images for Kubernetes components, via &lt;code&gt;ctr&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;images_files&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=(&lt;/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;&amp;#34;registry.k8s.io/kube-apiserver:&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;KUBE_RELEASE&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&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&#34;&gt;&amp;#34;registry.k8s.io/kube-controller-manager:&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;KUBE_RELEASE&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&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&#34;&gt;&amp;#34;registry.k8s.io/kube-scheduler:&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;KUBE_RELEASE&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&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&#34;&gt;&amp;#34;registry.k8s.io/kube-proxy:&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;KUBE_RELEASE&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&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&#34;&gt;&amp;#34;registry.k8s.io/pause:3.9&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&#34;&gt;&amp;#34;registry.k8s.io/etcd:3.5.7-0&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&#34;&gt;&amp;#34;registry.k8s.io/coredns/coredns:v1.10.1&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:#666&#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;for&lt;/span&gt; index in &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;!image_files[@]&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt;; &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;do&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;if&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;[[&lt;/span&gt;-f &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;image_files&lt;/span&gt;[&lt;span style=&#34;color:#b8860b&#34;&gt;$index&lt;/span&gt;]&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;]]&lt;/span&gt;; &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;then&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:#080;font-style:italic&#34;&gt;# The below line loads the images where they need to be on the VM&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ctr -n k8s.io images import &lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;image_files&lt;/span&gt;[&lt;span style=&#34;color:#b8860b&#34;&gt;$index&lt;/span&gt;]&lt;span style=&#34;color:#b68;font-weight:bold&#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;else&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&#34;&gt;echo&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;File &lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;image_files&lt;/span&gt;[&lt;span style=&#34;color:#b8860b&#34;&gt;$index&lt;/span&gt;]&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt; not found!&amp;#34;&lt;/span&gt; 1&amp;gt;&amp;amp;&lt;span style=&#34;color:#666&#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&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;fi&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;done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A totally reasonable question here could be &amp;quot;Why not use the Docker registry that was just stood up to house the K8s component images?&amp;quot; This simply didn&#39;t work even with the proper modification to the configuration file that gets passed to kubeadm.&lt;/p&gt;
&lt;h3 id=&#34;spin-up-the-kubernetes-cluster&#34;&gt;Spin up the Kubernetes cluster&lt;/h3&gt;
&lt;p&gt;Check if a cluster is already running and tear it down if it 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-bash&#34; data-lang=&#34;bash&#34;&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; systemctl is-active --quiet kubelet; &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;then&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:#080;font-style:italic&#34;&gt;# Reset the Kubernetes cluster&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&#34;&gt;echo&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;A Kubernetes cluster is already running. Resetting the cluster...&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;    kubeadm reset -f
&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;fi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Log into the Docker registry from inside the air-gapped VM:&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# OK for a demo; use secure credentials in production!&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:#b8860b&#34;&gt;DOCKER_USER&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;user
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;DOCKER_PASS&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;pass
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f&#34;&gt;echo&lt;/span&gt; &lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;DOCKER_PASS&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt; | docker login --username&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;DOCKER_USER&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt; --password-stdin localhost:5000
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Create a cluster configuration file and initialize the cluster:&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f&#34;&gt;echo&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&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&#34;&gt;
&lt;/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: kubeadm.k8s.io/v1beta3
&lt;/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: 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&#34;&gt;clusterName: 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:#b44&#34;&gt;kubernetesVersion: v1.27.3
&lt;/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;networking:
&lt;/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;    dnsDomain: cluster.local
&lt;/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;    podSubnet: 10.244.0.0/16 # --pod-network-cidr
&lt;/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;    serviceSubnet: 10.96.0.0/12
&lt;/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;---
&lt;/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: kubeadm.k8s.io/v1beta3
&lt;/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: InitConfiguration
&lt;/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;localAPIEndpoint:
&lt;/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;    advertiseAddress: 10.10.10.10 # Update to the IP address of the air gap VM
&lt;/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;    bindPort: 6443
&lt;/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;nodeRegistration:
&lt;/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;    criSocket: unix:///run/containerd/containerd.sock # or rely on autodetection
&lt;/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: airgap # this must match the hostname of the air gap VM
&lt;/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;# Since this is a single node cluster, this taint has to be commented out,
&lt;/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;# otherwise the coredns pods will not come up.
&lt;/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;# taints:
&lt;/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;# - effect: NoSchedule
&lt;/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;# key: node-role.kubernetes.io/master&amp;#34;&lt;/span&gt; &amp;gt; kubeadm_cluster.yaml
&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;kubeadm init --config kubeadm_config.yaml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Set &lt;code&gt;$KUBECONFIG&lt;/code&gt; and use &lt;code&gt;kubectl&lt;/code&gt; to wait until the API server is healthy:&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;KUBECONFIG&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;/etc/kubernetes/admin.conf
&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;until&lt;/span&gt; kubectl get nodes; &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;do&lt;/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&#34;&gt;echo&lt;/span&gt; -e &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;\nWaiting for API server to respond...&amp;#34;&lt;/span&gt; 1&amp;gt;&amp;amp;&lt;span style=&#34;color:#666&#34;&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    sleep &lt;span style=&#34;color:#666&#34;&gt;5&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;done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;set-up-networking&#34;&gt;Set up networking&lt;/h3&gt;
&lt;p&gt;Update Flannel image locations in the Flannel manifest, and apply 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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sed -i &lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;s/image: docker\.io/image: localhost:5000/g&amp;#39;&lt;/span&gt; kube-flannel.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kubectl apply -f kube-flannel.yaml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Run &lt;code&gt;kubectl get pods -A --watch&lt;/code&gt; until all pods are up and running.&lt;/p&gt;
&lt;h2 id=&#34;run-an-example-pod&#34;&gt;Run an example Pod&lt;/h2&gt;
&lt;p&gt;With a cluster operational, the next step is a workload. For this simple demonstration, the &lt;a href=&#34;https://github.com/stefanprodan/podinfo&#34;&gt;Podinfo&lt;/a&gt; application will be deployed.&lt;/p&gt;
&lt;h3 id=&#34;install-helm&#34;&gt;Install Helm&lt;/h3&gt;
&lt;p&gt;This first part of the procedure must be executed from the host/laptop. If not already present, install Helm following &lt;a href=&#34;https://helm.sh/docs/intro/install/&#34;&gt;Installing Helm&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Next, download the helm binary for Linux:&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;UARCH&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;$(&lt;/span&gt;uname -m&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;)&lt;/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;# Reset the architecture variables if needed&lt;/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; &lt;span style=&#34;color:#666&#34;&gt;[[&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;$UARCH&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;arm64&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;||&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;$UARCH&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;aarch64&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;]]&lt;/span&gt;; &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;then&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:#b8860b&#34;&gt;ARCH&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;aarch64&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:#b8860b&#34;&gt;K8s_ARCH&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;arm64&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:#a2f;font-weight:bold&#34;&gt;else&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:#b8860b&#34;&gt;ARCH&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;x86_64&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:#b8860b&#34;&gt;K8s_ARCH&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;amd64&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:#a2f;font-weight:bold&#34;&gt;fi&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;curl -LO https://get.helm.sh/helm-v3.12.2-linux-&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;K8s_ARCH&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;.tar.gz
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Add the Podinfo helm repository, download the Podinfo helm chart, download the Podinfo container image, and then finally save it to the local disk:&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;helm repo add https://stefanprodan.github.io/podinfo
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;helm fetch podinfo/podinfo --version 6.4.0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker pull ghcr.io/stefanprodan/podinfo:6.4.0
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;save-the-podinfo-image-to-a-tar-file-on-the-local-disk&#34;&gt;Save the podinfo image to a tar file on the local disk&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;docker save -o podinfo_podinfo-6.4.0.tar ghcr.io/stefanprodan/podinfo
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-suggestion&#34; data-lang=&#34;suggestion&#34;&gt;
### Transfer the image across the air gap

Reuse the `~/tmp` directory created on the air gapped VM to transport these artifacts across the air gap:

```bash
scp -i &amp;lt;&amp;lt;SSH_KEY&amp;gt;&amp;gt; &amp;lt;&amp;lt;FILE&amp;gt;&amp;gt; &amp;lt;&amp;lt;AIRGAP_VM_USER&amp;gt;&amp;gt;@&amp;lt;&amp;lt;AIRGAP_VM_IP&amp;gt;&amp;gt;:~/tmp/
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;continue-on-the-isolated-side&#34;&gt;Continue on the isolated side&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Now pivot over to the air gap VM for the rest of the installation procedure.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Switch into &lt;code&gt;~/tmp&lt;/code&gt;:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;cd ~/tmp
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Extract and move the &lt;code&gt;helm&lt;/code&gt; binary:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;tar -zxvf helm-v3.0.0-linux-amd64.tar.gz
mv linux-amd64/helm /usr/local/bin/helm
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Load the Podinfo container image into the local Docker registry:&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker load -i podinfo_podinfo-6.4.0.tar
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker tag podinfo/podinfo:6.4.0 localhost:5000/podinfo/podinfo:6.4.0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker push localhost:5000/podinfo/podinfo:6.4.0
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Ensure &amp;quot;$KUBECONFIG` is set correctly, then install the Podinfo Helm chart:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# Outside of a demo or lab environment, use lower (or even least) privilege
# credentials to manage your workloads.
export KUBECONFIG=/etc/kubernetes/admin.conf
helm install podinfo ./podinfo-6.4.0.tgz --set image.repository=localhost:5000/podinfo/podinfo
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Verify that the Podinfo application comes up:&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kubectl get pods -n default
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Or run k9s (a terminal user interface for Kubernetes):&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;k9s
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;zarf&#34;&gt;Zarf&lt;/h2&gt;
&lt;p&gt;Zarf is an open-source tool that takes a declarative approach to software packaging and delivery, including air gap. This same podinfo application will be installed onto the air gap VM using Zarf in this section. The first step is to install &lt;a href=&#34;https://zarf.dev/install/&#34;&gt;Zarf&lt;/a&gt; on the host/laptop.&lt;/p&gt;
&lt;p&gt;Alternatively, a prebuilt binary can be downloaded onto the host/laptop from &lt;a href=&#34;https://github.com/defenseunicorns/zarf/releases/&#34;&gt;GitHub&lt;/a&gt; for various OS/CPU architectures.&lt;/p&gt;
&lt;p&gt;A binary is also needed across the air gap on the VM:&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;UARCH&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;$(&lt;/span&gt;uname -m&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;)&lt;/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;# Set the architecture variables if needed&lt;/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; &lt;span style=&#34;color:#666&#34;&gt;[[&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;$UARCH&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;arm64&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;||&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;$UARCH&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;aarch64&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;]]&lt;/span&gt;; &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;then&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:#b8860b&#34;&gt;ARCH&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;aarch64&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:#b8860b&#34;&gt;K8s_ARCH&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;arm64&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:#a2f;font-weight:bold&#34;&gt;else&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:#b8860b&#34;&gt;ARCH&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;x86_64&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:#b8860b&#34;&gt;K8s_ARCH&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;amd64&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:#a2f;font-weight:bold&#34;&gt;fi&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&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;ZARF_VERSION&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;v0.28.3
&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;curl -LO &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;https://github.com/defenseunicorns/zarf/releases/download/&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;ZARF_VERSION&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;/zarf_&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;ZARF_VERSION&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;_Linux_&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;K8s_ARCH&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Zarf needs to bootstrap itself into a Kubernetes cluster through the use of an init package. That also needs to be transported across the air gap so let&#39;s download it onto the host/laptop:&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;curl -LO &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;https://github.com/defenseunicorns/zarf/releases/download/&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;ZARF_VERSION&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;/zarf-init-&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;K8s_ARCH&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;ZARF_VERSION&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;.tar.zst&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The way that Zarf is declarative is through the use of a zarf.yaml file. Here is the zarf.yaml file that will be used for this Podinfo installation. Write it to whatever directory you you have write access to on your host/laptop; your home directory is fine:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;echo &amp;#39;kind: ZarfPackageConfig
metadata:
    name: podinfo
    description: &amp;#34;Deploy helm chart for the podinfo application in K8s via zarf&amp;#34;
components:
    - name: podinfo
        required: true
        charts:
            - name: podinfo
              version: 6.4.0
              namespace: podinfo-helm-namespace
              releaseName: podinfo
              url: https://stefanprodan.github.io/podinfo
        images:
        - ghcr.io/stefanprodan/podinfo:6.4.0&amp;#39; &amp;gt; zarf.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The next step is to build the Podinfo package. This must be done from the same directory location where the zarf.yaml file is located.&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;zarf package create --confirm
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This command will download the defined helm chart and image and put them into a single file written to disk. This single file is all that needs to be carried across the air gap:&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ls zarf-package-*
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Sample 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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;zarf-package-podinfo-arm64.tar.zst
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Transport the linux zarf binary, zarf init package and Podinfo package over to the air gapped VM:&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;scp -i &lt;span style=&#34;color:#b44&#34;&gt;&amp;lt;&amp;lt;SSH_KEY&amp;gt;&amp;gt; &amp;lt;&amp;lt;FILE&amp;gt;&amp;gt; &amp;lt;&amp;lt;AIRGAP_VM_US&lt;/span&gt;ER&amp;gt;&amp;gt;@&lt;span style=&#34;color:#b44&#34;&gt;&amp;lt;&amp;lt;AIRGA&lt;/span&gt;P_VM_IP&amp;gt;&amp;gt;:~/tmp/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;From the air gapped VM, switch into the ~/tmp directory where all of the artifacts were placed:&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f&#34;&gt;cd&lt;/span&gt; ~/tmp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Set &lt;code&gt;$KUBECONFIG&lt;/code&gt; to a file with credentials for the local cluster; also set the the Zarf 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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;KUBECONFIG&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;/etc/kubernetes/admin.conf
&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&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;ZARF_VERSION&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;$(&lt;/span&gt;zarf version&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Make the &lt;code&gt;zarf&lt;/code&gt; binary executable and (as &lt;code&gt;root&lt;/code&gt;) move it to &lt;code&gt;/usr/bin&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;chmod +x zarf &lt;span style=&#34;color:#666&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; sudo mv zarf /usr/bin
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Likewise, move the Zarf init package to &lt;code&gt;/usr/bin&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mv zarf-init-arm64-&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;ZARF_VERSION&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;.tar.zst /usr/bin
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Initialize Zarf into the cluster:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;zarf init --confirm --components=git-server
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;When this command is done, a Zarf package is ready to be deployed.&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;zarf package deploy
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This command will search the current directory for a Zarf package. Select the podinfo package (zarf-package-podinfo-${K8s_ARCH}.tar.zst) and continue. Once the package deployment is complete, run &lt;code&gt;zarf tools monitor&lt;/code&gt; in order to bring up k9s to view the cluster.&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;This is one method that can be used to spin up an air-gapped cluster and two methods to deploy
a mission application. Your mileage may vary on different operating systems regarding the
exact software artifacts that need to be carried across the air gap, but conceptually this procedure is still valid.&lt;/p&gt;
&lt;p&gt;This demo also created an artificial air-gapped environment. In the real world, every missed dependency
could represent hours, if not days, or weeks of lost time to get running software in the air-gapped environment.
This artificial air gap also obscured some common methods or air gap software delivery such as using a
&lt;em&gt;data diode&lt;/em&gt;. Depending on the environment, the diode can be very expensive to use.
Also, none of the artifacts were scanned before being carried across the air gap.
The presence of the air gap in general means that the workload running there is more sensitive, and nothing should be carried across unless it&#39;s known to be safe.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>CRI-O is moving towards pkgs.k8s.io</title>
      <link>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/10/10/cri-o-community-package-infrastructure/</link>
      <pubDate>Tue, 10 Oct 2023 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/10/10/cri-o-community-package-infrastructure/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Author:&lt;/strong&gt; Sascha Grunert&lt;/p&gt;
&lt;p&gt;The Kubernetes community &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/08/31/legacy-package-repository-deprecation/&#34;&gt;recently announced&lt;/a&gt;
that their legacy package repositories are frozen, and now they moved to
&lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/08/15/pkgs-k8s-io-introduction&#34;&gt;introduced community-owned package repositories&lt;/a&gt; powered by the
&lt;a href=&#34;https://build.opensuse.org/project/subprojects/isv:kubernetes&#34;&gt;OpenBuildService (OBS)&lt;/a&gt;.
CRI-O has a long history of utilizing
&lt;a href=&#34;https://github.com/cri-o/cri-o/blob/e292f17/install.md#install-packaged-versions-of-cri-o&#34;&gt;OBS for their package builds&lt;/a&gt;,
but all of the packaging efforts have been done manually so far.&lt;/p&gt;
&lt;p&gt;The CRI-O community absolutely loves Kubernetes, which means that they&#39;re
delighted to announce that:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;All future CRI-O packages will be shipped as part of the officially supported
Kubernetes infrastructure hosted on pkgs.k8s.io!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;There will be a deprecation phase for the existing packages, which is currently
being &lt;a href=&#34;https://github.com/cri-o/cri-o/discussions/7315&#34;&gt;discussed in the CRI-O community&lt;/a&gt;.
The new infrastructure will only support releases of CRI-O &lt;code&gt;&amp;gt;= v1.28.2&lt;/code&gt; as well as
release branches newer than &lt;code&gt;release-1.28&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;how-to-use-the-new-packages&#34;&gt;How to use the new packages&lt;/h2&gt;
&lt;p&gt;In the same way as the Kubernetes community, CRI-O provides &lt;code&gt;deb&lt;/code&gt; and &lt;code&gt;rpm&lt;/code&gt;
packages as part of a dedicated subproject in OBS, called
&lt;a href=&#34;https://build.opensuse.org/project/show/isv:kubernetes:addons:cri-o&#34;&gt;&lt;code&gt;isv:kubernetes:addons:cri-o&lt;/code&gt;&lt;/a&gt;.
This project acts as an umbrella and provides &lt;code&gt;stable&lt;/code&gt; (for CRI-O tags) as well as
&lt;code&gt;prerelease&lt;/code&gt; (for CRI-O &lt;code&gt;release-1.y&lt;/code&gt; and &lt;code&gt;main&lt;/code&gt; branches) package builds.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Stable Releases:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://build.opensuse.org/project/show/isv:kubernetes:addons:cri-o:stable&#34;&gt;&lt;code&gt;isv:kubernetes:addons:cri-o:stable&lt;/code&gt;&lt;/a&gt;: Stable Packages
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://build.opensuse.org/project/show/isv:kubernetes:addons:cri-o:stable:v1.29&#34;&gt;&lt;code&gt;isv:kubernetes:addons:cri-o:stable:v1.29&lt;/code&gt;&lt;/a&gt;: &lt;code&gt;v1.29.z&lt;/code&gt; tags&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://build.opensuse.org/project/show/isv:kubernetes:addons:cri-o:stable:v1.28&#34;&gt;&lt;code&gt;isv:kubernetes:addons:cri-o:stable:v1.28&lt;/code&gt;&lt;/a&gt;: &lt;code&gt;v1.28.z&lt;/code&gt; tags&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Prereleases:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://build.opensuse.org/project/show/isv:kubernetes:addons:cri-o:prerelease&#34;&gt;&lt;code&gt;isv:kubernetes:addons:cri-o:prerelease&lt;/code&gt;&lt;/a&gt;: Prerelease Packages
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://build.opensuse.org/project/show/isv:kubernetes:addons:cri-o:prerelease:main&#34;&gt;&lt;code&gt;isv:kubernetes:addons:cri-o:prerelease:main&lt;/code&gt;&lt;/a&gt;: &lt;a href=&#34;https://github.com/cri-o/cri-o/commits/main&#34;&gt;&lt;code&gt;main&lt;/code&gt;&lt;/a&gt; branch&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://build.opensuse.org/project/show/isv:kubernetes:addons:cri-o:prerelease:v1.29&#34;&gt;&lt;code&gt;isv:kubernetes:addons:cri-o:prerelease:v1.29&lt;/code&gt;&lt;/a&gt;: &lt;a href=&#34;https://github.com/cri-o/cri-o/commits/release-1.29&#34;&gt;&lt;code&gt;release-1.29&lt;/code&gt;&lt;/a&gt; branch&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://build.opensuse.org/project/show/isv:kubernetes:addons:cri-o:prerelease:v1.28&#34;&gt;&lt;code&gt;isv:kubernetes:addons:cri-o:prerelease:v1.28&lt;/code&gt;&lt;/a&gt;: &lt;a href=&#34;https://github.com/cri-o/cri-o/commits/release-1.28&#34;&gt;&lt;code&gt;release-1.28&lt;/code&gt;&lt;/a&gt; branch&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are no stable releases available in the v1.29 repository yet, because
v1.29.0 will be released in December. The CRI-O community will also &lt;strong&gt;not&lt;/strong&gt;
support release branches older than &lt;code&gt;release-1.28&lt;/code&gt;, because there have been CI
requirements merged into &lt;code&gt;main&lt;/code&gt; which could be only backported to &lt;code&gt;release-1.28&lt;/code&gt;
with appropriate efforts.&lt;/p&gt;
&lt;p&gt;For example, If an end-user would like to install the latest available version
of the CRI-O &lt;code&gt;main&lt;/code&gt; branch, then they can add the repository in the same way as
they do for Kubernetes.&lt;/p&gt;
&lt;h3 id=&#34;rpm-based-distributions&#34;&gt;&lt;code&gt;rpm&lt;/code&gt; Based Distributions&lt;/h3&gt;
&lt;p&gt;For &lt;code&gt;rpm&lt;/code&gt; based distributions, you can run the following commands as a &lt;code&gt;root&lt;/code&gt; user
to install CRI-O together with Kubernetes:&lt;/p&gt;
&lt;h4 id=&#34;add-the-kubernetes-repo&#34;&gt;Add the Kubernetes repo&lt;/h4&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;cat &lt;span style=&#34;color:#b44&#34;&gt;&amp;lt;&amp;lt;EOF | tee /etc/yum.repos.d/kubernetes.repo
&lt;/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;[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:#b44&#34;&gt;name=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:#b44&#34;&gt;baseurl=https://pkgs.k8s.io/core:/stable:/v1.28/rpm/
&lt;/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;enabled=1
&lt;/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;gpgcheck=1
&lt;/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;gpgkey=https://pkgs.k8s.io/core:/stable:/v1.28/rpm/repodata/repomd.xml.key
&lt;/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;h4 id=&#34;add-the-cri-o-repo&#34;&gt;Add the CRI-O repo&lt;/h4&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;cat &lt;span style=&#34;color:#b44&#34;&gt;&amp;lt;&amp;lt;EOF | tee /etc/yum.repos.d/cri-o.repo
&lt;/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;[cri-o]
&lt;/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=CRI-O
&lt;/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;baseurl=https://pkgs.k8s.io/addons:/cri-o:/prerelease:/main/rpm/
&lt;/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;enabled=1
&lt;/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;gpgcheck=1
&lt;/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;gpgkey=https://pkgs.k8s.io/addons:/cri-o:/prerelease:/main/rpm/repodata/repomd.xml.key
&lt;/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;h4 id=&#34;install-official-package-dependencies&#34;&gt;Install official package dependencies&lt;/h4&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;dnf install -y &lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;&lt;/span&gt;    conntrack &lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;&lt;/span&gt;    container-selinux &lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;&lt;/span&gt;    ebtables &lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;&lt;/span&gt;    ethtool &lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;&lt;/span&gt;    iptables &lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;&lt;/span&gt;    socat
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;install-the-packages-from-the-added-repos&#34;&gt;Install the packages from the added repos&lt;/h4&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;dnf install -y --repo cri-o --repo kubernetes &lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;&lt;/span&gt;    cri-o &lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;&lt;/span&gt;    kubeadm &lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;&lt;/span&gt;    kubectl &lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;&lt;/span&gt;    kubelet
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;deb-based-distributions&#34;&gt;&lt;code&gt;deb&lt;/code&gt; Based Distributions&lt;/h3&gt;
&lt;p&gt;For &lt;code&gt;deb&lt;/code&gt; based distributions, you can run the following commands as a &lt;code&gt;root&lt;/code&gt;
user:&lt;/p&gt;
&lt;h4 id=&#34;install-dependencies-for-adding-the-repositories&#34;&gt;Install dependencies for adding the repositories&lt;/h4&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;apt-get update
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;apt-get install -y software-properties-common curl
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;add-the-kubernetes-repository&#34;&gt;Add the Kubernetes repository&lt;/h4&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;curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.28/deb/Release.key |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f&#34;&gt;echo&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.28/deb/ /&amp;#34;&lt;/span&gt; |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    tee /etc/apt/sources.list.d/kubernetes.list
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;add-the-cri-o-repository&#34;&gt;Add the CRI-O repository&lt;/h4&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;curl -fsSL https://pkgs.k8s.io/addons:/cri-o:/prerelease:/main/deb/Release.key |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    gpg --dearmor -o /etc/apt/keyrings/cri-o-apt-keyring.gpg
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f&#34;&gt;echo&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;deb [signed-by=/etc/apt/keyrings/cri-o-apt-keyring.gpg] https://pkgs.k8s.io/addons:/cri-o:/prerelease:/main/deb/ /&amp;#34;&lt;/span&gt; |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    tee /etc/apt/sources.list.d/cri-o.list
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;install-the-packages&#34;&gt;Install the packages&lt;/h4&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;apt-get update
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;apt-get install -y cri-o kubelet kubeadm kubectl
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;start-cri-o&#34;&gt;Start CRI-O&lt;/h4&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;systemctl start crio.service
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The Project&#39;s &lt;code&gt;prerelease:/main&lt;/code&gt; prefix at the CRI-O&#39;s package path, can be replaced with
&lt;code&gt;stable:/v1.28&lt;/code&gt;, &lt;code&gt;stable:/v1.29&lt;/code&gt;, &lt;code&gt;prerelease:/v1.28&lt;/code&gt; or &lt;code&gt;prerelease:/v1.29&lt;/code&gt;
if another stream package is used.&lt;/p&gt;
&lt;p&gt;Bootstrapping &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/setup/production-environment/tools/kubeadm/install-kubeadm/&#34;&gt;a cluster using &lt;code&gt;kubeadm&lt;/code&gt;&lt;/a&gt;
can be done by running &lt;code&gt;kubeadm init&lt;/code&gt; command, which automatically detects that
CRI-O is running in the background. There are also &lt;code&gt;Vagrantfile&lt;/code&gt; examples
available for &lt;a href=&#34;https://github.com/cri-o/packaging/blob/91df5f7/test/rpm/Vagrantfile&#34;&gt;Fedora 38&lt;/a&gt;
as well as &lt;a href=&#34;https://github.com/cri-o/packaging/blob/91df5f7/test/deb/Vagrantfile&#34;&gt;Ubuntu 22.04&lt;/a&gt;
for testing the packages together with &lt;code&gt;kubeadm&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;how-it-works-under-the-hood&#34;&gt;How it works under the hood&lt;/h2&gt;
&lt;p&gt;Everything related to these packages lives in the new
&lt;a href=&#34;https://github.com/cri-o/packaging&#34;&gt;CRI-O packaging repository&lt;/a&gt;.
It contains a &lt;a href=&#34;https://github.com/cri-o/packaging/blob/91df5f7/.github/workflows/schedule.yml&#34;&gt;daily reconciliation&lt;/a&gt;
GitHub action workflow, for all supported release branches as well as tags of
CRI-O. A &lt;a href=&#34;https://github.com/cri-o/packaging/actions/workflows/obs.yml&#34;&gt;test pipeline&lt;/a&gt;
in the OBS workflow ensures that the packages can be correctly installed and
used before being published. All of the staging and publishing of the
packages is done with the help of the &lt;a href=&#34;https://github.com/kubernetes/release/blob/1f85912/docs/krel/README.md&#34;&gt;Kubernetes Release Toolbox (krel)&lt;/a&gt;,
which is also used for the official Kubernetes &lt;code&gt;deb&lt;/code&gt; and &lt;code&gt;rpm&lt;/code&gt; packages.&lt;/p&gt;
&lt;p&gt;The package build inputs will undergo daily reconciliation and will be supplied by
CRI-O&#39;s static binary bundles.
These bundles are built and signed for each commit in the CRI-O CI,
and contain everything CRI-O requires to run on a certain architecture.
The static builds are reproducible, powered by &lt;a href=&#34;https://github.com/NixOS/nixpkgs&#34;&gt;nixpkgs&lt;/a&gt;
and available only for &lt;code&gt;x86_64&lt;/code&gt;, &lt;code&gt;aarch64&lt;/code&gt; and &lt;code&gt;ppc64le&lt;/code&gt; architecture.&lt;/p&gt;
&lt;p&gt;The CRI-O maintainers will be happy to listen to any feedback or suggestions on the new
packaging efforts! Thank you for reading this blog post, feel free to reach out
to the maintainers via the Kubernetes &lt;a href=&#34;https://kubernetes.slack.com/messages/CAZH62UR1&#34;&gt;Slack channel #crio&lt;/a&gt;
or create an issue in the &lt;a href=&#34;https://github.com/cri-o/packaging/issues&#34;&gt;packaging repository&lt;/a&gt;.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Spotlight on SIG Architecture: Conformance</title>
      <link>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/10/05/sig-architecture-conformance-spotlight-2023/</link>
      <pubDate>Thu, 05 Oct 2023 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/10/05/sig-architecture-conformance-spotlight-2023/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Author&lt;/strong&gt;: Frederico Muñoz (SAS Institute)&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This is the first interview of a SIG Architecture Spotlight series
that will cover the different subprojects. We start with the SIG
Architecture: Conformance subproject&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;In this &lt;a href=&#34;https://github.com/kubernetes/community/blob/master/sig-architecture/README.md&#34;&gt;SIG
Architecture&lt;/a&gt;
spotlight, we talked with &lt;a href=&#34;https://github.com/Riaankl&#34;&gt;Riaan
Kleinhans&lt;/a&gt; (ii.nz), Lead for the
&lt;a href=&#34;https://github.com/kubernetes/community/blob/master/sig-architecture/README.md#conformance-definition-1&#34;&gt;Conformance
sub-project&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;about-sig-architecture-and-the-conformance-subproject&#34;&gt;About SIG Architecture and the Conformance subproject&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Frederico (FSM)&lt;/strong&gt;: Hello Riaan, and welcome! For starters, tell us a
bit about yourself, your role and how you got involved in Kubernetes.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Riaan Kleinhans (RK)&lt;/strong&gt;: Hi! My name is Riaan Kleinhans and I live in
South Africa. I am the Project manager for the &lt;a href=&#34;https://ii.nz&#34;&gt;ii.nz&lt;/a&gt; team in New
Zealand. When I joined ii the plan was to move to New Zealand in April
2020 and then Covid happened. Fortunately, being a flexible and
dynamic team we were able to make it work remotely and in very
different time zones.&lt;/p&gt;
&lt;p&gt;The ii team have been tasked with managing the Kubernetes Conformance
testing technical debt and writing tests to clear the technical
debt. I stepped into the role of project manager to be the link
between monitoring, test writing and the community. Through that work
I had the privilege of meeting &lt;a href=&#34;https://github.com/dankohn&#34;&gt;Dan Kohn&lt;/a&gt;
in those first months, his enthusiasm about the work we were doing was
a great inspiration.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;FSM&lt;/strong&gt;: Thank you - so, your involvement in SIG Architecture started
because of the conformance work?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;RK&lt;/strong&gt;: SIG Architecture is the home for the Kubernetes Conformance
subproject. Initially, most of my interactions were directly with SIG
Architecture through the Conformance sub-project. However, as we
began organizing the work by SIG, we started engaging directly with
each individual SIG. These engagements with the SIGs that own the
untested APIs have helped us accelerate our work.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;FSM&lt;/strong&gt;: How would you describe the main goals and
areas of intervention of the Conformance sub-project?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;RM&lt;/strong&gt;: The Kubernetes Conformance sub-project focuses on guaranteeing
compatibility and adherence to the Kubernetes specification by
developing and maintaining a comprehensive conformance test suite. Its
main goals include assuring compatibility across different Kubernetes
implementations, verifying adherence to the API specification,
supporting the ecosystem by encouraging conformance certification, and
fostering collaboration within the Kubernetes community. By providing
standardised tests and promoting consistent behaviour and
functionality, the Conformance subproject ensures a reliable and
compatible Kubernetes ecosystem for developers and users alike.&lt;/p&gt;
&lt;h2 id=&#34;more-on-the-conformance-test-suite&#34;&gt;More on the Conformance Test Suite&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;FSM&lt;/strong&gt;: A part of providing those standardised tests is, I believe,
the &lt;a href=&#34;https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/conformance-tests.md&#34;&gt;Conformance Test
Suite&lt;/a&gt;. Could
you explain what it is and its importance?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;RK&lt;/strong&gt;: The Kubernetes Conformance Test Suite checks if Kubernetes
distributions meet the project&#39;s specifications, ensuring
compatibility across different implementations. It covers various
features like APIs, networking, storage, scheduling, and
security. Passing the tests confirms proper implementation and
promotes a consistent and portable container orchestration platform.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;FSM&lt;/strong&gt;: Right, the tests are important in the way they define the
minimum features that any Kubernetes cluster must support. Could you
describe the process around determining which features are considered
for inclusion? Is there any tension between a more minimal approach,
and proposals from the other SIGs?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;RK&lt;/strong&gt;: The requirements for each endpoint that undergoes conformance
testing are clearly defined by SIG Architecture. Only API endpoints
that are generally available and non-optional features are eligible
for conformance. Over the years, there have been several discussions
regarding conformance profiles, exploring the possibility of including
optional endpoints like RBAC, which are widely used by most end users,
in specific profiles. However, this aspect is still a work in
progress.&lt;/p&gt;
&lt;p&gt;Endpoints that do not meet the conformance criteria are listed in
&lt;a href=&#34;https://github.com/kubernetes/kubernetes/blob/master/test/conformance/testdata/ineligible_endpoints.yaml&#34;&gt;ineligible_endpoints.yaml&lt;/a&gt;,
which is publicly accessible in the Kubernetes repo. This file can be
updated to add or remove endpoints as their status or requirements
change. These ineligible endpoints are also visible on
&lt;a href=&#34;https://apisnoop.cncf.io/&#34;&gt;APISnoop&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Ensuring transparency and incorporating community input regarding the
eligibility or ineligibility of endpoints is of utmost importance to
SIG Architecture.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;FSM&lt;/strong&gt;: Writing tests for new features is something generally
requires some kind of enforcement. How do you see the evolution of
this in Kubernetes? Was there a specific effort to improve the process
in a way that required tests would be a first-class citizen, or was
that never an issue?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;RK&lt;/strong&gt;: When discussions surrounding the Kubernetes conformance
programme began in 2018, only approximately 11% of endpoints were
covered by tests. At that time, the CNCF&#39;s governing board requested
that if funding were to be provided for the work to cover missing
conformance tests, the Kubernetes Community should adopt a policy of
not allowing new features to be added unless they include conformance
tests for their stable APIs.&lt;/p&gt;
&lt;p&gt;SIG Architecture is responsible for stewarding this requirement, and
&lt;a href=&#34;https://apisnoop.cncf.io/&#34;&gt;APISnoop&lt;/a&gt; has proven to be an invaluable
tool in this regard. Through automation, APISnoop generates a pull
request every weekend to highlight any discrepancies in Conformance
coverage. If any endpoints are promoted to General Availability
without a conformance test, it will be promptly identified. This
approach helps prevent the accumulation of new technical debt.&lt;/p&gt;
&lt;p&gt;Additionally, there are plans in the near future to create a release
informing job, which will add an additional layer to prevent any new
technical debt.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;FSM&lt;/strong&gt;: I see, tooling and automation play an important role
there. What are, in your opinion, the areas that, conformance-wise,
still require some work to be done? In other words, what are the
current priority areas marked for improvement?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;RK&lt;/strong&gt;: We have reached the “100% Conformance Tested” milestone in
release 1.27!&lt;/p&gt;
&lt;p&gt;At that point, the community took another look at all the endpoints
that were listed as ineligible for conformance. The list was populated
through community input over several years.  Several endpoints
that were previously deemed ineligible for conformance have been
identified and relocated to a new dedicated list, which is currently
receiving focused attention for conformance test development. Again,
that list can also be checked on apisnoop.cncf.io.&lt;/p&gt;
&lt;p&gt;To ensure the avoidance of new technical debt in the conformance
project, there are upcoming plans to establish a release informing job
as an additional preventive measure.&lt;/p&gt;
&lt;p&gt;While APISnoop is currently hosted on CNCF infrastructure, the project
has been generously donated to the Kubernetes community. Consequently,
it will be transferred to community-owned infrastructure before the
end of 2023.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;FSM&lt;/strong&gt;: That&#39;s great news! For anyone wanting to help, what are the
venues for collaboration that you would highlight? Do all of them
require solid knowledge of Kubernetes as a whole, or are there ways
someone newer to the project can contribute?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;RK&lt;/strong&gt;: Contributing to conformance testing is akin to the task of
&amp;quot;washing the dishes&amp;quot; – it may not be highly visible, but it remains
incredibly important. It necessitates a strong understanding of
Kubernetes, particularly in the areas where the endpoints need to be
tested. This is why working with each SIG that owns the API endpoint
being tested is so important.&lt;/p&gt;
&lt;p&gt;As part of our commitment to making test writing accessible to
everyone, the ii team is currently engaged in the development of a
&amp;quot;click and deploy&amp;quot; solution. This solution aims to enable anyone to
swiftly create a working environment on real hardware within
minutes. We will share updates regarding this development as soon as
we are ready.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;FSM&lt;/strong&gt;: That&#39;s very helpful, thank you. Any final comments you would
like to share with our readers?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;RK&lt;/strong&gt;: Conformance testing is a collaborative community endeavour that
involves extensive cooperation among SIGs. SIG Architecture has
spearheaded the initiative and provided guidance. However, the
progress of the work relies heavily on the support of all SIGs in
reviewing, enhancing, and endorsing the tests.&lt;/p&gt;
&lt;p&gt;I would like to extend my sincere appreciation to the ii team for
their unwavering commitment to resolving technical debt over the
years. In particular, &lt;a href=&#34;https://github.com/hh&#34;&gt;Hippie Hacker&lt;/a&gt;&#39;s
guidance and stewardship of the vision has been
invaluable. Additionally, I want to give special recognition to
Stephen Heywood for shouldering the majority of the test writing
workload in recent releases, as well as to Zach Mandeville for his
contributions to APISnoop.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;FSM&lt;/strong&gt;: Many thanks for your availability and insightful comments,
I&#39;ve personally learned quite a bit with it and I&#39;m sure our readers
will as well.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Announcing the 2023 Steering Committee Election Results</title>
      <link>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/10/02/steering-committee-results-2023/</link>
      <pubDate>Mon, 02 Oct 2023 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/10/02/steering-committee-results-2023/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Author&lt;/strong&gt;: Kaslin Fields&lt;/p&gt;
&lt;p&gt;The &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/elections/steering/2023&#34;&gt;2023 Steering Committee Election&lt;/a&gt; is now complete. The Kubernetes Steering Committee consists of 7 seats, 4 of which were up for election in 2023. 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;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;), 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;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;Bob Killen (&lt;a href=&#34;https://github.com/mrbobbytables&#34;&gt;@mrbobbytables&lt;/a&gt;), Google&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Nabarun Pal (&lt;a href=&#34;https://github.com/palnabarun&#34;&gt;@palnabarun&lt;/a&gt;), VMware&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Stephen Augustus 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;Davanum Srinavas (&lt;a href=&#34;https://github.com/dims&#34;&gt;@dims&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Kaslin Fields (&lt;a href=&#34;https://github.com/kaslin&#34;&gt;@kaslin&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;Christoph Blecker (&lt;a href=&#34;https://github.com/cblecker&#34;&gt;@cblecker&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Carlos Tadeu Panato Jr. (&lt;a href=&#34;https://github.com/cpanato&#34;&gt;@cpanato&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Tim Pepper (&lt;a href=&#34;https://github.com/tpepper&#34;&gt;@tpepper&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://github.com/orgs/kubernetes/projects/40&#34;&gt;backlog items&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 9:30am 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 Steering AMA at the &lt;a href=&#34;https://k8s.dev/summit&#34;&gt;Kubernetes Contributor Summit in Chicago&lt;/a&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;This post was 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>Happy 7th Birthday kubeadm!</title>
      <link>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/09/26/happy-7th-birthday-kubeadm/</link>
      <pubDate>Tue, 26 Sep 2023 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/09/26/happy-7th-birthday-kubeadm/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Author:&lt;/strong&gt; Fabrizio Pandini (VMware)&lt;/p&gt;
&lt;p&gt;What a journey so far!&lt;/p&gt;
&lt;p&gt;Starting from the initial blog post &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2016/09/how-we-made-kubernetes-easy-to-install/&#34;&gt;“How we made Kubernetes insanely easy to install”&lt;/a&gt; in September 2016, followed by an exciting growth that lead to general availability / &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2018/12/04/production-ready-kubernetes-cluster-creation-with-kubeadm/&#34;&gt;“Production-Ready Kubernetes Cluster Creation with kubeadm”&lt;/a&gt; two years later.&lt;/p&gt;
&lt;p&gt;And later on a continuous, steady and reliable flow of small improvements that is still going on as of today.&lt;/p&gt;
&lt;h2 id=&#34;what-is-kubeadm-quick-refresher&#34;&gt;What is kubeadm? (quick refresher)&lt;/h2&gt;
&lt;p&gt;kubeadm is focused on bootstrapping Kubernetes clusters on existing infrastructure and performing an essential set of maintenance tasks. The core of the kubeadm interface is quite simple: new control plane nodes
are created by running &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/reference/setup-tools/kubeadm/kubeadm-init/&#34;&gt;&lt;code&gt;kubeadm init&lt;/code&gt;&lt;/a&gt; and
worker nodes are joined to the control plane by running
&lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/reference/setup-tools/kubeadm/kubeadm-join/&#34;&gt;&lt;code&gt;kubeadm join&lt;/code&gt;&lt;/a&gt;.
Also included are utilities for managing already bootstrapped clusters, such as control plane upgrades
and token and certificate renewal.&lt;/p&gt;
&lt;p&gt;To keep kubeadm lean, focused, and vendor/infrastructure agnostic, the following tasks are out of its scope:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Infrastructure provisioning&lt;/li&gt;
&lt;li&gt;Third-party networking&lt;/li&gt;
&lt;li&gt;Non-critical add-ons, e.g. for monitoring, logging, and visualization&lt;/li&gt;
&lt;li&gt;Specific cloud provider integrations&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Infrastructure provisioning, for example, is left to other SIG Cluster Lifecycle projects, such as the
&lt;a href=&#34;https://cluster-api.sigs.k8s.io/&#34;&gt;Cluster API&lt;/a&gt;. Instead, kubeadm covers only the common denominator
in every Kubernetes cluster: the
&lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/concepts/overview/components/#control-plane-components&#34;&gt;control plane&lt;/a&gt;.
The user may install their preferred networking solution and other add-ons on top of Kubernetes
&lt;em&gt;after&lt;/em&gt; cluster creation.&lt;/p&gt;
&lt;p&gt;Behind the scenes, kubeadm does a lot. The tool makes sure you have all the key components:
etcd, the API server, the scheduler, the controller manager. You can join more control plane nodes
for improving resiliency or join worker nodes for running your workloads. You get cluster DNS
and kube-proxy set up for you. TLS between components is enabled and used for encryption in transit.&lt;/p&gt;
&lt;h2 id=&#34;let-s-celebrate-past-present-and-future-of-kubeadm&#34;&gt;Let&#39;s celebrate! Past, present and future of kubeadm&lt;/h2&gt;
&lt;p&gt;In all and for all kubeadm&#39;s story is tightly coupled with Kubernetes&#39; story, and with this amazing community.&lt;/p&gt;
&lt;p&gt;Therefore celebrating kubeadm is first of all celebrating this community, a set of people, who joined forces in finding a common ground, a minimum viable tool, for bootstrapping Kubernetes clusters.&lt;/p&gt;
&lt;p&gt;This tool, was instrumental to the Kubernetes success back in time as well as it is today, and the silver line of kubeadm&#39;s value proposition can be summarized in two points&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;An obsession in making things deadly simple for the majority of the users: kubeadm init &amp;amp; kubeadm join, that&#39;s all you need!&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A sharp focus on a well-defined problem scope: bootstrapping Kubernetes clusters on existing infrastructure. As our slogan says: &lt;em&gt;keep it simple, keep it extensible!&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This silver line, this clear contract, is the foundation the entire kubeadm user base relies on, and this post is a celebration for kubeadm&#39;s users as well.&lt;/p&gt;
&lt;p&gt;We are deeply thankful for any feedback from our users, for the enthusiasm that they are continuously showing for this tool via Slack, GitHub, social media, blogs, in person at every KubeCon or at the various meet ups around the world. Keep going!&lt;/p&gt;
&lt;p&gt;What continues to amaze me after all those years is the great things people are building on top of kubeadm, and as of today there is a strong and very active list of projects doing so:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://minikube.sigs.k8s.io/&#34;&gt;minikube&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kind.sigs.k8s.io/&#34;&gt;kind&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://cluster-api.sigs.k8s.io/&#34;&gt;Cluster API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kubespray.io/&#34;&gt;Kubespray&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;and many more; if you are using Kubernetes today, there is a good chance that you are using kubeadm even without knowing it 😜&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This community, the kubeadm’s users, the projects building on top of kubeadm are the highlights of kubeadm’s 7th birthday celebration and the foundation for what will come next!&lt;/p&gt;
&lt;p&gt;Stay tuned, and feel free to reach out to us!&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Try &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/setup/&#34;&gt;kubeadm&lt;/a&gt; to install Kubernetes today&lt;/li&gt;
&lt;li&gt;Get involved with the Kubernetes project on &lt;a href=&#34;https://github.com/kubernetes/kubernetes&#34;&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Connect with the community on &lt;a href=&#34;http://slack.k8s.io/&#34;&gt;Slack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Follow us on Twitter &lt;a href=&#34;https://twitter.com/kubernetesio&#34;&gt;@Kubernetesio&lt;/a&gt; for latest updates&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>kubeadm: Use etcd Learner to Join a Control Plane Node Safely</title>
      <link>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/09/25/kubeadm-use-etcd-learner-mode/</link>
      <pubDate>Mon, 25 Sep 2023 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/09/25/kubeadm-use-etcd-learner-mode/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Author:&lt;/strong&gt; Paco Xu (DaoCloud)&lt;/p&gt;
&lt;p&gt;The &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/reference/setup-tools/kubeadm/&#34;&gt;&lt;code&gt;kubeadm&lt;/code&gt;&lt;/a&gt; tool now supports etcd learner mode, which
allows you to enhance the resilience and stability
of your Kubernetes clusters by leveraging the &lt;a href=&#34;https://etcd.io/docs/v3.4/learning/design-learner/#appendix-learner-implementation-in-v34&#34;&gt;learner mode&lt;/a&gt;
feature introduced in etcd version 3.4.
This guide will walk you through using etcd learner mode with kubeadm. By default, kubeadm runs
a local etcd instance on each control plane node.&lt;/p&gt;
&lt;p&gt;In v1.27, kubeadm introduced a new feature gate &lt;code&gt;EtcdLearnerMode&lt;/code&gt;. With this feature gate enabled,
when joining a new control plane node, a new etcd member will be created as a learner and
promoted to a voting member only after the etcd data are fully aligned.&lt;/p&gt;
&lt;h2 id=&#34;what-are-the-advantages-of-using-etcd-learner-mode&#34;&gt;What are the advantages of using etcd learner mode?&lt;/h2&gt;
&lt;p&gt;etcd learner mode offers several compelling reasons to consider its adoption
in Kubernetes clusters:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Enhanced Resilience&lt;/strong&gt;: etcd learner nodes are non-voting members that catch up with
the leader&#39;s logs before becoming fully operational. This prevents new cluster members
from disrupting the quorum or causing leader elections, making the cluster more resilient
during membership changes.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Reduced Cluster Unavailability&lt;/strong&gt;: Traditional approaches to adding new members often
result in cluster unavailability periods, especially in slow infrastructure or misconfigurations.
etcd learner mode minimizes such disruptions.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Simplified Maintenance&lt;/strong&gt;: Learner nodes provide a safer and reversible way to add or replace
cluster members. This reduces the risk of accidental cluster outages due to misconfigurations or
missteps during member additions.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Improved Network Tolerance&lt;/strong&gt;: In scenarios involving network partitions, learner mode allows
for more graceful handling. Depending on the partition a new member lands, it can seamlessly
integrate with the existing cluster without causing disruptions.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In summary, the etcd learner mode improves the reliability and manageability of Kubernetes clusters
during member additions and changes, making it a valuable feature for cluster operators.&lt;/p&gt;
&lt;h2 id=&#34;how-nodes-join-a-cluster-that-s-using-the-new-mode&#34;&gt;How nodes join a cluster that&#39;s using the new mode&lt;/h2&gt;
&lt;h3 id=&#34;create-K8s-cluster-etcd-learner-mode&#34;&gt;Create a Kubernetes cluster backed by etcd in learner mode&lt;/h3&gt;
&lt;p&gt;For a general explanation about creating highly available clusters with kubeadm, you can refer to
&lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/setup/production-environment/tools/kubeadm/high-availability/&#34;&gt;Creating Highly Available Clusters with kubeadm&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To create a Kubernetes cluster, backed by etcd in learner mode, using kubeadm, follow these steps:&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;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# kubeadm init --feature-gates=EtcdLearnerMode=true ...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kubeadm init --config&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;kubeadm-config.yaml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The kubeadm configuration file is like 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;kubeadm.k8s.io/v1beta3&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;ClusterConfiguration&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;EtcdLearnerMode&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;The kubeadm tool deploys a single-node Kubernetes cluster with etcd set to use learner mode.&lt;/p&gt;
&lt;h3 id=&#34;join-nodes-to-the-kubernetes-cluster&#34;&gt;Join nodes to the Kubernetes cluster&lt;/h3&gt;
&lt;p&gt;Before joining a control-plane node to the new Kubernetes cluster, ensure that the existing control plane nodes
and all etcd members are healthy.&lt;/p&gt;
&lt;p&gt;Check the cluster health with &lt;code&gt;etcdctl&lt;/code&gt;. If &lt;code&gt;etcdctl&lt;/code&gt; isn&#39;t available, you can run this tool inside a container image.
You would do that directly with your container runtime using a tool such as &lt;code&gt;crictl run&lt;/code&gt; and not through Kubernetes&lt;/p&gt;
&lt;p&gt;Here is an example on a client command that uses secure communication to check the cluster health of the etcd cluster:&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;&lt;span style=&#34;color:#b8860b&#34;&gt;ETCDCTL_API&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;3&lt;/span&gt; etcdctl --endpoints 127.0.0.1:2379 &lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;&lt;/span&gt;  --cert&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;/etc/kubernetes/pki/etcd/server.crt &lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;&lt;/span&gt;  --key&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;/etc/kubernetes/pki/etcd/server.key &lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;&lt;/span&gt;  --cacert&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;/etc/kubernetes/pki/etcd/ca.crt &lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;&lt;/span&gt;  member list
&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;dc543c4d307fadb9, started, node1, https://10.6.177.40:2380, https://10.6.177.40:2379, &lt;span style=&#34;color:#a2f&#34;&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To check if the Kubernetes control plane is healthy, run &lt;code&gt;kubectl get node -l node-role.kubernetes.io/control-plane=&lt;/code&gt;
and check if the nodes are ready.&lt;/p&gt;
&lt;div class=&#34;alert alert-info note callout&#34; role=&#34;alert&#34;&gt;
  &lt;strong&gt;Note:&lt;/strong&gt; It is recommended to have an odd number of members in an etcd cluster.
&lt;/div&gt;
&lt;p&gt;Before joining a worker node to the new Kubernetes cluster, ensure that the control plane nodes are healthy.&lt;/p&gt;
&lt;h2 id=&#34;what-s-next&#34;&gt;What&#39;s next&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;The feature gate &lt;code&gt;EtcdLearnerMode&lt;/code&gt; is alpha in v1.27 and we expect it to graduate to beta in the next
minor release of Kubernetes (v1.29).&lt;/li&gt;
&lt;li&gt;etcd has an open issue that may make the process more automatic:
&lt;a href=&#34;https://github.com/etcd-io/etcd/issues/15107&#34;&gt;Support auto-promoting a learner member to a voting member&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Learn more about the kubeadm &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/reference/config-api/kubeadm-config.v1beta3/&#34;&gt;configuration format&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;feedback&#34;&gt;Feedback&lt;/h2&gt;
&lt;p&gt;Was this guide helpful? If you have any feedback or encounter any issues, please let us know.
Your feedback is always welcome! Join the bi-weekly &lt;a href=&#34;https://docs.google.com/document/d/1Gmc7LyCIL_148a9Tft7pdhdee0NBHdOfHS1SAF0duI4/edit&#34;&gt;SIG Cluster Lifecycle meeting&lt;/a&gt;
or weekly &lt;a href=&#34;https://docs.google.com/document/d/130_kiXjG7graFNSnIAgtMS1G8zPDwpkshgfRYS0nggo/edit&#34;&gt;kubeadm office hours&lt;/a&gt;.
Or reach us via &lt;a href=&#34;https://slack.k8s.io/&#34;&gt;Slack&lt;/a&gt; (channel &lt;strong&gt;#kubeadm&lt;/strong&gt;), or the
&lt;a href=&#34;https://groups.google.com/g/kubernetes-sig-cluster-lifecycle&#34;&gt;SIG&#39;s mailing list&lt;/a&gt;.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>User Namespaces: Now Supports Running Stateful Pods in Alpha!</title>
      <link>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/09/13/userns-alpha/</link>
      <pubDate>Wed, 13 Sep 2023 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/09/13/userns-alpha/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Authors:&lt;/strong&gt; Rodrigo Campos Catelin (Microsoft), Giuseppe Scrivano (Red Hat), Sascha Grunert (Red Hat)&lt;/p&gt;
&lt;p&gt;Kubernetes v1.25 introduced support for user namespaces for only stateless
pods. Kubernetes 1.28 lifted that restriction, after some design changes were
done in 1.27.&lt;/p&gt;
&lt;p&gt;The beauty of this feature is that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;it is trivial to adopt (you just need to set a bool in the pod spec)&lt;/li&gt;
&lt;li&gt;doesn&#39;t need any changes for &lt;strong&gt;most&lt;/strong&gt; applications&lt;/li&gt;
&lt;li&gt;improves security by &lt;em&gt;drastically&lt;/em&gt; enhancing the isolation of containers and
mitigating CVEs rated HIGH and CRITICAL.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This post explains the basics of user namespaces and also shows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the changes that arrived in the recent Kubernetes v1.28 release&lt;/li&gt;
&lt;li&gt;a &lt;strong&gt;demo of a vulnerability rated as HIGH&lt;/strong&gt; that is not exploitable with user namespaces&lt;/li&gt;
&lt;li&gt;the runtime requirements to use this feature&lt;/li&gt;
&lt;li&gt;what you can expect in future releases regarding user namespaces.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;what-is-a-user-namespace&#34;&gt;What is a user namespace?&lt;/h2&gt;
&lt;p&gt;A user namespace is a Linux feature that isolates the user and group identifiers
(UIDs and GIDs) of the containers from the ones on the host. The indentifiers
in the container can be mapped to indentifiers on the host in a way where the
host UID/GIDs used for different containers never overlap. Even more, the
identifiers can be mapped to &lt;em&gt;unprivileged&lt;/em&gt; non-overlapping UIDs and GIDs on the
host. This basically means two things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;As the UIDs and GIDs for different containers are mapped to different UIDs
and GIDs on the host, containers have a harder time to attack each other even
if they escape the container boundaries. For example, if container A is running
with different UIDs and GIDs on the host than container B, the operations it
can do on container B&#39;s files and process are limited: only read/write what a
file allows to others, as it will never have permission for the owner or
group (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;As the UIDs and GIDs are mapped to unprivileged users on the host, if a
container escapes the container boundaries, even if it is running 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.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Furthermore, capabilities granted are only valid inside the user namespace and
not on the host.&lt;/p&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. And 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-28&#34;&gt;Changes in 1.28&lt;/h2&gt;
&lt;p&gt;As already mentioned, starting from 1.28, Kubernetes supports user namespaces
with stateful pods. This means that pods with user namespaces can use any type
of volume, they are no longer limited to only some volume types as before.&lt;/p&gt;
&lt;p&gt;The feature gate to activate this feature was renamed, it is no longer
&lt;code&gt;UserNamespacesStatelessPodsSupport&lt;/code&gt; but from 1.28 onwards you should use
&lt;code&gt;UserNamespacesSupport&lt;/code&gt;. There were many changes done and the requirements on
the node hosts changed. So with Kubernetes 1.28 the feature flag was renamed to
reflect this.&lt;/p&gt;
&lt;h2 id=&#34;demo&#34;&gt;Demo&lt;/h2&gt;
&lt;p&gt;Rodrigo created a demo which exploits &lt;a href=&#34;https://unit42.paloaltonetworks.com/cve-2022-0492-cgroups/&#34;&gt;CVE 2022-0492&lt;/a&gt; and shows how
the exploit can occur without user namespaces. He also shows how it is not
possible to use this exploit from a Pod where the containers are using this
feature.&lt;/p&gt;
&lt;p&gt;This vulnerability is rated &lt;strong&gt;HIGH&lt;/strong&gt; and allows &lt;strong&gt;a container with no special
privileges to read/write to any path on the host&lt;/strong&gt; and launch processes as root
on the host too.&lt;/p&gt;

&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
  &lt;iframe src=&#34;https://www.youtube.com/embed/M4a2b4KkXN8&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; allowfullscreen title=&#34;Mitigation of CVE-2022-0492 on Kubernetes by enabling User Namespace support&#34;&gt;&lt;/iframe&gt;
&lt;/div&gt;

&lt;p&gt;Most applications in containers run as root today, or as a semi-predictable
non-root user (user ID 65534 is a somewhat popular choice). When you run a Pod
with containers using a userns, Kubernetes runs those containers as unprivileged
users, with no changes needed in your app.&lt;/p&gt;
&lt;p&gt;This means two containers running as user 65534 will effectively be mapped to
different users on the host, limiting what they can do to each other in case of
an escape, and if they are running as root, the privileges on the host are
reduced to the one of an unprivileged user.&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 as well as 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 to use idmap mounts with tmpfs
was merged in Linux 6.3.&lt;/p&gt;
&lt;p&gt;If you are using CRI-O with crun, this is &lt;a href=&#34;https://github.com/cri-o/cri-o/releases/tag/v1.28.1&#34;&gt;supported in CRI-O
1.28.1&lt;/a&gt; and crun 1.9 or greater. If you are using CRI-O with runc,
this is still not supported.&lt;/p&gt;
&lt;p&gt;containerd support is currently targeted for containerd 2.0; it is likely that
it won&#39;t matter if you use it with crun or runc.&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. The redesign done in 1.27
is not supported by containerd 1.7, therefore it only works, in terms of user
namespaces support, with Kubernetes 1.25 and 1.26.&lt;/p&gt;
&lt;p&gt;One limitation present in containerd 1.7 is that it needs to change the
ownership of every file and directory inside the container image, during Pod
startup. This means it has a storage overhead and can significantly impact the
container startup latency. Containerd 2.0 will probably include a implementation
that will eliminate the startup latency added and the storage overhead. Take
this into account if you plan to use containerd 1.7 with user namespaces in
production.&lt;/p&gt;
&lt;p&gt;None of these containerd limitations apply to &lt;a href=&#34;https://github.com/cri-o/cri-o/releases/tag/v1.28.1&#34;&gt;CRI-O 1.28&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;what-s-next&#34;&gt;What’s next?&lt;/h2&gt;
&lt;p&gt;Looking ahead to Kubernetes 1.29, the plan is to work with SIG Auth to integrate user
namespaces to Pod Security Standards (PSS) and the Pod Security Admission. For
the time being, the plan is to relax checks in PSS policies when user namespaces are
in use. This means that the fields &lt;code&gt;spec[.*].securityContext&lt;/code&gt; &lt;code&gt;runAsUser&lt;/code&gt;,
&lt;code&gt;runAsNonRoot&lt;/code&gt;, &lt;code&gt;allowPrivilegeEscalation&lt;/code&gt; and &lt;code&gt;capabilities&lt;/code&gt; will not trigger a
violation if user namespaces are in use. The behavior will probably be controlled by
utilizing a API Server feature gate, like &lt;code&gt;UserNamespacesPodSecurityStandards&lt;/code&gt;
or similar.&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>Comparing Local Kubernetes Development Tools: Telepresence, Gefyra, and mirrord</title>
      <link>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/09/12/local-k8s-development-tools/</link>
      <pubDate>Tue, 12 Sep 2023 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/09/12/local-k8s-development-tools/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Author:&lt;/strong&gt; Eyal Bukchin (MetalBear)&lt;/p&gt;
&lt;p&gt;The Kubernetes development cycle is an evolving landscape with a myriad of tools seeking to streamline the process. Each tool has its unique approach, and the choice often comes down to individual project requirements, the team&#39;s expertise, and the preferred workflow.&lt;/p&gt;
&lt;p&gt;Among the various solutions, a category we dubbed “Local K8S Development tools” has emerged, which seeks to enhance the Kubernetes development experience by connecting locally running components to the Kubernetes cluster. This facilitates rapid testing of new code in cloud conditions, circumventing the traditional cycle of Dockerization, CI, and deployment.&lt;/p&gt;
&lt;p&gt;In this post, we compare three solutions in this category: Telepresence, Gefyra, and our own contender, mirrord.&lt;/p&gt;
&lt;h2 id=&#34;telepresence&#34;&gt;Telepresence&lt;/h2&gt;
&lt;p&gt;The oldest and most well-established solution in the category, &lt;a href=&#34;https://www.telepresence.io/&#34;&gt;Telepresence&lt;/a&gt; uses a VPN (or more specifically, a &lt;code&gt;tun&lt;/code&gt; device) to connect the user&#39;s machine (or a locally running container) and the cluster&#39;s network. It then supports the interception of incoming traffic to a specific service in the cluster, and its redirection to a local port. The traffic being redirected can also be filtered to avoid completely disrupting the remote service. It also offers complementary features to support file access (by locally mounting a volume mounted to a pod) and importing environment variables.
Telepresence requires the installation of a local daemon on the user&#39;s machine (which requires root privileges) and a Traffic Manager component on the cluster. Additionally, it runs an Agent as a sidecar on the pod to intercept the desired traffic.&lt;/p&gt;
&lt;h2 id=&#34;gefyra&#34;&gt;Gefyra&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://gefyra.dev/&#34;&gt;Gefyra&lt;/a&gt;, similar to Telepresence, employs a VPN to connect to the cluster. However, it only supports connecting locally running Docker containers to the cluster. This approach enhances portability across different OSes and local setups. However, the downside is that it does not support natively run uncontainerized code.&lt;/p&gt;
&lt;p&gt;Gefyra primarily focuses on network traffic, leaving file access and environment variables unsupported. Unlike Telepresence, it doesn&#39;t alter the workloads in the cluster, ensuring a straightforward clean-up process if things go awry.&lt;/p&gt;
&lt;h2 id=&#34;mirrord&#34;&gt;mirrord&lt;/h2&gt;
&lt;p&gt;The newest of the three tools, &lt;a href=&#34;https://mirrord.dev/&#34;&gt;mirrord&lt;/a&gt; adopts a different approach by injecting itself
into the local binary (utilizing &lt;code&gt;LD_PRELOAD&lt;/code&gt; on Linux or &lt;code&gt;DYLD_INSERT_LIBRARIES&lt;/code&gt; on macOS),
and overriding libc function calls, which it then proxies a temporary agent it runs in the cluster.
For example, when the local process tries to read a file mirrord intercepts that call and sends it
to the agent, which then reads the file from the remote pod. This method allows mirrord to cover
all inputs and outputs to the process – covering network access, file access, and
environment variables uniformly.&lt;/p&gt;
&lt;p&gt;By working at the process level, mirrord supports running multiple local processes simultaneously, each in the context of their respective pod in the cluster, without requiring them to be containerized and without needing root permissions on the user’s machine.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;table&gt;
&lt;caption&gt;Comparison of Telepresence, Gefyra, and mirrord&lt;/caption&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;td class=&#34;empty&#34;&gt;&lt;/td&gt;
&lt;th&gt;Telepresence&lt;/th&gt;
&lt;th&gt;Gefyra&lt;/th&gt;
&lt;th&gt;mirrord&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th scope=&#34;row&#34;&gt;Cluster connection scope&lt;/th&gt;
&lt;td&gt;Entire machine or container&lt;/td&gt;
&lt;td&gt;Container&lt;/td&gt;
&lt;td&gt;Process&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&#34;row&#34;&gt;Developer OS support&lt;/th&gt;
&lt;td&gt;Linux, macOS, Windows&lt;/td&gt;
&lt;td&gt;Linux, macOS, Windows&lt;/td&gt;
&lt;td&gt;Linux, macOS, Windows (WSL)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&#34;row&#34;&gt;Incoming traffic features&lt;/th&gt;
&lt;td&gt;Interception&lt;/td&gt;
&lt;td&gt;Interception&lt;/td&gt;
&lt;td&gt;Interception or mirroring&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&#34;row&#34;&gt;File access&lt;/th&gt;
&lt;td&gt;Supported&lt;/td&gt;
&lt;td&gt;Unsupported&lt;/td&gt;
&lt;td&gt;Supported&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&#34;row&#34;&gt;Environment variables&lt;/th&gt;
&lt;td&gt;Supported&lt;/td&gt;
&lt;td&gt;Unsupported&lt;/td&gt;
&lt;td&gt;Supported&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&#34;row&#34;&gt;Requires local root&lt;/th&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&#34;row&#34;&gt;How to use&lt;/th&gt;
&lt;td&gt;&lt;ul&gt;&lt;li&gt;CLI&lt;/li&gt;&lt;li&gt;Docker Desktop extension&lt;/li&gt;&lt;/ul&gt;&lt;/td&gt;
&lt;td&gt;&lt;ul&gt;&lt;li&gt;CLI&lt;/li&gt;&lt;li&gt;Docker Desktop extension&lt;/li&gt;&lt;/ul&gt;&lt;/td&gt;
&lt;td&gt;&lt;ul&gt;&lt;li&gt;CLI&lt;/li&gt;&lt;li&gt;Visual Studio Code extension&lt;/li&gt;&lt;li&gt;IntelliJ plugin&lt;/li&gt;&lt;/ul&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Telepresence, Gefyra, and mirrord each offer unique approaches to streamline the Kubernetes development cycle, each having its strengths and weaknesses. Telepresence is feature-rich but comes with complexities, mirrord offers a seamless experience and supports various functionalities, while Gefyra aims for simplicity and robustness.&lt;/p&gt;
&lt;p&gt;Your choice between them should depend on the specific requirements of your project, your team&#39;s familiarity with the tools, and the desired development workflow. Whichever tool you choose, we believe the local Kubernetes development approach can provide an easy, effective, and cheap solution to the bottlenecks of the Kubernetes development cycle, and will become even more prevalent as these tools continue to innovate and evolve.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes Legacy Package Repositories Will Be Frozen On September 13, 2023</title>
      <link>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/08/31/legacy-package-repository-deprecation/</link>
      <pubDate>Thu, 31 Aug 2023 15:30:00 -0700</pubDate>
      
      <guid>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/08/31/legacy-package-repository-deprecation/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Authors&lt;/strong&gt;: Bob Killen (Google), Chris Short (AWS), Jeremy Rickard (Microsoft), Marko Mudrinić (Kubermatic), Tim Bannister (The Scale Factory)&lt;/p&gt;
&lt;p&gt;On August 15, 2023, the Kubernetes project announced the general availability of
the community-owned package repositories for Debian and RPM packages available
at &lt;code&gt;pkgs.k8s.io&lt;/code&gt;. The new package repositories are replacement for the legacy
Google-hosted package repositories: &lt;code&gt;apt.kubernetes.io&lt;/code&gt; and &lt;code&gt;yum.kubernetes.io&lt;/code&gt;.
The
&lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/08/15/pkgs-k8s-io-introduction/&#34;&gt;announcement blog post for &lt;code&gt;pkgs.k8s.io&lt;/code&gt;&lt;/a&gt;
highlighted that we will stop publishing packages to the legacy repositories in
the future.&lt;/p&gt;
&lt;p&gt;Today, we&#39;re formally deprecating the legacy package repositories (&lt;code&gt;apt.kubernetes.io&lt;/code&gt;
and &lt;code&gt;yum.kubernetes.io&lt;/code&gt;), and we&#39;re announcing our plans to freeze the contents of
the repositories as of &lt;strong&gt;September 13, 2023&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Please continue reading in order to learn what does this mean for you as an user or
distributor, and what steps you may need to take.&lt;/p&gt;
&lt;h2 id=&#34;how-does-this-affect-me-as-a-kubernetes-end-user&#34;&gt;How does this affect me as a Kubernetes end user?&lt;/h2&gt;
&lt;p&gt;This change affects users &lt;strong&gt;directly installing upstream versions of Kubernetes&lt;/strong&gt;,
either manually by following the official
&lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/setup/production-environment/tools/kubeadm/install-kubeadm/&#34;&gt;installation&lt;/a&gt; and
&lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/&#34;&gt;upgrade&lt;/a&gt; instructions, or
by &lt;strong&gt;using a Kubernetes installer&lt;/strong&gt; that&#39;s using packages provided by the Kubernetes
project.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;This change also affects you if you run Linux on your own PC and have installed &lt;code&gt;kubectl&lt;/code&gt; using the legacy package repositories&lt;/strong&gt;.
We&#39;ll explain later on how to &lt;a href=&#34;#check-if-affected&#34;&gt;check&lt;/a&gt; if you&#39;re affected.&lt;/p&gt;
&lt;p&gt;If you use &lt;strong&gt;fully managed&lt;/strong&gt; Kubernetes, for example through a service from a cloud
provider, you would only be affected by this change if you also installed &lt;code&gt;kubectl&lt;/code&gt;
on your Linux PC using packages from the legacy repositories. Cloud providers are
generally using their own Kubernetes distributions and therefore they don&#39;t use
packages provided by the Kubernetes project; more importantly, if someone else is
managing Kubernetes for you, then they would usually take responsibility for that check.&lt;/p&gt;
&lt;p&gt;If you have a managed &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/concepts/overview/components/#control-plane-components&#34;&gt;control plane&lt;/a&gt;
but you are responsible for &lt;strong&gt;managing the nodes yourself&lt;/strong&gt;, and any of those nodes run Linux,
you should &lt;a href=&#34;#check-if-affected&#34;&gt;check&lt;/a&gt; whether you are affected.&lt;/p&gt;
&lt;p&gt;If you&#39;re managing your clusters on your own by following the official installation
and upgrade instructions, please follow the instructions in this blog post to migrate
to the (new) community-owned package repositories.&lt;/p&gt;
&lt;p&gt;If you&#39;re using a Kubernetes installer that&#39;s using packages provided by the
Kubernetes project, please check the installer tool&#39;s communication channels for
information about what steps you need to take, and eventually if needed, follow up
with maintainers to let them know about this change.&lt;/p&gt;
&lt;p&gt;The following diagram shows who&#39;s affected by this change in a visual form
(click on diagram for the larger version):&lt;/p&gt;

&lt;figure class=&#34;diagram-large&#34;&gt;&lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/08/31/legacy-package-repository-deprecation/flow.svg&#34;&gt;
    &lt;img src=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/08/31/legacy-package-repository-deprecation/flow.svg&#34;
         alt=&#34;Visual explanation of who&amp;#39;s affected by the legacy repositories being deprecated and frozen. Textual explanation is available above this diagram.&#34;/&gt; &lt;/a&gt;
&lt;/figure&gt;

&lt;h2 id=&#34;how-does-this-affect-me-as-a-kubernetes-distributor&#34;&gt;How does this affect me as a Kubernetes distributor?&lt;/h2&gt;
&lt;p&gt;If you&#39;re using the legacy repositories as part of your project (e.g. a Kubernetes
installer tool), you should migrate to the community-owned repositories as soon as
possible and inform your users about this change and what steps they need to take.&lt;/p&gt;
&lt;h2 id=&#34;timeline-of-changes&#34;&gt;Timeline of changes&lt;/h2&gt;
&lt;!-- note to maintainers - the trailing whitespace is significant --&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;15th August 2023:&lt;/strong&gt;&lt;br&gt;
Kubernetes announces a new, community-managed source for Linux software packages of Kubernetes components&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;31st August 2023:&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;(this announcement)&lt;/em&gt; Kubernetes formally deprecates the legacy
package repositories&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;13th September 2023&lt;/strong&gt; (approximately):&lt;br&gt;
Kubernetes will freeze the legacy package repositories,
(&lt;code&gt;apt.kubernetes.io&lt;/code&gt; and &lt;code&gt;yum.kubernetes.io&lt;/code&gt;).
The freeze will happen immediately following the patch releases that are scheduled for September, 2023.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The Kubernetes patch releases scheduled for September 2023 (v1.28.2, v1.27.6,
v1.26.9, v1.25.14) will have packages published &lt;strong&gt;both&lt;/strong&gt; to the community-owned and
the legacy repositories.&lt;/p&gt;
&lt;p&gt;We&#39;ll freeze the legacy repositories after cutting the patch releases for September
which means that we&#39;ll completely stop publishing packages to the legacy repositories
at that point.&lt;/p&gt;
&lt;p&gt;For the v1.28, v1.27, v1.26, and v1.25 patch releases from October 2023 and onwards,
we&#39;ll only publish packages to the new package repositories (&lt;code&gt;pkgs.k8s.io&lt;/code&gt;).&lt;/p&gt;
&lt;h3 id=&#34;what-about-future-minor-releases&#34;&gt;What about future minor releases?&lt;/h3&gt;
&lt;p&gt;Kubernetes 1.29 and onwards will have packages published &lt;strong&gt;only&lt;/strong&gt; to the
community-owned repositories (&lt;code&gt;pkgs.k8s.io&lt;/code&gt;).&lt;/p&gt;
&lt;h2 id=&#34;can-i-continue-to-use-the-legacy-package-repositories&#34;&gt;Can I continue to use the legacy package repositories?&lt;/h2&gt;
&lt;p&gt;&lt;del&gt;The existing packages in the legacy repositories will be available for the foreseeable
future. However, the Kubernetes project can&#39;t provide &lt;em&gt;any&lt;/em&gt; guarantees on how long
is that going to be. The deprecated legacy repositories, and their contents, might
be removed at any time in the future and without a further notice period.&lt;/del&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;UPDATE&lt;/strong&gt;: The legacy packages are expected to go away in January 2024.&lt;/p&gt;
&lt;p&gt;The Kubernetes project &lt;strong&gt;strongly recommends&lt;/strong&gt; migrating to the new community-owned
repositories &lt;strong&gt;as soon as possible&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Given that no new releases will be published to the legacy repositories &lt;strong&gt;after the September 13, 2023&lt;/strong&gt;
cut-off point, &lt;strong&gt;you will not be able to upgrade to any patch or minor release made from that date onwards.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Whilst the project makes every effort to release secure software, there may one
day be a high-severity vulnerability in Kubernetes, and consequently an important
release to upgrade to. The advice we&#39;re announcing will help you be as prepared for
any future security update, whether trivial or urgent.&lt;/p&gt;
&lt;h2 id=&#34;check-if-affected&#34;&gt;How can I check if I&#39;m using the legacy repositories?&lt;/h2&gt;
&lt;p&gt;The steps to check if you&#39;re using the legacy repositories depend on whether you&#39;re
using Debian-based distributions (Debian, Ubuntu, and more) or RPM-based distributions
(CentOS, RHEL, Rocky Linux, and more) in your cluster.&lt;/p&gt;
&lt;p&gt;Run these instructions on one of your nodes in the cluster.&lt;/p&gt;
&lt;h3 id=&#34;debian-based-linux-distributions&#34;&gt;Debian-based Linux distributions&lt;/h3&gt;
&lt;p&gt;The repository definitions (sources) are located in &lt;code&gt;/etc/apt/sources.list&lt;/code&gt; and &lt;code&gt;/etc/apt/sources.list.d/&lt;/code&gt;
on Debian-based distributions. Inspect these two locations and try to locate a
package repository definition that looks like:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;deb [signed-by=/etc/apt/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;If you find a repository definition that looks like this, you&#39;re using the legacy repository and you need to migrate.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If the repository definition uses &lt;code&gt;pkgs.k8s.io&lt;/code&gt;, you&#39;re already using the
community-hosted repositories and you don&#39;t need to take any action.&lt;/p&gt;
&lt;p&gt;On most systems, this repository definition should be located in
&lt;code&gt;/etc/apt/sources.list.d/kubernetes.list&lt;/code&gt; (as recommended by the Kubernetes
documentation), but on some systems it might be in a different location.&lt;/p&gt;
&lt;p&gt;If you can&#39;t find a repository definition related to Kubernetes, it&#39;s likely that you
don&#39;t use package managers to install Kubernetes and you don&#39;t need to take any action.&lt;/p&gt;
&lt;h3 id=&#34;rpm-based-linux-distributions&#34;&gt;RPM-based Linux distributions&lt;/h3&gt;
&lt;p&gt;The repository definitions are located in &lt;code&gt;/etc/yum.repos.d&lt;/code&gt; if you&#39;re using the
&lt;code&gt;yum&lt;/code&gt; package manager, or &lt;code&gt;/etc/dnf/dnf.conf&lt;/code&gt; and &lt;code&gt;/etc/dnf/repos.d/&lt;/code&gt; if you&#39;re using
&lt;code&gt;dnf&lt;/code&gt; package manager. Inspect those locations and try to locate a package repository
definition that looks like this:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-\$basearch
enabled=1
gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
exclude=kubelet kubeadm kubectl
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;If you find a repository definition that looks like this, you&#39;re using the legacy repository and you need to migrate.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If the repository definition uses &lt;code&gt;pkgs.k8s.io&lt;/code&gt;, you&#39;re already using the
community-hosted repositories and you don&#39;t need to take any action.&lt;/p&gt;
&lt;p&gt;On most systems, that repository definition should be located in &lt;code&gt;/etc/yum.repos.d/kubernetes.repo&lt;/code&gt;
(as recommended by the Kubernetes documentation), but on some systems it might be
in a different location.&lt;/p&gt;
&lt;p&gt;If you can&#39;t find a repository definition related to Kubernetes, it&#39;s likely that you
don&#39;t use package managers to install Kubernetes and you don&#39;t need to take any action.&lt;/p&gt;
&lt;h2 id=&#34;how-can-i-migrate-to-the-new-community-operated-repositories&#34;&gt;How can I migrate to the new community-operated repositories?&lt;/h2&gt;
&lt;p&gt;For more information on how to migrate to the new community
managed packages, please refer to the
&lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/08/15/pkgs-k8s-io-introduction/&#34;&gt;announcement blog post for &lt;code&gt;pkgs.k8s.io&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;why-is-the-kubernetes-project-making-this-change&#34;&gt;Why is the Kubernetes project making this change?&lt;/h2&gt;
&lt;p&gt;Kubernetes has been publishing packages solely to the Google-hosted repository
since Kubernetes v1.5, or the past &lt;strong&gt;seven&lt;/strong&gt; years! Following in the footsteps of
migrating to our community-managed registry, &lt;code&gt;registry.k8s.io&lt;/code&gt;, we are now migrating the
Kubernetes package repositories to our own community-managed infrastructure. We’re
thankful to Google for their continuous hosting and support all these years, but
this transition marks another big milestone for the project’s goal of migrating
to complete community-owned infrastructure.&lt;/p&gt;
&lt;h2 id=&#34;is-there-a-kubernetes-tool-to-help-me-migrate&#34;&gt;Is there a Kubernetes tool to help me migrate?&lt;/h2&gt;
&lt;p&gt;We don&#39;t have any announcement to make about tooling there. As a Kubernetes user, you
have to manually modify your configuration to use the new repositories. Automating
the migration from the legacy to the community-owned repositories is technically
challenging and we want to avoid any potential risks associated with this.&lt;/p&gt;
&lt;h2 id=&#34;acknowledgments&#34;&gt;Acknowledgments&lt;/h2&gt;
&lt;p&gt;First of all, we want to acknowledge the contributions from Alphabet. Staff at Google
have provided their time; Google as a business has provided both the infrastructure
to serve packages, and the security context for giving those packages trustworthy
digital signatures.
These have been important to the adoption and growth of Kubernetes.&lt;/p&gt;
&lt;p&gt;Releasing software might not be glamorous but it&#39;s important. Many people within
the Kubernetes contributor community have contributed to the new way that we, as a
project, have for building and publishing packages.&lt;/p&gt;
&lt;p&gt;And finally, we want to once again acknowledge the help from SUSE. OpenBuildService,
from SUSE, is the technology that the powers the new community-managed package repositories.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Gateway API v0.8.0: Introducing Service Mesh Support</title>
      <link>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/08/29/gateway-api-v0-8/</link>
      <pubDate>Tue, 29 Aug 2023 10:00:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/08/29/gateway-api-v0-8/</guid>
      <description>
        
        
        &lt;p&gt;&lt;em&gt;&lt;strong&gt;Authors:&lt;/strong&gt;&lt;/em&gt; Flynn (Buoyant), John Howard (Google), Keith Mattix (Microsoft), Michael Beaumont (Kong), Mike Morris (independent), Rob Scott (Google)&lt;/p&gt;
&lt;p&gt;We are thrilled to announce the v0.8.0 release of Gateway API! With this
release, Gateway API support for service mesh has reached &lt;a href=&#34;https://gateway-api.sigs.k8s.io/geps/overview/#status&#34;&gt;Experimental
status&lt;/a&gt;. We look forward to your feedback!&lt;/p&gt;
&lt;p&gt;We&#39;re especially delighted to announce that Kuma 2.3+, Linkerd 2.14+, and Istio
1.16+ are all fully-conformant implementations of Gateway API service mesh
support.&lt;/p&gt;
&lt;h2 id=&#34;service-mesh-support-in-gateway-api&#34;&gt;Service mesh support in Gateway API&lt;/h2&gt;
&lt;p&gt;While the initial focus of Gateway API was always ingress (north-south)
traffic, it was clear almost from the beginning that the same basic routing
concepts should also be applicable to service mesh (east-west) traffic. In
2022, the Gateway API subproject started the &lt;a href=&#34;https://gateway-api.sigs.k8s.io/concepts/gamma/&#34;&gt;GAMMA initiative&lt;/a&gt;, a
dedicated vendor-neutral workstream, specifically to examine how best to fit
service mesh support into the framework of the Gateway API resources, without
requiring users of Gateway API to relearn everything they understand about the
API.&lt;/p&gt;
&lt;p&gt;Over the last year, GAMMA has dug deeply into the challenges and possible
solutions around using Gateway API for service mesh. The end result is a small
number of &lt;a href=&#34;https://gateway-api.sigs.k8s.io/contributing/enhancement-requests/&#34;&gt;enhancement proposals&lt;/a&gt; that subsume many hours of thought and
debate, and provide a minimum viable path to allow Gateway API to be used for
service mesh.&lt;/p&gt;
&lt;h3 id=&#34;how-will-mesh-routing-work-when-using-gateway-api&#34;&gt;How will mesh routing work when using Gateway API?&lt;/h3&gt;
&lt;p&gt;You can find all the details in the &lt;a href=&#34;https://gateway-api.sigs.k8s.io/concepts/gamma/#how-the-gateway-api-works-for-service-mesh&#34;&gt;Gateway API Mesh routing
documentation&lt;/a&gt; and &lt;a href=&#34;https://gateway-api.sigs.k8s.io/geps/gep-1426/&#34;&gt;GEP-1426&lt;/a&gt;, but the short version for Gateway
API v0.8.0 is that an HTTPRoute can now have a &lt;code&gt;parentRef&lt;/code&gt; that is a Service,
rather than just a Gateway. We anticipate future GEPs in this area as we gain
more experience with service mesh use cases -- binding to a Service makes it
possible to use the Gateway API with a service mesh, but there are several
interesting use cases that remain difficult to cover.&lt;/p&gt;
&lt;p&gt;As an example, you might use an HTTPRoute to do an A-B test in the mesh 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/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;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;bar-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;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;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;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;demo-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;port&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;5000&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;headers&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;Exact&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;env&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;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;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;demo-app-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;port&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;5000&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;demo-app-v2&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;5000&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;Any request to port 5000 of the &lt;code&gt;demo-app&lt;/code&gt; Service that has the header &lt;code&gt;env: v1&lt;/code&gt; will be routed to &lt;code&gt;demo-app-v1&lt;/code&gt;, while any request without that header
will be routed to &lt;code&gt;demo-app-v2&lt;/code&gt; -- and since this is being handled by the
service mesh, not the ingress controller, the A/B test can happen anywhere in
the application&#39;s call graph.&lt;/p&gt;
&lt;h3 id=&#34;how-do-i-know-this-will-be-truly-portable&#34;&gt;How do I know this will be truly portable?&lt;/h3&gt;
&lt;p&gt;Gateway API has been investing heavily in conformance tests across all
features it supports, and mesh is no exception. One of the challenges that the
GAMMA initiative ran into is that many of these tests were strongly tied to
the idea that a given implementation provides an ingress controller. Many
service meshes don&#39;t, and requiring a GAMMA-conformant mesh to also implement
an ingress controller seemed impractical at best. This resulted in work
restarting on Gateway API &lt;em&gt;conformance profiles&lt;/em&gt;, as discussed in &lt;a href=&#34;https://gateway-api.sigs.k8s.io/geps/gep-1709/&#34;&gt;GEP-1709&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The basic idea of conformance profiles is that we can define subsets of the
Gateway API, and allow implementations to choose (and document) which subsets
they conform to. GAMMA is adding a new profile, named &lt;code&gt;Mesh&lt;/code&gt; and described in
&lt;a href=&#34;https://gateway-api.sigs.k8s.io/geps/gep-1686/&#34;&gt;GEP-1686&lt;/a&gt;, which checks only the mesh functionality as defined by GAMMA. At
this point, Kuma 2.3+, Linkerd 2.14+, and Istio 1.16+ are all conformant with
the &lt;code&gt;Mesh&lt;/code&gt; profile.&lt;/p&gt;
&lt;h2 id=&#34;what-else-is-in-gateway-api-v0-8-0&#34;&gt;What else is in Gateway API v0.8.0?&lt;/h2&gt;
&lt;p&gt;This release is all about preparing Gateway API for the upcoming v1.0 release
where HTTPRoute, Gateway, and GatewayClass will graduate to GA. There are two
main changes related to this: CEL validation and API version changes.&lt;/p&gt;
&lt;h3 id=&#34;cel-validation&#34;&gt;CEL Validation&lt;/h3&gt;
&lt;p&gt;The first major change is that Gateway API v0.8.0 is the start of a transition
from webhook validation to &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/reference/using-api/cel/&#34;&gt;CEL validation&lt;/a&gt; using information built into
the CRDs. That will mean different things depending on the version of
Kubernetes you&#39;re using:&lt;/p&gt;
&lt;h4 id=&#34;kubernetes-1-25&#34;&gt;Kubernetes 1.25+&lt;/h4&gt;
&lt;p&gt;CEL validation is fully supported, and almost all validation is implemented in
CEL. (The sole exception is that header names in header modifier filters can
only do case-insensitive validation. There is more information in &lt;a href=&#34;https://github.com/kubernetes-sigs/gateway-api/issues/2277&#34;&gt;issue
2277&lt;/a&gt;.)&lt;/p&gt;
&lt;p&gt;We recommend &lt;em&gt;not&lt;/em&gt; using the validating webhook on these Kubernetes versions.&lt;/p&gt;
&lt;h4 id=&#34;kubernetes-1-23-and-1-24&#34;&gt;Kubernetes 1.23 and 1.24&lt;/h4&gt;
&lt;p&gt;CEL validation is not supported, but Gateway API v0.8.0 CRDs can still be
installed. When you upgrade to Kubernetes 1.25+, the validation included in
these CRDs will automatically take effect.&lt;/p&gt;
&lt;p&gt;We recommend continuing to use the validating webhook on these Kubernetes
versions.&lt;/p&gt;
&lt;h4 id=&#34;kubernetes-1-22-and-older&#34;&gt;Kubernetes 1.22 and older&lt;/h4&gt;
&lt;p&gt;Gateway API only commits to support for &lt;a href=&#34;https://gateway-api.sigs.k8s.io/concepts/versioning/#supported-versions&#34;&gt;5 most recent versions of
Kubernetes&lt;/a&gt;. As such, these versions are no longer
supported by Gateway API, and unfortunately Gateway API v0.8.0 cannot be
installed on them, since CRDs containing CEL validation will be rejected.&lt;/p&gt;
&lt;h3 id=&#34;api-version-changes&#34;&gt;API Version Changes&lt;/h3&gt;
&lt;p&gt;As we prepare for a v1.0 release that will graduate Gateway, GatewayClass, and
HTTPRoute to the &lt;code&gt;v1&lt;/code&gt; API Version from &lt;code&gt;v1beta1&lt;/code&gt;, we are continuing the process
of moving away from &lt;code&gt;v1alpha2&lt;/code&gt; for resources that have graduated to &lt;code&gt;v1beta1&lt;/code&gt;.
For more information on this change and everything else included in this
release, refer to the &lt;a href=&#34;https://github.com/kubernetes-sigs/gateway-api/releases/tag/v0.8.0&#34;&gt;v0.8.0 release notes&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;how-can-i-get-started-with-gateway-api&#34;&gt;How can I get started with Gateway API?&lt;/h2&gt;
&lt;p&gt;Gateway API represents the future of load balancing, routing, and service mesh
APIs in Kubernetes. There are already more than 20 &lt;a href=&#34;https://gateway-api.sigs.k8s.io/implementations/&#34;&gt;implementations&lt;/a&gt;
available (including both ingress controllers and service meshes) and the list
keeps growing.&lt;/p&gt;
&lt;p&gt;If you&#39;re interested in getting started with Gateway API, take a look at the
&lt;a href=&#34;https://gateway-api.sigs.k8s.io/concepts/api-overview/&#34;&gt;API concepts documentation&lt;/a&gt; and check out some of the
&lt;a href=&#34;https://gateway-api.sigs.k8s.io/guides/getting-started/&#34;&gt;Guides&lt;/a&gt; to try it out. Because this is a CRD-based API, you can
install the latest version on any Kubernetes 1.23+ cluster.&lt;/p&gt;
&lt;p&gt;If you&#39;re specifically interested in helping to contribute to Gateway API, we
would love to have you! Please feel free to &lt;a href=&#34;https://github.com/kubernetes-sigs/gateway-api/issues/new/choose&#34;&gt;open a new issue&lt;/a&gt; on the
repository, or join in the &lt;a href=&#34;https://github.com/kubernetes-sigs/gateway-api/discussions&#34;&gt;discussions&lt;/a&gt;. Also check out the &lt;a href=&#34;https://gateway-api.sigs.k8s.io/contributing/community/&#34;&gt;community
page&lt;/a&gt; which includes links to the Slack channel and community
meetings. We look forward to seeing you!!&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://gateway-api.sigs.k8s.io/geps/gep-1324/&#34;&gt;GEP-1324&lt;/a&gt; provides an overview of the GAMMA goals and some important
definitions. This GEP is well worth a read for its discussion of the problem
space.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gateway-api.sigs.k8s.io/geps/gep-1426/&#34;&gt;GEP-1426&lt;/a&gt; defines how to use Gateway API route resources, such as
HTTPRoute, to manage traffic within a service mesh.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gateway-api.sigs.k8s.io/geps/gep-1686/&#34;&gt;GEP-1686&lt;/a&gt; builds on the work of &lt;a href=&#34;https://gateway-api.sigs.k8s.io/geps/gep-1709/&#34;&gt;GEP-1709&lt;/a&gt; to define a &lt;em&gt;conformance
profile&lt;/em&gt; for service meshes to be declared conformant with Gateway API.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Although these are &lt;a href=&#34;https://gateway-api.sigs.k8s.io/geps/overview/#status&#34;&gt;Experimental&lt;/a&gt; patterns, note that they are available
in the &lt;a href=&#34;https://gateway-api.sigs.k8s.io/concepts/versioning/#release-channels-eg-experimental-standard&#34;&gt;&lt;code&gt;standard&lt;/code&gt; release channel&lt;/a&gt;, since the GAMMA initiative has not
needed to introduce new resources or fields to date.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes 1.28: A New (alpha) Mechanism For Safer Cluster Upgrades</title>
      <link>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/08/28/kubernetes-1-28-feature-mixed-version-proxy-alpha/</link>
      <pubDate>Mon, 28 Aug 2023 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/08/28/kubernetes-1-28-feature-mixed-version-proxy-alpha/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Author:&lt;/strong&gt; Richa Banker (Google)&lt;/p&gt;
&lt;p&gt;This blog describes the &lt;em&gt;mixed version proxy&lt;/em&gt;, a new alpha feature in Kubernetes 1.28. The
mixed version proxy enables an HTTP request for a resource to be served by the correct API server
in cases where there are multiple API servers at varied versions in a cluster. For example,
this is useful during a cluster upgrade, or when you&#39;re rolling out the runtime configuration of
the cluster&#39;s control plane.&lt;/p&gt;
&lt;h2 id=&#34;what-problem-does-this-solve&#34;&gt;What problem does this solve?&lt;/h2&gt;
&lt;p&gt;When a cluster undergoes an upgrade, the kube-apiservers existing at different versions in that scenario can serve different sets (groups, versions, resources) of built-in resources. A resource request made in this scenario may be served by any of the available apiservers, potentially resulting in the request ending up at an apiserver that may not be aware of the requested resource; consequently it being served a 404 not found error which is incorrect. Furthermore, incorrect serving of the 404 errors can lead to serious consequences such as namespace deletion being blocked incorrectly or objects being garbage collected mistakenly.&lt;/p&gt;
&lt;h2 id=&#34;how-do-we-solve-the-problem&#34;&gt;How do we solve the problem?&lt;/h2&gt;

&lt;figure class=&#34;diagram-large&#34;&gt;
    &lt;img src=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/images/blog/2023-08-28-a-new-alpha-mechanism-for-safer-cluster-upgrades/mvp-flow-diagram.svg&#34;/&gt; 
&lt;/figure&gt;

&lt;p&gt;The new feature “Mixed Version Proxy” provides the kube-apiserver with the capability to proxy a request to a peer kube-apiserver which is aware of the requested resource and hence can serve the request. To do this, a new filter has been added to the handler chain in the API server&#39;s aggregation layer.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The new filter in the handler chain checks if the request is for a group/version/resource that the apiserver doesn&#39;t know about (using the existing &lt;a href=&#34;https://github.com/kubernetes/kubernetes/blob/release-1.28/pkg/apis/apiserverinternal/types.go#L25-L37&#34;&gt;StorageVersion API&lt;/a&gt;). If so, it proxies the request to one of the apiservers that is listed in the ServerStorageVersion object. If the identified peer apiserver fails to respond (due to reasons like network connectivity, race between the request being received and the controller registering the apiserver-resource info in ServerStorageVersion object), then error 503(&amp;quot;Service Unavailable&amp;quot;) is served.&lt;/li&gt;
&lt;li&gt;To prevent indefinite proxying of the request, a (new for v1.28) HTTP header &lt;code&gt;X-Kubernetes-APIServer-Rerouted: true&lt;/code&gt; is added to the original request once it is determined that the request cannot be served by the original API server. Setting that to true marks that the original API server couldn&#39;t handle the request and it should therefore be proxied. If a destination peer API server sees this header, it never proxies the request further.&lt;/li&gt;
&lt;li&gt;To set the network location of a kube-apiserver that peers will use to proxy requests, the value passed in &lt;code&gt;--advertise-address&lt;/code&gt; or (when &lt;code&gt;--advertise-address&lt;/code&gt; is unspecified) the &lt;code&gt;--bind-address&lt;/code&gt; flag is used. For users with network configurations that would not allow communication between peer kube-apiservers using the addresses specified in these flags, there is an option to pass in the correct peer address as &lt;code&gt;--peer-advertise-ip&lt;/code&gt; and &lt;code&gt;--peer-advertise-port&lt;/code&gt; flags that are introduced in this feature.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;how-do-i-enable-this-feature&#34;&gt;How do I enable this feature?&lt;/h2&gt;
&lt;p&gt;Following are the required steps to enable the feature:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Download the &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/releases/download/&#34;&gt;latest Kubernetes project&lt;/a&gt; (version &lt;code&gt;v1.28.0&lt;/code&gt; or later)&lt;/li&gt;
&lt;li&gt;Switch on the feature gate with the command line flag &lt;code&gt;--feature-gates=UnknownVersionInteroperabilityProxy=true&lt;/code&gt; on the kube-apiservers&lt;/li&gt;
&lt;li&gt;Pass the CA bundle that will be used by source kube-apiserver to authenticate destination kube-apiserver&#39;s serving certs using the flag &lt;code&gt;--peer-ca-file&lt;/code&gt; on the kube-apiservers. Note: this is a required flag for this feature to work. There is no default value enabled for this flag.&lt;/li&gt;
&lt;li&gt;Pass the correct ip and port of the local kube-apiserver that will be used by peers to connect to this kube-apiserver while proxying a request. Use the flags &lt;code&gt;--peer-advertise-ip&lt;/code&gt; and &lt;code&gt;peer-advertise-port&lt;/code&gt; to the kube-apiservers upon startup. If unset, the value passed to either &lt;code&gt;--advertise-address&lt;/code&gt; or &lt;code&gt;--bind-address&lt;/code&gt; is used. If those too, are unset, the host&#39;s default interface will be used.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;what-s-missing&#34;&gt;What’s missing?&lt;/h2&gt;
&lt;p&gt;Currently we only proxy resource requests to a peer kube-apiserver when its determined to do so. Next we need to address how to work discovery requests in such scenarios. Right now we are planning to have the following capabilities for beta&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Merged discovery across all kube-apiservers&lt;/li&gt;
&lt;li&gt;Use an egress dialer for network connections made to peer kube-apiservers&lt;/li&gt;
&lt;/ul&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;Read the &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/concepts/architecture/mixed-version-proxy&#34;&gt;Mixed Version Proxy documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Read &lt;a href=&#34;https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/4020-unknown-version-interoperability-proxy&#34;&gt;KEP-4020: Unknown Version Interoperability Proxy&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;how-can-i-get-involved&#34;&gt;How can I get involved?&lt;/h2&gt;
&lt;p&gt;Reach us on &lt;a href=&#34;https://slack.k8s.io/&#34;&gt;Slack&lt;/a&gt;: &lt;a href=&#34;https://kubernetes.slack.com/messages/sig-api-machinery&#34;&gt;#sig-api-machinery&lt;/a&gt;, or through the &lt;a href=&#34;https://groups.google.com/forum/#!forum/kubernetes-sig-api-machinery&#34;&gt;mailing list&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Huge thanks to the contributors that have helped in the design, implementation, and review of this feature: Daniel Smith, Han Kang, Joe Betz, Jordan Liggit, Antonio Ojea, David Eads and Ben Luddy!&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes v1.28: Introducing native sidecar containers</title>
      <link>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/08/25/native-sidecar-containers/</link>
      <pubDate>Fri, 25 Aug 2023 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/08/25/native-sidecar-containers/</guid>
      <description>
        
        
        &lt;p&gt;&lt;em&gt;&lt;strong&gt;Authors:&lt;/strong&gt;&lt;/em&gt; Todd Neal (AWS), Matthias Bertschy (ARMO), Sergey Kanzhelev (Google), Gunju Kim (NAVER), Shannon Kularathna (Google)&lt;/p&gt;
&lt;p&gt;This post explains how to use the new sidecar feature, which enables restartable init containers and is available in alpha in Kubernetes 1.28. We want your feedback so that we can graduate this feature as soon as possible.&lt;/p&gt;
&lt;p&gt;The concept of a “sidecar” has been part of Kubernetes since nearly the very beginning. In 2015, sidecars were described in a &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2015/06/the-distributed-system-toolkit-patterns/&#34;&gt;blog post&lt;/a&gt; about composite containers as additional containers that “extend and enhance the ‘main’ container”. Sidecar containers have become a common Kubernetes deployment pattern and are often used for network proxies or as part of a logging system. Until now, sidecars were a concept that Kubernetes users applied without native support. The lack of native support has caused some usage friction, which this enhancement aims to resolve.&lt;/p&gt;
&lt;h2 id=&#34;what-are-sidecar-containers-in-1-28&#34;&gt;What are sidecar containers in 1.28?&lt;/h2&gt;
&lt;p&gt;Kubernetes 1.28 adds a new &lt;code&gt;restartPolicy&lt;/code&gt; field to &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/concepts/workloads/pods/init-containers/&#34;&gt;init containers&lt;/a&gt; that is available when the &lt;code&gt;SidecarContainers&lt;/code&gt; &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/reference/command-line-tools-reference/feature-gates/&#34;&gt;feature gate&lt;/a&gt; is enabled.&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;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;initContainers&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;secret-fetch&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;secret-fetch:1.0&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;network-proxy&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;network-proxy:1.0&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;restartPolicy&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Always&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The field is optional and, if set, the only valid value is Always. Setting this field changes the behavior of init containers as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The container restarts if it exits&lt;/li&gt;
&lt;li&gt;Any subsequent init container starts immediately after the &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#define-startup-probes&#34;&gt;startupProbe&lt;/a&gt; has successfully completed instead of waiting for the restartable init container to exit&lt;/li&gt;
&lt;li&gt;The resource usage calculation changes for the pod as restartable init container resources are now added to the sum of the resource requests by the main containers&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/concepts/workloads/pods/pod-lifecycle/#pod-termination&#34;&gt;Pod termination&lt;/a&gt; continues to only depend on the main containers. An init container with a &lt;code&gt;restartPolicy&lt;/code&gt; of &lt;code&gt;Always&lt;/code&gt; (named a sidecar) won&#39;t prevent the pod from terminating after the main containers exit.&lt;/p&gt;
&lt;p&gt;The following properties of restartable init containers make them ideal for the sidecar deployment pattern:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Init containers have a well-defined startup order regardless of whether you set a &lt;code&gt;restartPolicy&lt;/code&gt;, so you can ensure that your sidecar starts before any container declarations that come after the sidecar declaration in your manifest.&lt;/li&gt;
&lt;li&gt;Sidecar containers don&#39;t extend the lifetime of the Pod, so you can use them in short-lived Pods with no changes to the Pod lifecycle.&lt;/li&gt;
&lt;li&gt;Sidecar containers are restarted on exit, which improves resilience and lets you use sidecars to provide services that your main containers can more reliably consume.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;when-to-use-sidecar-containers&#34;&gt;When to use sidecar containers&lt;/h2&gt;
&lt;p&gt;You might find built-in sidecar containers useful for workloads such as the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Batch or AI/ML workloads&lt;/strong&gt;, or other Pods that run to completion. These workloads will experience the most significant benefits.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Network proxies&lt;/strong&gt; that start up before any other container in the manifest. Every other container that runs can use the proxy container&#39;s services. For instructions, see the &lt;a href=&#34;https://istio.io/latest/blog/2023/native-sidecars/&#34;&gt;Kubernetes Native sidecars in Istio blog post&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Log collection containers&lt;/strong&gt;, which can now start before any other container and run until the Pod terminates. This improves the reliability of log collection in your Pods.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Jobs&lt;/strong&gt;, which can use sidecars for any purpose without Job completion being blocked by the running sidecar. No additional configuration is required to ensure this behavior.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;how-did-users-get-sidecar-behavior-before-1-28&#34;&gt;How did users get sidecar behavior before 1.28?&lt;/h2&gt;
&lt;p&gt;Prior to the sidecar feature, the following options were available for implementing sidecar behavior depending on the desired lifetime of the sidecar container:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Lifetime of sidecar less than Pod lifetime&lt;/strong&gt;: Use an init container, which provides well-defined startup order. However, the sidecar has to exit for other init containers and main Pod containers to start.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Lifetime of sidecar equal to Pod lifetime&lt;/strong&gt;: Use a main container that runs alongside your workload containers in the Pod. This method doesn&#39;t give you control over startup order, and lets the sidecar container potentially block Pod termination after the workload containers exit.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The built-in sidecar feature solves for the use case of having a lifetime equal to the Pod lifetime and has the following additional benefits:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Provides control over startup order&lt;/li&gt;
&lt;li&gt;Doesn’t block Pod termination&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;transitioning-existing-sidecars-to-the-new-model&#34;&gt;Transitioning existing sidecars to the new model&lt;/h2&gt;
&lt;p&gt;We recommend only using the sidecars feature gate in &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/reference/command-line-tools-reference/feature-gates/#feature-stages&#34;&gt;short lived testing clusters&lt;/a&gt; at the alpha stage. If you have an existing sidecar that is configured as a main container so it can run for the lifetime of the pod, it can be moved to the &lt;code&gt;initContainers&lt;/code&gt; section of the pod spec and given a &lt;code&gt;restartPolicy&lt;/code&gt; of &lt;code&gt;Always&lt;/code&gt;. In many cases, the sidecar should work as before with the added benefit of having a defined startup ordering and not prolonging the pod lifetime.&lt;/p&gt;
&lt;h2 id=&#34;known-issues&#34;&gt;Known issues&lt;/h2&gt;
&lt;p&gt;The alpha release of built-in sidecar containers has the following known issues, which we&#39;ll resolve before graduating the feature to beta:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The CPU, memory, device, and topology manager are unaware of the sidecar container lifetime and additional resource usage, and will operate as if the Pod had lower resource requests than it actually does.&lt;/li&gt;
&lt;li&gt;The output of &lt;code&gt;kubectl describe node&lt;/code&gt; is incorrect when sidecars are in use. The output shows resource usage that&#39;s lower than the actual usage because it doesn&#39;t use the new resource usage calculation for sidecar containers.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;we-need-your-feedback&#34;&gt;We need your feedback!&lt;/h2&gt;
&lt;p&gt;In the alpha stage, we want you to try out sidecar containers in your environments and open issues if you encounter bugs or friction points. We&#39;re especially interested in feedback about the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The shutdown sequence, especially with multiple sidecars running&lt;/li&gt;
&lt;li&gt;The backoff timeout adjustment for crashing sidecars&lt;/li&gt;
&lt;li&gt;The behavior of Pod readiness and liveness probes when sidecars are running&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To open an issue, see the &lt;a href=&#34;https://github.com/kubernetes/kubernetes/issues/new/choose&#34;&gt;Kubernetes GitHub repository&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;what-s-next&#34;&gt;What’s next?&lt;/h2&gt;
&lt;p&gt;In addition to the known issues that will be resolved, we&#39;re working on adding termination ordering for sidecar and main containers. This will ensure that sidecar containers only terminate after the Pod&#39;s main containers have exited.&lt;/p&gt;
&lt;p&gt;We’re excited to see the sidecar feature come to Kubernetes and are interested in feedback.&lt;/p&gt;
&lt;h2 id=&#34;acknowledgements&#34;&gt;Acknowledgements&lt;/h2&gt;
&lt;p&gt;Many years have passed since the original KEP was written, so we apologize if we omit anyone who worked on this feature over the years. This is a best-effort attempt to recognize the people involved in this effort.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/mrunalp/&#34;&gt;mrunalp&lt;/a&gt; for design discussions and reviews&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/thockin/&#34;&gt;thockin&lt;/a&gt; for API discussions and support thru years&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/bobbypage&#34;&gt;bobbypage&lt;/a&gt; for reviews&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/smarterclayton&#34;&gt;smarterclayton&lt;/a&gt; for detailed review and feedback&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/howardjohn&#34;&gt;howardjohn&lt;/a&gt; for feedback over years and trying it early during implementation&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/derekwaynecarr&#34;&gt;derekwaynecarr&lt;/a&gt; and &lt;a href=&#34;https://github.com/dchen1107&#34;&gt;dchen1107&lt;/a&gt; for leadership&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/Jpbetz&#34;&gt;jpbetz&lt;/a&gt; for API and termination ordering designs as well as code reviews&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/Joseph-Irving&#34;&gt;Joseph-Irving&lt;/a&gt; and &lt;a href=&#34;https://github.com/rata&#34;&gt;rata&lt;/a&gt; for the early iterations design and reviews years back&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/swatisehgal&#34;&gt;swatisehgal&lt;/a&gt; and &lt;a href=&#34;https://github.com/ffromani&#34;&gt;ffromani&lt;/a&gt; for early feedback on resource managers impact&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/Alculquicondor&#34;&gt;alculquicondor&lt;/a&gt; for feedback on addressing the version skew of the scheduler&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/Wojtek-t&#34;&gt;wojtek-t&lt;/a&gt; for PRR review of a KEP&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/ahg-g&#34;&gt;ahg-g&lt;/a&gt; for reviewing the scheduler portion of a KEP&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/Adisky&#34;&gt;adisky&lt;/a&gt; for the Job completion issue&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;more-information&#34;&gt;More Information&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Read &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/concepts/workloads/pods/init-containers/#api-for-sidecar-containers&#34;&gt;API for sidecar containers&lt;/a&gt; in the Kubernetes documentation&lt;/li&gt;
&lt;li&gt;Read the &lt;a href=&#34;https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/753-sidecar-containers/README.md&#34;&gt;Sidecar KEP&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes 1.28: Beta support for using swap on Linux</title>
      <link>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/08/24/swap-linux-beta/</link>
      <pubDate>Thu, 24 Aug 2023 10:00:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/08/24/swap-linux-beta/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Author:&lt;/strong&gt; Itamar Holder (Red Hat)&lt;/p&gt;
&lt;p&gt;The 1.22 release &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2021/08/09/run-nodes-with-swap-alpha/&#34;&gt;introduced Alpha support&lt;/a&gt;
for configuring swap memory usage for Kubernetes workloads running on Linux on a per-node basis.
Now, in release 1.28, support for swap on Linux nodes has graduated to Beta, along with many
new improvements.&lt;/p&gt;
&lt;p&gt;Prior to version 1.22, Kubernetes did not provide support for swap memory on Linux systems.
This was due to the inherent difficulty in guaranteeing and accounting for pod memory utilization
when swap memory was involved. As a result, swap support was deemed out of scope in the initial
design of Kubernetes, and the default behavior of a kubelet was to fail to start if swap memory
was detected on a node.&lt;/p&gt;
&lt;p&gt;In version 1.22, the swap feature for Linux was initially introduced in its Alpha stage. This represented
a significant advancement, providing Linux users with the opportunity to experiment with the swap
feature for the first time. However, as an Alpha version, it was not fully developed and had
several issues, including inadequate support for cgroup v2, insufficient metrics and summary
API statistics, inadequate testing, and more.&lt;/p&gt;
&lt;p&gt;Swap in Kubernetes has numerous &lt;a href=&#34;https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/2400-node-swap/README.md#user-stories&#34;&gt;use cases&lt;/a&gt;
for a wide range of users. As a result, the node special interest group within the Kubernetes project
has invested significant effort into supporting swap on Linux nodes for beta.
Compared to the alpha, the kubelet&#39;s support for running with swap enabled is more stable and
robust, more user-friendly, and addresses many known shortcomings. This graduation to beta
represents a crucial step towards achieving the goal of fully supporting swap in Kubernetes.&lt;/p&gt;
&lt;h2 id=&#34;how-do-i-use-it&#34;&gt;How do I use it?&lt;/h2&gt;
&lt;p&gt;The utilization of swap memory on a node where it has already been provisioned can be
facilitated by the activation of the &lt;code&gt;NodeSwap&lt;/code&gt; feature gate on the kubelet.
Additionally, you must disable the &lt;code&gt;failSwapOn&lt;/code&gt; configuration setting, or the deprecated
&lt;code&gt;--fail-swap-on&lt;/code&gt; command line flag must be deactivated.&lt;/p&gt;
&lt;p&gt;It is possible to configure the &lt;code&gt;memorySwap.swapBehavior&lt;/code&gt; option to define the manner in which a node utilizes swap memory. For instance,&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;# this fragment goes into the kubelet&amp;#39;s configuration file&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;memorySwap&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;swapBehavior&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;UnlimitedSwap&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 available configuration options for &lt;code&gt;swapBehavior&lt;/code&gt; are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;UnlimitedSwap&lt;/code&gt; (default): Kubernetes workloads can use as much swap memory as they
request, up to the system limit.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;LimitedSwap&lt;/code&gt;: The utilization of swap memory by Kubernetes workloads is subject to limitations.
Only Pods of &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/concepts/workloads/pods/pod-qos/#burstable&#34;&gt;Burstable&lt;/a&gt; QoS are permitted to employ swap.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If configuration for &lt;code&gt;memorySwap&lt;/code&gt; is not specified and the feature gate is
enabled, by default the kubelet will apply the same behaviour as the
&lt;code&gt;UnlimitedSwap&lt;/code&gt; setting.&lt;/p&gt;
&lt;p&gt;Note that &lt;code&gt;NodeSwap&lt;/code&gt; is supported for &lt;strong&gt;cgroup v2&lt;/strong&gt; only. For Kubernetes v1.28,
using swap along with cgroup v1 is no longer supported.&lt;/p&gt;
&lt;h2 id=&#34;install-a-swap-enabled-cluster-with-kubeadm&#34;&gt;Install a swap-enabled cluster with kubeadm&lt;/h2&gt;
&lt;h3 id=&#34;before-you-begin&#34;&gt;Before you begin&lt;/h3&gt;
&lt;p&gt;It is required for this demo that the kubeadm tool be installed, following the steps outlined in the
&lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm&#34;&gt;kubeadm installation guide&lt;/a&gt;.
If swap is already enabled on the node, cluster creation may
proceed. If swap is not enabled, please refer to the provided instructions for enabling swap.&lt;/p&gt;
&lt;h3 id=&#34;create-a-swap-file-and-turn-swap-on&#34;&gt;Create a swap file and turn swap on&lt;/h3&gt;
&lt;p&gt;I&#39;ll demonstrate creating 4GiB of unencrypted swap.&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;dd &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;if&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;/dev/zero &lt;span style=&#34;color:#b8860b&#34;&gt;of&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;/swapfile &lt;span style=&#34;color:#b8860b&#34;&gt;bs&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;128M &lt;span style=&#34;color:#b8860b&#34;&gt;count&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;32&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;chmod &lt;span style=&#34;color:#666&#34;&gt;600&lt;/span&gt; /swapfile
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mkswap /swapfile
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;swapon /swapfile
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;swapon -s &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# enable the swap file only until this node is rebooted&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To start the swap file at boot time, add line like &lt;code&gt;/swapfile swap swap defaults 0 0&lt;/code&gt; to &lt;code&gt;/etc/fstab&lt;/code&gt; file.&lt;/p&gt;
&lt;h3 id=&#34;set-up-a-kubernetes-cluster-that-uses-swap-enabled-nodes&#34;&gt;Set up a Kubernetes cluster that uses swap-enabled nodes&lt;/h3&gt;
&lt;p&gt;To make things clearer, here is an example kubeadm configuration file &lt;code&gt;kubeadm-config.yaml&lt;/code&gt; for the swap enabled cluster.&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;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;kubeadm.k8s.io/v1beta3&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;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;InitConfiguration&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#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;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;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;failSwapOn&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;span style=&#34;display:flex;&#34;&gt;&lt;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;NodeSwap&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;memorySwap&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;swapBehavior&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;LimitedSwap&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 create a single-node cluster using &lt;code&gt;kubeadm init --config kubeadm-config.yaml&lt;/code&gt;.
During init, there is a warning that swap is enabled on the node and in case the kubelet
&lt;code&gt;failSwapOn&lt;/code&gt; is set to true. We plan to remove this warning in a future release.&lt;/p&gt;
&lt;h2 id=&#34;how-is-the-swap-limit-being-determined-with-limitedswap&#34;&gt;How is the swap limit being determined with LimitedSwap?&lt;/h2&gt;
&lt;p&gt;The configuration of swap memory, including its limitations, presents a significant
challenge. Not only is it prone to misconfiguration, but as a system-level property, any
misconfiguration could potentially compromise the entire node rather than just a specific
workload. To mitigate this risk and ensure the health of the node, we have implemented
Swap in Beta with automatic configuration of limitations.&lt;/p&gt;
&lt;p&gt;With &lt;code&gt;LimitedSwap&lt;/code&gt;, Pods that do not fall under the Burstable QoS classification (i.e.
&lt;code&gt;BestEffort&lt;/code&gt;/&lt;code&gt;Guaranteed&lt;/code&gt; Qos Pods) are prohibited from utilizing swap memory.
&lt;code&gt;BestEffort&lt;/code&gt; QoS Pods exhibit unpredictable memory consumption patterns and lack
information regarding their memory usage, making it difficult to determine a safe
allocation of swap memory. Conversely, &lt;code&gt;Guaranteed&lt;/code&gt; QoS Pods are typically employed for
applications that rely on the precise allocation of resources specified by the workload,
with memory being immediately available. To maintain the aforementioned security and node
health guarantees, these Pods are not permitted to use swap memory when &lt;code&gt;LimitedSwap&lt;/code&gt; is
in effect.&lt;/p&gt;
&lt;p&gt;Prior to detailing the calculation of the swap limit, it is necessary to define the following terms:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;nodeTotalMemory&lt;/code&gt;: The total amount of physical memory available on the node.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;totalPodsSwapAvailable&lt;/code&gt;: The total amount of swap memory on the node that is available for use by Pods (some swap memory may be reserved for system use).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;containerMemoryRequest&lt;/code&gt;: The container&#39;s memory request.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Swap limitation is configured as:
&lt;code&gt;(containerMemoryRequest / nodeTotalMemory) × totalPodsSwapAvailable&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;In other words, the amount of swap that a container is able to use is proportionate to its
memory request, the node&#39;s total physical memory and the total amount of swap memory on
the node that is available for use by Pods.&lt;/p&gt;
&lt;p&gt;It is important to note that, for containers within Burstable QoS Pods, it is possible to
opt-out of swap usage by specifying memory requests that are equal to memory limits.
Containers configured in this manner will not have access to swap memory.&lt;/p&gt;
&lt;h2 id=&#34;how-does-it-work&#34;&gt;How does it work?&lt;/h2&gt;
&lt;p&gt;There are a number of possible ways that one could envision swap use on a node.
When swap is already provisioned and available on a node,
SIG Node have &lt;a href=&#34;https://github.com/kubernetes/enhancements/blob/9d127347773ad19894ca488ee04f1cd3af5774fc/keps/sig-node/2400-node-swap/README.md#proposal&#34;&gt;proposed&lt;/a&gt;
the kubelet should be able to be configured so that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It can start with swap on.&lt;/li&gt;
&lt;li&gt;It will direct the Container Runtime Interface to allocate zero swap memory
to Kubernetes workloads by default.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Swap configuration on a node is exposed to a cluster admin via the
&lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/reference/config-api/kubelet-config.v1&#34;&gt;&lt;code&gt;memorySwap&lt;/code&gt; in the KubeletConfiguration&lt;/a&gt;.
As a cluster administrator, you can specify the node&#39;s behaviour in the
presence of swap memory by setting &lt;code&gt;memorySwap.swapBehavior&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The kubelet &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/concepts/architecture/cri/&#34;&gt;employs the CRI&lt;/a&gt;
(container runtime interface) API to direct the CRI to
configure specific cgroup v2 parameters (such as &lt;code&gt;memory.swap.max&lt;/code&gt;) in a manner that will
enable the desired swap configuration for a container. The CRI is then responsible to
write these settings to the container-level cgroup.&lt;/p&gt;
&lt;h2 id=&#34;how-can-i-monitor-swap&#34;&gt;How can I monitor swap?&lt;/h2&gt;
&lt;p&gt;A notable deficiency in the Alpha version was the inability to monitor and introspect swap
usage. This issue has been addressed in the Beta version introduced in Kubernetes 1.28, which now
provides the capability to monitor swap usage through several different methods.&lt;/p&gt;
&lt;p&gt;The beta version of kubelet now collects
&lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/reference/instrumentation/node-metrics/&#34;&gt;node-level metric statistics&lt;/a&gt;,
which can be accessed at the &lt;code&gt;/metrics/resource&lt;/code&gt; and &lt;code&gt;/stats/summary&lt;/code&gt; kubelet HTTP endpoints.
This allows clients who can directly interrogate the kubelet to
monitor swap usage and remaining swap memory when using LimitedSwap. Additionally, a
&lt;code&gt;machine_swap_bytes&lt;/code&gt; metric has been added to cadvisor to show the total physical swap capacity of the
machine.&lt;/p&gt;
&lt;h2 id=&#34;caveats&#34;&gt;Caveats&lt;/h2&gt;
&lt;p&gt;Having swap available on a system reduces predictability. Swap&#39;s performance is
worse than regular memory, sometimes by many orders of magnitude, which can
cause unexpected performance regressions. Furthermore, swap changes a system&#39;s
behaviour under memory pressure. Since enabling swap permits
greater memory usage for workloads in Kubernetes that cannot be predictably
accounted for, it also increases the risk of noisy neighbours and unexpected
packing configurations, as the scheduler cannot account for swap memory usage.&lt;/p&gt;
&lt;p&gt;The performance of a node with swap memory enabled depends on the underlying
physical storage. When swap memory is in use, performance will be significantly
worse in an I/O operations per second (IOPS) constrained environment, such as a
cloud VM with I/O throttling, when compared to faster storage mediums like
solid-state drives or NVMe.&lt;/p&gt;
&lt;p&gt;As such, we do not advocate the utilization of swap memory for workloads or
environments that are subject to performance constraints. Furthermore, it is
recommended to employ &lt;code&gt;LimitedSwap&lt;/code&gt;, as this significantly mitigates the risks
posed to the node.&lt;/p&gt;
&lt;p&gt;Cluster administrators and developers should benchmark their nodes and applications
before using swap in production scenarios, and &lt;a href=&#34;#how-do-i-get-involved&#34;&gt;we need your help&lt;/a&gt; with that!&lt;/p&gt;
&lt;h3 id=&#34;security-risk&#34;&gt;Security risk&lt;/h3&gt;
&lt;p&gt;Enabling swap on a system without encryption poses a security risk, as critical information,
such as volumes that represent Kubernetes Secrets, &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/concepts/configuration/secret/#information-security-for-secrets&#34;&gt;may be swapped out to the disk&lt;/a&gt;.
If an unauthorized individual gains
access to the disk, they could potentially obtain these confidential data. To mitigate this risk, the
Kubernetes project strongly recommends that you encrypt your swap space.
However, handling encrypted swap is not within the scope of
kubelet; rather, it is a general OS configuration concern and should be addressed at that level.
It is the administrator&#39;s responsibility to provision encrypted swap to mitigate this risk.&lt;/p&gt;
&lt;p&gt;Furthermore, as previously mentioned, with &lt;code&gt;LimitedSwap&lt;/code&gt; the user has the option to completely
disable swap usage for a container by specifying memory requests that are equal to memory limits.
This will prevent the corresponding containers from accessing swap memory.&lt;/p&gt;
&lt;h2 id=&#34;looking-ahead&#34;&gt;Looking ahead&lt;/h2&gt;
&lt;p&gt;The Kubernetes 1.28 release introduced Beta support for swap memory on Linux nodes,
and we will continue to work towards &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/reference/command-line-tools-reference/feature-gates/#feature-stages&#34;&gt;general availability&lt;/a&gt;
for this feature. I hope that this will include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add the ability to set a system-reserved quantity of swap from what kubelet detects on the host.&lt;/li&gt;
&lt;li&gt;Adding support for controlling swap consumption at the Pod level via cgroups.
&lt;ul&gt;
&lt;li&gt;This point is still under discussion.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Collecting feedback from test user cases.
&lt;ul&gt;
&lt;li&gt;We will consider introducing new configuration modes for swap, such as a
node-wide swap limit for workloads.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;how-can-i-learn-more&#34;&gt;How can I learn more?&lt;/h2&gt;
&lt;p&gt;You can review the current &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/concepts/architecture/nodes/#swap-memory&#34;&gt;documentation&lt;/a&gt;
for using swap with Kubernetes.&lt;/p&gt;
&lt;p&gt;For more information, and to assist with testing and provide feedback, please
see &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/4128&#34;&gt;KEP-2400&lt;/a&gt; and its
&lt;a href=&#34;https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/2400-node-swap/README.md&#34;&gt;design proposal&lt;/a&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;Your feedback is always welcome! SIG Node &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-node#meetings&#34;&gt;meets regularly&lt;/a&gt;
and &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-node#contact&#34;&gt;can be reached&lt;/a&gt;
via &lt;a href=&#34;https://slack.k8s.io/&#34;&gt;Slack&lt;/a&gt; (channel &lt;strong&gt;#sig-node&lt;/strong&gt;), or the SIG&#39;s
&lt;a href=&#34;https://groups.google.com/forum/#!forum/kubernetes-sig-node&#34;&gt;mailing list&lt;/a&gt;. A Slack
channel dedicated to swap is also available at &lt;strong&gt;#sig-node-swap&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Feel free to reach out to me, Itamar Holder (&lt;strong&gt;@iholder101&lt;/strong&gt; on Slack and GitHub)
if you&#39;d like to help or ask further questions.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes 1.28: Node podresources API Graduates to GA</title>
      <link>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/08/23/kubelet-podresources-api-ga/</link>
      <pubDate>Wed, 23 Aug 2023 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/08/23/kubelet-podresources-api-ga/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Author:&lt;/strong&gt; Francesco Romani (Red Hat)&lt;/p&gt;
&lt;p&gt;The podresources API is an API served by the kubelet locally on the node, which exposes the compute resources exclusively
allocated to containers. With the release of Kubernetes 1.28, that API is now Generally Available.&lt;/p&gt;
&lt;h2 id=&#34;what-problem-does-it-solve&#34;&gt;What problem does it solve?&lt;/h2&gt;
&lt;p&gt;The kubelet can allocate exclusive resources to containers, like
&lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/tasks/administer-cluster/cpu-management-policies/&#34;&gt;CPUs, granting exclusive access to full cores&lt;/a&gt;
or &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/tasks/administer-cluster/memory-manager/&#34;&gt;memory, either regions or hugepages&lt;/a&gt;.
Workloads which require high performance, or low latency (or both) leverage these features.
The kubelet also can assign &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins/&#34;&gt;devices to containers&lt;/a&gt;.
Collectively, these features which enable exclusive assignments are known as &amp;quot;resource managers&amp;quot;.&lt;/p&gt;
&lt;p&gt;Without an API like podresources, the only possible option to learn about resource assignment was to read the state files the
resource managers use. While done out of necessity, the problem with this approach is the path and the format of these file are
both internal implementation details. Albeit very stable, the project reserves the right to change them freely.
Consuming the content of the state files is thus fragile and unsupported, and projects doing this are recommended to consider
moving to podresources API or to other supported APIs.&lt;/p&gt;
&lt;h2 id=&#34;overview-of-the-api&#34;&gt;Overview of the API&lt;/h2&gt;
&lt;p&gt;The podresources API was &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins/#monitoring-device-plugin-resources&#34;&gt;initially proposed to enable device monitoring&lt;/a&gt;.
In order to enable monitoring agents, a key prerequisite is to enable introspection of device assignment, which is performed by the kubelet.
Serving this purpose was the initial goal of the API. The first iteration of the API only had a single function implemented, &lt;code&gt;List&lt;/code&gt;,
to  return information about the assignment of devices to containers.
The API is used by &lt;a href=&#34;https://github.com/k8snetworkplumbingwg/multus-cni&#34;&gt;multus CNI&lt;/a&gt; and by
&lt;a href=&#34;https://github.com/NVIDIA/dcgm-exporter&#34;&gt;GPU monitoring tools&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Since its inception, the podresources API increased its scope to cover other resource managers than device manager.
Starting from Kubernetes 1.20, the &lt;code&gt;List&lt;/code&gt; API reports also CPU cores and memory regions (including hugepages); the API also
reports the NUMA locality of the devices, while the locality of CPUs and memory can be inferred from the system.&lt;/p&gt;
&lt;p&gt;In Kubernetes 1.21, the API &lt;a href=&#34;https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/2403-pod-resources-allocatable-resources/README.md&#34;&gt;gained&lt;/a&gt;
the &lt;code&gt;GetAllocatableResources&lt;/code&gt; function.
This newer API complements the existing &lt;code&gt;List&lt;/code&gt; API and enables monitoring agents to determine the unallocated resources,
thus enabling new features built on top of the podresources API like a
&lt;a href=&#34;https://github.com/kubernetes-sigs/scheduler-plugins/blob/master/pkg/noderesourcetopology/README.md&#34;&gt;NUMA-aware scheduler plugin&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Finally, in Kubernetes 1.27, another function, &lt;code&gt;Get&lt;/code&gt; was introduced to be more friendly with CNI meta-plugins, to make it simpler to access resources
allocated to a specific pod, rather than having to filter through resources for all pods on the node. The &lt;code&gt;Get&lt;/code&gt; function is currently alpha level.&lt;/p&gt;
&lt;h2 id=&#34;consuming-the-api&#34;&gt;Consuming the API&lt;/h2&gt;
&lt;p&gt;The podresources API is served by the kubelet locally, on the same node on which is running.
On unix flavors, the endpoint is served over a unix domain socket; the default path is &lt;code&gt;/var/lib/kubelet/pod-resources/kubelet.sock&lt;/code&gt;.
On windows, the endpoint is served over a named pipe; the default path is &lt;code&gt;npipe://\\.\pipe\kubelet-pod-resources&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In order for the containerized monitoring application consume the API, the socket should be mounted inside the container.
A good practice is to mount the directory on which the podresources socket endpoint sits rather than the socket directly.
This will ensure that after a kubelet restart, the containerized monitor application will be able to re-connect to the socket.&lt;/p&gt;
&lt;p&gt;An example manifest for a hypothetical monitoring agent consuming the podresources API and deployed as a DaemonSet could look 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;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;DaemonSet&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;podresources-monitoring-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;namespace&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;monitoring&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;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;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;podresources-monitoring&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;template&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;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;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;podresources-monitoring&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;args&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;- --podresources-socket=unix:///host-podresources/kubelet.sock&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;- /bin/podresources-monitor&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;podresources-monitor:latest &lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# just for an example&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;mountPath&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;/host-podresources&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;host-podresources&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;serviceAccountName&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;podresources-monitor&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;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;/var/lib/kubelet/pod-resources&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;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;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;host-podresources&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;I hope you find it straightforward to consume the podresources API  programmatically.
The kubelet API package provides the protocol file and the go type definitions; however, a client package is not yet available from the project,
and the existing code should not be used directly.
The &lt;a href=&#34;https://github.com/kubernetes/kubernetes/blob/v1.28.0-rc.0/pkg/kubelet/apis/podresources/client.go#L32&#34;&gt;recommended&lt;/a&gt;
approach is to reimplement the client in your projects, copying and pasting the related functions like for example
the multus project is &lt;a href=&#34;https://github.com/k8snetworkplumbingwg/multus-cni/blob/v4.0.2/pkg/kubeletclient/kubeletclient.go&#34;&gt;doing&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;When operating the containerized monitoring application consuming the podresources API, few points are worth highlighting to prevent &amp;quot;gotcha&amp;quot; moments:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Even though the API only exposes data, and doesn&#39;t allow by design clients to mutate the kubelet state, the gRPC request/response model requires
read-write access to the podresources API socket. In other words, it is not possible to limit the container mount to &lt;code&gt;ReadOnly&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Multiple clients are allowed to connect to the podresources socket and consume the API, since it is stateless.&lt;/li&gt;
&lt;li&gt;The kubelet has &lt;a href=&#34;https://github.com/kubernetes/kubernetes/pull/116459&#34;&gt;built-in rate limits&lt;/a&gt; to mitigate local Denial of Service attacks from
misbehaving or malicious consumers. The consumers of the API must tolerate rate limit errors returned by the server. The rate limit is currently
hardcoded and global, so misbehaving clients can consume all the quota and potentially starve correctly behaving clients.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;future-enhancements&#34;&gt;Future enhancements&lt;/h2&gt;
&lt;p&gt;For historical reasons, the podresources API has a less precise specification than typical kubernetes APIs (such as the Kubernetes HTTP API, or the container runtime interface).
This leads to unspecified behavior in corner cases.
An &lt;a href=&#34;https://issues.k8s.io/119423&#34;&gt;effort&lt;/a&gt; is ongoing to rectify this state and to have a more precise specification.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&#34;https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/3063-dynamic-resource-allocation&#34;&gt;Dynamic Resource Allocation (DRA)&lt;/a&gt; infrastructure
is a major overhaul of the resource management.
The &lt;a href=&#34;https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/3695-pod-resources-for-dra&#34;&gt;integration&lt;/a&gt; with the podresources API
is already ongoing.&lt;/p&gt;
&lt;p&gt;An &lt;a href=&#34;https://issues.k8s.io/119817&#34;&gt;effort&lt;/a&gt; is ongoing to recommend or create a reference client package ready to be consumed.&lt;/p&gt;
&lt;h2 id=&#34;getting-involved&#34;&gt;Getting involved&lt;/h2&gt;
&lt;p&gt;This feature is driven by &lt;a href=&#34;https://github.com/Kubernetes/community/blob/master/sig-node/README.md&#34;&gt;SIG Node&lt;/a&gt;.
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.28: Improved failure handling for Jobs</title>
      <link>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/08/21/kubernetes-1-28-jobapi-update/</link>
      <pubDate>Mon, 21 Aug 2023 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/08/21/kubernetes-1-28-jobapi-update/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Authors:&lt;/strong&gt; Kevin Hannon (G-Research), Michał Woźniak (Google)&lt;/p&gt;
&lt;p&gt;This blog discusses two new features in Kubernetes 1.28 to improve Jobs for batch
users: &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/concepts/workloads/controllers/job/#pod-replacement-policy&#34;&gt;Pod replacement policy&lt;/a&gt;
and &lt;a href=&#34;https://deploy-preview-57407--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;/p&gt;
&lt;p&gt;These features continue the effort started by the
&lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/concepts/workloads/controllers/job/#pod-failure-policy&#34;&gt;Pod failure policy&lt;/a&gt;
to improve the handling of Pod failures in a Job.&lt;/p&gt;
&lt;h2 id=&#34;pod-replacement-policy&#34;&gt;Pod replacement policy&lt;/h2&gt;
&lt;p&gt;By default, when a pod enters a terminating state (e.g. due to preemption or
eviction), Kubernetes immediately creates a replacement Pod. Therefore, both Pods are running
at the same time. In API terms, a pod is considered terminating when it has a
&lt;code&gt;deletionTimestamp&lt;/code&gt; and it has a phase &lt;code&gt;Pending&lt;/code&gt; or &lt;code&gt;Running&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The scenario when two Pods are running at a given time is problematic for
some popular machine learning frameworks, such as
TensorFlow and &lt;a href=&#34;https://jax.readthedocs.io/en/latest/&#34;&gt;JAX&lt;/a&gt;, which require at most one Pod running at the same time,
for a given index.
Tensorflow gives the following error if two pods are running for a given index.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt; /job:worker/task:4: Duplicate task registration with task_name=/job:worker/replica:0/task:4
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;See more details in the (&lt;a href=&#34;https://github.com/kubernetes/kubernetes/issues/115844&#34;&gt;issue&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Creating the replacement Pod before the previous one fully terminates can also
cause problems in clusters with scarce resources or with tight budgets, such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;cluster resources can be difficult to obtain for Pods pending to be scheduled,
as Kubernetes might take a long time to find available nodes until the existing
Pods are fully terminated.&lt;/li&gt;
&lt;li&gt;if cluster autoscaler is enabled, the replacement Pods might produce undesired
scale ups.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;pod-replacement-policy-how-to-use&#34;&gt;How can you use it?&lt;/h3&gt;
&lt;p&gt;This is an alpha feature, which you can enable by turning on &lt;code&gt;JobPodReplacementPolicy&lt;/code&gt;
&lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/reference/command-line-tools-reference/feature-gates/&#34;&gt;feature gate&lt;/a&gt; in
your cluster.&lt;/p&gt;
&lt;p&gt;Once the feature is enabled in your cluster, you can use it by creating a new Job that specifies a
&lt;code&gt;podReplacementPolicy&lt;/code&gt; field as shown here:&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;Job&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;new&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#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;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;podReplacementPolicy&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Failed&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#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;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In that Job, the Pods would only be replaced once they reached the &lt;code&gt;Failed&lt;/code&gt; phase,
and not when they are terminating.&lt;/p&gt;
&lt;p&gt;Additionally, you can inspect the &lt;code&gt;.status.terminating&lt;/code&gt; field of a Job. The value
of the field is the number of Pods owned by the Job that are currently terminating.&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 jobs/myjob -o&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;jsonpath&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;{.items[*].status.terminating}&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;3 # three Pods are terminating and have not yet reached the Failed phase
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This can be particularly useful for external queueing controllers, such as
&lt;a href=&#34;https://github.com/kubernetes-sigs/kueue&#34;&gt;Kueue&lt;/a&gt;, that tracks quota
from running Pods of a Job until the resources are reclaimed from
the currently terminating Job.&lt;/p&gt;
&lt;p&gt;Note that the &lt;code&gt;podReplacementPolicy: Failed&lt;/code&gt; is the default when using a custom
&lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/concepts/workloads/controllers/job/#pod-failure-policy&#34;&gt;Pod failure policy&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;backoff-limit-per-index&#34;&gt;Backoff limit per index&lt;/h2&gt;
&lt;p&gt;By default, Pod failures for &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/concepts/workloads/controllers/job/#completion-mode&#34;&gt;Indexed Jobs&lt;/a&gt;
are counted towards the global limit of retries, represented by &lt;code&gt;.spec.backoffLimit&lt;/code&gt;.
This means, that if there is a consistently failing index, it is restarted
repeatedly until it exhausts the limit. Once the limit is reached the entire
Job is marked failed and some indexes may never be even started.&lt;/p&gt;
&lt;p&gt;This is problematic for use cases where you want to handle Pod failures for
every index independently. For example, if you use Indexed Jobs for running
integration tests where each index corresponds to a testing suite. In that case,
you may want to account for possible flake tests allowing for 1 or 2 retries per
suite. There might be some buggy suites, making the corresponding
indexes fail consistently. In that case you may prefer to limit retries for
the buggy suites, yet allowing other suites to complete.&lt;/p&gt;
&lt;p&gt;The feature allows you to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;complete execution of all indexes, despite some indexes failing.&lt;/li&gt;
&lt;li&gt;better utilize the computational resources by avoiding unnecessary retries of consistently failing indexes.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;backoff-limit-per-index-how-to-use&#34;&gt;How can you use it?&lt;/h3&gt;
&lt;p&gt;This is an alpha feature, which you can enable by turning on the
&lt;code&gt;JobBackoffLimitPerIndex&lt;/code&gt;
&lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/reference/command-line-tools-reference/feature-gates/&#34;&gt;feature gate&lt;/a&gt;
in your cluster.&lt;/p&gt;
&lt;p&gt;Once the feature is enabled in your cluster, you can create an Indexed Job with the
&lt;code&gt;.spec.backoffLimitPerIndex&lt;/code&gt; field specified.&lt;/p&gt;
&lt;h4 id=&#34;example&#34;&gt;Example&lt;/h4&gt;
&lt;p&gt;The following example demonstrates how to use this feature to make sure the
Job executes all indexes (provided there is no other reason for the early Job
termination, such as reaching the &lt;code&gt;activeDeadlineSeconds&lt;/code&gt; timeout, or being
manually deleted by the user), and the number of failures is controlled per index.&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;batch/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;Job&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;job-backoff-limit-per-index-execute-all&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;completions&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;8&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;parallelism&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;completionMode&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Indexed&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;backoffLimitPerIndex&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;template&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;restartPolicy&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Never&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# this example container returns an error, and fails,&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#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;# when it is run as the second or third index in any Job&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#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;# (even after a 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;image&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;python&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;- python3&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;- -c&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#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;          import os, sys, time
&lt;/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;          id = int(os.environ.get(&amp;#34;JOB_COMPLETION_INDEX&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;          if id == 1 or id == 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:#b44;font-style:italic&#34;&gt;            sys.exit(1)
&lt;/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;          time.sleep(1)&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;Now, inspect the Pods after the job is finished:&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-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kubectl get pods -l job-name&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;job-backoff-limit-per-index-execute-all
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Returns output similar to this:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;NAME                                              READY   STATUS      RESTARTS   AGE
job-backoff-limit-per-index-execute-all-0-b26vc   0/1     Completed   0          49s
job-backoff-limit-per-index-execute-all-1-6j5gd   0/1     Error       0          49s
job-backoff-limit-per-index-execute-all-1-6wd82   0/1     Error       0          37s
job-backoff-limit-per-index-execute-all-2-c66hg   0/1     Error       0          32s
job-backoff-limit-per-index-execute-all-2-nf982   0/1     Error       0          43s
job-backoff-limit-per-index-execute-all-3-cxmhf   0/1     Completed   0          33s
job-backoff-limit-per-index-execute-all-4-9q6kq   0/1     Completed   0          28s
job-backoff-limit-per-index-execute-all-5-z9hqf   0/1     Completed   0          28s
job-backoff-limit-per-index-execute-all-6-tbkr8   0/1     Completed   0          23s
job-backoff-limit-per-index-execute-all-7-hxjsq   0/1     Completed   0          22s
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Additionally, you can take a look at the status for that Job:&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-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kubectl get &lt;span style=&#34;color:#a2f&#34;&gt;jobs&lt;/span&gt; job-backoff-limit-per-index-fail-index -o yaml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The output ends with a &lt;code&gt;status&lt;/code&gt; similar to:&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:#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;completedIndexes&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;0&lt;/span&gt;,&lt;span style=&#34;color:#666&#34;&gt;3-7&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;failedIndexes&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:#666&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;succeeded&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;6&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;failed&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;4&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;conditions&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;Job has failed indexes&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;reason&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;FailedIndexes&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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 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;type&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Failed&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;Here, indexes &lt;code&gt;1&lt;/code&gt;  and &lt;code&gt;2&lt;/code&gt; were both retried once. After the second failure,
in each of them, the specified &lt;code&gt;.spec.backoffLimitPerIndex&lt;/code&gt; was exceeded, so
the retries were stopped. For comparison, if the per-index backoff was disabled,
then the buggy indexes would retry until the global &lt;code&gt;backoffLimit&lt;/code&gt; was exceeded,
and then the entire Job would be marked failed, before some of the higher
indexes are started.&lt;/p&gt;
&lt;h2 id=&#34;how-can-you-learn-more&#34;&gt;How can you learn more?&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Read the user-facing documentation for &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/concepts/workloads/controllers/job/#pod-replacement-policy&#34;&gt;Pod replacement policy&lt;/a&gt;,
&lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/concepts/workloads/controllers/job/#backoff-limit-per-index&#34;&gt;Backoff limit per index&lt;/a&gt;, and
&lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/concepts/workloads/controllers/job/#pod-failure-policy&#34;&gt;Pod failure policy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Read the KEPs for &lt;a href=&#34;https://github.com/kubernetes/enhancements/tree/master/keps/sig-apps/3939-allow-replacement-when-fully-terminated&#34;&gt;Pod Replacement Policy&lt;/a&gt;,
&lt;a href=&#34;https://github.com/kubernetes/enhancements/tree/master/keps/sig-apps/3850-backoff-limits-per-index-for-indexed-jobs&#34;&gt;Backoff limit per index&lt;/a&gt;, and
&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;getting-involved&#34;&gt;Getting Involved&lt;/h2&gt;
&lt;p&gt;These features were sponsored by &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-apps&#34;&gt;SIG Apps&lt;/a&gt;.  Batch use cases are actively
being improved for Kubernetes users in the
&lt;a href=&#34;https://github.com/kubernetes/community/tree/master/wg-batch&#34;&gt;batch working group&lt;/a&gt;.
Working groups are relatively short-lived initiatives focused on specific goals.
The goal of the WG Batch is to improve experience for batch workload users, offer support for
batch processing use cases, and enhance the
Job API for common use cases.  If that interests you, please join the working
group either by subscriping to our
&lt;a href=&#34;https://groups.google.com/a/kubernetes.io/g/wg-batch&#34;&gt;mailing list&lt;/a&gt; or on
&lt;a href=&#34;https://kubernetes.slack.com/messages/wg-batch&#34;&gt;Slack&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;acknowledgments&#34;&gt;Acknowledgments&lt;/h2&gt;
&lt;p&gt;As with any Kubernetes feature, multiple people contributed to getting this
done, from testing and filing bugs to reviewing code.&lt;/p&gt;
&lt;p&gt;We would not have been able to achieve either of these features without Aldo
Culquicondor (Google) providing excellent domain knowledge and expertise
throughout the Kubernetes ecosystem.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes v1.28: Retroactive Default StorageClass move to GA</title>
      <link>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/08/18/retroactive-default-storage-class-ga/</link>
      <pubDate>Fri, 18 Aug 2023 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/08/18/retroactive-default-storage-class-ga/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Author:&lt;/strong&gt; Roman Bednář (Red Hat)&lt;/p&gt;
&lt;p&gt;Announcing graduation to General Availability (GA) - Retroactive Default StorageClass Assignment in Kubernetes v1.28!&lt;/p&gt;
&lt;p&gt;Kubernetes SIG Storage team is thrilled to announce that the &amp;quot;Retroactive Default StorageClass Assignment&amp;quot; feature,
introduced as an alpha in Kubernetes v1.25, has now graduated to GA and is officially part of the Kubernetes v1.28 release.
This enhancement brings a significant improvement to how default
&lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/concepts/storage/storage-classes/&#34;&gt;StorageClasses&lt;/a&gt; are assigned to PersistentVolumeClaims (PVCs).&lt;/p&gt;
&lt;p&gt;With this feature enabled, you no longer need to create a default StorageClass first and then a PVC to assign the class.
Instead, any PVCs without a StorageClass assigned will now be retroactively updated to include the default StorageClass.
This enhancement ensures that PVCs no longer get stuck in an unbound state, and storage provisioning works seamlessly,
even when a default StorageClass is not defined at the time of PVC creation.&lt;/p&gt;
&lt;h2 id=&#34;what-changed&#34;&gt;What changed?&lt;/h2&gt;
&lt;p&gt;The PersistentVolume (PV) controller has been modified to automatically assign a default StorageClass to any unbound
PersistentVolumeClaim with the &lt;code&gt;storageClassName&lt;/code&gt; not set. Additionally, the PersistentVolumeClaim
admission validation mechanism within
the API server has been adjusted to allow changing values from an unset state to an actual StorageClass name.&lt;/p&gt;
&lt;h2 id=&#34;how-to-use-it&#34;&gt;How to use it?&lt;/h2&gt;
&lt;p&gt;As this feature has graduated to GA, there&#39;s no need to enable a feature gate anymore.
Simply make sure you are running Kubernetes v1.28 or later, and the feature will be available for use.&lt;/p&gt;
&lt;p&gt;For more details, read about
&lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/concepts/storage/persistent-volumes/#retroactive-default-storageclass-assignment&#34;&gt;default StorageClass assignment&lt;/a&gt; in the Kubernetes documentation.
You can also read the previous &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/01/05/retroactive-default-storage-class/&#34;&gt;blog post&lt;/a&gt; announcing beta graduation in v1.26.&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 1.28: Non-Graceful Node Shutdown Moves to GA</title>
      <link>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/08/16/kubernetes-1-28-non-graceful-node-shutdown-ga/</link>
      <pubDate>Wed, 16 Aug 2023 10:00:00 -0800</pubDate>
      
      <guid>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/08/16/kubernetes-1-28-non-graceful-node-shutdown-ga/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Authors:&lt;/strong&gt; Xing Yang (VMware) and Ashutosh Kumar (Elastic)&lt;/p&gt;
&lt;p&gt;The Kubernetes Non-Graceful Node Shutdown feature is now GA in Kubernetes v1.28.
It was introduced as
&lt;a href=&#34;https://github.com/kubernetes/enhancements/tree/master/keps/sig-storage/2268-non-graceful-shutdown&#34;&gt;alpha&lt;/a&gt;
in Kubernetes v1.24, and promoted to
&lt;a href=&#34;https://kubernetes.io/blog/2022/12/16/kubernetes-1-26-non-graceful-node-shutdown-beta/&#34;&gt;beta&lt;/a&gt;
in Kubernetes v1.26.
This feature allows stateful workloads to restart on a different node if the
original node is shutdown unexpectedly or ends up in a non-recoverable state
such as the hardware failure or unresponsive OS.&lt;/p&gt;
&lt;h2 id=&#34;what-is-a-non-graceful-node-shutdown&#34;&gt;What is a Non-Graceful Node Shutdown&lt;/h2&gt;
&lt;p&gt;In a Kubernetes cluster, a node can be shutdown in a planned graceful way or
unexpectedly because of reasons such as power outage or something else external.
A node shutdown could lead to workload failure if the node is not drained
before the shutdown. A node shutdown can be either graceful or non-graceful.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&#34;https://kubernetes.io/blog/2021/04/21/graceful-node-shutdown-beta/&#34;&gt;Graceful Node Shutdown&lt;/a&gt;
feature allows Kubelet to detect a node shutdown event, properly terminate the pods,
and release resources, before the actual shutdown.&lt;/p&gt;
&lt;p&gt;When a node is shutdown but not detected by Kubelet&#39;s Node Shutdown Manager,
this becomes a non-graceful node shutdown.
Non-graceful node shutdown is usually not a problem for stateless apps, however,
it is a problem for stateful apps.
The stateful application cannot function properly if the pods are stuck on the
shutdown node and are not restarting on a running node.&lt;/p&gt;
&lt;p&gt;In the case of a non-graceful node shutdown, you can manually add an &lt;code&gt;out-of-service&lt;/code&gt; taint on the Node.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;kubectl taint nodes &amp;lt;node-name&amp;gt; node.kubernetes.io/out-of-service=nodeshutdown:NoExecute
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This taint triggers pods on the node to be forcefully deleted if there are no
matching tolerations on the pods. Persistent volumes attached to the shutdown node
will be detached, and new pods will be created successfully on a different running
node.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Before applying the out-of-service taint, you must verify that a node is
already in shutdown or power-off state (not in the middle of restarting).&lt;/p&gt;
&lt;p&gt;Once all the workload pods that are linked to the out-of-service node are moved to
a new running node, and the shutdown node has been recovered, you should remove that
taint on the affected node after the node is recovered.&lt;/p&gt;
&lt;h2 id=&#34;what-s-new-in-stable&#34;&gt;What’s new in stable&lt;/h2&gt;
&lt;p&gt;With the promotion of the Non-Graceful Node Shutdown feature to stable, the
feature gate  &lt;code&gt;NodeOutOfServiceVolumeDetach&lt;/code&gt; is locked to true on
&lt;code&gt;kube-controller-manager&lt;/code&gt; and cannot be disabled.&lt;/p&gt;
&lt;p&gt;Metrics &lt;code&gt;force_delete_pods_total&lt;/code&gt; and &lt;code&gt;force_delete_pod_errors_total&lt;/code&gt; in the
Pod GC Controller are enhanced to account for all forceful pods deletion.
A reason is added to the metric to indicate whether the pod is forcefully deleted
because it is terminated, orphaned, terminating with the &lt;code&gt;out-of-service&lt;/code&gt; taint,
or terminating and unscheduled.&lt;/p&gt;
&lt;p&gt;A &amp;quot;reason&amp;quot; is also added to the metric &lt;code&gt;attachdetach_controller_forced_detaches&lt;/code&gt;
in the Attach Detach Controller to indicate whether the force detach is caused by
the &lt;code&gt;out-of-service&lt;/code&gt; taint or a timeout.&lt;/p&gt;
&lt;h2 id=&#34;what-s-next&#34;&gt;What’s next?&lt;/h2&gt;
&lt;p&gt;This feature requires a user to manually add a taint to the node to trigger
workloads failover and remove the taint after the node is recovered.
In the future, we plan to find ways to automatically detect and fence nodes
that are shutdown/failed and automatically failover workloads to another node.&lt;/p&gt;
&lt;h2 id=&#34;how-can-i-learn-more&#34;&gt;How can I learn more?&lt;/h2&gt;
&lt;p&gt;Check out additional documentation on this feature
&lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/concepts/architecture/nodes/#non-graceful-node-shutdown&#34;&gt;here&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;We offer a huge thank you to all the contributors who helped with design,
implementation, and review of this feature and helped move it from alpha, beta, to stable:&lt;/p&gt;
&lt;ul&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;Derek Carr (&lt;a href=&#34;https://github.com/derekwaynecarr&#34;&gt;derekwaynecarr&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Danielle Endocrimes (&lt;a href=&#34;https://github.com/endocrimes&#34;&gt;endocrimes&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;Tim Hockin  (&lt;a href=&#34;https://github.com/thockin&#34;&gt;thockin&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Ashutosh Kumar (&lt;a href=&#34;https://github.com/sonasingh46&#34;&gt;sonasingh46&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;Yuiko Mouri (&lt;a href=&#34;https://github.com/YuikoTakada&#34;&gt;YuikoTakada&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Mrunal Patel (&lt;a href=&#34;https://github.com/mrunalp&#34;&gt;mrunalp&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;David Porter (&lt;a href=&#34;https://github.com/bobbypage&#34;&gt;bobbypage&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Yassine Tijani (&lt;a href=&#34;https://github.com/yastij&#34;&gt;yastij&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Jing Xu (&lt;a href=&#34;https://github.com/jingxu97&#34;&gt;jingxu97&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Xing Yang (&lt;a href=&#34;https://github.com/xing-yang&#34;&gt;xing-yang&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This feature is a collaboration between SIG Storage and SIG Node.
For those interested in getting involved with the design and development of any
part of the Kubernetes Storage system, join the Kubernetes Storage Special
Interest Group (SIG).
For those interested in getting involved with the design and development of the
components that support the controlled interactions between pods and host
resources, join the Kubernetes Node SIG.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>pkgs.k8s.io: Introducing Kubernetes Community-Owned Package Repositories</title>
      <link>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/08/15/pkgs-k8s-io-introduction/</link>
      <pubDate>Tue, 15 Aug 2023 20:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/08/15/pkgs-k8s-io-introduction/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Author&lt;/strong&gt;: Marko Mudrinić (Kubermatic)&lt;/p&gt;
&lt;p&gt;On behalf of Kubernetes SIG Release, I am very excited to introduce the
Kubernetes community-owned software
repositories for Debian and RPM packages: &lt;code&gt;pkgs.k8s.io&lt;/code&gt;! The new package
repositories are replacement for the Google-hosted package repositories
(&lt;code&gt;apt.kubernetes.io&lt;/code&gt; and &lt;code&gt;yum.kubernetes.io&lt;/code&gt;) that we&#39;ve been using since
Kubernetes v1.5.&lt;/p&gt;
&lt;p&gt;This blog post contains information about these new package repositories,
what does it mean to you as an end user, and how to migrate to the new
repositories.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ℹ️  Update (August 31, 2023):&lt;/strong&gt; the &lt;em&gt;&lt;strong&gt;legacy Google-hosted repositories are deprecated
and will be frozen starting with September 13, 2023.&lt;/strong&gt;&lt;/em&gt;
Check out &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/08/31/legacy-package-repository-deprecation/&#34;&gt;the deprecation announcement&lt;/a&gt;
for more details about this change.&lt;/p&gt;
&lt;h2 id=&#34;what-you-need-to-know-about-the-new-package-repositories&#34;&gt;What you need to know about the new package repositories?&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;(updated on August 31, 2023)&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;This is an &lt;strong&gt;opt-in change&lt;/strong&gt;; you&#39;re required to manually migrate from the
Google-hosted repository to the Kubernetes community-owned repositories.
See &lt;a href=&#34;#how-to-migrate&#34;&gt;how to migrate&lt;/a&gt; later in this announcement for migration information
and instructions.&lt;/li&gt;
&lt;li&gt;The legacy Google-hosted repositories are &lt;strong&gt;deprecated as of August 31, 2023&lt;/strong&gt;,
and will be &lt;strong&gt;frozen approximately as of September 13, 2023&lt;/strong&gt;. The freeze will happen
immediately following the patch releases that are scheduled for September 2023.
Freezing the legacy repositories means that we will publish packages for the Kubernetes
project only to the community-owned repositories as of the September 13, 2023 cut-off point.
Check out the &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/08/31/legacy-package-repository-deprecation/&#34;&gt;deprecation announcement&lt;/a&gt;
for more details about this change.&lt;/li&gt;
&lt;li&gt;The existing packages in the legacy repositories will be available for the foreseeable future.
However, the Kubernetes project can&#39;t provide any guarantees on how long is that going to be.
The deprecated legacy repositories, and their contents, might be removed at any time in the future
and without a further notice period.&lt;/li&gt;
&lt;li&gt;Given that no new releases will be published to the legacy repositories after
the September 13, 2023 cut-off point, you will not be able to upgrade to any patch or minor
release made from that date onwards if you don&#39;t migrate to the new Kubernetes package repositories.
That said, we recommend migrating to the new Kubernetes package repositories &lt;strong&gt;as soon as possible&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;The new Kubernetes package repositories contain packages beginning with those
Kubernetes versions that were still under support when the community took
over the package builds. This means that anything before v1.24.0 will only be
available in the Google-hosted repository.&lt;/li&gt;
&lt;li&gt;There&#39;s a dedicated package repository for each Kubernetes minor version.
When upgrading to a different minor release, you must bear in mind that
the package repository details also change.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;why-are-we-introducing-new-package-repositories&#34;&gt;Why are we introducing new package repositories?&lt;/h2&gt;
&lt;p&gt;As the Kubernetes project is growing, we want to ensure the best possible
experience for the end users. The Google-hosted repository has been serving
us well for many years, but we started facing some problems that require
significant changes to how we publish packages. Another goal that we have is to
use community-owned infrastructure for all critical components and that
includes package repositories.&lt;/p&gt;
&lt;p&gt;Publishing packages to the Google-hosted repository is a manual process that
can be done only by a team of Google employees called
&lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/releases/release-managers/#build-admins&#34;&gt;Google Build Admins&lt;/a&gt;.
&lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/releases/release-managers/#release-managers&#34;&gt;The Kubernetes Release Managers team&lt;/a&gt;
is a very diverse team especially in terms of timezones that we work in.
Given this constraint, we have to do very careful planning for every release to
ensure that we have both Release Manager and Google Build Admin available to
carry out the release.&lt;/p&gt;
&lt;p&gt;Another problem is that we only have a single package repository. Because of
this, we were not able to publish packages for prerelease versions (alpha,
beta, and rc). This made testing Kubernetes prereleases harder for anyone who
is interested to do so. The feedback that we receive from people testing these
releases is critical to ensure the best quality of releases, so we want to make
testing these releases as easy as possible. On top of that, having only one
repository limited us when it comes to publishing dependencies like &lt;code&gt;cri-tools&lt;/code&gt;
and &lt;code&gt;kubernetes-cni&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Regardless of all these issues, we&#39;re very thankful to Google and Google Build
Admins for their involvement, support, and help all these years!&lt;/p&gt;
&lt;h2 id=&#34;how-the-new-package-repositories-work&#34;&gt;How the new package repositories work?&lt;/h2&gt;
&lt;p&gt;The new package repositories are hosted at &lt;code&gt;pkgs.k8s.io&lt;/code&gt; for both Debian and
RPM packages. At this time, this domain points to a CloudFront CDN backed by S3
bucket that contains repositories and packages. However, we plan on onboarding
additional mirrors in the future, giving possibility for other companies to
help us with serving packages.&lt;/p&gt;
&lt;p&gt;Packages are built and published via the &lt;a href=&#34;http://openbuildservice.org&#34;&gt;OpenBuildService (OBS) platform&lt;/a&gt;.
After a long period of evaluating different solutions, we made a decision to
use OpenBuildService as a platform to manage our repositories and packages.
First of all, OpenBuildService is an open source platform used by a large
number of open source projects and companies, like openSUSE, VideoLAN,
Dell, Intel, and more. OpenBuildService has many features making it very
flexible and easy to integrate with our existing release tooling. It also
allows us to build packages in a similar way as for the Google-hosted
repository making the migration process as seamless as possible.&lt;/p&gt;
&lt;p&gt;SUSE sponsors the Kubernetes project with access to their reference
OpenBuildService setup (&lt;a href=&#34;http://build.opensuse.org&#34;&gt;&lt;code&gt;build.opensuse.org&lt;/code&gt;&lt;/a&gt;) and
with technical support to integrate OBS with our release processes.&lt;/p&gt;
&lt;p&gt;We use SUSE&#39;s OBS instance for building and publishing packages. Upon building
a new release, our tooling automatically pushes needed artifacts and
package specifications to &lt;code&gt;build.opensuse.org&lt;/code&gt;. That will trigger the build
process that&#39;s going to build packages for all supported architectures (AMD64,
ARM64, PPC64LE, S390X). At the end, generated packages will be automatically
pushed to our community-owned S3 bucket making them available to all users.&lt;/p&gt;
&lt;p&gt;We want to take this opportunity to thank SUSE for allowing us to use
&lt;code&gt;build.opensuse.org&lt;/code&gt; and their generous support to make this integration
possible!&lt;/p&gt;
&lt;h2 id=&#34;what-are-significant-differences-between-the-google-hosted-and-kubernetes-package-repositories&#34;&gt;What are significant differences between the Google-hosted and Kubernetes package repositories?&lt;/h2&gt;
&lt;p&gt;There are three significant differences that you should be aware of:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;There&#39;s a dedicated package repository for each Kubernetes minor release.
For example, repository called &lt;code&gt;core:/stable:/v1.28&lt;/code&gt; only hosts packages for
stable Kubernetes v1.28 releases. This means you can install v1.28.0 from
this repository, but you can&#39;t install v1.27.0 or any other minor release
other than v1.28. Upon upgrading to another minor version, you have to add a
new repository and optionally remove the old one&lt;/li&gt;
&lt;li&gt;There&#39;s a difference in what &lt;code&gt;cri-tools&lt;/code&gt; and &lt;code&gt;kubernetes-cni&lt;/code&gt; package
versions are available in each Kubernetes repository
&lt;ul&gt;
&lt;li&gt;These two packages are dependencies for &lt;code&gt;kubelet&lt;/code&gt; and &lt;code&gt;kubeadm&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Kubernetes repositories for v1.24 to v1.27 have same versions of these
packages as the Google-hosted repository&lt;/li&gt;
&lt;li&gt;Kubernetes repositories for v1.28 and onwards are going to have published
only versions that are used by that Kubernetes minor release
&lt;ul&gt;
&lt;li&gt;Speaking of v1.28, only kubernetes-cni 1.2.0 and cri-tools v1.28 are going
to be available in the repository for Kubernetes v1.28&lt;/li&gt;
&lt;li&gt;Similar for v1.29, we only plan on publishing cri-tools v1.29 and
whatever kubernetes-cni version is going to be used by Kubernetes v1.29&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The revision part of the package version (the &lt;code&gt;-00&lt;/code&gt; part in &lt;code&gt;1.28.0-00&lt;/code&gt;) is
now autogenerated by the OpenBuildService platform and has a different format.
The revision is now in the format of &lt;code&gt;-x.y&lt;/code&gt;, e.g. &lt;code&gt;1.28.0-1.1&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;does-this-in-any-way-affect-existing-google-hosted-repositories&#34;&gt;Does this in any way affect existing Google-hosted repositories?&lt;/h2&gt;
&lt;p&gt;The Google-hosted repository and all packages published to it will continue
working in the same way as before. There are no changes in how we build and
publish packages to the Google-hosted repository, all newly-introduced changes
are only affecting packages publish to the community-owned repositories.&lt;/p&gt;
&lt;p&gt;However, as mentioned at the beginning of this blog post, we plan to stop
publishing packages to the Google-hosted repository in the future.&lt;/p&gt;
&lt;h2 id=&#34;how-to-migrate&#34;&gt;How to migrate to the Kubernetes community-owned repositories?&lt;/h2&gt;
&lt;h3 id=&#34;how-to-migrate-deb&#34;&gt;Debian, Ubuntu, and operating systems using &lt;code&gt;apt&lt;/code&gt;/&lt;code&gt;apt-get&lt;/code&gt;&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Replace the &lt;code&gt;apt&lt;/code&gt; repository definition so that &lt;code&gt;apt&lt;/code&gt; points to the new
repository instead of the Google-hosted repository. Make sure to replace the
Kubernetes minor version in the command below with the minor version
that you&#39;re currently using:&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;&lt;span style=&#34;color:#a2f&#34;&gt;echo&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.28/deb/ /&amp;#34;&lt;/span&gt; | sudo tee /etc/apt/sources.list.d/kubernetes.list
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Download the public signing key for the Kubernetes package repositories.
The same signing key is used for all repositories, so you can disregard the
version in the URL:&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;curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.28/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Update the &lt;code&gt;apt&lt;/code&gt; package index:&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;sudo apt-get update
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;how-to-migrate-rpm&#34;&gt;CentOS, Fedora, RHEL, and operating systems using &lt;code&gt;rpm&lt;/code&gt;/&lt;code&gt;dnf&lt;/code&gt;&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Replace the &lt;code&gt;yum&lt;/code&gt; repository definition so that &lt;code&gt;yum&lt;/code&gt; points to the new
repository instead of the Google-hosted repository. Make sure to replace the
Kubernetes minor version in the command below with the minor version
that you&#39;re currently using:&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;cat &lt;span style=&#34;color:#b44&#34;&gt;&amp;lt;&amp;lt;EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
&lt;/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;[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:#b44&#34;&gt;name=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:#b44&#34;&gt;baseurl=https://pkgs.k8s.io/core:/stable:/v1.28/rpm/
&lt;/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;enabled=1
&lt;/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;gpgcheck=1
&lt;/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;gpgkey=https://pkgs.k8s.io/core:/stable:/v1.28/rpm/repodata/repomd.xml.key
&lt;/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;exclude=kubelet kubeadm kubectl cri-tools kubernetes-cni
&lt;/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;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;can-i-rollback-to-the-google-hosted-repository-after-migrating-to-the-kubernetes-repositories&#34;&gt;Can I rollback to the Google-hosted repository after migrating to the Kubernetes repositories?&lt;/h2&gt;
&lt;p&gt;In general, yes. Just do the same steps as when migrating, but use parameters
for the Google-hosted repository. You can find those parameters in a document
like &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/setup/production-environment/tools/kubeadm/install-kubeadm&#34;&gt;&amp;quot;Installing kubeadm&amp;quot;&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;why-isn-t-there-a-stable-list-of-domains-ips-why-can-t-i-restrict-package-downloads&#34;&gt;Why isn’t there a stable list of domains/IPs? Why can’t I restrict package downloads?&lt;/h2&gt;
&lt;p&gt;Our plan for &lt;code&gt;pkgs.k8s.io&lt;/code&gt; is to make it work as a redirector to a set of
backends (package mirrors) based on user&#39;s location. The nature of this change
means that a user downloading a package could be redirected to any mirror at
any time. Given the architecture and our plans to onboard additional mirrors in
the near future, we can&#39;t provide a list of IP addresses or domains that you
can add to an allow list.&lt;/p&gt;
&lt;p&gt;Restrictive control mechanisms like man-in-the-middle proxies or network
policies that restrict access to a specific list of IPs/domains will break with
this change. For these scenarios, we encourage you to mirror the release
packages to a local package repository that you have strict control over.&lt;/p&gt;
&lt;h2 id=&#34;what-should-i-do-if-i-detect-some-abnormality-with-the-new-repositories&#34;&gt;What should I do if I detect some abnormality with the new repositories?&lt;/h2&gt;
&lt;p&gt;If you encounter any issue with new Kubernetes package repositories, please
file an issue in the
&lt;a href=&#34;https://github.com/kubernetes/release/issues/new/choose&#34;&gt;&lt;code&gt;kubernetes/release&lt;/code&gt; repository&lt;/a&gt;.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes v1.28: Planternetes</title>
      <link>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/08/15/kubernetes-v1-28-release/</link>
      <pubDate>Tue, 15 Aug 2023 12:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/08/15/kubernetes-v1-28-release/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Authors&lt;/strong&gt;: &lt;a href=&#34;https://github.com/kubernetes/sig-release/blob/master/releases/release-1.28/release-team.md&#34;&gt;Kubernetes v1.28 Release Team&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Announcing the release of Kubernetes v1.28 Planternetes, the second release of 2023!&lt;/p&gt;
&lt;p&gt;This release consists of 45 enhancements. Of those enhancements, 19 are entering Alpha, 14 have graduated to Beta, and 12 have graduated to Stable.&lt;/p&gt;
&lt;h2 id=&#34;release-theme-and-logo&#34;&gt;Release Theme And Logo&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Kubernetes v1.28: &lt;em&gt;Planternetes&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The theme for Kubernetes v1.28 is &lt;em&gt;Planternetes&lt;/em&gt;.&lt;/p&gt;

&lt;figure class=&#34;release-logo&#34;&gt;
    &lt;img src=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/images/blog/2023-08-15-kubernetes-1.28-blog/kubernetes-1.28.png&#34;
         alt=&#34;Kubernetes 1.28 Planternetes logo&#34;/&gt; 
&lt;/figure&gt;

&lt;p&gt;Each Kubernetes release is the culmination of the hard work of thousands of individuals from our community. The people behind this release come from a wide range of backgrounds, some of us industry veterans, parents, others students and newcomers to open-source. We combine our unique experience to create a collective artifact with global impact.&lt;/p&gt;
&lt;p&gt;Much like a garden, our release has ever-changing growth, challenges and opportunities. This theme celebrates the meticulous care, intention and efforts to get the release to where we are today. Harmoniously together, we grow better.&lt;/p&gt;
&lt;h1 id=&#34;what-s-new-major-themes&#34;&gt;What&#39;s New (Major Themes)&lt;/h1&gt;
&lt;h2 id=&#34;changes-to-supported-skew-between-control-plane-and-node-versions&#34;&gt;Changes to supported skew between control plane and node versions&lt;/h2&gt;
&lt;p&gt;Kubernetes v1.28 expands the supported skew between core node and control plane
components by one minor version, from &lt;em&gt;n-2&lt;/em&gt; to &lt;em&gt;n-3&lt;/em&gt;, so that node components
(kubelet and kube-proxy) for the oldest supported minor version work with
control plane components (kube-apiserver, kube-scheduler, kube-controller-manager,
cloud-controller-manager) for the newest supported minor version.&lt;/p&gt;
&lt;p&gt;Some cluster operators avoid node maintenance and especially changes to node
behavior, because nodes are where the workloads run. For minor version upgrades
to a kubelet, the supported process includes draining that node, and hence
disruption to any Pods that had been executing there. For Kubernetes end users
with very long running workloads, and where Pods should stay running wherever
possible, reducing the time lost to node maintenance is a benefit.&lt;/p&gt;
&lt;p&gt;The Kubernetes yearly support period already made annual upgrades possible. Users can
upgrade to the latest patch versions to pick up security fixes and do 3 sequential
minor version upgrades once a year to &amp;quot;catch up&amp;quot; to the latest supported minor version.&lt;/p&gt;
&lt;p&gt;Previously, to stay within the supported skew, a cluster operator planning an annual
upgrade would have needed to upgrade their nodes twice (perhaps only hours apart). Now,
with Kubernetes v1.28, you have the option of making a minor version upgrade to
nodes just once in each calendar year and still staying within upstream support.&lt;/p&gt;
&lt;p&gt;If you&#39;d like to stay current and upgrade your clusters more often, that&#39;s
fine and is still completely supported.&lt;/p&gt;
&lt;h2 id=&#34;generally-available-recovery-from-non-graceful-node-shutdown&#34;&gt;Generally available: recovery from non-graceful node shutdown&lt;/h2&gt;
&lt;p&gt;If a node shuts down unexpectedly or ends up in a non-recoverable state (perhaps due to hardware failure or unresponsive OS), Kubernetes allows you to clean up afterward and allow stateful workloads to restart on a different node. For Kubernetes v1.28, that&#39;s now a stable feature.&lt;/p&gt;
&lt;p&gt;This allows stateful workloads to fail over to a different node successfully after the original node is shut down or in a non-recoverable state, such as the hardware failure or broken OS.&lt;/p&gt;
&lt;p&gt;Versions of Kubernetes earlier than v1.20 lacked handling for node shutdown on Linux, the kubelet integrates with systemd
and implements graceful node shutdown (beta, and enabled by default). However, even an intentional
shutdown might not get handled well that could be because:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the node runs Windows&lt;/li&gt;
&lt;li&gt;the node runs Linux, but uses a different &lt;code&gt;init&lt;/code&gt; (not &lt;code&gt;systemd&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;the shutdown does not trigger the system inhibitor locks mechanism&lt;/li&gt;
&lt;li&gt;because of a node-level configuration error
(such as not setting appropriate values for &lt;code&gt;shutdownGracePeriod&lt;/code&gt; and &lt;code&gt;shutdownGracePeriodCriticalPods&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When a node shutdowns or fails, and that shutdown was not detected by the kubelet, the pods that are part
of a StatefulSet will be stuck in terminating status on the shutdown node. If the stopped node restarts, the
kubelet on that node can clean up (&lt;code&gt;DELETE&lt;/code&gt;) the Pods that the Kubernetes API still sees as bound to that node.
However, if the node stays stopped - or if the kubelet isn&#39;t able to start after a reboot - then Kubernetes may
not be able to create replacement Pods. When the kubelet on the shut-down node is not available to delete
the old pods, an associated StatefulSet cannot create a new pod (which would have the same name).&lt;/p&gt;
&lt;p&gt;There&#39;s also a problem with storage. If there are volumes used by the pods, existing VolumeAttachments will
not be disassociated from the original - and now shut down - node so the PersistentVolumes used by these
pods cannot be attached to a different, healthy node. As a result, an application running on an
affected StatefulSet may not be able to function properly. If the original, shut down node does come up, then
their pods will be deleted by its kubelet and new pods can be created on a different running node.
If the original node does not come up (common with an &lt;a href=&#34;https://glossary.cncf.io/immutable-infrastructure/&#34;&gt;immutable infrastructure&lt;/a&gt; design),  those pods would be stuck in a &lt;code&gt;Terminating&lt;/code&gt; status on the shut-down node forever.&lt;/p&gt;
&lt;p&gt;For more information on how to trigger cleanup after a non-graceful node shutdown,
read &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/concepts/architecture/nodes/#non-graceful-node-shutdown&#34;&gt;non-graceful node shutdown&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;improvements-to-customresourcedefinition-validation-rules&#34;&gt;Improvements to CustomResourceDefinition validation rules&lt;/h2&gt;
&lt;p&gt;The &lt;a href=&#34;https://github.com/google/cel-go&#34;&gt;Common Expression Language (CEL)&lt;/a&gt; can be used to validate
&lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/concepts/extend-kubernetes/api-extension/custom-resources/&#34;&gt;custom resources&lt;/a&gt;. The primary goal is to allow the majority of the validation use cases that might once have needed you, as a CustomResourceDefinition (CRD) author, to design and implement a webhook. Instead, and as a beta feature, you can add &lt;em&gt;validation expressions&lt;/em&gt; directly into the schema of a CRD.&lt;/p&gt;
&lt;p&gt;CRDs need direct support for non-trivial validation. While admission webhooks do support CRDs validation, they significantly complicate the development and operability of CRDs.&lt;/p&gt;
&lt;p&gt;In 1.28, two optional fields &lt;code&gt;reason&lt;/code&gt; and &lt;code&gt;fieldPath&lt;/code&gt; were added to allow user to specify the failure reason and fieldPath when validation failed.&lt;/p&gt;
&lt;p&gt;For more information, read &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#validation-rules&#34;&gt;validation rules&lt;/a&gt; in the CRD documentation.&lt;/p&gt;
&lt;h2 id=&#34;validatingadmissionpolicies-graduate-to-beta&#34;&gt;ValidatingAdmissionPolicies graduate to beta&lt;/h2&gt;
&lt;p&gt;Common Expression language for admission control is customizable, in-process validation of requests to the Kubernetes API server as an alternative to validating admission webhooks.&lt;/p&gt;
&lt;p&gt;This builds on the capabilities of the CRD Validation Rules feature that graduated to beta in 1.25 but with a focus on the policy enforcement capabilities of validating admission control.&lt;/p&gt;
&lt;p&gt;This will lower the infrastructure barrier to enforcing customizable policies as well as providing primitives that help the community establish and adhere to the best practices of both K8s and its extensions.&lt;/p&gt;
&lt;p&gt;To use &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/reference/access-authn-authz/validating-admission-policy/&#34;&gt;ValidatingAdmissionPolicies&lt;/a&gt;, you need to enable both the &lt;code&gt;admissionregistration.k8s.io/v1beta1&lt;/code&gt; API group and the &lt;code&gt;ValidatingAdmissionPolicy&lt;/code&gt; feature gate in your cluster&#39;s control plane.&lt;/p&gt;
&lt;h2 id=&#34;match-conditions-for-admission-webhooks&#34;&gt;Match conditions for admission webhooks&lt;/h2&gt;
&lt;p&gt;Kubernetes v1.27 lets you specify &lt;em&gt;match conditions&lt;/em&gt; for admission webhooks,
which lets you narrow the scope of when Kubernetes makes a remote HTTP call at admission time.
The &lt;code&gt;matchCondition&lt;/code&gt; field for ValidatingWebhookConfiguration and MutatingWebhookConfiguration
is a CEL expression that must evaluate to true for the admission request to be sent to the webhook.&lt;/p&gt;
&lt;p&gt;In Kubernetes v1.28, that field moved to beta, and it&#39;s enabled by default.&lt;/p&gt;
&lt;p&gt;To learn more, see &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/reference/access-authn-authz/extensible-admission-controllers/#matching-requests-matchconditions&#34;&gt;&lt;code&gt;matchConditions&lt;/code&gt;&lt;/a&gt; in the Kubernetes documentation.&lt;/p&gt;
&lt;h2 id=&#34;beta-support-for-enabling-swap-space-on-linux&#34;&gt;Beta support for enabling swap space on Linux&lt;/h2&gt;
&lt;p&gt;This adds swap support to nodes in a controlled, predictable manner so that Kubernetes users can perform testing and provide data to continue building cluster capabilities on top of swap.&lt;/p&gt;
&lt;p&gt;There are two distinct types of users for swap, who may overlap:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Node administrators, who may want swap available for node-level performance tuning and stability/reducing noisy neighbor issues.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Application developers, who have written applications that would benefit from using swap memory.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;mixed-version-proxy&#34;&gt;Mixed version proxy (alpha)&lt;/h2&gt;
&lt;p&gt;When a cluster has multiple API servers at mixed versions (such as during an upgrade/downgrade or when runtime-config changes and a rollout happens), not every apiserver can serve every resource at every version.&lt;/p&gt;
&lt;p&gt;For Kubernetes v1.28, you can enable the &lt;em&gt;mixed version proxy&lt;/em&gt; within the API server&#39;s aggregation layer.
The mixed version proxy finds requests that the local API server doesn&#39;t recognize but another API server
inside the control plan is able to support. Having found a suitable peer, the aggregation layer proxies
the request to a compatible API server; this is transparent from the client&#39;s perspective.&lt;/p&gt;
&lt;p&gt;When an upgrade or downgrade is performed on a cluster, for some period of time the API servers
within the control plane may be at differing versions; when that happens, different subsets of the
API servers are able to serve different sets of built-in resources (different groups, versions, and resources
are all possible). This new alpha mechanism lets you hide that skew from clients.&lt;/p&gt;
&lt;h2 id=&#34;source-code-reorganization-for-control-plane-components&#34;&gt;Source code reorganization for control plane components&lt;/h2&gt;
&lt;p&gt;Kubernetes contributors have begun to reorganize the code for the kube-apiserver to build on a new staging repository that consumes &lt;a href=&#34;https://github.com/kubernetes/apiserver&#34;&gt;k/apiserver&lt;/a&gt; but has a bigger, carefully chosen subset of the functionality of kube-apiserver such that it is reusable.&lt;/p&gt;
&lt;p&gt;This is a gradual reorganization; eventually there will be a new git repository with generic functionality abstracted from Kubernetes&#39; API server.&lt;/p&gt;
&lt;h2 id=&#34;cdi-device-plugin&#34;&gt;Support for CDI injection into containers (alpha)&lt;/h2&gt;
&lt;p&gt;CDI provides a standardized way of injecting complex devices into a container (i.e. devices that logically require more than just a single /dev node to be injected for them to work). This new feature enables plugin developers to utilize the CDIDevices field added to the CRI in 1.27 to pass CDI devices directly to CDI enabled runtimes (of which containerd and crio-o are in recent releases).&lt;/p&gt;
&lt;h2 id=&#34;sidecar-init-containers&#34;&gt;API awareness of sidecar containers (alpha)&lt;/h2&gt;
&lt;p&gt;Kubernetes 1.28 introduces an alpha &lt;code&gt;restartPolicy&lt;/code&gt; field for &lt;a href=&#34;https://github.com/kubernetes/website/blob/main/content/en/docs/concepts/workloads/pods/init-containers.md&#34;&gt;init containers&lt;/a&gt;,
and uses that to indicate when an init container is also a &lt;em&gt;sidecar container&lt;/em&gt;.
The kubelet will start init containers with &lt;code&gt;restartPolicy: Always&lt;/code&gt; in the order
they are defined, along with other init containers.
Instead of waiting for that sidecar container to complete before starting the main
container(s) for the Pod, the kubelet only waits for the sidecar init container to have started.&lt;/p&gt;
&lt;p&gt;The kubelet will consider the startup for the sidecar container as being completed
if the startup probe succeeds and the postStart handler is completed.
This condition is represented with the field Started of ContainerStatus type.
If you do not define a startup probe, the kubelet will consider the container
startup to be completed immediately after the postStart handler completion.&lt;/p&gt;
&lt;p&gt;For init containers, you can either omit the &lt;code&gt;restartPolicy&lt;/code&gt; field, or set it to &lt;code&gt;Always&lt;/code&gt;. Omitting the field
means that you want a true init container that runs to completion before application startup.&lt;/p&gt;
&lt;p&gt;Sidecar containers do not block Pod completion: if all regular containers are complete, sidecar
containers in that Pod will be terminated.&lt;/p&gt;
&lt;p&gt;Once the sidecar container has started (process running, &lt;code&gt;postStart&lt;/code&gt; was successful, and
any configured startup probe is passing), and then there&#39;s a failure, that sidecar container will be
restarted even when the Pod&#39;s overall &lt;code&gt;restartPolicy&lt;/code&gt; is &lt;code&gt;Never&lt;/code&gt; or &lt;code&gt;OnFailure&lt;/code&gt;.
Furthermore, sidecar containers will be restarted (on failure or on normal exit)
&lt;em&gt;even during Pod termination&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;To learn more, read &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/concepts/workloads/pods/init-containers/#api-for-sidecar-containers&#34;&gt;API for sidecar containers&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;automatic-retroactive-assignment-of-a-default-storageclass-graduates-to-stable&#34;&gt;Automatic, retroactive assignment of a default StorageClass graduates to stable&lt;/h2&gt;
&lt;p&gt;Kubernetes automatically sets a &lt;code&gt;storageClassName&lt;/code&gt; for a PersistentVolumeClaim (PVC) if you don&#39;t provide
a value. The control plane also sets a StorageClass for any existing PVC that doesn&#39;t have a &lt;code&gt;storageClassName&lt;/code&gt;
defined.
Previous versions of Kubernetes also had this behavior; for Kubernetes v1.28 it is automatic and always
active; the feature has graduated to stable (general availability).&lt;/p&gt;
&lt;p&gt;To learn more, read about &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/concepts/storage/storage-classes/&#34;&gt;StorageClass&lt;/a&gt; in the Kubernetes
documentation.&lt;/p&gt;
&lt;h2 id=&#34;pod-replacement-policy&#34;&gt;Pod replacement policy for Jobs (alpha)&lt;/h2&gt;
&lt;p&gt;Kubernetes 1.28 adds a new field for the Job API that allows you to specify if you want the control
plane to make new Pods as soon as the previous Pods begin termination (existing behavior),
or only once the existing pods are fully terminated (new, optional behavior).&lt;/p&gt;
&lt;p&gt;Many common machine learning frameworks, such as Tensorflow and JAX, require unique pods per index.
With the older behaviour, if a pod that belongs to an &lt;code&gt;Indexed&lt;/code&gt; Job enters a terminating state (due to preemption, eviction or other external factors), a replacement pod is created but then immediately fails to start due
to the clash with the old pod that has not yet shut down.&lt;/p&gt;
&lt;p&gt;Having a replacement Pod appear before the previous one fully terminates can also cause problems
in clusters with scarce resources or with tight budgets. These resources can be difficult to obtain so pods may only be able to find nodes once the existing pods have been terminated. If cluster autoscaler is enabled, early creation of replacement Pods might produce undesired scale-ups.&lt;/p&gt;
&lt;p&gt;To learn more, read &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/concepts/workloads/controllers/job/#delayed-creation-of-replacement-pods&#34;&gt;Delayed creation of replacement pods&lt;/a&gt;
in the Job documentation.&lt;/p&gt;
&lt;h2 id=&#34;job-per-index-retry-backoff&#34;&gt;Job retry backoff limit, per index (alpha)&lt;/h2&gt;
&lt;p&gt;This extends the Job API to support indexed jobs where the backoff limit is per index, and the Job can continue execution despite some of its indexes failing.&lt;/p&gt;
&lt;p&gt;Currently, the indexes of an indexed job share a single backoff limit. When the job reaches this shared backoff limit, the job controller marks the entire job as failed, and the resources are cleaned up, including indexes that have yet to run to completion.&lt;/p&gt;
&lt;p&gt;As a result, the existing implementation did not cover the situation where the workload is truly
&lt;a href=&#34;https://en.wikipedia.org/wiki/Embarrassingly_parallel&#34;&gt;embarrassingly parallel&lt;/a&gt;: each index is
fully independent of other indexes.&lt;/p&gt;
&lt;p&gt;For instance, if indexed jobs were used as the basis for a suite of long-running integration tests, then each test run would only be able to find a single test failure.&lt;/p&gt;
&lt;p&gt;For more information, read &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/concepts/workloads/controllers/job/#handling-pod-and-container-failures&#34;&gt;Handling Pod and container failures&lt;/a&gt; in the Kubernetes documentation.&lt;/p&gt;
&lt;hr /&gt;
&lt;a id=&#34;cri-container-and-pod-statistics-without-cadvisor&#34; /&gt;
&lt;p&gt;&lt;strong&gt;Correction&lt;/strong&gt;: the feature CRI container and pod statistics without cAdvisor has been removed as it did not make the release.
The original release announcement stated that Kubernetes 1.28 included the new feature.&lt;/p&gt;
&lt;h2 id=&#34;feature-graduations-and-deprecations-in-kubernetes-v1-28&#34;&gt;Feature graduations and deprecations in Kubernetes v1.28&lt;/h2&gt;
&lt;h3 id=&#34;graduations-to-stable&#34;&gt;Graduations to stable&lt;/h3&gt;
&lt;p&gt;This release includes a total of 12 enhancements promoted to Stable:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/1440&#34;&gt;&lt;code&gt;kubectl events&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/3333&#34;&gt;Retroactive default StorageClass assignment&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/2268&#34;&gt;Non-graceful node shutdown&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/606&#34;&gt;Support 3rd party device monitoring plugins&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/3325&#34;&gt;Auth API to get self-user attributes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/1669&#34;&gt;Proxy Terminating Endpoints&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/2595&#34;&gt;Expanded DNS Configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/3178&#34;&gt;Cleaning up IPTables Chain Ownership&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/3453&#34;&gt;Minimizing iptables-restore input size&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/3743&#34;&gt;Graduate the kubelet pod resources endpoint to GA&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/2403&#34;&gt;Extend podresources API to report allocatable resources&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/3685&#34;&gt;Move EndpointSlice Reconciler into Staging&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;Removals:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/1488&#34;&gt;Removal of CSI Migration for GCE PD&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Deprecations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/kubernetes/pull/118303&#34;&gt;Ceph RBD in-tree plugin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/kubernetes/pull/118143&#34;&gt;Ceph FS in-tree plugin&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;release-notes&#34;&gt;Release Notes&lt;/h2&gt;
&lt;p&gt;The complete details of the Kubernetes v1.28 release are available in our &lt;a href=&#34;https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.28.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.28 is available for download on &lt;a href=&#34;https://github.com/kubernetes/kubernetes/releases/tag/v1.28.0&#34;&gt;GitHub&lt;/a&gt;. To get started with Kubernetes, you can run local Kubernetes clusters using &lt;a href=&#34;https://minikube.sigs.k8s.io/docs/&#34;&gt;minikube&lt;/a&gt;, &lt;a href=&#34;https://kind.sigs.k8s.io/&#34;&gt;kind&lt;/a&gt;, etc. You can also easily install v1.28 using &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/setup/production-environment/tools/kubeadm/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 comprised 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 release team for the hours spent hard at work to ensure we deliver a solid Kubernetes v1.28 release for our community.&lt;/p&gt;
&lt;p&gt;Special thanks to our release lead, Grace Nguyen, for guiding us through a smooth and successful release cycle.&lt;/p&gt;
&lt;h2 id=&#34;ecosystem-updates&#34;&gt;Ecosystem Updates&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;KubeCon + CloudNativeCon China 2023 will take place in Shanghai, China, from 26 – 28 September 2023! You can find more information about the conference and registration on the &lt;a href=&#34;https://www.lfasiallc.com/kubecon-cloudnativecon-open-source-summit-china/&#34;&gt;event site&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;KubeCon + CloudNativeCon North America 2023 will take place in Chicago, Illinois, The United States of America, from 6 – 9 November 2023! 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;event site&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;project-velocity&#34;&gt;Project Velocity&lt;/h2&gt;
&lt;p&gt;The &lt;a href=&#34;https://k8s.devstats.cncf.io/d/12/dashboards?orgId=1&amp;amp;refresh=15m&#34;&gt;CNCF K8s DevStats&lt;/a&gt; project aggregates a number of interesting data points related to the velocity of Kubernetes and various sub-projects. This includes everything from individual contributions to the number of companies that are contributing and is an illustration of the depth and breadth of effort that goes into evolving this ecosystem.&lt;/p&gt;
&lt;p&gt;In the v1.28 release cycle, which &lt;a href=&#34;https://github.com/kubernetes/sig-release/tree/master/releases/release-1.28&#34;&gt;ran for 14 weeks&lt;/a&gt; (May 15 to August 15), we saw contributions from &lt;a href=&#34;https://k8s.devstats.cncf.io/d/9/companies-table?orgId=1&amp;amp;var-period_name=v1.27.0%20-%20now&amp;amp;var-metric=contributions&#34;&gt;911 companies&lt;/a&gt; and &lt;a href=&#34;https://k8s.devstats.cncf.io/d/66/developer-activity-counts-by-companies?orgId=1&amp;amp;var-period_name=v1.27.0%20-%20now&amp;amp;var-metric=contributions&amp;amp;var-repogroup_name=Kubernetes&amp;amp;var-repo_name=kubernetes%2Fkubernetes&amp;amp;var-country_name=All&amp;amp;var-companies=All&#34;&gt;1440 individuals&lt;/a&gt;.&lt;/p&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.28 release team on Wednesday, September 6th, 2023, at 9 A.M. PDT 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-128-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.&lt;/p&gt;
&lt;p&gt;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:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Find out more about contributing to Kubernetes at the &lt;a href=&#34;https://www.kubernetes.dev/&#34;&gt;Kubernetes Contributors website&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Follow us on Twitter &lt;a href=&#34;https://twitter.com/kubernetesio&#34;&gt;@Kubernetesio&lt;/a&gt; for the latest updates.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Join the community discussion on &lt;a href=&#34;https://discuss.kubernetes.io/&#34;&gt;Discuss&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Join the community on &lt;a href=&#34;https://communityinviter.com/apps/kubernetes/community&#34;&gt;Slack&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Post questions (or answer questions) on &lt;a href=&#34;https://serverfault.com/questions/tagged/kubernetes&#34;&gt;Server Fault&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://docs.google.com/forms/d/e/1FAIpQLScuI7Ye3VQHQTwBASrgkjQDSS5TP0g3AXfFhwSM9YpHgxRKFA/viewform&#34;&gt;Share&lt;/a&gt; your Kubernetes story.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&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;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&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;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Spotlight on SIG ContribEx</title>
      <link>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/08/14/sig-contribex-spotlight-2023/</link>
      <pubDate>Mon, 14 Aug 2023 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/08/14/sig-contribex-spotlight-2023/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Author&lt;/strong&gt;: Fyka Ansari&lt;/p&gt;
&lt;p&gt;Welcome to the world of Kubernetes and its vibrant contributor
community! In this blog post, we&#39;ll be shining a spotlight on the
&lt;a href=&#34;https://github.com/kubernetes/community/blob/master/sig-contributor-experience/README.md&#34;&gt;Special Interest Group for Contributor
Experience&lt;/a&gt;
(SIG ContribEx), an essential component of the Kubernetes project.&lt;/p&gt;
&lt;p&gt;SIG ContribEx in Kubernetes is responsible for developing and
maintaining a healthy and productive community of contributors to the
project. This involves identifying and addressing bottlenecks that may
hinder the project&#39;s growth and feature velocity, such as pull request
latency and the number of open pull requests and issues.&lt;/p&gt;
&lt;p&gt;SIG ContribEx works to improve the overall contributor experience by
creating and maintaining guidelines, tools, and processes that
facilitate collaboration and communication among contributors. They
also focus on community building and support, including outreach
programs and mentorship initiatives to onboard and retain new
contributors.&lt;/p&gt;
&lt;p&gt;Ultimately, the role of SIG ContribEx is to foster a welcoming and
inclusive environment that encourages contribution and supports the
long-term sustainability of the Kubernetes project.&lt;/p&gt;
&lt;p&gt;In this blog post, &lt;a href=&#34;https://twitter.com/1fyka&#34;&gt;Fyka Ansari&lt;/a&gt; interviews
&lt;a href=&#34;https://twitter.com/kaslinfields&#34;&gt;Kaslin Fields&lt;/a&gt;, a DevRel Engineer
at Google, who is a chair of SIG ContribEx, and &lt;a href=&#34;https://twitter.com/MadhavJivrajani&#34;&gt;Madhav
Jivrajani&lt;/a&gt;, a Software Engineer
at VMWare who serves as a SIG ContribEx Tech Lead. This interview
covers various aspects of SIG ContribEx, including current
initiatives, exciting developments, and how interested individuals can
get involved and contribute to the group. It provides valuable
insights into the workings of SIG ContribEx and highlights the
importance of its role in the Kubernetes ecosystem.&lt;/p&gt;
&lt;h3 id=&#34;introductions&#34;&gt;Introductions&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Fyka:&lt;/strong&gt; Let&#39;s start by diving into your background and how you got
involved in the Kubernetes ecosystem. Can you tell us more about that
journey?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Kaslin:&lt;/strong&gt; I first got involved in the Kubernetes ecosystem through
my mentor, Jonathan Rippy, who introduced me to containers during my
early days in tech. Eventually, I transitioned to a team working with
containers, which sparked my interest in Kubernetes when it was
announced. While researching Kubernetes in that role, I eagerly sought
opportunities to engage with the containers/Kubernetes community. It
was not until my subsequent job that I found a suitable role to
contribute consistently. I joined SIG ContribEx, specifically in the
Contributor Comms subproject, to both deepen my knowledge of
Kubernetes and support the community better.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Madhav:&lt;/strong&gt; My journey with Kubernetes began when I was a student,
searching for interesting and exciting projects to work on. With my
peers, I discovered open source and attended The New Contributor
Workshop organized by the Kubernetes community. The workshop not only
provided valuable insights into the community structure but also gave
me a sense of warmth and welcome, which motivated me to join and
remain involved. I realized that collaboration is at the heart of
open-source communities, and to get answers and support, I needed to
contribute and do my part. I started working on issues in ContribEx,
particularly focusing on GitHub automation, despite not fully
understanding the task at first. I continued to contribute for various
technical and non-technical aspects of the project, finding it to be
one of the most professionally rewarding experiences in my life.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Fyka:&lt;/strong&gt; That&#39;s such an inspiration in itself! I&#39;m sure beginners who
are reading this got the ultimate motivation to take their first
steps. Embracing the Learning journey, seeking mentorship, and
engaging with the Kubernetes community can pave the way for exciting
opportunities in the tech industry. Your stories proved the importance
of starting small and being proactive, just like Madhav said Don&#39;t be
afraid to take on tasks, even if you&#39;re uncertain at first.&lt;/p&gt;
&lt;h3 id=&#34;primary-goals-and-scope&#34;&gt;Primary goals and scope&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Fyka:&lt;/strong&gt; Given your experience as a member of SIG ContribEx, could
you tell us a bit about the group&#39;s primary goals and initiatives? Its
current focus areas? What do you see as the scope of SIG ContribEx and
the impact it has on the Kubernetes community?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Kaslin:&lt;/strong&gt; SIG ContribEx&#39;s primary goals are to simplify the
contributions of Kubernetes contributors and foster a welcoming
community. It collaborates with other Kubernetes SIGs, such as
planning the Contributor Summit at KubeCon, ensuring it meets the
needs of various groups. The group&#39;s impact is evident in projects
like updating org membership policies and managing critical platforms
like Zoom, YouTube, and Slack. Its scope encompasses making the
contributor experience smoother and supporting the overall Kubernetes
community.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Madhav:&lt;/strong&gt; The Kubernetes project has vertical SIGs and cross-cutting
SIGs, ContribEx is a deeply cross-cutting SIG, impacting virtually
every area of the Kubernetes community. Adding to Kaslin,
sustainability in the Kubernetes project and community is critical now
more than ever, it plays a central role in addressing critical issues,
such as maintainer succession, by facilitating cohorts for SIGs to
train experienced community members to take on leadership
roles. Excellent examples include SIG CLI and SIG Apps, leading to the
onboarding of new reviewers. Additionally, SIG ContribEx is essential
in managing GitHub automation tools, including bots and commands used
by contributors for interacting with &lt;a href=&#34;https://docs.prow.k8s.io/&#34;&gt;Prow&lt;/a&gt;
and other automation (label syncing, group and GitHub team management,
etc).&lt;/p&gt;
&lt;h3 id=&#34;beginner-s-guide&#34;&gt;Beginner&#39;s guide!&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Fyka:&lt;/strong&gt; I&#39;ll never forget talking to Kaslin when I joined the
community and needed help with contributing. Kaslin, your quick and
clear answers were a huge help in getting me started. Can you both
give some tips for people new to contributing to Kubernetes? What
makes SIG ContribEx a great starting point? Why should beginners and
current contributors consider it? And what cool opportunities are
there for newbies to jump in?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Kaslin:&lt;/strong&gt; If you want to contribute to Kubernetes for the first
time, it can be overwhelming to know where to start. A good option is
to join SIG ContribEx as it offers great opportunities to know and
serve the community. Within SIG ContribEx, various subprojects allow
you to explore different parts of the Kubernetes project while you
learn how contributions work. Once you know a bit more, it’s common
for you to move to other SIGs within the project, and we think that’s
wonderful. While many newcomers look for &amp;quot;good first issues&amp;quot; to start
with, these opportunities can be scarce and get claimed
quickly. Instead, the real benefit lies in attending meetings and
getting to know the community. As you learn more about the project and
the people involved, you&#39;ll be better equipped to offer your help, and
the community will be more inclined to seek your assistance when
needed. As a co-lead for the Contributor Comms subproject, I can
confidently say that it&#39;s an excellent place for beginners to get
involved. We have supportive leads and particularly beginner-friendly
projects too.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Madhav:&lt;/strong&gt; To begin, read the &lt;a href=&#34;https://github.com/kubernetes/community/tree/master#readme&#34;&gt;SIG
README&lt;/a&gt; on
GitHub, which provides an overview of the projects the SIG
manages. While attending meetings is beneficial for all SIGs, it&#39;s
especially recommended for SIG ContribEx, as each subproject gets
dedicated slots for updates and areas that need help. If you can&#39;t
attend in real-time due to time zone differences, you can catch the
meeting recordings or
&lt;a href=&#34;https://docs.google.com/document/d/1K3vjCZ9C3LwYrOJOhztQtFuDQCe-urv-ewx1bI8IPVQ/edit?usp=sharing&#34;&gt;Notes&lt;/a&gt;
later.&lt;/p&gt;
&lt;h3 id=&#34;skills-you-learn&#34;&gt;Skills you learn!&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Fyka:&lt;/strong&gt; What skills do you look for when bringing in new
contributors to SIG ContribEx, from passion to expertise?
Additionally, what skills can contributors expect to develop while
working with SIG ContribEx?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Kaslin:&lt;/strong&gt; Skills folks need to have or will acquire vary depending
on what area of ContribEx they work upon. Even within a subproject, a
range of skills can be useful and/or developed. For example, the tech
lead role involves technical tasks and overseeing automation, while
the social media lead role requires excellent communication
skills. Working with SIG ContribEx allows contributors to acquire
various skills based on their chosen subproject. By participating in
meetings, listening, learning, and taking on tasks related to their
interests, they can develop and hone these skills. Some subprojects
may require more specialized skills, like program management for the
mentoring project, but all contributors can benefit from offering
their talents to help teach others and contribute to the community.&lt;/p&gt;
&lt;h3 id=&#34;sub-projects-under-sig-contribex&#34;&gt;Sub-projects under SIG ContribEx&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Fyka:&lt;/strong&gt; SIG ContribEx has several smaller projects. Can you tell me
about the aims of these projects and how they&#39;ve impacted the
Kubernetes community?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Kaslin:&lt;/strong&gt; Some SIGs have one or two subprojects and some have none
at all, but in SIG ContribEx, we have ELEVEN!&lt;/p&gt;
&lt;p&gt;Here’s a list of them and their respective mission statements&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Community&lt;/strong&gt;: Manages the community repository, documentation,
and operations.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Community management&lt;/strong&gt;: Handles communication platforms and
policies for the community.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Contributor-comms&lt;/strong&gt;: Focuses on promoting the success of
Kubernetes contributors through marketing.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Contributors-documentation&lt;/strong&gt;: Writes and maintains documentation
for contributing to Kubernetes.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Devstats&lt;/strong&gt;: Maintains and updates the &lt;a href=&#34;https://k8s.devstats.cncf.io&#34;&gt;Kubernetes
statistics&lt;/a&gt; website.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Elections&lt;/strong&gt;: Oversees community elections and maintains related
documentation and software.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Events&lt;/strong&gt;: Organizes contributor-focused events like the
Contributor Summit.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Github management&lt;/strong&gt;: Manages permissions, repositories, and
groups on GitHub.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mentoring&lt;/strong&gt;: Develop programs to help contributors progress in
their contributions.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sigs-GitHub-actions&lt;/strong&gt;: Repository for GitHub actions related to
all SIGs in Kubernetes.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Slack-infra&lt;/strong&gt;: Creates and maintains tools and automation for
Kubernetes Slack.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Madhav:&lt;/strong&gt; Also, Devstats is critical from a sustainability
standpoint!&lt;/p&gt;
&lt;p&gt;&lt;em&gt;(If you are willing to learn more and get involved with any of these
sub-projects, check out the&lt;/em&gt; &lt;a href=&#34;https://github.com/kubernetes/community/blob/master/sig-contributor-experience/README.md#subprojects&#34;&gt;SIG ContribEx
README&lt;/a&gt;)._&lt;/p&gt;
&lt;h3 id=&#34;accomplishments&#34;&gt;Accomplishments&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Fyka:&lt;/strong&gt; With that said, any SIG-related accomplishment that you’re
proud of?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Kaslin:&lt;/strong&gt; I&#39;m proud of the accomplishments made by SIG ContribEx and
its contributors in supporting the community. Some of the recent
achievements include:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;em&gt;Establishment of the elections subproject&lt;/em&gt;: Kubernetes is a massive
project, and ensuring smooth leadership transitions is
crucial. The contributors in this subproject organize fair and
consistent elections, which helps keep the project running
effectively.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;New issue triage proces&lt;/em&gt;: With such a large open-source project
like Kubernetes, there&#39;s always a lot of work to be done. To
ensure things progress safely, we implemented new labels and
updated functionality for issue triage using our PROW tool. This
reduces bottlenecks in the workflow and allows leaders to
accomplish more.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;New org membership requirements&lt;/em&gt;: Becoming an org member in
Kubernetes can be overwhelming for newcomers. We view org
membership as a significant milestone for contributors aiming to
take on leadership roles. We recently updated the rules to
automatically remove privileges from inactive members, making sure
that the right people have access to the necessary tools and
responsibilities.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Overall, these accomplishments have greatly benefited our fellow
contributors and strengthened the Kubernetes community.&lt;/p&gt;
&lt;h3 id=&#34;upcoming-initiatives&#34;&gt;Upcoming initiatives&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Fyka:&lt;/strong&gt; Could you give us a sneak peek into what&#39;s next for the
group? We&#39;re excited to hear about upcoming projects and initiatives
from this dynamic team.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Madhav:&lt;/strong&gt; We’d love for more groups to sign up for mentoring
cohorts! We’re probably going to have to spend some time polishing the
process around that.&lt;/p&gt;
&lt;h3 id=&#34;final-thoughts&#34;&gt;Final thoughts&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Fyka:&lt;/strong&gt; As we wrap up our conversation, would you like to share some
final thoughts for those interested in contributing to SIG ContribEx
or getting involved with Kubernetes?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Madhav&lt;/strong&gt;: Kubernetes is meant to be overwhelming and difficult
initially! You’re coming into something that’s taken multiple people,
from multiple countries, multiple years to build. Embrace that
diversity! Use the high entropy initially to collide around and gain
as much knowledge about the project and community as possible before
you decide to settle in your niche.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Fyka:&lt;/strong&gt; Thank You Madhav and Kaslin, it was an absolute pleasure
chatting about SIG ContribEx and your experiences as a member. It&#39;s
clear that the role of SIG ContribEx in Kubernetes is significant and
essential, ensuring scalability, growth and productivity, and I hope
this interview inspires more people to get involved and contribute to
Kubernetes. I wish SIG ContribEx all the best, and can&#39;t wait to see
what exciting things lie ahead!&lt;/p&gt;
&lt;h2 id=&#34;what-next&#34;&gt;What next?&lt;/h2&gt;
&lt;p&gt;We love meeting new contributors and helping them in investigating
different Kubernetes project spaces. If you are interested in getting
more involved with SIG ContribEx, here are some resources for you to
get started:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-contributor-experience#contributor-experience-special-interest-group&#34;&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://groups.google.com/g/kubernetes-sig-contribex&#34;&gt;Mailing list&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/community/labels/sig%2Fcontributor-experience&#34;&gt;Open Community
Issues/PRs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://slack.k8s.io/&#34;&gt;Slack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kubernetes.slack.com/messages/sig-contribex&#34;&gt;Slack channel
#sig-contribex&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;SIG Contribex also hosted a &lt;a href=&#34;https://youtu.be/5Bs1bs6iFmY&#34;&gt;KubeCon
talk&lt;/a&gt; about studying Kubernetes
Contributor experiences.&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Spotlight on SIG CLI</title>
      <link>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/07/20/sig-cli-spotlight-2023/</link>
      <pubDate>Thu, 20 Jul 2023 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/07/20/sig-cli-spotlight-2023/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Author&lt;/strong&gt;: Arpit Agrawal&lt;/p&gt;
&lt;p&gt;In the world of Kubernetes, managing containerized applications at
scale requires powerful and efficient tools. The command-line
interface (CLI) is an integral part of any developer or operator’s
toolkit, offering a convenient and flexible way to interact with a
Kubernetes cluster.&lt;/p&gt;
&lt;p&gt;SIG CLI plays a crucial role in improving the &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-cli&#34;&gt;Kubernetes
CLI&lt;/a&gt;
experience by focusing on the development and enhancement of
&lt;code&gt;kubectl&lt;/code&gt;, the primary command-line tool for Kubernetes.&lt;/p&gt;
&lt;p&gt;In this SIG CLI Spotlight, Arpit Agrawal, SIG ContribEx-Comms team
member, talked with &lt;a href=&#34;https://github.com/KnVerey&#34;&gt;Katrina Verey&lt;/a&gt;, Tech
Lead &amp;amp; Chair of SIG CLI,and &lt;a href=&#34;https://github.com/soltysh&#34;&gt;Maciej
Szulik&lt;/a&gt;, SIG CLI Batch Lead, about SIG
CLI, current projects, challenges and how anyone can get involved.&lt;/p&gt;
&lt;p&gt;So, whether you are a seasoned Kubernetes enthusiast or just getting
started, understanding the significance of SIG CLI will undoubtedly
enhance your Kubernetes journey.&lt;/p&gt;
&lt;h2 id=&#34;introductions&#34;&gt;Introductions&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Arpit&lt;/strong&gt;: Could you tell us a bit about yourself, your role, and how
you got involved in SIG CLI?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Maciej&lt;/strong&gt;: I’m one of the technical leads for SIG-CLI. I was working
on Kubernetes in multiple areas since 2014, and in 2018 I got
appointed a lead.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Katrina&lt;/strong&gt;: I’ve been working with Kubernetes as an end-user since
2016, but it was only in late 2019 that I discovered how well SIG CLI
aligned with my experience from internal projects. I started regularly
attending meetings and made a few small PRs, and by 2021 I was working
more deeply with the
&lt;a href=&#34;https://github.com/kubernetes-sigs/kustomize&#34;&gt;Kustomize&lt;/a&gt; team
specifically. Later that year, I was appointed to my current roles as
subproject owner for Kustomize and KRM Functions, and as SIG CLI Tech
Lead and Chair.&lt;/p&gt;
&lt;h2 id=&#34;about-sig-cli&#34;&gt;About SIG CLI&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Arpit&lt;/strong&gt;: Thank you! Could you share with us the purpose and goals of SIG CLI?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Maciej&lt;/strong&gt;: Our
&lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-cli/&#34;&gt;charter&lt;/a&gt;
has the most detailed description, but in few words, we handle all CLI
tooling that helps you manage your Kubernetes manifests and interact
with your Kubernetes clusters.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Arpit&lt;/strong&gt;: I see. And how does SIG CLI work to promote best-practices
for CLI development and usage in the cloud native ecosystem?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Maciej&lt;/strong&gt;: Within &lt;code&gt;kubectl&lt;/code&gt;, we have several on-going efforts that
try to encourage new contributors to align existing commands to new
standards. We publish several libraries which hopefully make it easier
to write CLIs that interact with Kubernetes APIs, such as cli-runtime
and
&lt;a href=&#34;https://github.com/kubernetes-sigs/kustomize/tree/master/kyaml&#34;&gt;kyaml&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Katrina&lt;/strong&gt;: We also maintain some interoperability specifications for
CLI tooling, such as the &lt;a href=&#34;https://github.com/kubernetes-sigs/kustomize/blob/master/cmd/config/docs/api-conventions/functions-spec.md&#34;&gt;KRM Functions
Specification&lt;/a&gt;
(GA) and the new ApplySet
Specification
(alpha).&lt;/p&gt;
&lt;h2 id=&#34;current-projects-and-challenges&#34;&gt;Current projects and challenges&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Arpit&lt;/strong&gt;: Going through the README file, it’s clear SIG CLI has a
number of subprojects, could you highlight some important ones?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Maciej&lt;/strong&gt;: The four most active subprojects that are, in my opinion,
worthy of your time investment would be:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/kubectl&#34;&gt;&lt;code&gt;kubectl&lt;/code&gt;&lt;/a&gt;:  the canonical Kubernetes CLI.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes-sigs/kustomize&#34;&gt;Kustomize&lt;/a&gt;: a
template-free customization tool for Kubernetes yaml manifest files.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kui.tools&#34;&gt;KUI&lt;/a&gt; - a GUI interface to Kubernetes, think
&lt;code&gt;kubectl&lt;/code&gt; on steroids.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes-sigs/krew&#34;&gt;&lt;code&gt;krew&lt;/code&gt;&lt;/a&gt;: a plugin manager for &lt;code&gt;kubectl&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Arpit&lt;/strong&gt;: Are there any upcoming initiatives or developments that SIG
CLI is working on?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Maciej&lt;/strong&gt;: There are always several initiatives we’re working on at
any given point in time. It’s best to join &lt;a href=&#34;https://github.com/kubernetes/community/tree/master/sig-cli/#meetings&#34;&gt;one of our
calls&lt;/a&gt;
to learn about the current ones.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Katrina&lt;/strong&gt;: For major features, you can check out &lt;a href=&#34;https://www.kubernetes.dev/resources/keps/&#34;&gt;our open
KEPs&lt;/a&gt;. For instance, in
1.27 we introduced alphas for &lt;a href=&#34;https://kubernetes.io/blog/2023/05/09/introducing-kubectl-applyset-pruning/&#34;&gt;a new pruning mode in kubectl
apply&lt;/a&gt;,
and for kubectl create plugins. Exciting ideas that are currently
under discussion include an interactive mode for &lt;code&gt;kubectl&lt;/code&gt; delete
(&lt;a href=&#34;https://kubernetes.io/blog/2023/05/09/introducing-kubectl-applyset-pruning&#34;&gt;KEP
3895&lt;/a&gt;)
and the &lt;code&gt;kuberc&lt;/code&gt; user preferences file (&lt;a href=&#34;https://kubernetes.io/blog/2023/05/09/introducing-kubectl-applyset-pruning&#34;&gt;KEP
3104&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Arpit&lt;/strong&gt;: Could you discuss any challenges that SIG CLI faces in its
efforts to improve CLIs for cloud-native technologies? What are the
future efforts to solve them?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Katrina&lt;/strong&gt;: The biggest challenge we’re facing with every decision is
backwards compatibility and ensuring we don’t break existing users. It
frequently happens that fixing what&#39;s on the surface may seem
straightforward, but even fixing a bug could constitute a breaking
change for some users, which means we need to go through an extended
deprecation process to change it, or in some cases we can’t change it
at all. Another challenge is the need to balance customization with
usability in the flag sets we expose on our tools. For example, we get
many proposals for new flags that would certainly be useful to some
users, but not a large enough subset to justify the increased
complexity having them in the tool entails for everyone. The &lt;code&gt;kuberc&lt;/code&gt;
proposal may help with some of these problems by giving individual
users the ability to set or override default values we can’t change,
and even create custom subcommands via aliases&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Arpit&lt;/strong&gt;: With every new version release of Kubernetes, maintaining
consistency and integrity is surely challenging: how does the SIG CLI
team tackle it?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Maciej&lt;/strong&gt;: This is mostly similar to the topic mentioned in the
previous question: every new change, especially to existing commands
goes through a lot of scrutiny to ensure we don’t break existing
users. At any point in time we have to keep a reasonable balance
between features and not breaking users.&lt;/p&gt;
&lt;h2 id=&#34;future-plans-and-contribution&#34;&gt;Future plans and contribution&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Arpit&lt;/strong&gt;: How do you see the role of CLI tools in the cloud-native
ecosystem evolving in the future?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Maciej&lt;/strong&gt;: I think that CLI tools were and will always be an
important piece of the ecosystem. Whether used by administrators on
remote machines that don’t have GUI or in every CI/CD pipeline, they
are irreplaceable.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Arpit&lt;/strong&gt;: Kubernetes is a community-driven project. Any
recommendation for anyone looking into getting involved in SIG CLI
work? Where should they start? Are there any prerequisites?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Maciej&lt;/strong&gt;: There are no prerequisites other than a little bit of free
time on your hands and willingness to learn something new :-)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Katrina&lt;/strong&gt;: A working knowledge of &lt;a href=&#34;https://go.dev/&#34;&gt;Go&lt;/a&gt; often helps,
but we also have areas in need of non-code contributions, such as the
&lt;a href=&#34;https://github.com/kubernetes-sigs/kustomize/issues/4338&#34;&gt;Kustomize docs consolidation
project&lt;/a&gt;.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Confidential Kubernetes: Use Confidential Virtual Machines and Enclaves to improve your cluster security</title>
      <link>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/07/06/confidential-kubernetes/</link>
      <pubDate>Thu, 06 Jul 2023 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/07/06/confidential-kubernetes/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Authors:&lt;/strong&gt; Fabian Kammel (Edgeless Systems), Mikko Ylinen (Intel), Tobin Feldman-Fitzthum (IBM)&lt;/p&gt;
&lt;p&gt;In this blog post, we will introduce the concept of Confidential Computing (CC) to improve any computing environment&#39;s security and privacy properties. Further, we will show how
the Cloud-Native ecosystem, particularly Kubernetes, can benefit from the new compute paradigm.&lt;/p&gt;
&lt;p&gt;Confidential Computing is a concept that has been introduced previously in the cloud-native world. The
&lt;a href=&#34;https://confidentialcomputing.io/&#34;&gt;Confidential Computing Consortium&lt;/a&gt; (CCC) is a project community in the Linux Foundation
that already worked on
&lt;a href=&#34;https://confidentialcomputing.io/wp-content/uploads/sites/85/2019/12/CCC_Overview.pdf&#34;&gt;Defining and Enabling Confidential Computing&lt;/a&gt;.
In the &lt;a href=&#34;https://confidentialcomputing.io/wp-content/uploads/sites/85/2023/01/CCC-A-Technical-Analysis-of-Confidential-Computing-v1.3_Updated_November_2022.pdf&#34;&gt;Whitepaper&lt;/a&gt;,
they provide a great motivation for the use of Confidential Computing:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Data exists in three states: in transit, at rest, and in use. …Protecting sensitive data
in all of its states is more critical than ever. Cryptography is now commonly deployed
to provide both data confidentiality (stopping unauthorized viewing) and data integrity
(preventing or detecting unauthorized changes). While techniques to protect data in transit
and at rest are now commonly deployed, the third state - protecting data in use - is the new frontier.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Confidential Computing aims to primarily solve the problem of &lt;strong&gt;protecting data in use&lt;/strong&gt;
by introducing a hardware-enforced Trusted Execution Environment (TEE).&lt;/p&gt;
&lt;h2 id=&#34;trusted-execution-environments&#34;&gt;Trusted Execution Environments&lt;/h2&gt;
&lt;p&gt;For more than a decade, Trusted Execution Environments (TEEs) have been available in commercial
computing hardware in the form of &lt;a href=&#34;https://en.wikipedia.org/wiki/Hardware_security_module&#34;&gt;Hardware Security Modules&lt;/a&gt;
(HSMs) and &lt;a href=&#34;https://www.iso.org/standard/50970.html&#34;&gt;Trusted Platform Modules&lt;/a&gt; (TPMs). These
technologies provide trusted environments for shielded computations. They can
store highly sensitive cryptographic keys and carry out critical cryptographic operations
such as signing or encrypting data.&lt;/p&gt;
&lt;p&gt;TPMs are optimized for low cost, allowing them to be integrated into mainboards and act as a
system&#39;s physical root of trust. To keep the cost low, TPMs are limited in scope, i.e., they
provide storage for only a few keys and are capable of just a small subset of cryptographic operations.&lt;/p&gt;
&lt;p&gt;In contrast, HSMs are optimized for high performance, providing secure storage for far
more keys and offering advanced physical attack detection mechanisms. Additionally, high-end HSMs
can be programmed so that arbitrary code can be compiled and executed. The downside
is that they are very costly. A managed CloudHSM from AWS costs
&lt;a href=&#34;https://aws.amazon.com/cloudhsm/pricing/&#34;&gt;around $1.50 / hour&lt;/a&gt; or ~$13,500 / year.&lt;/p&gt;
&lt;p&gt;In recent years, a new kind of TEE has gained popularity. Technologies like
&lt;a href=&#34;https://developer.amd.com/sev/&#34;&gt;AMD SEV&lt;/a&gt;,
&lt;a href=&#34;https://www.intel.com/content/www/us/en/developer/tools/software-guard-extensions/overview.html&#34;&gt;Intel SGX&lt;/a&gt;,
and &lt;a href=&#34;https://www.intel.com/content/www/us/en/developer/articles/technical/intel-trust-domain-extensions.html&#34;&gt;Intel TDX&lt;/a&gt;
provide TEEs that are closely integrated with userspace. Rather than low-power or high-performance
devices that support specific use cases, these TEEs shield normal processes or virtual machines
and can do so with relatively low overhead. These technologies each have different design goals,
advantages, and limitations, and they are available in different environments, including consumer
laptops, servers, and mobile devices.&lt;/p&gt;
&lt;p&gt;Additionally, we should mention
&lt;a href=&#34;https://www.arm.com/technologies/trustzone-for-cortex-a&#34;&gt;ARM TrustZone&lt;/a&gt;, which is optimized
for embedded devices such as smartphones, tablets, and smart TVs, as well as
&lt;a href=&#34;https://aws.amazon.com/ec2/nitro/nitro-enclaves/&#34;&gt;AWS Nitro Enclaves&lt;/a&gt;, which are only available
on &lt;a href=&#34;https://aws.amazon.com/&#34;&gt;Amazon Web Services&lt;/a&gt; and have a different threat model compared
to the CPU-based solutions by Intel and AMD.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.ibm.com/docs/en/linux-on-systems?topic=virtualization-secure-execution&#34;&gt;IBM Secure Execution for Linux&lt;/a&gt;
lets you run your Kubernetes cluster&#39;s nodes as KVM guests within a trusted execution environment on
IBM Z series hardware. You can use this hardware-enhanced virtual machine isolation to
provide strong isolation between tenants in a cluster, with hardware attestation about the (virtual) node&#39;s integrity.&lt;/p&gt;
&lt;h3 id=&#34;security-properties-and-feature-set&#34;&gt;Security properties and feature set&lt;/h3&gt;
&lt;p&gt;In the following sections, we will review the security properties and additional features
these new technologies bring to the table. Only some solutions will provide all properties;
we will discuss each technology in further detail in their respective section.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;Confidentiality&lt;/strong&gt; property ensures that information cannot be viewed while it is
in use in the TEE. This provides us with the highly desired feature to secure
&lt;strong&gt;data in use&lt;/strong&gt;. Depending on the specific TEE used, both code and data may be protected
from outside viewers. The differences in TEE architectures and how their use
in a cloud native context are important considerations when designing end-to-end security
for sensitive workloads with a minimal &lt;strong&gt;Trusted Computing Base&lt;/strong&gt; (TCB) in mind. CCC has recently
worked on a &lt;a href=&#34;https://confidentialcomputing.io/wp-content/uploads/sites/85/2023/01/Common-Terminology-for-Confidential-Computing.pdf&#34;&gt;common vocabulary and supporting material&lt;/a&gt;
that helps to explain where confidentiality boundaries are drawn with the different TEE
architectures and how that impacts the TCB size.&lt;/p&gt;
&lt;p&gt;Confidentiality is a great feature, but an attacker can still manipulate
or inject arbitrary code and data for the TEE to execute and, therefore, easily leak critical
information. &lt;strong&gt;Integrity&lt;/strong&gt; guarantees a TEE owner that neither code nor data can be
tampered with while running critical computations.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Availability&lt;/strong&gt; is a basic property often discussed in the context of information
security. However, this property is outside the scope of most TEEs. Usually, they can be controlled
(shut down, restarted, …) by some higher level abstraction. This could be the CPU itself, the
hypervisor, or the kernel. This is to preserve the overall system&#39;s availability,
not the TEE itself. When running in the cloud, availability is usually guaranteed by
the cloud provider in terms of Service Level Agreements (SLAs) and is not cryptographically enforceable.&lt;/p&gt;
&lt;p&gt;Confidentiality and Integrity by themselves are only helpful in some cases. For example,
consider a TEE running in a remote cloud. How would you know the TEE is genuine and running
your intended software? It could be an imposter stealing your data as soon as you send it over.
This fundamental problem is addressed by &lt;strong&gt;Attestability&lt;/strong&gt;. Attestation allows us to verify
the identity, confidentiality, and integrity of TEEs based on cryptographic certificates issued
from the hardware itself. This feature can also be made available to clients outside of the
confidential computing hardware in the form of remote attestation.&lt;/p&gt;
&lt;p&gt;TEEs can hold and process information that predates or outlives the trusted environment. That
could mean across restarts, different versions, or platform migrations. Therefore &lt;strong&gt;Recoverability&lt;/strong&gt;
is an important feature. Data and the state of a TEE need to be sealed before they are written
to persistent storage to maintain confidentiality and integrity guarantees. The access to such
sealed data needs to be well-defined. In most cases, the unsealing is bound to a TEE&#39;s identity.
Hence, making sure the recovery can only happen in the same confidential context.&lt;/p&gt;
&lt;p&gt;This does not have to limit the flexibility of the overall system.
&lt;a href=&#34;https://www.amd.com/system/files/TechDocs/SEV-SNP-strengthening-vm-isolation-with-integrity-protection-and-more.pdf&#34;&gt;AMD SEV-SNP&#39;s migration agent (MA)&lt;/a&gt;
allows users to migrate a confidential virtual machine to a different host system
while keeping the security properties of the TEE intact.&lt;/p&gt;
&lt;h2 id=&#34;feature-comparison&#34;&gt;Feature comparison&lt;/h2&gt;
&lt;p&gt;These sections of the article will dive a little bit deeper into the specific implementations,
compare supported features and analyze their security properties.&lt;/p&gt;
&lt;h3 id=&#34;amd-sev&#34;&gt;AMD SEV&lt;/h3&gt;
&lt;p&gt;AMD&#39;s &lt;a href=&#34;https://developer.amd.com/sev/&#34;&gt;Secure Encrypted Virtualization (SEV)&lt;/a&gt; technologies
are a set of features to enhance the security of virtual machines on AMD&#39;s server CPUs. SEV
transparently encrypts the memory of each VM with a unique key. SEV can also calculate a
signature of the memory contents, which can be sent to the VM&#39;s owner as an attestation that
the initial guest memory was not manipulated.&lt;/p&gt;
&lt;p&gt;The second generation of SEV, known as
&lt;a href=&#34;https://www.amd.com/content/dam/amd/en/documents/epyc-business-docs/white-papers/Protecting-VM-Register-State-with-SEV-ES.pdf&#34;&gt;Encrypted State&lt;/a&gt;
or SEV-ES, provides additional protection from the hypervisor by encrypting all
CPU register contents when a context switch occurs.&lt;/p&gt;
&lt;p&gt;The third generation of SEV,
&lt;a href=&#34;https://www.amd.com/system/files/TechDocs/SEV-SNP-strengthening-vm-isolation-with-integrity-protection-and-more.pdf&#34;&gt;Secure Nested Paging&lt;/a&gt;
or SEV-SNP, is designed to prevent software-based integrity attacks and reduce the risk associated with
compromised memory integrity. The basic principle of SEV-SNP integrity is that if a VM can read
a private (encrypted) memory page, it must always read the value it last wrote.&lt;/p&gt;
&lt;p&gt;Additionally, by allowing the guest to obtain remote attestation statements dynamically,
SNP enhances the remote attestation capabilities of SEV.&lt;/p&gt;
&lt;p&gt;AMD SEV has been implemented incrementally. New features and improvements have been added with
each new CPU generation. The Linux community makes these features available as part of the KVM hypervisor
and for host and guest kernels. The first SEV features were discussed and implemented in 2016 - see
&lt;a href=&#34;https://www.usenix.org/conference/usenixsecurity16/technical-sessions/presentation/kaplan&#34;&gt;AMD x86 Memory Encryption Technologies&lt;/a&gt;
from the 2016 Usenix Security Symposium. The latest big addition was
&lt;a href=&#34;https://www.phoronix.com/news/AMD-SEV-SNP-Arrives-Linux-5.19&#34;&gt;SEV-SNP guest support in Linux 5.19&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://azure.microsoft.com/en-us/updates/azureconfidentialvm/&#34;&gt;Confidential VMs based on AMD SEV-SNP&lt;/a&gt;
are available in Microsoft Azure since July 2022. Similarly, Google Cloud Platform (GCP) offers
&lt;a href=&#34;https://cloud.google.com/compute/confidential-vm/docs/about-cvm&#34;&gt;confidential VMs based on AMD SEV-ES&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;intel-sgx&#34;&gt;Intel SGX&lt;/h3&gt;
&lt;p&gt;Intel&#39;s
&lt;a href=&#34;https://www.intel.com/content/www/us/en/developer/tools/software-guard-extensions/overview.html&#34;&gt;Software Guard Extensions&lt;/a&gt;
has been available since 2015 and were introduced with the Skylake architecture.&lt;/p&gt;
&lt;p&gt;SGX is an instruction set that enables users to create a protected and isolated process called
an &lt;em&gt;enclave&lt;/em&gt;. It provides a reverse sandbox that protects enclaves from the operating system,
firmware, and any other privileged execution context.&lt;/p&gt;
&lt;p&gt;The enclave memory cannot be read or written from outside the enclave, regardless of
the current privilege level and CPU mode. The only way to call an enclave function is
through a new instruction that performs several protection checks. Its memory is encrypted.
Tapping the memory or connecting the DRAM modules to another system will yield only encrypted
data. The memory encryption key randomly changes every power cycle. The key is stored
within the CPU and is not accessible.&lt;/p&gt;
&lt;p&gt;Since the enclaves are process isolated, the operating system&#39;s libraries are not usable as is;
therefore, SGX enclave SDKs are required to compile programs for SGX. This also implies applications
need to be designed and implemented to consider the trusted/untrusted isolation boundaries.
On the other hand, applications get built with very minimal TCB.&lt;/p&gt;
&lt;p&gt;An emerging approach to easily transition to process-based confidential computing
and avoid the need to build custom applications is to utilize library OSes. These OSes
facilitate running native, unmodified Linux applications inside SGX enclaves.
A library OS intercepts all application requests to the host OS and processes them securely
without the application knowing it&#39;s running a TEE.&lt;/p&gt;
&lt;p&gt;The 3rd generation Xeon CPUs (aka Ice Lake Server - &amp;quot;ICX&amp;quot;) and later generations did switch to using a technology called
&lt;a href=&#34;https://www.intel.com/content/www/us/en/developer/articles/news/runtime-encryption-of-memory-with-intel-tme-mk.html&#34;&gt;Total Memory Encryption - Multi-Key&lt;/a&gt;
(TME-MK) that uses AES-XTS, moving away from the
&lt;a href=&#34;https://eprint.iacr.org/2016/204.pdf&#34;&gt;Memory Encryption Engine&lt;/a&gt;
that the consumer and Xeon E CPUs used. This increased the possible
&lt;a href=&#34;https://sgx101.gitbook.io/sgx101/sgx-bootstrap/enclave#enclave-page-cache-epc&#34;&gt;enclave page cache&lt;/a&gt;
(EPC) size (up to 512GB/CPU) and improved performance. More info
about SGX on multi-socket platforms can be found in the
&lt;a href=&#34;https://www.intel.com/content/dam/www/public/us/en/documents/white-papers/supporting-intel-sgx-on-mulit-socket-platforms.pdf&#34;&gt;Whitepaper&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;A &lt;a href=&#34;https://ark.intel.com/content/www/us/en/ark/search/featurefilter.html?productType=873&#34;&gt;list of supported platforms&lt;/a&gt;
is available from Intel.&lt;/p&gt;
&lt;p&gt;SGX is available on
&lt;a href=&#34;https://azure.microsoft.com/de-de/updates/intel-sgx-based-confidential-computing-vms-now-available-on-azure-dedicated-hosts/&#34;&gt;Azure&lt;/a&gt;,
&lt;a href=&#34;https://www.alibabacloud.com/help/en/elastic-compute-service/latest/build-an-sgx-encrypted-computing-environment&#34;&gt;Alibaba Cloud&lt;/a&gt;,
&lt;a href=&#34;https://cloud.ibm.com/docs/bare-metal?topic=bare-metal-bm-server-provision-sgx&#34;&gt;IBM&lt;/a&gt;, and many more.&lt;/p&gt;
&lt;h3 id=&#34;intel-tdx&#34;&gt;Intel TDX&lt;/h3&gt;
&lt;p&gt;Where Intel SGX aims to protect the context of a single process,
&lt;a href=&#34;https://www.intel.com/content/www/us/en/developer/articles/technical/intel-trust-domain-extensions.html&#34;&gt;Intel&#39;s Trusted Domain Extensions&lt;/a&gt;
protect a full virtual machine and are, therefore, most closely comparable to AMD SEV.&lt;/p&gt;
&lt;p&gt;As with SEV-SNP, guest support for TDX was &lt;a href=&#34;https://www.phoronix.com/news/Intel-TDX-For-Linux-5.19&#34;&gt;merged in Linux Kernel 5.19&lt;/a&gt;.
However, hardware support will land with &lt;a href=&#34;https://en.wikipedia.org/wiki/Sapphire_Rapids&#34;&gt;Sapphire Rapids&lt;/a&gt; during 2023:
&lt;a href=&#34;https://www.alibabacloud.com/help/en/elastic-compute-service/latest/build-a-tdx-confidential-computing-environment&#34;&gt;Alibaba Cloud provides&lt;/a&gt;
invitational preview instances, and
&lt;a href=&#34;https://techcommunity.microsoft.com/t5/azure-confidential-computing/preview-introducing-dcesv5-and-ecesv5-series-confidential-vms/ba-p/3800718&#34;&gt;Azure has announced&lt;/a&gt;
its TDX preview opportunity.&lt;/p&gt;
&lt;h2 id=&#34;overhead-analysis&#34;&gt;Overhead analysis&lt;/h2&gt;
&lt;p&gt;The benefits that Confidential Computing technologies provide via strong isolation and enhanced
security to customer data and workloads are not for free. Quantifying this impact is challenging and
depends on many factors: The TEE technology, the benchmark, the metrics, and the type of workload
all have a huge impact on the expected performance overhead.&lt;/p&gt;
&lt;p&gt;Intel SGX-based TEEs are hard to benchmark, as &lt;a href=&#34;https://arxiv.org/pdf/2205.06415.pdf&#34;&gt;shown&lt;/a&gt;
&lt;a href=&#34;https://www.ibr.cs.tu-bs.de/users/mahhouk/papers/eurosec2021.pdf&#34;&gt;by&lt;/a&gt;
&lt;a href=&#34;https://dl.acm.org/doi/fullHtml/10.1145/3533737.3535098&#34;&gt;different papers&lt;/a&gt;. The chosen SDK/library
OS, the application itself, as well as the resource requirements (especially large memory requirements)
have a huge impact on performance. A single-digit percentage overhead can be expected if an application
is well suited to run inside an enclave.&lt;/p&gt;
&lt;p&gt;Confidential virtual machines based on AMD SEV-SNP require no changes to the executed program
and operating system and are a lot easier to benchmark. A
&lt;a href=&#34;https://community.amd.com/t5/business/microsoft-azure-confidential-computing-powered-by-3rd-gen-epyc/ba-p/497796&#34;&gt;benchmark from Azure and AMD&lt;/a&gt;
shows that SEV-SNP VM overhead is &amp;lt;10%, sometimes as low as 2%.&lt;/p&gt;
&lt;p&gt;Although there is a performance overhead, it should be low enough to enable real-world workloads
to run in these protected environments and improve the security and privacy of our data.&lt;/p&gt;
&lt;h2 id=&#34;confidential-computing-compared-to-fhe-zkp-and-mpc&#34;&gt;Confidential Computing compared to FHE, ZKP, and MPC&lt;/h2&gt;
&lt;p&gt;Fully Homomorphic Encryption (FHE), Zero Knowledge Proof/Protocol (ZKP), and Multi-Party
Computations (MPC) are all a form of encryption or cryptographic protocols that offer
similar security guarantees to Confidential Computing but do not require hardware support.&lt;/p&gt;
&lt;p&gt;Fully (also partially and somewhat) homomorphic encryption allows one to perform
computations, such as addition or multiplication, on encrypted data. This provides
the property of encryption in use but does not provide integrity protection or attestation
like confidential computing does. Therefore, these two technologies can &lt;a href=&#34;https://confidentialcomputing.io/2023/03/29/confidential-computing-and-homomorphic-encryption/&#34;&gt;complement to each other&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Zero Knowledge Proofs or Protocols are a privacy-preserving technique (PPT) that
allows one party to prove facts about their data without revealing anything else about
the data. ZKP can be used instead of or in addition to Confidential Computing to protect
the privacy of the involved parties and their data. Similarly, Multi-Party Computation
enables multiple parties to work together on a computation, i.e., each party provides
their data to the result without leaking it to any other parties.&lt;/p&gt;
&lt;h2 id=&#34;use-cases-of-confidential-computing&#34;&gt;Use cases of Confidential Computing&lt;/h2&gt;
&lt;p&gt;The presented Confidential Computing platforms show that both the isolation of a single container
process and, therefore, minimization of the trusted computing base and the isolation of a
``
full virtual machine are possible. This has already enabled a lot of interesting and secure
projects to emerge:&lt;/p&gt;
&lt;h3 id=&#34;confidential-containers&#34;&gt;Confidential Containers&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/confidential-containers&#34;&gt;Confidential Containers&lt;/a&gt; (CoCo) is a
CNCF sandbox project that isolates Kubernetes pods inside of confidential virtual machines.&lt;/p&gt;
&lt;p&gt;CoCo can be installed on a Kubernetes cluster with an operator.
The operator will create a set of runtime classes that can be used to deploy
pods inside an enclave on several different platforms, including
AMD SEV, Intel TDX, Secure Execution for IBM Z, and Intel SGX.&lt;/p&gt;
&lt;p&gt;CoCo is typically used with signed and/or encrypted container images
which are pulled, verified, and decrypted inside the enclave.
Secrets, such as image decryption keys, are conditionally provisioned
to the enclave by a trusted Key Broker Service that validates the
hardware evidence of the TEE prior to releasing any sensitive information.&lt;/p&gt;
&lt;p&gt;CoCo has several deployment models. Since the Kubernetes control plane
is outside the TCB, CoCo is suitable for managed environments. CoCo can
be run in virtual environments that don&#39;t support nesting with the help of an
API adaptor that starts pod VMs in the cloud. CoCo can also be run on
bare metal, providing strong isolation even in multi-tenant environments.&lt;/p&gt;
&lt;h3 id=&#34;managed-confidential-kubernetes&#34;&gt;Managed confidential Kubernetes&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://learn.microsoft.com/en-us/azure/confidential-computing/confidential-node-pool-aks&#34;&gt;Azure&lt;/a&gt; and
&lt;a href=&#34;https://cloud.google.com/blog/products/identity-security/announcing-general-availability-of-confidential-gke-nodes&#34;&gt;GCP&lt;/a&gt;
both support the use of confidential virtual machines as worker nodes for their managed Kubernetes offerings.&lt;/p&gt;
&lt;p&gt;Both services aim for better workload protection and security guarantees by enabling memory encryption
for container workloads. However, they don&#39;t seek to fully isolate the cluster or workloads against
the service provider or infrastructure. Specifically, they don&#39;t offer a dedicated confidential control
plane or expose attestation capabilities for the confidential cluster/nodes.&lt;/p&gt;
&lt;p&gt;Azure also enables
&lt;a href=&#34;https://learn.microsoft.com/en-us/azure/confidential-computing/confidential-nodes-aks-overview&#34;&gt;Confidential Containers&lt;/a&gt;
in their managed Kubernetes offering. They support the creation based on
&lt;a href=&#34;https://learn.microsoft.com/en-us/azure/confidential-computing/confidential-containers-enclaves&#34;&gt;Intel SGX enclaves&lt;/a&gt;
and &lt;a href=&#34;https://techcommunity.microsoft.com/t5/azure-confidential-computing/microsoft-introduces-preview-of-confidential-containers-on-azure/ba-p/3410394&#34;&gt;AMD SEV-based VMs&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;constellation&#34;&gt;Constellation&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/edgelesssys/constellation&#34;&gt;Constellation&lt;/a&gt; is a Kubernetes engine that aims to
provide the best possible data security. Constellation wraps your entire Kubernetes cluster into
a single confidential context that is shielded from the underlying cloud infrastructure. Everything
inside is always encrypted, including at runtime in memory. It shields both the worker and control
plane nodes. In addition, it already integrates with popular CNCF software such as Cilium for
secure networking and provides extended CSI drivers to write data securely.&lt;/p&gt;
&lt;h3 id=&#34;occlum-and-gramine&#34;&gt;Occlum and Gramine&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://occlum.io/&#34;&gt;Occlum&lt;/a&gt; and &lt;a href=&#34;https://gramineproject.io/&#34;&gt;Gramine&lt;/a&gt; are examples of open source
library OS projects that can be used to run unmodified applications in SGX enclaves. They
are member projects under the CCC, but similar projects and products maintained by companies
also exist. With these libOS projects, existing containerized applications can be
easily converted into confidential computing enabled containers. Many curated prebuilt
containers are also available.&lt;/p&gt;
&lt;h2 id=&#34;where-are-we-today-vendors-limitations-and-foss-landscape&#34;&gt;Where are we today? Vendors, limitations, and FOSS landscape&lt;/h2&gt;
&lt;p&gt;As we hope you have seen from the previous sections, Confidential Computing is a powerful new concept
to improve security, but we are still in the (early) adoption phase. New products are
starting to emerge to take advantage of the unique properties.&lt;/p&gt;
&lt;p&gt;Google and Microsoft are the first major cloud providers to have confidential offerings that
can run unmodified applications inside a protected boundary.
Still, these offerings are limited to compute, while end-to-end solutions for confidential
databases, cluster networking, and load balancers have to be self-managed.&lt;/p&gt;
&lt;p&gt;These technologies provide opportunities to bring even the most
sensitive workloads into the cloud and enables them to leverage all the
tools in the CNCF landscape.&lt;/p&gt;
&lt;h2 id=&#34;call-to-action&#34;&gt;Call to action&lt;/h2&gt;
&lt;p&gt;If you are currently working on a high-security product that struggles to run in the
public cloud due to legal requirements or are looking to bring the privacy and security
of your cloud-native project to the next level: Reach out to all the great projects
we have highlighted! Everyone is keen to improve the security of our ecosystem, and you can
play a vital role in that journey.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/confidential-containers&#34;&gt;Confidential Containers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/edgelesssys/constellation&#34;&gt;Constellation: Always Encrypted Kubernetes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://occlum.io/&#34;&gt;Occlum&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gramineproject.io/&#34;&gt;Gramine&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;CCC also maintains a &lt;a href=&#34;https://confidentialcomputing.io/projects/&#34;&gt;list of projects&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Verifying Container Image Signatures Within CRI Runtimes</title>
      <link>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/06/29/container-image-signature-verification/</link>
      <pubDate>Thu, 29 Jun 2023 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/06/29/container-image-signature-verification/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Author&lt;/strong&gt;: Sascha Grunert&lt;/p&gt;
&lt;p&gt;The Kubernetes community has been signing their container image-based artifacts
since release v1.24. While the graduation of the &lt;a href=&#34;https://github.com/kubernetes/enhancements/issues/3031&#34;&gt;corresponding enhancement&lt;/a&gt;
from &lt;code&gt;alpha&lt;/code&gt; to &lt;code&gt;beta&lt;/code&gt; in v1.26 introduced signatures for the binary artifacts,
other projects followed the approach by providing image signatures for their
releases, too. This means that they either create the signatures within their
own CI/CD pipelines, for example by using GitHub actions, or rely on the
Kubernetes &lt;a href=&#34;https://github.com/kubernetes-sigs/promo-tools/blob/e2b96dd/docs/image-promotion.md&#34;&gt;image promotion&lt;/a&gt; process to automatically sign the images by
proposing pull requests to the &lt;a href=&#34;https://github.com/kubernetes/k8s.io/tree/4b95cc2/k8s.gcr.io&#34;&gt;k/k8s.io&lt;/a&gt; repository. A requirement for
using this process is that the project is part of the &lt;code&gt;kubernetes&lt;/code&gt; or
&lt;code&gt;kubernetes-sigs&lt;/code&gt; GitHub organization, so that they can utilize the community
infrastructure for pushing images into staging buckets.&lt;/p&gt;
&lt;p&gt;Assuming that a project now produces signed container image artifacts, how can
one actually verify the signatures? It is possible to do it manually like
outlined in the &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/tasks/administer-cluster/verify-signed-artifacts/#verifying-image-signatures&#34;&gt;official Kubernetes documentation&lt;/a&gt;. The problem with this
approach is that it involves no automation at all and should be only done for
testing purposes. In production environments, tools like the &lt;a href=&#34;https://docs.sigstore.dev/policy-controller/overview&#34;&gt;sigstore
policy-controller&lt;/a&gt; can help with the automation. These tools
provide a higher level API by using &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/concepts/extend-kubernetes/api-extension/custom-resources&#34;&gt;Custom Resource Definitions (CRD)&lt;/a&gt; as
well as an integrated &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/reference/access-authn-authz/admission-controllers&#34;&gt;admission controller and webhook&lt;/a&gt; to verify
the signatures.&lt;/p&gt;
&lt;p&gt;The general usage flow for an admission controller based verification is:&lt;/p&gt;

&lt;figure&gt;
    &lt;img src=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/06/29/container-image-signature-verification/flow.svg&#34;
         alt=&#34;Create an instance of the policy and annotate the namespace to validate the signatures. Then create the pod. The controller evaluates the policy and if it passes, then it does the image pull if necessary. If the policy evaluation fails, then it will not admit the pod.&#34;/&gt; 
&lt;/figure&gt;

&lt;p&gt;A key benefit of this architecture is simplicity: A single instance within the
cluster validates the signatures before any image pull can happen in the
container runtime on the nodes, which gets initiated by the kubelet. This
benefit also brings along the issue of separation: The node which should pull
the container image is not necessarily the same node that performs the admission. This
means that if the controller is compromised, then a cluster-wide policy
enforcement can no longer be possible.&lt;/p&gt;
&lt;p&gt;One way to solve this issue is doing the policy evaluation directly within the
&lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/concepts/architecture/cri&#34;&gt;Container Runtime Interface (CRI)&lt;/a&gt; compatible container runtime. The
runtime is directly connected to the &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/reference/command-line-tools-reference/kubelet&#34;&gt;kubelet&lt;/a&gt; on a node and does all
the tasks like pulling images. &lt;a href=&#34;https://github.com/cri-o/cri-o&#34;&gt;CRI-O&lt;/a&gt; is one of those available runtimes
and will feature full support for container image signature verification in v1.28.&lt;/p&gt;
&lt;p&gt;How does it work? CRI-O reads a file called &lt;a href=&#34;https://github.com/containers/image/blob/b3e0ba2/docs/containers-policy.json.5.md#sigstoresigned&#34;&gt;&lt;code&gt;policy.json&lt;/code&gt;&lt;/a&gt;, which
contains all the rules defined for container images. For example, you can define a
policy which only allows signed images &lt;code&gt;quay.io/crio/signed&lt;/code&gt; for any tag or
digest 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-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;default&amp;#34;&lt;/span&gt;: [{ &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;reject&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;transports&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;docker&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;quay.io/crio/signed&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;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;sigstoreSigned&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;signedIdentity&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;matchRepository&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;fulcio&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;oidcIssuer&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;https://github.com/login/oauth&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;subjectEmail&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;sgrunert@redhat.com&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;caData&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUI5ekNDQVh5Z0F3SUJBZ0lVQUxaTkFQRmR4SFB3amVEbG9Ed3lZQ2hBTy80d0NnWUlLb1pJemowRUF3TXcKS2pFVk1CTUdBMVVFQ2hNTWMybG5jM1J2Y21VdVpHVjJNUkV3RHdZRFZRUURFd2h6YVdkemRHOXlaVEFlRncweQpNVEV3TURjeE16VTJOVGxhRncwek1URXdNRFV4TXpVMk5UaGFNQ294RlRBVEJnTlZCQW9UREhOcFozTjBiM0psCkxtUmxkakVSTUE4R0ExVUVBeE1JYzJsbmMzUnZjbVV3ZGpBUUJnY3Foa2pPUFFJQkJnVXJnUVFBSWdOaUFBVDcKWGVGVDRyYjNQUUd3UzRJYWp0TGszL09sbnBnYW5nYUJjbFlwc1lCcjVpKzR5bkIwN2NlYjNMUDBPSU9aZHhleApYNjljNWlWdXlKUlErSHowNXlpK1VGM3VCV0FsSHBpUzVzaDArSDJHSEU3U1hyazFFQzVtMVRyMTlMOWdnOTJqCll6QmhNQTRHQTFVZER3RUIvd1FFQXdJQkJqQVBCZ05WSFJNQkFmOEVCVEFEQVFIL01CMEdBMVVkRGdRV0JCUlkKd0I1ZmtVV2xacWw2ekpDaGt5TFFLc1hGK2pBZkJnTlZIU01FR0RBV2dCUll3QjVma1VXbFpxbDZ6SkNoa3lMUQpLc1hGK2pBS0JnZ3Foa2pPUFFRREF3TnBBREJtQWpFQWoxbkhlWFpwKzEzTldCTmErRURzRFA4RzFXV2cxdENNCldQL1dIUHFwYVZvMGpoc3dlTkZaZ1NzMGVFN3dZSTRxQWpFQTJXQjlvdDk4c0lrb0YzdlpZZGQzL1Z0V0I1YjkKVE5NZWE3SXgvc3RKNVRmY0xMZUFCTEU0Qk5KT3NRNHZuQkhKCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=&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;rekorPublicKeyData&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFMkcyWSsydGFiZFRWNUJjR2lCSXgwYTlmQUZ3cgprQmJtTFNHdGtzNEwzcVg2eVlZMHp1ZkJuaEM4VXIvaXk1NUdoV1AvOUEvYlkyTGhDMzBNOStSWXR3PT0KLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg==&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;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;p&gt;CRI-O has to be started to use that policy as the global source of truth:&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;&amp;gt;&lt;/span&gt; sudo crio --log-level debug --signature-policy ./policy.json
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;CRI-O is now able to pull the image while verifying its signatures. This can be
done by using &lt;a href=&#34;https://github.com/kubernetes-sigs/cri-tools&#34;&gt;&lt;code&gt;crictl&lt;/code&gt; (cri-tools)&lt;/a&gt;, 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-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;&amp;gt;&lt;/span&gt; sudo crictl -D pull quay.io/crio/signed
&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;DEBU[…] get image connection
&lt;/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;DEBU[…] PullImageRequest: &amp;amp;PullImageRequest{Image:&amp;amp;ImageSpec{Image:quay.io/crio/signed,Annotations:map[string]string{},},Auth:nil,SandboxConfig:nil,}
&lt;/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;DEBU[…] PullImageResponse: &amp;amp;PullImageResponse{ImageRef:quay.io/crio/signed@sha256:18b42e8ea347780f35d979a829affa178593a8e31d90644466396e1187a07f3a,}
&lt;/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;Image is up to date for quay.io/crio/signed@sha256:18b42e8ea347780f35d979a829affa178593a8e31d90644466396e1187a07f3a
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The CRI-O debug logs will also indicate that the signature got successfully
validated:&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;DEBU[…] IsRunningImageAllowed for image docker:quay.io/crio/signed:latest
&lt;/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;DEBU[…]  Using transport &amp;#34;docker&amp;#34; specific policy section quay.io/crio/signed
&lt;/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;DEBU[…] Reading /var/lib/containers/sigstore/crio/signed@sha256=18b42e8ea347780f35d979a829affa178593a8e31d90644466396e1187a07f3a/signature-1
&lt;/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;DEBU[…] Looking for sigstore attachments in quay.io/crio/signed:sha256-18b42e8ea347780f35d979a829affa178593a8e31d90644466396e1187a07f3a.sig
&lt;/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;DEBU[…] GET https://quay.io/v2/crio/signed/manifests/sha256-18b42e8ea347780f35d979a829affa178593a8e31d90644466396e1187a07f3a.sig
&lt;/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;DEBU[…] Content-Type from manifest GET is &amp;#34;application/vnd.oci.image.manifest.v1+json&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:#888&#34;&gt;DEBU[…] Found a sigstore attachment manifest with 1 layers
&lt;/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;DEBU[…] Fetching sigstore attachment 1/1: sha256:8276724a208087e73ae5d9d6e8f872f67808c08b0acdfdc73019278807197c45
&lt;/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;DEBU[…] Downloading /v2/crio/signed/blobs/sha256:8276724a208087e73ae5d9d6e8f872f67808c08b0acdfdc73019278807197c45
&lt;/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;DEBU[…] GET https://quay.io/v2/crio/signed/blobs/sha256:8276724a208087e73ae5d9d6e8f872f67808c08b0acdfdc73019278807197c45
&lt;/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;DEBU[…]  Requirement 0: allowed
&lt;/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;DEBU[…] Overall: allowed
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;All of the defined fields like &lt;code&gt;oidcIssuer&lt;/code&gt; and &lt;code&gt;subjectEmail&lt;/code&gt; in the policy
have to match, while &lt;code&gt;fulcio.caData&lt;/code&gt; and &lt;code&gt;rekorPublicKeyData&lt;/code&gt; are the public
keys from the upstream &lt;a href=&#34;https://github.com/sigstore/fulcio&#34;&gt;fulcio (OIDC PKI)&lt;/a&gt; and &lt;a href=&#34;https://github.com/sigstore/rekor&#34;&gt;rekor
(transparency log)&lt;/a&gt; instances.&lt;/p&gt;
&lt;p&gt;This means that if you now invalidate the &lt;code&gt;subjectEmail&lt;/code&gt; of the policy, for example to
&lt;code&gt;wrong@mail.com&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-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;&amp;gt;&lt;/span&gt; jq &lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;.transports.docker.&amp;#34;quay.io/crio/signed&amp;#34;[0].fulcio.subjectEmail = &amp;#34;wrong@mail.com&amp;#34;&amp;#39;&lt;/span&gt; policy.json &amp;gt; new-policy.json
&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;&amp;gt;&lt;/span&gt; mv new-policy.json policy.json
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then remove the image, since it already exists locally:&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;&amp;gt;&lt;/span&gt; sudo crictl rmi quay.io/crio/signed
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now when you pull the image, CRI-O complains that the required email is wrong:&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;&amp;gt;&lt;/span&gt; sudo crictl pull quay.io/crio/signed
&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;FATA[…] pulling image: rpc error: code = Unknown desc = Source image rejected: Required email wrong@mail.com not found (got []string{&amp;#34;sgrunert@redhat.com&amp;#34;})
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It is also possible to test an unsigned image against the policy. For that you
have to modify the key &lt;code&gt;quay.io/crio/signed&lt;/code&gt; to something like
&lt;code&gt;quay.io/crio/unsigned&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-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;&amp;gt;&lt;/span&gt; sed -i &lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;s;quay.io/crio/signed;quay.io/crio/unsigned;&amp;#39;&lt;/span&gt; policy.json
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If you now pull the container image, CRI-O will complain that no signature exists
for 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-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;&amp;gt;&lt;/span&gt; sudo crictl pull quay.io/crio/unsigned
&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;FATA[…] pulling image: rpc error: code = Unknown desc = SignatureValidationFailed: Source image rejected: A signature was required, but no signature exists
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It is important to mention that CRI-O will match the
&lt;code&gt;.critical.identity.docker-reference&lt;/code&gt; field within the signature to match with
the image repository. For example, if you verify the image
&lt;code&gt;registry.k8s.io/kube-apiserver-amd64:v1.28.0-alpha.3&lt;/code&gt;, then the corresponding
&lt;code&gt;docker-reference&lt;/code&gt; should be &lt;code&gt;registry.k8s.io/kube-apiserver-amd64&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-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;&amp;gt;&lt;/span&gt; cosign verify registry.k8s.io/kube-apiserver-amd64:v1.28.0-alpha.3 &lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;    --certificate-identity krel-trust@k8s-releng-prod.iam.gserviceaccount.com \
&lt;/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;    --certificate-oidc-issuer https://accounts.google.com \
&lt;/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;    | jq -r &amp;#39;.[0].critical.identity.&amp;#34;docker-reference&amp;#34;&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:#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;&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:#888&#34;&gt;registry.k8s.io/kubernetes/kube-apiserver-amd64
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The Kubernetes community introduced &lt;code&gt;registry.k8s.io&lt;/code&gt; as proxy mirror for
various registries. Before the release of &lt;a href=&#34;https://github.com/kubernetes-sigs/promo-tools/releases/tag/v4.0.2&#34;&gt;kpromo v4.0.2&lt;/a&gt;, images
had been signed with the actual mirror rather than &lt;code&gt;registry.k8s.io&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-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;&amp;gt;&lt;/span&gt; cosign verify registry.k8s.io/kube-apiserver-amd64:v1.28.0-alpha.2 &lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;    --certificate-identity krel-trust@k8s-releng-prod.iam.gserviceaccount.com \
&lt;/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;    --certificate-oidc-issuer https://accounts.google.com \
&lt;/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;    | jq -r &amp;#39;.[0].critical.identity.&amp;#34;docker-reference&amp;#34;&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:#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;&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:#888&#34;&gt;asia-northeast2-docker.pkg.dev/k8s-artifacts-prod/images/kubernetes/kube-apiserver-amd64
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The change of the &lt;code&gt;docker-reference&lt;/code&gt; to &lt;code&gt;registry.k8s.io&lt;/code&gt; makes it easier for
end users to validate the signatures, because they cannot know anything about the
underlying infrastructure being used. The feature to set the identity on image
signing has been added to &lt;a href=&#34;https://github.com/sigstore/cosign/pull/2984&#34;&gt;cosign&lt;/a&gt; via the flag &lt;code&gt;sign --sign-container-identity&lt;/code&gt; as well and will be part of its upcoming release.&lt;/p&gt;
&lt;p&gt;The Kubernetes image pull error code &lt;code&gt;SignatureValidationFailed&lt;/code&gt; got &lt;a href=&#34;https://github.com/kubernetes/kubernetes/pull/117717&#34;&gt;recently added to
Kubernetes&lt;/a&gt; and will be available from v1.28. This error code allows
end-users to understand image pull failures directly from the kubectl CLI. For
example, if you run CRI-O together with Kubernetes using the policy which requires
&lt;code&gt;quay.io/crio/unsigned&lt;/code&gt; to be signed, then a pod definition 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-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;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;quay.io/crio/unsigned&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;Will cause the &lt;code&gt;SignatureValidationFailed&lt;/code&gt; error when applying the pod manifest:&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;&amp;gt;&lt;/span&gt; kubectl apply -f pod.yaml
&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;pod/pod created
&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-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;&amp;gt;&lt;/span&gt; kubectl get pods
&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;NAME   READY   STATUS                      RESTARTS   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;pod    0/1     SignatureValidationFailed   0          4s
&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-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;&amp;gt;&lt;/span&gt; kubectl describe pod pod | tail -n8
&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;  Type     Reason     Age                From               Message
&lt;/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&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;  Normal   Scheduled  58s                default-scheduler  Successfully assigned default/pod to 127.0.0.1
&lt;/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;  Normal   BackOff    22s (x2 over 55s)  kubelet            Back-off pulling image &amp;#34;quay.io/crio/unsigned&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:#888&#34;&gt;  Warning  Failed     22s (x2 over 55s)  kubelet            Error: ImagePullBackOff
&lt;/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;  Normal   Pulling    9s (x3 over 58s)   kubelet            Pulling image &amp;#34;quay.io/crio/unsigned&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:#888&#34;&gt;  Warning  Failed     6s (x3 over 55s)   kubelet            Failed to pull image &amp;#34;quay.io/crio/unsigned&amp;#34;: SignatureValidationFailed: Source image rejected: A signature was required, but no signature exists
&lt;/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;  Warning  Failed     6s (x3 over 55s)   kubelet            Error: SignatureValidationFailed
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This overall behavior provides a more Kubernetes native experience and does not
rely on third party software to be installed in the cluster.&lt;/p&gt;
&lt;p&gt;There are still a few corner cases to consider: For example, what if you want to
allow policies per namespace in the same way the policy-controller supports it?
Well, there is an upcoming CRI-O feature in v1.28 for that! CRI-O will support
the &lt;code&gt;--signature-policy-dir&lt;/code&gt; / &lt;code&gt;signature_policy_dir&lt;/code&gt; option, which defines the
root path for pod namespace-separated signature policies. This means that CRI-O
will lookup that path and assemble a policy like &lt;code&gt;&amp;lt;SIGNATURE_POLICY_DIR&amp;gt;/&amp;lt;NAMESPACE&amp;gt;.json&lt;/code&gt;,
which will be used on image pull if existing. If no pod namespace is
provided on image pull (&lt;a href=&#34;https://github.com/kubernetes/cri-api/blob/e5515a5/pkg/apis/runtime/v1/api.proto#L1448&#34;&gt;via the sandbox config&lt;/a&gt;), or the
concatenated path is non-existent, then CRI-O&#39;s global policy will be used as
fallback.&lt;/p&gt;
&lt;p&gt;Another corner case to consider is critical for the correct signature
verification within container runtimes: The kubelet only invokes container image
pulls if the image does not already exist on disk. This means that an
unrestricted policy from Kubernetes namespace A can allow pulling an image,
while namespace B is not able to enforce the policy because it already exits on
the node. Finally, CRI-O has to verify the policy not only on image pull, but
also on container creation. This fact makes things even a bit more complicated,
because the CRI does not really pass down the user specified image reference on
container creation, but an already resolved image ID, or digest. A &lt;a href=&#34;https://github.com/kubernetes/kubernetes/pull/118652&#34;&gt;small
change to the CRI&lt;/a&gt; can help with that.&lt;/p&gt;
&lt;p&gt;Now that everything happens within the container runtime, someone has to
maintain and define the policies to provide a good user experience around that
feature. The CRDs of the policy-controller are great, while we could imagine that
a daemon within the cluster can write the policies for CRI-O per namespace. This
would make any additional hook obsolete and moves the responsibility of
verifying the image signature to the actual instance which pulls the image. &lt;a href=&#34;https://groups.google.com/g/kubernetes-sig-node/c/kgpxqcsJ7Vc/m/7X7t_ElsAgAJ&#34;&gt;I
evaluated&lt;/a&gt; other possible paths toward a better container image
signature verification within plain Kubernetes, but I could not find a great fit
for a native API. This means that I believe that a CRD is the way to go, but
users still need an instance which actually serves it.&lt;/p&gt;
&lt;p&gt;Thank you for reading this blog post! If you&#39;re interested in more, providing
feedback or asking for help, then feel free to get in touch with me directly via
&lt;a href=&#34;https://kubernetes.slack.com/messages/crio&#34;&gt;Slack (#crio)&lt;/a&gt; or the &lt;a href=&#34;https://groups.google.com/forum/#!forum/kubernetes-sig-node&#34;&gt;SIG Node mailing list&lt;/a&gt;.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>dl.k8s.io to adopt a Content Delivery Network</title>
      <link>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/06/09/dl-adopt-cdn/</link>
      <pubDate>Fri, 09 Jun 2023 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/06/09/dl-adopt-cdn/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Authors&lt;/strong&gt;: Arnaud Meukam (VMware), Hannah Aubry (Fastly), Frederico
Muñoz (SAS Institute)&lt;/p&gt;
&lt;p&gt;We&#39;re happy to announce that dl.k8s.io, home of the official Kubernetes
binaries, will soon be powered by &lt;a href=&#34;https://www.fastly.com&#34;&gt;Fastly&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Fastly is known for its high-performance content delivery network (CDN) designed
to deliver content quickly and reliably around the world. With its powerful
network, Fastly will help us deliver official Kubernetes binaries to users
faster and more reliably than ever before.&lt;/p&gt;
&lt;p&gt;The decision to use Fastly was made after an extensive evaluation process in
which we carefully evaluated several potential content delivery network
providers. Ultimately, we chose Fastly because of their commitment to the open
internet and proven track record of delivering fast and secure digital
experiences to some of the most known open source projects (through their &lt;a href=&#34;https://www.fastly.com/fast-forward&#34;&gt;Fast
Forward&lt;/a&gt; program).&lt;/p&gt;
&lt;h2 id=&#34;what-you-need-to-know-about-this-change&#34;&gt;What you need to know about this change&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;On Monday, July 24th, the IP addresses and backend storage associated with the
dl.k8s.io domain name will change.&lt;/li&gt;
&lt;li&gt;The change will not impact the vast majority of users since the domain
name will remain the same.&lt;/li&gt;
&lt;li&gt;If you restrict access to specific IP ranges, access to the dl.k8s.io domain
could stop working.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you think you may be impacted or want to know more about this change,
please keep reading.&lt;/p&gt;
&lt;h2 id=&#34;why-are-we-making-this-change&#34;&gt;Why are we making this change&lt;/h2&gt;
&lt;p&gt;The official Kubernetes binaries site, dl.k8s.io, is used by thousands of users
all over the world, and currently serves &lt;em&gt;more than 5 petabytes of binaries each
month&lt;/em&gt;. This change will allow us to improve access to those resources by
leveraging a world-wide CDN.&lt;/p&gt;
&lt;h2 id=&#34;does-this-affect-dl-k8s-io-only-or-are-other-domains-also-affected&#34;&gt;Does this affect dl.k8s.io only, or are other domains also affected?&lt;/h2&gt;
&lt;p&gt;Only dl.k8s.io will be affected by this change.&lt;/p&gt;
&lt;h2 id=&#34;my-company-specifies-the-domain-names-that-we-are-allowed-to-be-accessed-will-this-change-affect-the-domain-name&#34;&gt;My company specifies the domain names that we are allowed to be accessed. Will this change affect the domain name?&lt;/h2&gt;
&lt;p&gt;No, the domain name (&lt;code&gt;dl.k8s.io&lt;/code&gt;) will remain the same: no change will be
necessary, and access to the Kubernetes release binaries site should not be
affected.&lt;/p&gt;
&lt;h2 id=&#34;my-company-uses-some-form-of-ip-filtering-will-this-change-affect-access-to-the-site&#34;&gt;My company uses some form of IP filtering. Will this change affect access to the site?&lt;/h2&gt;
&lt;p&gt;If IP-based filtering is in place, it’s possible that access to the site will be
affected when the new IP addresses become active.&lt;/p&gt;
&lt;h2 id=&#34;if-my-company-doesn-t-use-ip-addresses-to-restrict-network-traffic-do-we-need-to-do-anything&#34;&gt;If my company doesn’t use IP addresses to restrict network traffic, do we need to do anything?&lt;/h2&gt;
&lt;p&gt;No, the switch to the CDN should be transparent.&lt;/p&gt;
&lt;h2 id=&#34;will-there-be-a-dual-running-period&#34;&gt;Will there be a dual running period?&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;No, it is a cutover.&lt;/strong&gt; You can, however, test your networks right now to check
if they can route to the new public IP addresses from Fastly.  You should add
the new IPs to your network&#39;s &lt;code&gt;allowlist&lt;/code&gt; before July 24th. Once the transfer is
complete, ensure your networks use the new IP addresses to connect to
the &lt;code&gt;dl.k8s.io&lt;/code&gt; service.&lt;/p&gt;
&lt;h2 id=&#34;what-are-the-new-ip-addresses&#34;&gt;What are the new IP addresses?&lt;/h2&gt;
&lt;p&gt;If you need to manage an allow list for downloads, you can get the ranges to
match from the Fastly API, in JSON: &lt;a href=&#34;https://api.fastly.com/public-ip-list&#34;&gt;public IP address
ranges&lt;/a&gt;.  You don&#39;t need any credentials
to download that list of ranges.&lt;/p&gt;
&lt;h2 id=&#34;what-next-steps-would-you-recommend&#34;&gt;What next steps would you recommend?&lt;/h2&gt;
&lt;p&gt;If you have IP-based filtering in place, we recommend the following course of
action &lt;strong&gt;before July, 24th&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add the new IP addresses to your allowlist.&lt;/li&gt;
&lt;li&gt;Conduct tests with your networks/firewall to ensure your networks can route to
the new IP addresses.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After the change is made, we recommend double-checking that HTTP calls are
accessing dl.k8s.io with the new IP addresses.&lt;/p&gt;
&lt;h2 id=&#34;what-should-i-do-if-i-detect-some-abnormality-after-the-cutover-date&#34;&gt;What should I do if I detect some abnormality after the cutover date?&lt;/h2&gt;
&lt;p&gt;If you encounter any weirdness during binaries download, please &lt;a href=&#34;https://github.com/kubernetes/k8s.io/issues/new/choose&#34;&gt;open an
issue&lt;/a&gt;.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Using OCI artifacts to distribute security profiles for seccomp, SELinux and AppArmor</title>
      <link>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/05/24/oci-security-profiles/</link>
      <pubDate>Wed, 24 May 2023 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/05/24/oci-security-profiles/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Author&lt;/strong&gt;: Sascha Grunert&lt;/p&gt;
&lt;p&gt;The &lt;a href=&#34;https://github.com/kubernetes-sigs/security-profiles-operator&#34;&gt;Security Profiles Operator (SPO)&lt;/a&gt; makes managing seccomp, SELinux and
AppArmor profiles within Kubernetes easier than ever. It allows cluster
administrators to define the profiles in a predefined custom resource YAML,
which then gets distributed by the SPO into the whole cluster. Modification and
removal of the security profiles are managed by the operator in the same way,
but that’s a small subset of its capabilities.&lt;/p&gt;
&lt;p&gt;Another core feature of the SPO is being able to stack seccomp profiles. This
means that users can define a &lt;code&gt;baseProfileName&lt;/code&gt; in the YAML specification, which
then gets automatically resolved by the operator and combines the syscall rules.
If a base profile has another &lt;code&gt;baseProfileName&lt;/code&gt;, then the operator will
recursively resolve the profiles up to a certain depth. A common use case is to
define base profiles for low level container runtimes (like &lt;a href=&#34;https://github.com/opencontainers/runc&#34;&gt;runc&lt;/a&gt; or
&lt;a href=&#34;https://github.com/containers/crun&#34;&gt;crun&lt;/a&gt;) which then contain syscalls which are required in any case to run
the container. Alternatively, application developers can define seccomp base
profiles for their standard distribution containers and stack dedicated profiles
for the application logic on top. This way developers can focus on maintaining
seccomp profiles which are way simpler and scoped to the application logic,
without having a need to take the whole infrastructure setup into account.&lt;/p&gt;
&lt;p&gt;But how to maintain those base profiles? For example, the amount of required
syscalls for a runtime can change over its release cycle in the same way it can
change for the main application. Base profiles have to be available in the same
cluster, otherwise the main seccomp profile will fail to deploy. This means that
they’re tightly coupled to the main application profiles, which acts against the
main idea of base profiles. Distributing and managing them as plain files feels
like an additional burden to solve.&lt;/p&gt;
&lt;h2 id=&#34;oci-artifacts-to-the-rescue&#34;&gt;OCI artifacts to the rescue&lt;/h2&gt;
&lt;p&gt;The &lt;a href=&#34;https://github.com/kubernetes-sigs/security-profiles-operator/releases/v0.8.0&#34;&gt;v0.8.0&lt;/a&gt; release of the Security Profiles Operator supports
managing base profiles as OCI artifacts! Imagine OCI artifacts as lightweight
container images, storing files in layers in the same way images do, but without
a process to be executed. Those artifacts can be used to store security profiles
like regular container images in compatible registries. This means they can be
versioned, namespaced and annotated similar to regular container images.&lt;/p&gt;
&lt;p&gt;To see how that works in action, specify a &lt;code&gt;baseProfileName&lt;/code&gt; prefixed with
&lt;code&gt;oci://&lt;/code&gt; within a seccomp profile CRD, 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;security-profiles-operator.x-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;SeccompProfile&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;defaultAction&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;SCMP_ACT_ERRNO&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;baseProfileName&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;oci://ghcr.io/security-profiles/runc:v1.1.5&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;syscalls&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;SCMP_ACT_ALLOW&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;names&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;- uname&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 operator will take care of pulling the content by using &lt;a href=&#34;https://oras.land&#34;&gt;oras&lt;/a&gt;, as
well as verifying the &lt;a href=&#34;https://github.com/sigstore/cosign&#34;&gt;sigstore (cosign)&lt;/a&gt; signatures of the artifact. If
the artifacts are not signed, then the SPO will reject them. The resulting
profile &lt;code&gt;test&lt;/code&gt; will then contain all base syscalls from the remote &lt;code&gt;runc&lt;/code&gt;
profile plus the additional allowed &lt;code&gt;uname&lt;/code&gt; one. It is also possible to
reference the base profile by its digest (SHA256) making the artifact to be
pulled more specific, for example by referencing
&lt;code&gt;oci://ghcr.io/security-profiles/runc@sha256:380…&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The operator internally caches pulled artifacts up to 24 hours for 1000
profiles, meaning that they will be refreshed after that time period, if the
cache is full or the operator daemon gets restarted.&lt;/p&gt;
&lt;p&gt;Because the overall resulting syscalls are hidden from the user (I only have the
&lt;code&gt;baseProfileName&lt;/code&gt; listed in the SeccompProfile, and not the syscalls themselves), I&#39;ll additionally
annotate that SeccompProfile with the final &lt;code&gt;syscalls&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Here&#39;s how the SeccompProfile looks after I annotate 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-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;&amp;gt;&lt;/span&gt; kubectl describe seccompprofile &lt;span style=&#34;color:#a2f&#34;&gt;test&lt;/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;Name:         test
&lt;/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;Namespace:    security-profiles-operator
&lt;/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;Labels:       spo.x-k8s.io/profile-id=SeccompProfile-test
&lt;/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;Annotations:  syscalls:
&lt;/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;                [{&amp;#34;names&amp;#34;:[&amp;#34;arch_prctl&amp;#34;,&amp;#34;brk&amp;#34;,&amp;#34;capget&amp;#34;,&amp;#34;capset&amp;#34;,&amp;#34;chdir&amp;#34;,&amp;#34;clone&amp;#34;,&amp;#34;close&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:#888&#34;&gt;API Version:  security-profiles-operator.x-k8s.io/v1beta1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The SPO maintainers provide all public base profiles as part of the &lt;a href=&#34;https://github.com/orgs/security-profiles/packages&#34;&gt;“Security
Profiles” GitHub organization&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;managing-oci-security-profiles&#34;&gt;Managing OCI security profiles&lt;/h2&gt;
&lt;p&gt;Alright, now the official SPO provides a bunch of base profiles, but how can I
define my own? Well, first of all we have to choose a working registry. There
are a bunch of registries that already supports OCI artifacts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/distribution/distribution&#34;&gt;CNCF Distribution&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://aka.ms/acr&#34;&gt;Azure Container Registry&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://aws.amazon.com/ecr&#34;&gt;Amazon Elastic Container Registry&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://cloud.google.com/artifact-registry&#34;&gt;Google Artifact Registry&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.github.com/en/packages/guides/about-github-container-registry&#34;&gt;GitHub Packages container registry&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://hub.docker.com&#34;&gt;Docker Hub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://zotregistry.io&#34;&gt;Zot Registry&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The Security Profiles Operator ships a new command line interface called &lt;code&gt;spoc&lt;/code&gt;,
which is a little helper tool for managing OCI profiles among doing various other
things which are out of scope of this blog post. But, the command &lt;code&gt;spoc push&lt;/code&gt;
can be used to push a security profile to a registry:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;gt; export USERNAME=my-user
&amp;gt; export PASSWORD=my-pass
&amp;gt; spoc push -f ./examples/baseprofile-crun.yaml ghcr.io/security-profiles/crun:v1.8.3
16:35:43.899886 Pushing profile ./examples/baseprofile-crun.yaml to: ghcr.io/security-profiles/crun:v1.8.3
16:35:43.899939 Creating file store in: /tmp/push-3618165827
16:35:43.899947 Adding profile to store: ./examples/baseprofile-crun.yaml
16:35:43.900061 Packing files
16:35:43.900282 Verifying reference: ghcr.io/security-profiles/crun:v1.8.3
16:35:43.900310 Using tag: v1.8.3
16:35:43.900313 Creating repository for ghcr.io/security-profiles/crun
16:35:43.900319 Using username and password
16:35:43.900321 Copying profile to repository
16:35:46.976108 Signing container image
Generating ephemeral keys...
Retrieving signed certificate...

        Note that there may be personally identifiable information associated with this signed artifact.
        This may include the email address associated with the account with which you authenticate.
        This information will be used for signing this artifact and will be stored in public transparency logs and cannot be removed later.

By typing &amp;#39;y&amp;#39;, you attest that you grant (or have permission to grant) and agree to have this information stored permanently in transparency logs.
Your browser will now be opened to:
https://oauth2.sigstore.dev/auth/auth?access_type=…
Successfully verified SCT...
tlog entry created with index: 16520520
Pushing signature to: ghcr.io/security-profiles/crun
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can see that the tool automatically signs the artifact and pushes the
&lt;code&gt;./examples/baseprofile-crun.yaml&lt;/code&gt; to the registry, which is then directly ready
for usage within the SPO. If username and password authentication is required,
either use the &lt;code&gt;--username&lt;/code&gt;, &lt;code&gt;-u&lt;/code&gt; flag or export the &lt;code&gt;USERNAME&lt;/code&gt; environment
variable. To set the password, export the &lt;code&gt;PASSWORD&lt;/code&gt; environment variable.&lt;/p&gt;
&lt;p&gt;It is possible to add custom annotations to the security profile by using the
&lt;code&gt;--annotations&lt;/code&gt; / &lt;code&gt;-a&lt;/code&gt; flag multiple times in &lt;code&gt;KEY:VALUE&lt;/code&gt; format. Those have no
effect for now, but at some later point additional features of the operator may
rely them.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;spoc&lt;/code&gt; client is also able to pull security profiles from OCI artifact
compatible registries. To do that, just run &lt;code&gt;spoc pull&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-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;&amp;gt;&lt;/span&gt; spoc pull ghcr.io/security-profiles/runc:v1.1.5
&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;16:32:29.795597 Pulling profile from: ghcr.io/security-profiles/runc:v1.1.5
&lt;/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;16:32:29.795610 Verifying signature
&lt;/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:#888&#34;&gt;Verification for ghcr.io/security-profiles/runc:v1.1.5 --
&lt;/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;The following checks were performed on each of these signatures:
&lt;/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;  - Existence of the claims in the transparency log was verified offline
&lt;/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;  - The code-signing certificate was verified using trusted certificate authority certificates
&lt;/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:#888&#34;&gt;[{&amp;#34;critical&amp;#34;:{&amp;#34;identity&amp;#34;:{&amp;#34;docker-reference&amp;#34;:&amp;#34;ghcr.io/security-profiles/runc&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:#888&#34;&gt;16:32:33.208695 Creating file store in: /tmp/pull-3199397214
&lt;/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;16:32:33.208713 Verifying reference: ghcr.io/security-profiles/runc:v1.1.5
&lt;/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;16:32:33.208718 Creating repository for ghcr.io/security-profiles/runc
&lt;/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;16:32:33.208742 Using tag: v1.1.5
&lt;/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;16:32:33.208743 Copying profile from repository
&lt;/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;16:32:34.119652 Reading profile
&lt;/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;16:32:34.119677 Trying to unmarshal seccomp profile
&lt;/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;16:32:34.120114 Got SeccompProfile: runc-v1.1.5
&lt;/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;16:32:34.120119 Saving profile in: /tmp/profile.yaml
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The profile can be now found in &lt;code&gt;/tmp/profile.yaml&lt;/code&gt; or the specified output file
&lt;code&gt;--output-file&lt;/code&gt; / &lt;code&gt;-o&lt;/code&gt;. We can specify an username and password in the same way
as for &lt;code&gt;spoc push&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;spoc&lt;/code&gt; makes it easy to manage security profiles as OCI artifacts, which can be
then consumed directly by the operator itself.&lt;/p&gt;
&lt;p&gt;That was our compact journey through the latest possibilities of the Security
Profiles Operator! If you&#39;re interested in more, providing feedback or asking
for help, then feel free to get in touch with us directly via &lt;a href=&#34;https://kubernetes.slack.com/messages/security-profiles-operator&#34;&gt;Slack
(#security-profiles-operator)&lt;/a&gt; or &lt;a href=&#34;https://groups.google.com/forum/#!forum/kubernetes-dev&#34;&gt;the mailing list&lt;/a&gt;.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Having fun with seccomp profiles on the edge</title>
      <link>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/05/18/seccomp-profiles-edge/</link>
      <pubDate>Thu, 18 May 2023 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/05/18/seccomp-profiles-edge/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Author&lt;/strong&gt;: Sascha Grunert&lt;/p&gt;
&lt;p&gt;The &lt;a href=&#34;https://github.com/kubernetes-sigs/security-profiles-operator&#34;&gt;Security Profiles Operator (SPO)&lt;/a&gt; is a feature-rich
&lt;a href=&#34;https://kubernetes.io/docs/concepts/extend-kubernetes/operator&#34;&gt;operator&lt;/a&gt; for Kubernetes to make managing seccomp, SELinux and
AppArmor profiles easier than ever. Recording those profiles from scratch is one
of the key features of this operator, which usually involves the integration
into large CI/CD systems. Being able to test the recording capabilities of the
operator in edge cases is one of the recent development efforts of the SPO and
makes it excitingly easy to play around with seccomp profiles.&lt;/p&gt;
&lt;h2 id=&#34;recording-seccomp-profiles-with-spoc-record&#34;&gt;Recording seccomp profiles with &lt;code&gt;spoc record&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;a href=&#34;https://github.com/kubernetes-sigs/security-profiles-operator/releases/v0.8.0&#34;&gt;v0.8.0&lt;/a&gt; release of the Security Profiles Operator shipped a new
command line interface called &lt;code&gt;spoc&lt;/code&gt;, a little helper tool for recording and
replaying seccomp profiles among various other things that are out of scope of
this blog post.&lt;/p&gt;
&lt;p&gt;Recording a seccomp profile requires a binary to be executed, which can be a
simple golang application which just calls &lt;a href=&#34;https://man7.org/linux/man-pages/man2/uname.2.html&#34;&gt;&lt;code&gt;uname(2)&lt;/code&gt;&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;package&lt;/span&gt; main
&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;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;color:#b44&#34;&gt;&amp;#34;syscall&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:#a2f;font-weight:bold&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#00a000&#34;&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	utsname &lt;span style=&#34;color:#666&#34;&gt;:=&lt;/span&gt; syscall.Utsname{}
&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; err &lt;span style=&#34;color:#666&#34;&gt;:=&lt;/span&gt; syscall.&lt;span style=&#34;color:#00a000&#34;&gt;Uname&lt;/span&gt;(&lt;span style=&#34;color:#666&#34;&gt;&amp;amp;&lt;/span&gt;utsname); err &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;		&lt;span style=&#34;color:#a2f&#34;&gt;panic&lt;/span&gt;(err)
&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;p&gt;Building a binary from that code can be done by:&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;&amp;gt;&lt;/span&gt; go build -o main main.go
&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;&amp;gt;&lt;/span&gt; ldd ./main
&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;        not a dynamic executable
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now it&#39;s possible to download the latest binary of &lt;a href=&#34;https://github.com/kubernetes-sigs/security-profiles-operator/releases/download/v0.8.0/spoc.amd64&#34;&gt;&lt;code&gt;spoc&lt;/code&gt; from
GitHub&lt;/a&gt; and run the application on Linux with 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-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;&amp;gt;&lt;/span&gt; sudo ./spoc record ./main
&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;10:08:25.591945 Loading bpf module
&lt;/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;10:08:25.591958 Using system btf 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;libbpf: loading object &amp;#39;recorder.bpf.o&amp;#39; from buffer
&lt;/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&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;libbpf: prog &amp;#39;sys_enter&amp;#39;: relo #3: patched insn #22 (ALU/ALU64) imm 16 -&amp;gt; 16
&lt;/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;10:08:25.610767 Getting bpf program sys_enter
&lt;/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;10:08:25.610778 Attaching bpf tracepoint
&lt;/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;10:08:25.611574 Getting syscalls map
&lt;/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;10:08:25.611582 Getting pid_mntns map
&lt;/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;10:08:25.613097 Module successfully loaded
&lt;/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;10:08:25.613311 Processing events
&lt;/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;10:08:25.613693 Running command with PID: 336007
&lt;/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;10:08:25.613835 Received event: pid: 336007, mntns: 4026531841
&lt;/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;10:08:25.613951 No container ID found for PID (pid=336007, mntns=4026531841, err=unable to find container ID in cgroup path)
&lt;/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;10:08:25.614856 Processing recorded 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:#888&#34;&gt;10:08:25.614975 Found process mntns 4026531841 in bpf map
&lt;/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;10:08:25.615110 Got syscalls: read, close, mmap, rt_sigaction, rt_sigprocmask, madvise, nanosleep, clone, uname, sigaltstack, arch_prctl, gettid, futex, sched_getaffinity, exit_group, openat
&lt;/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;10:08:25.615195 Adding base syscalls: access, brk, capget, capset, chdir, chmod, chown, close_range, dup2, dup3, epoll_create1, epoll_ctl, epoll_pwait, execve, faccessat2, fchdir, fchmodat, fchown, fchownat, fcntl, fstat, fstatfs, getdents64, getegid, geteuid, getgid, getpid, getppid, getuid, ioctl, keyctl, lseek, mkdirat, mknodat, mount, mprotect, munmap, newfstatat, openat2, pipe2, pivot_root, prctl, pread64, pselect6, readlink, readlinkat, rt_sigreturn, sched_yield, seccomp, set_robust_list, set_tid_address, setgid, setgroups, sethostname, setns, setresgid, setresuid, setsid, setuid, statfs, statx, symlinkat, tgkill, umask, umount2, unlinkat, unshare, write
&lt;/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;10:08:25.616293 Wrote seccomp profile to: /tmp/profile.yaml
&lt;/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;10:08:25.616298 Unloading bpf module
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I have to execute &lt;code&gt;spoc&lt;/code&gt; as root because it will internally run an &lt;a href=&#34;https://ebpf.io&#34;&gt;ebpf&lt;/a&gt;
program by reusing the same code parts from the Security Profiles Operator
itself. I can see that the bpf module got loaded successfully and &lt;code&gt;spoc&lt;/code&gt;
attached the required tracepoint to it. Then it will track the main application
by using its &lt;a href=&#34;https://man7.org/linux/man-pages/man7/mount_namespaces.7.html&#34;&gt;mount namespace&lt;/a&gt; and process the recorded syscall data. The
nature of ebpf programs is that they see the whole context of the Kernel, which
means that &lt;code&gt;spoc&lt;/code&gt; tracks all syscalls of the system, but does not interfere with
their execution.&lt;/p&gt;
&lt;p&gt;The logs indicate that &lt;code&gt;spoc&lt;/code&gt; found the syscalls &lt;code&gt;read&lt;/code&gt;, &lt;code&gt;close&lt;/code&gt;,
&lt;code&gt;mmap&lt;/code&gt; and so on, including &lt;code&gt;uname&lt;/code&gt;. All other syscalls than &lt;code&gt;uname&lt;/code&gt; are coming
from the golang runtime and its garbage collection, which already adds overhead
to a basic application like in our demo. I can also see from the log line
&lt;code&gt;Adding base syscalls: …&lt;/code&gt; that &lt;code&gt;spoc&lt;/code&gt; adds a bunch of base syscalls to the
resulting profile. Those are used by the OCI runtime (like &lt;a href=&#34;https://github.com/opencontainers/runc&#34;&gt;runc&lt;/a&gt; or
&lt;a href=&#34;https://github.com/containers/crun&#34;&gt;crun&lt;/a&gt;) in order to be able to run a container. This means that &lt;code&gt;spoc&lt;/code&gt;
can be used to record seccomp profiles which then can be containerized directly.
This behavior can be disabled in &lt;code&gt;spoc&lt;/code&gt; by using the &lt;code&gt;--no-base-syscalls&lt;/code&gt;/&lt;code&gt;-n&lt;/code&gt;
or customized via the &lt;code&gt;--base-syscalls&lt;/code&gt;/&lt;code&gt;-b&lt;/code&gt; command line flags. This can be
helpful in cases where different OCI runtimes other than crun and runc are used,
or if I just want to record the seccomp profile for the application and stack
it with another &lt;a href=&#34;https://github.com/kubernetes-sigs/security-profiles-operator/blob/35ebdda/installation-usage.md#base-syscalls-for-a-container-runtime&#34;&gt;base profile&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The resulting profile is now available in &lt;code&gt;/tmp/profile.yaml&lt;/code&gt;, but the default
location can be changed using the &lt;code&gt;--output-file value&lt;/code&gt;/&lt;code&gt;-o&lt;/code&gt; flag:&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;&amp;gt;&lt;/span&gt; cat /tmp/profile.yaml
&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:#008000;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;security-profiles-operator.x-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;SeccompProfile&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;creationTimestamp&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;null&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;main&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;architectures&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- SCMP_ARCH_X86_64&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;defaultAction&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;SCMP_ACT_ERRNO&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;syscalls&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;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;SCMP_ACT_ALLOW&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;names&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;- access&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;- arch_prctl&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;- brk&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#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;- uname&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#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;status&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;The seccomp profile Custom Resource Definition (CRD) can be directly used
together with the Security Profiles Operator for managing it within Kubernetes.
&lt;code&gt;spoc&lt;/code&gt; is also capable of producing raw seccomp profiles (as JSON), by using the
&lt;code&gt;--type&lt;/code&gt;/&lt;code&gt;-t&lt;/code&gt; &lt;code&gt;raw-seccomp&lt;/code&gt; flag:&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;&amp;gt;&lt;/span&gt; sudo ./spoc record --type raw-seccomp ./main
&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;52.628827 Wrote seccomp profile to: /tmp/profile.json
&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-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;&amp;gt;&lt;/span&gt; jq . /tmp/profile.json
&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-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;defaultAction&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;SCMP_ACT_ERRNO&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;architectures&amp;#34;&lt;/span&gt;: [&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;SCMP_ARCH_X86_64&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;syscalls&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;names&amp;#34;&lt;/span&gt;: [&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;access&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;…&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;write&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;action&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;SCMP_ACT_ALLOW&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;p&gt;The utility &lt;code&gt;spoc record&lt;/code&gt; allows us to record complex seccomp profiles directly
from binary invocations in any Linux system which is capable of running the ebpf
code within the Kernel. But it can do more: How about modifying the seccomp
profile and then testing it by using &lt;code&gt;spoc run&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;running-seccomp-profiles-with-spoc-run&#34;&gt;Running seccomp profiles with &lt;code&gt;spoc run&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;spoc&lt;/code&gt; is also able to run binaries with applied seccomp profiles, making it
easy to test any modification to it. To do that, just run:&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;&amp;gt;&lt;/span&gt; sudo ./spoc run ./main
&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;10:29:58.153263 Reading file /tmp/profile.yaml
&lt;/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;10:29:58.153311 Assuming YAML profile
&lt;/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;10:29:58.154138 Setting up seccomp
&lt;/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;10:29:58.154178 Load seccomp profile
&lt;/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;10:29:58.154189 Starting audit log enricher
&lt;/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;10:29:58.154224 Enricher reading from file /var/log/audit/audit.log
&lt;/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;10:29:58.155356 Running command with PID: 437880
&lt;/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;color:#000080;font-weight:bold&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It looks like that the application exited successfully, which is anticipated
because I did not modify the previously recorded profile yet. I can also
specify a custom location for the profile by using the &lt;code&gt;--profile&lt;/code&gt;/&lt;code&gt;-p&lt;/code&gt; flag,
but this was not necessary because I did not modify the default output location
from the record. &lt;code&gt;spoc&lt;/code&gt; will automatically determine if it&#39;s a raw (JSON) or CRD
(YAML) based seccomp profile and then apply it to the process.&lt;/p&gt;
&lt;p&gt;The Security Profiles Operator supports a &lt;a href=&#34;https://github.com/kubernetes-sigs/security-profiles-operator/blob/35ebdda/installation-usage.md#using-the-log-enricher&#34;&gt;log enricher feature&lt;/a&gt;,
which provides additional seccomp related information by parsing the audit logs.
&lt;code&gt;spoc run&lt;/code&gt; uses the enricher in the same way to provide more data to the end
users when it comes to debugging seccomp profiles.&lt;/p&gt;
&lt;p&gt;Now I have to modify the profile to see anything valuable in the output. For
example, I could remove the allowed &lt;code&gt;uname&lt;/code&gt; syscall:&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;&amp;gt;&lt;/span&gt; jq &lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;del(.syscalls[0].names[] | select(. == &amp;#34;uname&amp;#34;))&amp;#39;&lt;/span&gt; /tmp/profile.json &amp;gt; /tmp/no-uname-profile.json
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And then try to run it again with the new profile &lt;code&gt;/tmp/no-uname-profile.json&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-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;&amp;gt;&lt;/span&gt; sudo ./spoc run -p /tmp/no-uname-profile.json ./main
&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;10:39:12.707798 Reading file /tmp/no-uname-profile.json
&lt;/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;10:39:12.707892 Setting up seccomp
&lt;/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;10:39:12.707920 Load seccomp profile
&lt;/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;10:39:12.707982 Starting audit log enricher
&lt;/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;10:39:12.707998 Enricher reading from file /var/log/audit/audit.log
&lt;/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;10:39:12.709164 Running command with PID: 480512
&lt;/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;panic: operation not permitted
&lt;/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:#888&#34;&gt;goroutine 1 [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:#888&#34;&gt;main.main()
&lt;/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;        /path/to/main.go:10 +0x85
&lt;/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;10:39:12.713035 Unable to run: launch runner: wait for command: exit status 2
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Alright, that was expected! The applied seccomp profile blocks the &lt;code&gt;uname&lt;/code&gt;
syscall, which results in an &amp;quot;operation not permitted&amp;quot; error. This error is
pretty generic and does not provide any hint on what got blocked by seccomp.
It is generally extremely difficult to predict how applications behave if single
syscalls are forbidden by seccomp. It could be possible that the application
terminates like in our simple demo, but it could also lead to a strange
misbehavior and the application does not stop at all.&lt;/p&gt;
&lt;p&gt;If I now change the default seccomp action of the profile from &lt;code&gt;SCMP_ACT_ERRNO&lt;/code&gt;
to &lt;code&gt;SCMP_ACT_LOG&lt;/code&gt; 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:#000080;font-weight:bold&#34;&gt;&amp;gt;&lt;/span&gt; jq &lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;.defaultAction = &amp;#34;SCMP_ACT_LOG&amp;#34;&amp;#39;&lt;/span&gt; /tmp/no-uname-profile.json &amp;gt; /tmp/no-uname-profile-log.json
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then the log enricher will give us a hint that the &lt;code&gt;uname&lt;/code&gt; syscall got blocked
when using &lt;code&gt;spoc run&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-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;&amp;gt;&lt;/span&gt; sudo ./spoc run -p /tmp/no-uname-profile-log.json ./main
&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;10:48:07.470126 Reading file /tmp/no-uname-profile-log.json
&lt;/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;10:48:07.470234 Setting up seccomp
&lt;/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;10:48:07.470245 Load seccomp profile
&lt;/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;10:48:07.470302 Starting audit log enricher
&lt;/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;10:48:07.470339 Enricher reading from file /var/log/audit/audit.log
&lt;/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;10:48:07.470889 Running command with PID: 522268
&lt;/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;10:48:07.472007 Seccomp: uname (63)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The application will not terminate any more, but seccomp will log the behavior
to &lt;code&gt;/var/log/audit/audit.log&lt;/code&gt; and &lt;code&gt;spoc&lt;/code&gt; will parse the data to correlate it
directly to our program. Generating the log messages to the audit subsystem
comes with a large performance overhead and should be handled with care in
production systems. It also comes with a security risk when running untrusted
apps in audit mode in production environments.&lt;/p&gt;
&lt;p&gt;This demo should give you an impression how to debug seccomp profile issues with
applications, probably by using our shiny new helper tool powered by the
features of the Security Profiles Operator. &lt;code&gt;spoc&lt;/code&gt; is a flexible and portable
binary suitable for edge cases where resources are limited and even Kubernetes
itself may not be available with its full capabilities.&lt;/p&gt;
&lt;p&gt;Thank you for reading this blog post! If you&#39;re interested in more, providing
feedback or asking for help, then feel free to get in touch with us directly via
&lt;a href=&#34;https://kubernetes.slack.com/messages/security-profiles-operator&#34;&gt;Slack (#security-profiles-operator)&lt;/a&gt; or the &lt;a href=&#34;https://groups.google.com/forum/#!forum/kubernetes-dev&#34;&gt;mailing list&lt;/a&gt;.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes 1.27: KMS V2 Moves to Beta</title>
      <link>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/05/16/kms-v2-moves-to-beta/</link>
      <pubDate>Tue, 16 May 2023 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/05/16/kms-v2-moves-to-beta/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Authors:&lt;/strong&gt; Anish Ramasekar, Mo Khan, and Rita Zhang (Microsoft)&lt;/p&gt;
&lt;p&gt;With Kubernetes 1.27, we (SIG Auth) are moving Key Management Service (KMS) v2 API to beta.&lt;/p&gt;
&lt;h2 id=&#34;what-is-kms&#34;&gt;What is KMS?&lt;/h2&gt;
&lt;p&gt;One of the first things to consider when securing a Kubernetes cluster is encrypting etcd data at
rest. KMS provides an interface for a provider to utilize a key stored in an external key service to
perform this encryption.&lt;/p&gt;
&lt;p&gt;KMS v1 has been a feature of Kubernetes since version 1.10, and is currently in beta as of version
v1.12. KMS v2 was introduced as alpha in v1.25.&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;

    The KMS v2 API and implementation changed in incompatible
ways in-between the alpha release in v1.25 and the beta release in v1.27. The design of KMS v2 has
changed since &lt;a href=&#34;https://kubernetes.io/blog/2022/09/09/kms-v2-improvements/&#34;&gt;the previous blog post&lt;/a&gt;
was written and it is not compatible with the design in this blog post. Attempting to upgrade from
old versions with the alpha feature enabled will result in data loss.

&lt;/div&gt;

&lt;h2 id=&#34;what-s-new-in-v2beta1&#34;&gt;What’s new in &lt;code&gt;v2beta1&lt;/code&gt;?&lt;/h2&gt;
&lt;p&gt;The KMS encryption provider uses an envelope encryption scheme to encrypt data in etcd. The data is
encrypted using a data encryption key (DEK). The DEKs are encrypted with a key encryption key (KEK)
that is stored and managed in a remote KMS. With KMS v1, a new DEK is generated for each encryption.
With KMS v2, a new DEK is only generated on server startup and when the KMS plugin informs the API
server that a KEK rotation has occurred.&lt;/p&gt;


&lt;div class=&#34;alert alert-warning&#34; role=&#34;alert&#34;&gt;
&lt;h4 class=&#34;alert-heading&#34;&gt;Caution&lt;/h4&gt;

    &lt;p&gt;If you are running virtual machine (VM) based nodes
that leverage VM state store with this feature, you must not use KMS v2.&lt;/p&gt;
&lt;p&gt;With KMS v2, the API server uses AES-GCM with a 12 byte nonce (8 byte atomic counter and 4 bytes
random data) for encryption. The following issues could occur if the VM is saved and restored:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The counter value may be lost or corrupted if the VM is saved in an inconsistent state or
restored improperly. This can lead to a situation where the same counter value is used twice,
resulting in the same nonce being used for two different messages.&lt;/li&gt;
&lt;li&gt;If the VM is restored to a previous state, the counter value may be set back to its previous
value, resulting in the same nonce being used again.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Although both of these cases are partially mitigated by the 4 byte random nonce, this can compromise
the security of the encryption.&lt;/p&gt;


&lt;/div&gt;

&lt;h3 id=&#34;sequence-diagram&#34;&gt;Sequence Diagram&lt;/h3&gt;
&lt;h4 id=&#34;encrypt-request&#34;&gt;Encrypt Request&lt;/h4&gt;
&lt;!-- source
```mermaid
%%{init:{&#34;theme&#34;:&#34;neutral&#34;, &#34;sequence&#34;: {&#34;mirrorActors&#34;:true},
    &#34;themeVariables&#34;: {
        &#34;actorBkg&#34;:&#34;royalblue&#34;,
        &#34;actorTextColor&#34;:&#34;white&#34;
}}}%%

sequenceDiagram
    participant user
    participant kube_api_server
    participant kms_plugin
    participant external_kms
    alt Generate DEK at startup
        Note over kube_api_server,external_kms: Refer to Generate Data Encryption Key (DEK) diagram for details
    end
    user-&gt;&gt;kube_api_server: create/update resource that&#39;s to be encrypted
    kube_api_server-&gt;&gt;kube_api_server: encrypt resource with DEK
    kube_api_server-&gt;&gt;etcd: store encrypted object
```
--&gt;

&lt;figure class=&#34;diagram-large&#34;&gt;
    &lt;img src=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/images/blog/2023-05-16-kubernetes-1.27-kmsv2-beta/kubernetes-1.27-encryption.svg&#34;
         alt=&#34;Sequence diagram for KMSv2 beta Encrypt&#34;/&gt; 
&lt;/figure&gt;

&lt;h4 id=&#34;decrypt-request&#34;&gt;Decrypt Request&lt;/h4&gt;
&lt;!-- source
```mermaid
%%{init:{&#34;theme&#34;:&#34;neutral&#34;, &#34;sequence&#34;: {&#34;mirrorActors&#34;:true},
    &#34;themeVariables&#34;: {
        &#34;actorBkg&#34;:&#34;royalblue&#34;,
        &#34;actorTextColor&#34;:&#34;white&#34;
}}}%%

sequenceDiagram
    participant user
    participant kube_api_server
    participant kms_plugin
    participant external_kms
    participant etcd
    user-&gt;&gt;kube_api_server: get/list resource that&#39;s encrypted
    kube_api_server-&gt;&gt;etcd: get encrypted resource
    etcd-&gt;&gt;kube_api_server: encrypted resource
    alt Encrypted DEK not in cache
        kube_api_server-&gt;&gt;kms_plugin: decrypt request
        kms_plugin-&gt;&gt;external_kms: decrypt DEK with remote KEK
        external_kms-&gt;&gt;kms_plugin: decrypted DEK
        kms_plugin-&gt;&gt;kube_api_server: return decrypted DEK
        kube_api_server-&gt;&gt;kube_api_server: cache decrypted DEK
    end
    kube_api_server-&gt;&gt;kube_api_server: decrypt resource with DEK
    kube_api_server-&gt;&gt;user: return decrypted resource
```
--&gt;

&lt;figure class=&#34;diagram-large&#34;&gt;
    &lt;img src=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/images/blog/2023-05-16-kubernetes-1.27-kmsv2-beta/kubernetes-1.27-decryption.svg&#34;
         alt=&#34;Sequence diagram for KMSv2 beta Decrypt&#34;/&gt; 
&lt;/figure&gt;

&lt;h4 id=&#34;status-request&#34;&gt;Status Request&lt;/h4&gt;
&lt;!-- source
```mermaid
%%{init:{&#34;theme&#34;:&#34;neutral&#34;, &#34;sequence&#34;: {&#34;mirrorActors&#34;:true},
    &#34;themeVariables&#34;: {
        &#34;actorBkg&#34;:&#34;royalblue&#34;,
        &#34;actorTextColor&#34;:&#34;white&#34;
}}}%%

sequenceDiagram
    participant kube_api_server
    participant kms_plugin
    participant external_kms
    alt Generate DEK at startup
        Note over kube_api_server,external_kms: Refer to Generate Data Encryption Key (DEK) diagram for details
    end
    loop every minute (or every 10s if error or unhealthy)
        kube_api_server-&gt;&gt;kms_plugin: status request
        kms_plugin-&gt;&gt;external_kms: validate remote KEK
        external_kms-&gt;&gt;kms_plugin: KEK status
        kms_plugin-&gt;&gt;kube_api_server: return status response &lt;br/&gt; {&#34;healthz&#34;: &#34;ok&#34;, key_id: &#34;&lt;remote KEK ID&gt;&#34;, &#34;version&#34;: &#34;v2beta1&#34;}
        alt KEK rotation detected (key_id changed), rotate DEK
            Note over kube_api_server,external_kms: Refer to Generate Data Encryption Key (DEK) diagram for details
        end
    end
```
--&gt;

&lt;figure class=&#34;diagram-large&#34;&gt;
    &lt;img src=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/images/blog/2023-05-16-kubernetes-1.27-kmsv2-beta/kubernetes-1.27-status.svg&#34;
         alt=&#34;Sequence diagram for KMSv2 beta Status&#34;/&gt; 
&lt;/figure&gt;

&lt;h4 id=&#34;generate-data-encryption-key-dek&#34;&gt;Generate Data Encryption Key (DEK)&lt;/h4&gt;
&lt;!-- source
```mermaid
%%{init:{&#34;theme&#34;:&#34;neutral&#34;, &#34;sequence&#34;: {&#34;mirrorActors&#34;:true},
    &#34;themeVariables&#34;: {
        &#34;actorBkg&#34;:&#34;royalblue&#34;,
        &#34;actorTextColor&#34;:&#34;white&#34;
}}}%%

sequenceDiagram
    participant kube_api_server
    participant kms_plugin
    participant external_kms
        kube_api_server-&gt;&gt;kube_api_server: generate DEK
        kube_api_server-&gt;&gt;kms_plugin: encrypt request
        kms_plugin-&gt;&gt;external_kms: encrypt DEK with remote KEK
        external_kms-&gt;&gt;kms_plugin: encrypted DEK
        kms_plugin-&gt;&gt;kube_api_server: return encrypt response &lt;br/&gt; {&#34;ciphertext&#34;: &#34;&lt;encrypted DEK&gt;&#34;, key_id: &#34;&lt;remote KEK ID&gt;&#34;, &#34;annotations&#34;: {}}
```
--&gt;

&lt;figure class=&#34;diagram-large&#34;&gt;
    &lt;img src=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/images/blog/2023-05-16-kubernetes-1.27-kmsv2-beta/kubernetes-1.27-generate-dek.svg&#34;
         alt=&#34;Sequence diagram for KMSv2 beta Generate DEK&#34;/&gt; 
&lt;/figure&gt;

&lt;h3 id=&#34;performance-improvements&#34;&gt;Performance Improvements&lt;/h3&gt;
&lt;p&gt;With KMS v2, we have made significant improvements to the performance of the KMS encryption
provider. In case of KMS v1, a new DEK is generated for every encryption. This means that for every
write request, the API server makes a call to the KMS plugin to encrypt the DEK using the remote
KEK. The API server also has to cache the DEKs to avoid making a call to the KMS plugin for every
read request. When the API server restarts, it has to populate the cache by making a call to the KMS
plugin for every DEK in the etcd store based on the cache size. This is a significant overhead for
the API server. With KMS v2, the API server generates a DEK at startup and caches it. The API server
also makes a call to the KMS plugin to encrypt the DEK using the remote KEK. This is a one-time call
at startup and on KEK rotation. The API server then uses the cached DEK to encrypt the resources.
This reduces the number of calls to the KMS plugin and improves the overall latency of the API
server requests.&lt;/p&gt;
&lt;p&gt;We conducted a test that created 12k secrets and measured the time taken for the API server to
encrypt the resources. The metric used was
&lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/reference/instrumentation/metrics/&#34;&gt;&lt;code&gt;apiserver_storage_transformation_duration_seconds&lt;/code&gt;&lt;/a&gt;.
For KMS v1, the test was run on a managed Kubernetes v1.25 cluster with 2 nodes. There was no
additional load on the cluster during the test. For KMS v2, the test was run in the Kubernetes CI
environment with the following &lt;a href=&#34;https://github.com/kubernetes/kubernetes/blob/release-1.27/test/e2e/testing-manifests/auth/encrypt/kind.yaml&#34;&gt;cluster
configuration&lt;/a&gt;.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;KMS Provider&lt;/th&gt;
&lt;th&gt;Time taken by 95 percentile&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;KMS v1&lt;/td&gt;
&lt;td&gt;160ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;KMS v2&lt;/td&gt;
&lt;td&gt;80μs&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The results show that the KMS v2 encryption provider is three orders of magnitude faster than the
KMS v1 encryption provider.&lt;/p&gt;
&lt;h2 id=&#34;what-s-next&#34;&gt;What&#39;s next?&lt;/h2&gt;
&lt;p&gt;For Kubernetes v1.28, we expect the feature to stay in beta. In the coming releases we want to
investigate:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Cryptographic changes to remove the limitation on VM state store.&lt;/li&gt;
&lt;li&gt;Kubernetes REST API changes to enable a more robust story around key rotation.&lt;/li&gt;
&lt;li&gt;Handling undecryptable resources. Refer to the
&lt;a href=&#34;https://github.com/kubernetes/enhancements/pull/3927&#34;&gt;KEP&lt;/a&gt; for details.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can learn more about KMS v2 by reading &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/tasks/administer-cluster/kms-provider/&#34;&gt;Using a KMS provider for data
encryption&lt;/a&gt;. You can also follow along on the
&lt;a href=&#34;https://github.com/kubernetes/enhancements/blob/master/keps/sig-auth/3299-kms-v2-improvements/#readme&#34;&gt;KEP&lt;/a&gt;
to track progress across the 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 blog post, we have covered the improvements made to the KMS encryption provider in
Kubernetes v1.27. We have also discussed the new KMS v2 API and how it works. We would love to hear
your feedback on this feature. In particular, we would like feedback from Kubernetes KMS plugin
implementors as they go through the process of building their integrations with this new API. Please
reach out to us on the &lt;a href=&#34;https://kubernetes.slack.com/archives/C03035EH4VB&#34;&gt;#sig-auth-kms-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 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;
&lt;h2 id=&#34;acknowledgements&#34;&gt;Acknowledgements&lt;/h2&gt;
&lt;p&gt;This feature has been an effort driven by contributors from several different companies. We would
like to extend a huge thank you to everyone that contributed their time and effort to help make this
possible.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes 1.27: updates on speeding up Pod startup</title>
      <link>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/05/15/speed-up-pod-startup/</link>
      <pubDate>Mon, 15 May 2023 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/05/15/speed-up-pod-startup/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Authors&lt;/strong&gt;: Paco Xu (DaoCloud), Sergey Kanzhelev (Google), Ruiwen Zhao (Google)&lt;/p&gt;
&lt;p&gt;How can Pod start-up be accelerated on nodes in large clusters? This is a common issue that
cluster administrators may face.&lt;/p&gt;
&lt;p&gt;This blog post focuses on methods to speed up pod start-up from the kubelet side. It does not
involve the creation time of pods by controller-manager through kube-apiserver, nor does it
include scheduling time for pods or webhooks executed on it.&lt;/p&gt;
&lt;p&gt;We have mentioned some important factors here to consider from the kubelet&#39;s perspective, but
this is not an exhaustive list. As Kubernetes v1.27 is released, this blog highlights
significant changes in v1.27 that aid in speeding up pod start-up.&lt;/p&gt;
&lt;h2 id=&#34;parallel-container-image-pulls&#34;&gt;Parallel container image pulls&lt;/h2&gt;
&lt;p&gt;Pulling images always takes some time and what&#39;s worse is that image pulls are done serially by
default. In other words, kubelet will send only one image pull request to the image service at
a time. Other image pull requests have to wait until the one being processed is complete.&lt;/p&gt;
&lt;p&gt;To enable parallel image pulls, set the &lt;code&gt;serializeImagePulls&lt;/code&gt; field to false in the kubelet
configuration. When &lt;code&gt;serializeImagePulls&lt;/code&gt; is disabled, requests for image pulls are immediately
sent to the image service and multiple images can be pulled concurrently.&lt;/p&gt;
&lt;h3 id=&#34;maximum-parallel-image-pulls-will-help-secure-your-node-from-overloading-on-image-pulling&#34;&gt;Maximum parallel image pulls will help secure your node from overloading on image pulling&lt;/h3&gt;
&lt;p&gt;We introduced a new feature in kubelet that sets a limit on the number of parallel image
pulls at the node level. This limit restricts the maximum number of images that can be pulled
simultaneously. If there is an image pull request beyond this limit, it will be blocked until
one of the ongoing image pulls finishes. Before enabling this feature, please ensure that your
container runtime&#39;s image service can handle parallel image pulls effectively.&lt;/p&gt;
&lt;p&gt;To limit the number of simultaneous image pulls, you can configure the &lt;code&gt;maxParallelImagePulls&lt;/code&gt;
field in kubelet. By setting &lt;code&gt;maxParallelImagePulls&lt;/code&gt; to a value of &lt;em&gt;n&lt;/em&gt;, only &lt;em&gt;n&lt;/em&gt; images will
be pulled concurrently. Any additional image pulls beyond this limit will wait until at least
one ongoing pull is complete.&lt;/p&gt;
&lt;p&gt;You can find more details in the associated KEP: &lt;a href=&#34;https://kep.k8s.io/3673&#34;&gt;Kubelet limit of Parallel Image Pulls&lt;/a&gt;
(KEP-3673).&lt;/p&gt;
&lt;h2 id=&#34;raised-default-api-query-per-second-limits-for-kubelet&#34;&gt;Raised default API query-per-second limits for kubelet&lt;/h2&gt;
&lt;p&gt;To improve pod startup in scenarios with multiple pods on a node, particularly sudden scaling
situations, it is necessary for Kubelet to synchronize the pod status and prepare configmaps,
secrets, or volumes. This requires a large bandwidth to access kube-apiserver.&lt;/p&gt;
&lt;p&gt;In versions prior to v1.27, the default &lt;code&gt;kubeAPIQPS&lt;/code&gt; was 5 and &lt;code&gt;kubeAPIBurst&lt;/code&gt; was 10. However,
the kubelet in v1.27 has increased these defaults to 50 and 100 respectively for better performance during
pod startup. It&#39;s worth noting that this isn&#39;t the only reason why we&#39;ve bumped up the API QPS
limits for Kubelet.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;It has a potential to be hugely throttled now (default QPS = 5)&lt;/li&gt;
&lt;li&gt;In large clusters they can generate significant load anyway as there are a lot of them&lt;/li&gt;
&lt;li&gt;They have a dedicated PriorityLevel and FlowSchema that we can easily control&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Previously, we often encountered &lt;code&gt;volume mount timeout&lt;/code&gt; on kubelet in node with more than 50 pods
during pod start up. We suggest that cluster operators bump &lt;code&gt;kubeAPIQPS&lt;/code&gt; to 20 and &lt;code&gt;kubeAPIBurst&lt;/code&gt; to 40,
especially if using bare metal nodes.&lt;/p&gt;
&lt;p&gt;More detials can be found in the KEP &lt;a href=&#34;https://kep.k8s.io/1040&#34;&gt;https://kep.k8s.io/1040&lt;/a&gt; and the pull request &lt;a href=&#34;https://github.com/kubernetes/kubernetes/pull/116121&#34;&gt;#116121&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;event-triggered-updates-to-container-status&#34;&gt;Event triggered updates to container status&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;Evented PLEG&lt;/code&gt; (PLEG is short for &amp;quot;Pod Lifecycle Event Generator&amp;quot;) is set to be in beta for v1.27,
Kubernetes offers two ways for the kubelet to detect Pod lifecycle events, such as the last
process in a container shutting down.
In Kubernetes v1.27, the &lt;em&gt;event based&lt;/em&gt; mechanism has graduated to beta but remains
disabled by default. If you do explicitly switch to event-based lifecycle change detection,
the kubelet is able to start Pods more quickly than with the default approach that relies on polling.
The default mechanism, polling for lifecycle changes, adds a noticeable overhead; this affects
the kubelet&#39;s ability to handle different tasks in parallel, and leads to poor performance and
reliability issues. For these reasons, we recommend that you switch your nodes to use
event-based pod lifecycle change detection.&lt;/p&gt;
&lt;p&gt;Further details can be found in the KEP &lt;a href=&#34;https://kep.k8s.io/3386&#34;&gt;https://kep.k8s.io/3386&lt;/a&gt; and
&lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/tasks/administer-cluster/switch-to-evented-pleg/&#34;&gt;Switching From Polling to CRI Event-based Updates to Container Status&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;raise-your-pod-resource-limit-if-needed&#34;&gt;Raise your pod resource limit if needed&lt;/h2&gt;
&lt;p&gt;During start-up, some pods may consume a considerable amount of CPU or memory. If the CPU limit is
low, this can significantly slow down the pod start-up process. To improve the memory management,
Kubernetes v1.22 introduced a feature gate called MemoryQoS to kubelet. This feature enables
kubelet to set memory QoS at container, pod, and QoS levels for better protection and guaranteed
quality of memory when running with cgroups v2. Although it has benefits, it is possible that
enabling this feature gate may affect the start-up speed of the pod if the pod startup consumes
a large amount of memory.&lt;/p&gt;
&lt;p&gt;Kubelet configuration now includes &lt;code&gt;memoryThrottlingFactor&lt;/code&gt;. This factor is multiplied by
the memory limit or node allocatable memory to set the cgroupv2 &lt;code&gt;memory.high&lt;/code&gt; value for enforcing
MemoryQoS. Decreasing this factor sets a lower high limit for container cgroups, increasing reclaim
pressure. Increasing this factor will put less reclaim pressure. The default value is 0.8 initially
and will change to 0.9 in Kubernetes v1.27. This parameter adjustment can reduce the potential
impact of this feature on pod startup speed.&lt;/p&gt;
&lt;p&gt;Further details can be found in the KEP &lt;a href=&#34;https://kep.k8s.io/2570&#34;&gt;https://kep.k8s.io/2570&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;what-s-more&#34;&gt;What&#39;s more?&lt;/h2&gt;
&lt;p&gt;In Kubernetes v1.26, a new histogram metric &lt;code&gt;pod_start_sli_duration_seconds&lt;/code&gt; was added for Pod
startup latency SLI/SLO details. Additionally, the kubelet log will now display more information
about pod start-related timestamps, as shown below:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Dec 30 15:33:13.375379 e2e-022435249c-674b9-minion-group-gdj4 kubelet[8362]: I1230 15:33:13.375359    8362 pod_startup_latency_tracker.go:102] &amp;quot;Observed pod startup duration&amp;quot; pod=&amp;quot;kube-system/konnectivity-agent-gnc9k&amp;quot; podStartSLOduration=-9.223372029479458e+09 pod.CreationTimestamp=&amp;quot;2022-12-30 15:33:06 +0000 UTC&amp;quot; firstStartedPulling=&amp;quot;2022-12-30 15:33:09.258791695 +0000 UTC m=+13.029631711&amp;quot; lastFinishedPulling=&amp;quot;0001-01-01 00:00:00 +0000 UTC&amp;quot; observedRunningTime=&amp;quot;2022-12-30 15:33:13.375009262 +0000 UTC m=+17.145849275&amp;quot; watchObservedRunningTime=&amp;quot;2022-12-30 15:33:13.375317944 +0000 UTC m=+17.146157970&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The SELinux Relabeling with Mount Options feature moved to Beta in v1.27. This feature speeds up
container startup by mounting volumes with the correct SELinux label instead of changing each file
on the volumes recursively. Further details can be found in the KEP &lt;a href=&#34;https://kep.k8s.io/1710&#34;&gt;https://kep.k8s.io/1710&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To identify the cause of slow pod startup, analyzing metrics and logs can be helpful. Other
factors that may impact pod startup include container runtime, disk speed, CPU and memory
resources on the node.&lt;/p&gt;
&lt;p&gt;SIG Node is responsible for ensuring fast Pod startup times, while addressing issues in large
clusters falls under the purview of SIG Scalability as well.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Kubernetes 1.27: In-place Resource Resize for Kubernetes Pods (alpha)</title>
      <link>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/05/12/in-place-pod-resize-alpha/</link>
      <pubDate>Fri, 12 May 2023 00:00:00 +0000</pubDate>
      
      <guid>https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/blog/2023/05/12/in-place-pod-resize-alpha/</guid>
      <description>
        
        
        &lt;p&gt;&lt;strong&gt;Author:&lt;/strong&gt; Vinay Kulkarni (Kubescaler Labs)&lt;/p&gt;
&lt;p&gt;If you have deployed Kubernetes pods with CPU and/or memory resources
specified, you may have noticed that changing the resource values involves
restarting the pod. This has been a disruptive operation for running
workloads... until now.&lt;/p&gt;
&lt;p&gt;In Kubernetes v1.27, we have added a new alpha feature that allows users
to resize CPU/memory resources allocated to pods without restarting the
containers. To facilitate this, the &lt;code&gt;resources&lt;/code&gt; field in a pod&#39;s containers
now allow mutation for &lt;code&gt;cpu&lt;/code&gt; and &lt;code&gt;memory&lt;/code&gt; resources. They can be changed
simply by patching the running pod spec.&lt;/p&gt;
&lt;p&gt;This also means that &lt;code&gt;resources&lt;/code&gt; field in the pod spec can no longer be
relied upon as an indicator of the pod&#39;s actual resources. Monitoring tools
and other such applications must now look at new fields in the pod&#39;s status.
Kubernetes queries the actual CPU and memory requests and limits enforced on
the running containers via a CRI (Container Runtime Interface) API call to the
runtime, such as containerd, which is responsible for running the containers.
The response from container runtime is reflected in the pod&#39;s status.&lt;/p&gt;
&lt;p&gt;In addition, a new &lt;code&gt;restartPolicy&lt;/code&gt; for resize has been added. It gives users
control over how their containers are handled when resources are resized.&lt;/p&gt;
&lt;h2 id=&#34;what-s-new-in-v1-27&#34;&gt;What&#39;s new in v1.27?&lt;/h2&gt;
&lt;p&gt;Besides the addition of resize policy in the pod&#39;s spec, a new field named
&lt;code&gt;allocatedResources&lt;/code&gt; has been added to &lt;code&gt;containerStatuses&lt;/code&gt; in the pod&#39;s status.
This field reflects the node resources allocated to the pod&#39;s containers.&lt;/p&gt;
&lt;p&gt;In addition, a new field called &lt;code&gt;resources&lt;/code&gt; has been added to the container&#39;s
status. This field reflects the actual resource requests and limits configured
on the running containers as reported by the container runtime.&lt;/p&gt;
&lt;p&gt;Lastly, a new field named &lt;code&gt;resize&lt;/code&gt; has been added to the pod&#39;s status to show the
status of the last requested resize. A value of &lt;code&gt;Proposed&lt;/code&gt; is an acknowledgement
of the requested resize and indicates that request was validated and recorded. A
value of &lt;code&gt;InProgress&lt;/code&gt; indicates that the node has accepted the resize request
and is in the process of applying the resize request to the pod&#39;s containers.
A value of &lt;code&gt;Deferred&lt;/code&gt; means that the requested resize cannot be granted at this
time, and the node will keep retrying. The resize may be granted when other pods
leave and free up node resources. A value of &lt;code&gt;Infeasible&lt;/code&gt; is a signal that the
node cannot accommodate the requested resize. This can happen if the requested
resize exceeds the maximum resources the node can ever allocate for a pod.&lt;/p&gt;
&lt;h2 id=&#34;when-to-use-this-feature&#34;&gt;When to use this feature&lt;/h2&gt;
&lt;p&gt;Here are a few examples where this feature may be useful:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pod is running on node but with either too much or too little resources.&lt;/li&gt;
&lt;li&gt;Pods are not being scheduled do to lack of sufficient CPU or memory in a
cluster that is underutilized by running pods that were overprovisioned.&lt;/li&gt;
&lt;li&gt;Evicting certain stateful pods that need more resources to schedule them
on bigger nodes is an expensive or disruptive operation when other lower
priority pods in the node can be resized down or moved.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;how-to-use-this-feature&#34;&gt;How to use this feature&lt;/h2&gt;
&lt;p&gt;In order to use this feature in v1.27, the &lt;code&gt;InPlacePodVerticalScaling&lt;/code&gt;
feature gate must be enabled. A local cluster with this feature enabled
can be started as shown below:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;root@vbuild:~/go/src/k8s.io/kubernetes# FEATURE_GATES=InPlacePodVerticalScaling=true ./hack/local-up-cluster.sh
go version go1.20.2 linux/arm64
+++ [0320 13:52:02] Building go targets for linux/arm64
    k8s.io/kubernetes/cmd/kubectl (static)
    k8s.io/kubernetes/cmd/kube-apiserver (static)
    k8s.io/kubernetes/cmd/kube-controller-manager (static)
    k8s.io/kubernetes/cmd/cloud-controller-manager (non-static)
    k8s.io/kubernetes/cmd/kubelet (non-static)
...
...
Logs:
  /tmp/etcd.log
  /tmp/kube-apiserver.log
  /tmp/kube-controller-manager.log

  /tmp/kube-proxy.log
  /tmp/kube-scheduler.log
  /tmp/kubelet.log

To start using your cluster, you can open up another terminal/tab and run:

  export KUBECONFIG=/var/run/kubernetes/admin.kubeconfig
  cluster/kubectl.sh

Alternatively, you can write to the default kubeconfig:

  export KUBERNETES_PROVIDER=local

  cluster/kubectl.sh config set-cluster local --server=https://localhost:6443 --certificate-authority=/var/run/kubernetes/server-ca.crt
  cluster/kubectl.sh config set-credentials myself --client-key=/var/run/kubernetes/client-admin.key --client-certificate=/var/run/kubernetes/client-admin.crt
  cluster/kubectl.sh config set-context local --cluster=local --user=myself
  cluster/kubectl.sh config use-context local
  cluster/kubectl.sh
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Once the local cluster is up and running, Kubernetes users can schedule pods
with resources, and resize the pods via kubectl. An example of how to use this
feature is illustrated in the following demo video.&lt;/p&gt;

&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
  &lt;iframe src=&#34;https://www.youtube.com/embed/1m2FOuB6Bh0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; allowfullscreen title=&#34;In-place resize of pod CPU and memory resources&#34;&gt;&lt;/iframe&gt;
&lt;/div&gt;

&lt;h2 id=&#34;example-use-cases&#34;&gt;Example Use Cases&lt;/h2&gt;
&lt;h3 id=&#34;cloud-based-development-environment&#34;&gt;Cloud-based Development Environment&lt;/h3&gt;
&lt;p&gt;In this scenario, developers or development teams write their code locally
but build and test their code in Kubernetes pods with consistent configs
that reflect production use. Such pods need minimal resources when the
developers are writing code, but need significantly more CPU and memory
when they build their code or run a battery of tests. This use case can
leverage in-place pod resize feature (with a little help from eBPF) to
quickly resize the pod&#39;s resources and avoid kernel OOM (out of memory)
killer from terminating their processes.&lt;/p&gt;
&lt;p&gt;This &lt;a href=&#34;https://www.youtube.com/watch?v=jjfa1cVJLwc&#34;&gt;KubeCon North America 2022 conference talk&lt;/a&gt;
illustrates the use case.&lt;/p&gt;
&lt;h3 id=&#34;java-processes-initialization-cpu-requirements&#34;&gt;Java processes initialization CPU requirements&lt;/h3&gt;
&lt;p&gt;Some Java applications may need significantly more CPU during initialization
than what is needed during normal process operation time. If such applications
specify CPU requests and limits suited for normal operation, they may suffer
from very long startup times. Such pods can request higher CPU values at the
time of pod creation, and can be resized down to normal running needs once the
application has finished initializing.&lt;/p&gt;
&lt;h2 id=&#34;known-issues&#34;&gt;Known Issues&lt;/h2&gt;
&lt;p&gt;This feature enters v1.27 at &lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/reference/command-line-tools-reference/feature-gates/#feature-stages&#34;&gt;alpha stage&lt;/a&gt;.
Below are a few known issues users may encounter:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;containerd versions below v1.6.9 do not have the CRI support needed for full
end-to-end operation of this feature. Attempts to resize pods will appear
to be &lt;em&gt;stuck&lt;/em&gt; in the &lt;code&gt;InProgress&lt;/code&gt; state, and &lt;code&gt;resources&lt;/code&gt; field in the pod&#39;s
status are never updated even though the new resources may have been enacted
on the running containers.&lt;/li&gt;
&lt;li&gt;Pod resize may encounter a race condition with other pod updates, causing
delayed enactment of pod resize.&lt;/li&gt;
&lt;li&gt;Reflecting the resized container resources in pod&#39;s status may take a while.&lt;/li&gt;
&lt;li&gt;Static CPU management policy is not supported with this feature.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;credits&#34;&gt;Credits&lt;/h2&gt;
&lt;p&gt;This feature is a result of the efforts of a very collaborative Kubernetes community.
Here&#39;s a little shoutout to just a few of the many many people that contributed
countless hours of their time and helped make this happen.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/thockin&#34;&gt;@thockin&lt;/a&gt; for detail-oriented API design and air-tight code reviews.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/derekwaynecarr&#34;&gt;@derekwaynecarr&lt;/a&gt; for simplifying the design and thorough API and node reviews.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/dchen1107&#34;&gt;@dchen1107&lt;/a&gt; for bringing vast knowledge from Borg and helping us avoid pitfalls.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/ruiwen-zhao&#34;&gt;@ruiwen-zhao&lt;/a&gt; for adding containerd support that enabled full E2E implementation.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/wangchen615&#34;&gt;@wangchen615&lt;/a&gt; for implementing comprehensive E2E tests and driving scheduler fixes.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/bobbypage&#34;&gt;@bobbypage&lt;/a&gt; for invaluable help getting CI ready and quickly investigating issues, covering for me on my vacation.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/Random-Liu&#34;&gt;@Random-Liu&lt;/a&gt; for thorough kubelet reviews and identifying problematic race conditions.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/Huang-Wei&#34;&gt;@Huang-Wei&lt;/a&gt;, &lt;a href=&#34;https://github.com/ahg-g&#34;&gt;@ahg-g&lt;/a&gt;, &lt;a href=&#34;https://github.com/alculquicondor&#34;&gt;@alculquicondor&lt;/a&gt; for helping get scheduler changes done.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/mikebrow&#34;&gt;@mikebrow&lt;/a&gt; &lt;a href=&#34;https://github.com/marosset&#34;&gt;@marosset&lt;/a&gt; for reviews on short notice that helped CRI changes make it into v1.25.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/endocrimes&#34;&gt;@endocrimes&lt;/a&gt;, &lt;a href=&#34;https://github.com/ehashman&#34;&gt;@ehashman&lt;/a&gt; for helping ensure that the oft-overlooked tests are in good shape.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/mrunalp&#34;&gt;@mrunalp&lt;/a&gt; for reviewing cgroupv2 changes and ensuring clean handling of v1 vs v2.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/liggitt&#34;&gt;@liggitt&lt;/a&gt;, &lt;a href=&#34;https://github.com/gjkim42&#34;&gt;@gjkim42&lt;/a&gt; for tracking down, root-causing important missed issues post-merge.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/SergeyKanzhelev&#34;&gt;@SergeyKanzhelev&lt;/a&gt; for supporting and shepherding various issues during the home stretch.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/pdgetrf&#34;&gt;@pdgetrf&lt;/a&gt; for making the first prototype a reality.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/dashpole&#34;&gt;@dashpole&lt;/a&gt; for bringing me up to speed on &#39;the Kubernetes way&#39; of doing things.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/bsalamat&#34;&gt;@bsalamat&lt;/a&gt;, &lt;a href=&#34;https://github.com/kgolab&#34;&gt;@kgolab&lt;/a&gt; for very thoughtful insights and suggestions in the early stages.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/sftim&#34;&gt;@sftim&lt;/a&gt;, &lt;a href=&#34;https://github.com/tengqm&#34;&gt;@tengqm&lt;/a&gt; for ensuring docs are easy to follow.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/dims&#34;&gt;@dims&lt;/a&gt; for being omnipresent and helping make merges happen at critical hours.&lt;/li&gt;
&lt;li&gt;Release teams for ensuring that the project stayed healthy.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And a big thanks to my very supportive management &lt;a href=&#34;https://www.linkedin.com/in/xiaoningding/&#34;&gt;Dr. Xiaoning Ding&lt;/a&gt;
and &lt;a href=&#34;https://www.linkedin.com/in/ying-xiong-59a2482/&#34;&gt;Dr. Ying Xiong&lt;/a&gt; for their patience and encouragement.&lt;/p&gt;
&lt;h2 id=&#34;references&#34;&gt;References&lt;/h2&gt;
&lt;h3 id=&#34;for-app-developers&#34;&gt;For app developers&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/tasks/configure-pod-container/resize-container-resources/&#34;&gt;Resize CPU and Memory Resources assigned to Containers&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/tasks/configure-pod-container/assign-memory-resource/&#34;&gt;Assign Memory Resources to Containers and Pods&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/tasks/configure-pod-container/assign-cpu-resource/&#34;&gt;Assign CPU Resources to Containers and Pods&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;for-cluster-administrators&#34;&gt;For cluster administrators&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/tasks/administer-cluster/manage-resources/memory-default-namespace/&#34;&gt;Configure Default Memory Requests and Limits for a Namespace&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://deploy-preview-57407--kubernetes-io-main-staging.netlify.app/docs/tasks/administer-cluster/manage-resources/cpu-default-namespace/&#34;&gt;Configure Default CPU Requests and Limits for a Namespace&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

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