<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Operator SDK – Best Practices</title>
    <link>/docs/best-practices/</link>
    <description>Recent content in Best Practices on Operator SDK</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    
	  <atom:link href="/docs/best-practices/index.xml" rel="self" type="application/rss+xml" />
    
    
      
        
      
    
    
    <item>
      <title>Docs: Operator Best Practices</title>
      <link>/docs/best-practices/best-practices/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/best-practices/best-practices/</guid>
      <description>
        
        
        &lt;h2 id=&#34;development&#34;&gt;Development&lt;/h2&gt;
&lt;p&gt;Considerations for Operator developers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;An Operator should manage a single type of application, essentially following the UNIX principle: do one thing and do it well.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If an application consists of multiple tiers or components, multiple Operators should be written one for each of them. For example, if the application consists of Redis, AMQ, and MySQL, there should be 3 Operators, not one.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If there is significant orchestration and sequencing involved, an Operator should be written that represents the entire stack, in turn delegating to other Operators for orchestrating their part of it.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Operators should own a CRD and only one Operator should control a CRD on a cluster. Two Operators managing the same CRD is not a recommended best practice. An API that exists with multiple implementations is a typical example of a no-op Operator. The no-op Operator doesn&amp;rsquo;t have any deployment or reconciliation loop to define the shared API and other Operators depend on this Operator to provide one implementation of the API, e.g. similar to PVCs or Ingress.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Inside an Operator, multiple controllers should be used if multiple CRDs are managed. This helps in separation of concerns and code readability. Note that this doesn&amp;rsquo;t necessarily mean that we need to have one container image per controller, but rather one reconciliation loop (which could be running as part of the same Operator binary) per CRD.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;An Operator shouldn&amp;rsquo;t deploy or manage other operators (such patterns are known as meta or super operators or include CRDs in its Operands). It&amp;rsquo;s the Operator Lifecycle Manager&amp;rsquo;s job to manage the deployment and lifecycle of operators. For further information check &lt;a href=&#34;https://olm.operatorframework.io/docs/concepts/olm-architecture/dependency-resolution/&#34;&gt;Dependency Resolution&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If multiple operators are packaged and shipped as a single entity by the same CSV for example, then it is recommended to add all owned and required CRDs, as well as all deployments for operators that manage the owned CRDs, to the same CSV.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Writing an Operator involves using the Kubernetes API, which in most scenarios will be built using same boilerplate code. Use a framework like the Operator SDK to save yourself time with this and to also get a suite of tooling to ease development and testing.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Operators shouldn’t make any assumptions about the namespace they are deployed in and they should not use hard-coded names of resources that they expect to already exist.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Operators shouldn’t hard code the namespaces they are watching. This should be configurable - having no namespace supplied is interpreted as watching all namespaces&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Semantic versioning (aka semver) should be used to version an Operator. Operators are long-running workloads on the cluster and its APIs are potentially in need of support over a longer period of time. Use the &lt;a href=&#34;https://semver.org&#34;&gt;semver.org guidelines&lt;/a&gt; to help determine when and how to bump versions when there are breaking or non-breaking changes.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Kubernetes API versioning guidelines should be used to version Operator CRDs. Use the &lt;a href=&#34;https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api_changes.md#so-you-want-to-change-the-api&#34;&gt;Kubernetes sig-architecture guidelines&lt;/a&gt; to get best practices on when to bump versions and when breaking changes are acceptable.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;When defining CRDs, you should use OpenAPI spec to create a structural schema for your CRDs.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Operators are instrumented to provide useful, actionable metrics to external systems (e.g. monitoring/alerting platforms).  Minimally, metrics should represent the software&amp;rsquo;s health and key performance indicators, as well as support the creation of &lt;a href=&#34;https://en.wikipedia.org/wiki/Service_level_indicator&#34;&gt;service levels indicators&lt;/a&gt; such as throughput, latency, availability, errors, capacity, etc.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Operators may create objects as part of their operational duty. Object accumulation can consume unnecessary resources, slow down the API and clutter the user interface. As such it is important for operators to keep good hygiene and to clean up resources when they are not needed. Here are instructions on &lt;a href=&#34;/docs/building-operators/golang/advanced-topics#handle-cleanup-on-deletion&#34;&gt;how to handle cleanup on deletion&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;summary&#34;&gt;Summary&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;One Operator per managed application&lt;/li&gt;
&lt;li&gt;Multiple operators should be used for complex, multi-tier application stacks&lt;/li&gt;
&lt;li&gt;CRD can only be owned by a single Operator, shared CRDs should be owned by a separate Operator&lt;/li&gt;
&lt;li&gt;One controller per custom resource definition&lt;/li&gt;
&lt;li&gt;Use a tool like Operator SDK&lt;/li&gt;
&lt;li&gt;Do not hard-code namespaces or resources names&lt;/li&gt;
&lt;li&gt;Make watch namespace configurable&lt;/li&gt;
&lt;li&gt;Use semver / observe Kubernetes guidelines on versioning APIs&lt;/li&gt;
&lt;li&gt;Use OpenAPI spec with structural schema on CRDs&lt;/li&gt;
&lt;li&gt;Operators expose metrics to external systems&lt;/li&gt;
&lt;li&gt;Operators cleanup resources on deletion&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;running-on-cluster&#34;&gt;Running On-Cluster&lt;/h2&gt;
&lt;p&gt;Considerations for on-cluster behavior&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Like all containers on Kubernetes, Operators need not run as root unless absolutely necessary. Operators should come with their own ServiceAccount and not rely on the &lt;code&gt;default&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Operators should not self-register their CRDs. These are global resources and careful consideration needs to be taken when setting those up. Also this requires the Operator to have global privileges which is potentially dangerous compared to that little extra convenience.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Operators use CRs as the primary interface to the cluster user. As such, at all times, meaningful status information should be written to those objects unless they are solely used to store data in a structured schema.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Operators should be updated frequently according to server versioning.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Operators need to support updating managed applications (Operands) that were set up by an older version of the Operator. There are multiple models for this:&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Operator fan-out&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;where the Operator allows the user to specify the version in the custom resource&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;single version&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;where the Operator is tied to the version of the operand.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;hybrid approach&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;where the Operator is tied to a range of versions, and the user can select some level of the version.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;An Operator should not deploy another Operator - an additional component on cluster should take care of this (OLM).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;When Operators change their APIs, CRD conversion (webhooks) should be used to deal with potentially older instances of them using the previous API version.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Operators should make it easy for users to use their APIs - validating and rejecting malformed requests via extensive Open API validation schema on CRDs or via an admission webhook is good practice.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The Operator itself should be really modest in its requirements - it should always be able to deploy by deploying its controllers, no user input should be required to start up the Operator.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If user input is required to change the configuration of the Operator itself, a Configuration CRD should be used. Init-containers as part of the Operator deployments can be used to create a default instance of those CRs and then the Operator manages their lifecycle.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;summary-1&#34;&gt;Summary:&lt;/h3&gt;
&lt;p&gt;On the cluster, an Operator&amp;hellip;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Does not run as root&lt;/li&gt;
&lt;li&gt;Does not self-register CRDs&lt;/li&gt;
&lt;li&gt;Does not install other Operators&lt;/li&gt;
&lt;li&gt;Does rely on dependencies via package manager (OLM)&lt;/li&gt;
&lt;li&gt;Writes meaningful status information on Custom Resources objects unless pure data structure&lt;/li&gt;
&lt;li&gt;Should be capable of updating from a previous version of the Operator&lt;/li&gt;
&lt;li&gt;Should be capable of managing an Operand from an older Operator version&lt;/li&gt;
&lt;li&gt;Uses CRD conversion (webhooks) if API/CRDs change&lt;/li&gt;
&lt;li&gt;Uses OpenAPI validation / Admission Webhooks to reject invalid CRs&lt;/li&gt;
&lt;li&gt;Should always be able to deploy and come up without user input&lt;/li&gt;
&lt;li&gt;Offers (pre)configuration via a &lt;code&gt;“Configuration CR”&lt;/code&gt; instantiated by InitContainers&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: Common recommendations and suggestions</title>
      <link>/docs/best-practices/common-recommendation/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/best-practices/common-recommendation/</guid>
      <description>
        
        
        &lt;h2 id=&#34;overview&#34;&gt;Overview&lt;/h2&gt;
&lt;p&gt;Any recommendations or best practices suggested by the Kubernetes community, such as how to &lt;a href=&#34;https://kubernetes.io/docs/concepts/extend-kubernetes/operator/&#34;&gt;develop Operator pattern solutions&lt;/a&gt; or how to &lt;a href=&#34;https://github.com/kubernetes-sigs/controller-runtime&#34;&gt;use controller-runtime&lt;/a&gt; are good recommendations for those who are looking to build operator projects with operator-sdk. Also, see &lt;a href=&#34;/docs/best-practices/best-practices&#34;&gt;Operator Best Practices&lt;/a&gt;. However, here are some common recommendations.&lt;/p&gt;
&lt;h2 id=&#34;common-recommendations&#34;&gt;Common Recommendations&lt;/h2&gt;
&lt;h3 id=&#34;develop-idempotent-reconciliation-solutions&#34;&gt;Develop idempotent reconciliation solutions&lt;/h3&gt;
&lt;p&gt;When developing operators, it is essential for the controller’s reconciliation loop to be idempotent. By following the &lt;a href=&#34;https://kubernetes.io/docs/concepts/extend-kubernetes/operator/&#34;&gt;Operator pattern&lt;/a&gt; you will create &lt;a href=&#34;https://kubernetes.io/docs/concepts/architecture/controller/&#34;&gt;Controllers&lt;/a&gt; which provide a reconcile function responsible for synchronizing resources until the desired state is reached on the cluster. Breaking this recommendation goes against  the design principles of &lt;a href=&#34;https://github.com/kubernetes-sigs/controller-runtime&#34;&gt;controller-runtime&lt;/a&gt; and may lead to unforeseen consequences such as resources becoming stuck and requiring manual intervention.&lt;/p&gt;
&lt;h3 id=&#34;understanding-kubernetes-apis&#34;&gt;Understanding Kubernetes APIs&lt;/h3&gt;
&lt;p&gt;Building your own operator commonly involves extending the Kubernetes API itself. It is helpful to understand exactly how &lt;a href=&#34;https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/&#34;&gt;Custom Resource Definitions interact with the Kubernetes API&lt;/a&gt;. Also, the Kubebuilder documentation on &lt;a href=&#34;https://book.kubebuilder.io/cronjob-tutorial/gvks.html&#34;&gt;Groups and Versions and Kinds&lt;/a&gt; may be helpful to better understand these concepts as they relate to operators.&lt;/p&gt;
&lt;h3 id=&#34;avoid-a-design-solution-where-more-than-one-kind-is-reconciled-by-the-same-controller&#34;&gt;Avoid a design solution where more than one Kind is reconciled by the same controller&lt;/h3&gt;
&lt;p&gt;Having many Kinds (such as CRDs) which are all managed by the same controller usually goes against the design proposed by &lt;a href=&#34;https://github.com/kubernetes-sigs/controller-runtime&#34;&gt;controller-runtime&lt;/a&gt;. Furthermore this might hurt concepts such as encapsulation, the Single Responsibility Principle, and Cohesion. Damaging these concepts may cause unexpected side effects, and increase the difficulty of extending, reusing, or maintaining the operator.&lt;/p&gt;
&lt;h3 id=&#34;ideally-operators-does-not-manage-other-operators&#34;&gt;Ideally Operators does not manage other Operators&lt;/h3&gt;
&lt;p&gt;From &lt;a href=&#34;https://olm.operatorframework.io/docs/concepts/olm-architecture/dependency-resolution/&#34;&gt;best practices&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;&amp;ldquo;Operators should own a CRD and only one Operator should control a CRD on a cluster.
Two Operators managing the same CRD is not a recommended best practice. In the case where an API exists but
with multiple implementations, this is typically an example of a no-op Operator because it doesn&amp;rsquo;t
have any deployment or reconciliation loop to define the shared API and other
Operators depend on this Operator to provide one implementation of the
API, e.g. similar to PVCs or Ingress.&amp;quot;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;&amp;ldquo;An Operator shouldn&amp;rsquo;t deploy or manage other operators (such patterns are known as meta or super operators
or include CRDs in its Operands). It&amp;rsquo;s the Operator Lifecycle Manager&amp;rsquo;s job to manage the deployment and
lifecycle of operators. For further information check &lt;a href=&#34;/docs/best-practices/best-practices&#34;&gt;Dependency Resolution&lt;/a&gt;.&amp;quot;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;what-does-it-mainly-mean&#34;&gt;What does it mainly mean:&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;If you want to define that your Operator depends on APIs which are owned by another Operator or on
another whole Operator itself you should use Operator Lifecycle Manager&amp;rsquo;s &lt;a href=&#34;/docs/best-practices/best-practices&#34;&gt;Dependency Resolution&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;If you want to reconcile core APIs (&lt;em&gt;defined by Kubernetes&lt;/em&gt;) or External APIs (&lt;em&gt;defined from other operators&lt;/em&gt;)
you should not re-define the API as owned by your project. Therefore, you can create the controller in this
cases by using the flag &lt;code&gt;--resource=false&lt;/code&gt;. (i.e. &lt;code&gt;$ operator-sdk create api --group ship --version v1beta1 --kind External --resource=false --controller=true&lt;/code&gt;).
&lt;strong&gt;Attention:&lt;/strong&gt; If you are using Golang-based language Operator then, you will need to update the markers and imports
manually until it become officially supported by the tool. For further information check the issue &lt;a href=&#34;https://github.com/kubernetes-sigs/kubebuilder/issues/1999&#34;&gt;#1999&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;WARNING:&lt;/strong&gt; if you create CRD&amp;rsquo;s via the reconciliations or via the Operands then, OLM cannot handle CRDs migration and update, validation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; By not following this guidance you might probably to be hurting concepts like as single responsibility principle
and damaging these concepts could cause unexpected side effects, such as; difficulty extending, reuse, or maintenance, only to mention a few.&lt;/p&gt;
&lt;h3 id=&#34;other-common-suggestions&#34;&gt;Other common suggestions&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Provide the images and tags used by the operator solution via environment variables in the &lt;code&gt;config/manager/manager.yaml&lt;/code&gt;:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre 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;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;spec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;...&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;spec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;...&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;containers&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;command&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;- /manager&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;...&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;env&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;MY_IMAGE&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;value&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;quay.io/example.com/image:0.0.1&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;Manage your solutions using &lt;a href=&#34;https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties&#34;&gt;Status Conditionals&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Use &lt;a href=&#34;/docs/building-operators/golang/advanced-topics/#handle-cleanup-on-deletion&#34;&gt;finalizers&lt;/a&gt; when/if required&lt;/li&gt;
&lt;li&gt;Cover the project with tests/CI to ensure its quality:
&lt;ul&gt;
&lt;li&gt;For any language-based operator, you can use &lt;a href=&#34;/docs/testing-operators/scorecard/&#34;&gt;Scorecard&lt;/a&gt; to implement functional tests&lt;/li&gt;
&lt;li&gt;For Go-based operators, you can also use &lt;a href=&#34;https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/envtest&#34;&gt;envtest&lt;/a&gt; to cover the controllers. For further information see &lt;a href=&#34;/docs/building-operators/golang/testing&#34;&gt;Testing with EnvTest&lt;/a&gt;. Also, see the &lt;code&gt;test&lt;/code&gt; directory for the Memcached sample under the &lt;a href=&#34;https://github.com/operator-framework/operator-sdk/tree/master/testdata/go/v4/memcached-operator&#34;&gt;testdata/go/v3/memcached-operator&lt;/a&gt; to know how can you build e2e tests.&lt;/li&gt;
&lt;li&gt;For Ansible-based operators, you can also use &lt;a href=&#34;https://molecule.readthedocs.io/&#34;&gt;Molecule&lt;/a&gt;, an Ansible testing framework. For further information see &lt;a href=&#34;/docs/building-operators/ansible/testing-guide&#34;&gt;Testing with Molecule&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;For Helm-based operators, you can also use &lt;a href=&#34;https://helm.sh/docs/topics/chart_tests/&#34;&gt;Chart tests&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Ensure that you checked the &lt;a href=&#34;/docs/faqs/#can-i-customize-the-projects-initialized-with-operator-sdk&#34;&gt;Can I customize the projects initialized with operator-sdk?&lt;/a&gt; and understand the &lt;a href=&#34;/docs/overview/project-layout&#34;&gt;Project Layout&lt;/a&gt; before starting to do your customizations as please you on top.&lt;/li&gt;
&lt;li&gt;Optimize manager resource values in &lt;code&gt;config/manager/manager.yaml&lt;/code&gt; according to project requirements. It is recommended to define resources limits in order to follow good practices and for security reasons. More info: &lt;a href=&#34;https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/&#34;&gt;Managing Resources for Containers&lt;/a&gt; and &lt;a href=&#34;https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html#rule-7-limit-resources-memory-cpu-file-descriptors-processes-restarts&#34;&gt;Docker Security Cheat Sheet&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Look for &lt;code&gt;TODO(user)&lt;/code&gt; in the source code generated by the CLI to ensure that you follow all suggested customizations.&lt;/li&gt;
&lt;li&gt;If you wish to integrate your project with OLM, you can also check its &lt;a href=&#34;https://olm.operatorframework.io/docs/best-practices/&#34;&gt;Best Practices&lt;/a&gt; section.&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: Resource pruning</title>
      <link>/docs/best-practices/resource-pruning/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/best-practices/resource-pruning/</guid>
      <description>
        
        
        &lt;h2 id=&#34;overview&#34;&gt;Overview&lt;/h2&gt;
&lt;p&gt;Operators can create &lt;a href=&#34;https://kubernetes.io/docs/concepts/workloads/controllers/job/&#34;&gt;Jobs&lt;/a&gt; or Pods as part of their normal operation, and when those Jobs or Pods
complete, they can remain on the Kubernetes cluster if not specifically removed. These resources
can consume valuable cluster resources like disk storage (e.g. etcd). These resources
are not tied to a Custom Resource using an &lt;code&gt;ownerReference&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Operator authors have traditionally had two pruning options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;leave the resource cleanup to a system admin to perform&lt;/li&gt;
&lt;li&gt;implement some form of pruning within their operator solution&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For our purposes when we say, &lt;em&gt;prune&lt;/em&gt;, we mean to remove a resource (e.g. kubectl delete) from
a Kubernetes cluster for a given namespace.&lt;/p&gt;
&lt;p&gt;This documentation describes the pattern and library useful for implementing a solution within an operator.&lt;/p&gt;
&lt;h2 id=&#34;operator-lib-prune-library&#34;&gt;operator-lib prune library&lt;/h2&gt;
&lt;p&gt;A simple pruning implementation can be found in the &lt;a href=&#34;https://github.com/operator-framework/operator-lib/tree/main/prune&#34;&gt;operator-lib prune package&lt;/a&gt;. This
package is written in Go and is meant to be used within Go-based operators. This package was
developed to include common pruning strategies as found in common operators. The package also allow
for customization of hooks and strategies.&lt;/p&gt;
&lt;h3 id=&#34;pruning-configuration&#34;&gt;Pruning Configuration&lt;/h3&gt;
&lt;p&gt;Users can configure the pruning library by creating code similar to this example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-golang&#34; data-lang=&#34;golang&#34;&gt;&lt;span style=&#34;color:#000&#34;&gt;cfg&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Config&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
	&lt;span style=&#34;color:#000&#34;&gt;Log&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;           &lt;span style=&#34;color:#000&#34;&gt;logf&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Log&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;WithName&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;prune&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;),&lt;/span&gt;
	&lt;span style=&#34;color:#000&#34;&gt;DryRun&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;false&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
	&lt;span style=&#34;color:#000&#34;&gt;Clientset&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;     &lt;span style=&#34;color:#000&#34;&gt;client&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
	&lt;span style=&#34;color:#000&#34;&gt;LabelSelector&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;app=churro&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
	&lt;span style=&#34;color:#000&#34;&gt;Resources&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[]&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;schema&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;GroupVersionKind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
		&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Group&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Version&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;PodKind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
	&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
	&lt;span style=&#34;color:#000&#34;&gt;Namespaces&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[]&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;string&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;default&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
	&lt;span style=&#34;color:#000&#34;&gt;Strategy&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;StrategyConfig&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
		&lt;span style=&#34;color:#000&#34;&gt;Mode&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;            &lt;span style=&#34;color:#000&#34;&gt;MaxCountStrategy&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
		&lt;span style=&#34;color:#000&#34;&gt;MaxCountSetting&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
	&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
	&lt;span style=&#34;color:#000&#34;&gt;PreDeleteHook&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;myhook&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Config Field&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Log&lt;/td&gt;
&lt;td&gt;a logr.Logger. It is optional if a logger is provided through the context to the Execute method, which is the case with the context of the Reconcile function of operator-sdk and controller-runtime&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DryRun&lt;/td&gt;
&lt;td&gt;a boolean determines whether to actually remove resources; &lt;code&gt;true&lt;/code&gt; means to execute but not to remove resources&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Clientset&lt;/td&gt;
&lt;td&gt;a client-go Kubernetes ClientSet that will be used for Kube API calls by the library&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LabelSelector&lt;/td&gt;
&lt;td&gt;Kubernetes label selector expression used to find resources to prune&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Resources&lt;/td&gt;
&lt;td&gt;Kube resource Kinds, currently PodKind and JobKind are supported by the library&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Namespaces&lt;/td&gt;
&lt;td&gt;a list of Kube Namespaces to search for resources&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Strategy&lt;/td&gt;
&lt;td&gt;specifies the pruning strategy to execute&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Strategy.Mode&lt;/td&gt;
&lt;td&gt;currently MaxCountStrategy, MaxAgeStrategy, or CustomStrategy are supported&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Strategy.MaxCountSetting&lt;/td&gt;
&lt;td&gt;integer value for &lt;em&gt;maxcount&lt;/em&gt; strategy, specifies how many resources should remain after pruning executes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Strategy.MaxAgeSetting&lt;/td&gt;
&lt;td&gt;golang time.Duration string value (e.g. 48h), specifies age of resources to prune&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Strategy.CustomSettings&lt;/td&gt;
&lt;td&gt;a golang map of values that can be passed into a Custom strategy function&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PreDeleteHook&lt;/td&gt;
&lt;td&gt;optionally specifies a golang function to call before pruning a resource&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CustomStrategy&lt;/td&gt;
&lt;td&gt;optionally specifies a golang function that implements a custom pruning strategy&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;pruning-execution&#34;&gt;Pruning Execution&lt;/h3&gt;
&lt;p&gt;Users can invoke the pruning by running the &lt;em&gt;Execute&lt;/em&gt; function on the pruning configuration
as follows:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-golang&#34; data-lang=&#34;golang&#34;&gt;&lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;cfg&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Execute&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Users might want to implement pruning execution by means of a cron package or simply call the prune
library based on some other triggering event.&lt;/p&gt;
&lt;p&gt;If a logger has been configured in the Config structure it takes precedence on the one provided through ctx.
Adding a logger.Logger to the context can be done with &lt;a href=&#34;https://pkg.go.dev/github.com/go-logr/logr#NewContext&#34;&gt;logr.NewContext&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;pruning-strategies&#34;&gt;Pruning Strategies&lt;/h2&gt;
&lt;h3 id=&#34;maxcount-strategy&#34;&gt;maxcount Strategy&lt;/h3&gt;
&lt;p&gt;A strategy of leaving a finite set of resources is implemented called &lt;em&gt;maxcount&lt;/em&gt;. This strategy
seeks to leave a specific number of resources, sorted by latest, on your cluster. For example, if
you have 10 resources that would be pruned, and you specified a &lt;em&gt;maxcount&lt;/em&gt; value of 4, then 6
resources would be pruned (removed) from your cluster starting with the oldest resources.&lt;/p&gt;
&lt;h3 id=&#34;maxage-strategy&#34;&gt;maxage Strategy&lt;/h3&gt;
&lt;p&gt;A strategy of removing resources greater than a specific time is called &lt;em&gt;maxage&lt;/em&gt;.  This strategy
seeks to remove resources older than a specified &lt;em&gt;maxage&lt;/em&gt; duration.  For example, a library
user might specify a value of &lt;em&gt;48h&lt;/em&gt; to indicate that any resource older than 48 hours would be
pruned.  Durations are specified using golang&amp;rsquo;s &lt;a href=&#34;https://pkg.go.dev/time#Duration&#34;&gt;time.Duration formatting&lt;/a&gt; (e.g. 48h).&lt;/p&gt;
&lt;h2 id=&#34;pruning-customization&#34;&gt;Pruning Customization&lt;/h2&gt;
&lt;h3 id=&#34;predelete-hook&#34;&gt;preDelete Hook&lt;/h3&gt;
&lt;p&gt;Users can provide a &lt;em&gt;preDelete&lt;/em&gt; hook when using the &lt;a href=&#34;https://github.com/operator-framework/operator-lib/tree/main/prune&#34;&gt;operator-lib prune package&lt;/a&gt;.&lt;br&gt;
This hook function will be called by the library before removing a resource.  This provides a means to examine
the resource logs for example, extracting any valued content, before the resource is removed
from the cluster.&lt;/p&gt;
&lt;p&gt;Here is an example of a &lt;em&gt;preDelete&lt;/em&gt; hook:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-golang&#34; data-lang=&#34;golang&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;myhook&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;context&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Context&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;cfg&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Config&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;res&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;ResourceInfo&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;error&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
        &lt;span style=&#34;color:#000&#34;&gt;log&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;prune&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Logger&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;cfg&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
        &lt;span style=&#34;color:#000&#34;&gt;log&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;V&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;4&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;).&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Info&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;pre-deletion&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;GVK&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;res&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;GVK&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;namespace&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;res&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Namespace&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;res&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
       	&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;res&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;GVK&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Kind&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;PodKind&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
                &lt;span style=&#34;color:#000&#34;&gt;req&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;cfg&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Clientset&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;CoreV1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;().&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Pods&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;res&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Namespace&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;).&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;GetLogs&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;res&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;v1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;PodLogOptions&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{})&lt;/span&gt;
                &lt;span style=&#34;color:#000&#34;&gt;podLogs&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;req&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Stream&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;context&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Background&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;())&lt;/span&gt;
                &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;nil&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
                        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt;
                &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
                &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;defer&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;podLogs&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Close&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;()&lt;/span&gt;

                &lt;span style=&#34;color:#000&#34;&gt;buf&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#204a87&#34;&gt;new&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;bytes&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Buffer&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
                &lt;span style=&#34;color:#000&#34;&gt;_&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;io&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Copy&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;buf&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;podLogs&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
                &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;nil&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
                        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt;
                &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;

                &lt;span style=&#34;color:#000&#34;&gt;log&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;V&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;4&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;).&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Info&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;pod log before removing is&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;log&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;buf&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;String&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;())&lt;/span&gt;
        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
	&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;nil&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;em&gt;Note&lt;/em&gt; if your custom hook returns an error, then the resource will not be removed by the
prune library.&lt;/p&gt;
&lt;h3 id=&#34;custom-strategy&#34;&gt;Custom Strategy&lt;/h3&gt;
&lt;p&gt;Library users can also write their own custom pruning strategy function to support advanced
cases. Custom strategy functions are passed in the prune configuration and a list of resources selected by
the library.  The custom strategy builds up a list of resources to be removed, returning the list to the prune library which
performs the actual resource removal. Here is an example custom strategy:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-golang&#34; data-lang=&#34;golang&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;myStrategy&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;context&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Context&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;cfg&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Config&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;resources&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[]&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ResourceInfo&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;resourcesToRemove&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[]&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ResourceInfo&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;error&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
        &lt;span style=&#34;color:#000&#34;&gt;log&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Logger&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctx&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;cfg&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
        &lt;span style=&#34;color:#000&#34;&gt;log&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;V&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;4&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;).&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Info&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;myStrategy called&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;resources&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;resources&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;config&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;cfg&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
	&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#204a87&#34;&gt;len&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;resources&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;3&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
		&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;resourcesToRemove&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;fmt&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Errorf&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;count of resources did not equal our expectation&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
	&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
	&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;resourcesToRemove&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;nil&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To have your custom strategy invoked, you will specify your function within the prune configuration
as follows:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-golang&#34; data-lang=&#34;golang&#34;&gt;&lt;span style=&#34;color:#000&#34;&gt;cfg&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Strategy&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Mode&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;CustomStrategy&lt;/span&gt;
&lt;span style=&#34;color:#000&#34;&gt;cfg&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Strategy&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;CustomSettings&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#204a87&#34;&gt;make&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;map&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;string&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;]&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;interface&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{})&lt;/span&gt;
&lt;span style=&#34;color:#000&#34;&gt;cfg&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;CustomStrategy&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;myStrategy&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Notice that you can optionally pass in settings to your custom function as a map using the &lt;code&gt;cfg.Strategy.CustomSettings&lt;/code&gt; field.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: Multi-Tenancy</title>
      <link>/docs/best-practices/multi-tenancy/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/best-practices/multi-tenancy/</guid>
      <description>
        
        
        &lt;h2 id=&#34;networkpolicy&#34;&gt;NetworkPolicy&lt;/h2&gt;
&lt;p&gt;If your Operator creates or manages &lt;a href=&#34;https://kubernetes.io/docs/concepts/services-networking/network-policies/&#34;&gt;NetworkPolicy&lt;/a&gt; configurations ensure that your solution:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;applies fine-grained network policies to the extent that is required for your managed application to function properly&lt;/li&gt;
&lt;li&gt;applies fine-grained network policies to enable your managed application internal components to communicate among each other&lt;/li&gt;
&lt;li&gt;allows users to configure your operator so it does not create or manage &lt;a href=&#34;https://kubernetes.io/docs/concepts/services-networking/network-policies/&#34;&gt;NetworkPolicy&lt;/a&gt; instances&lt;/li&gt;
&lt;li&gt;does not create &lt;code&gt;allow traffic from everywhere in the cluster&lt;/code&gt; type policies&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&#34;https://kubernetes.io/docs/concepts/services-networking/network-policies/&#34;&gt;NetworkPolicies&lt;/a&gt; are popular in multi-tenant cluster to provide an extra layer
of segregation among tenants within SDN solutions. Users typically customize this extensively with goal of disallowing network traffic among unrelated
tenants. Operators that deploy an &lt;code&gt;accept all traffic from anywhere in the cluster&lt;/code&gt; style policy, are creating an obstacle in
pursuing this goal, especially in instances where these policies cannot be disabled. In security-conscious environments policies like these are not allowed
in production. In such cases your operator should minimally &lt;strong&gt;have the option to prevent &lt;a href=&#34;https://kubernetes.io/docs/concepts/services-networking/network-policies/&#34;&gt;NetworkPolicy&lt;/a&gt; objects from being
created&lt;/strong&gt; and leave this responsibility to the user. In more advanced cases, your operator should create &lt;a href=&#34;https://kubernetes.io/docs/concepts/services-networking/network-policies/&#34;&gt;NetworkPolicy&lt;/a&gt;
configurations that follow the least-privilege principle, i.e. denying access to everything and from everywhere by default and only allowing access to specific authorized resources from specific authorized components.&lt;/p&gt;
&lt;h2 id=&#34;traffic-sharding&#34;&gt;Traffic sharding&lt;/h2&gt;
&lt;p&gt;The goal is to split or to isolated ingress traffic from certain environments, e.g. production and development environments, ending up on
different routers and in this way, being managed by a different Ingress controller. This is a popular configuration
option for heavily populated multi-tenant clusters, with several &lt;a href=&#34;https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/&#34;&gt;IngressController&lt;/a&gt; deployed.&lt;/p&gt;
&lt;p&gt;If your Operator creates ingress resources the recommendation is to allow the users to customize them,
through the use of a CRD. The required
&lt;a href=&#34;https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-class&#34;&gt;IngressClass&lt;/a&gt; needs then to be
propagated to the ingress resources created so that they get picked up by the desired &lt;a href=&#34;https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/&#34;&gt;IngressController&lt;/a&gt;.
Annotations are deprecated in favour of &lt;a href=&#34;https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-class&#34;&gt;IngressClass&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;route-resources&#34;&gt;Route resources&lt;/h3&gt;
&lt;p&gt;To run on the OpenShift distribution of Kubernetes you probably will use
the &lt;a href=&#34;https://docs.openshift.com/container-platform/4.9/rest_api/network_apis/route-route-openshift-io-v1.html#route-route-openshift-io-v1&#34;&gt;Route&lt;/a&gt; API. When sharding these routes may be configured with a label selector.
Based on this label selector they will amend their configuration when a route (having the label)
is created or not (if the route does not have the label). The label is applied at the &lt;code&gt;Route&lt;/code&gt; level
and there is no pre-defined convention here, so users set these custom labels in
accordance to how they configured their &lt;a href=&#34;https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/&#34;&gt;IngressController from operator.openshift.io/v1&lt;/a&gt; instances.&lt;/p&gt;
&lt;p&gt;In this way, &lt;strong&gt;your operator should allow the user to specify custom labels for any
Route that it manages&lt;/strong&gt;. Check the &lt;a href=&#34;https://docs.openshift.com/container-platform/4.9/networking/ingress-operator.html#nw-ingress-sharding-route-labels_configuring-ingress&#34;&gt;doc&lt;/a&gt; and this &lt;a href=&#34;https://rcarrata.com/openshift/ocp4_route_sharding/&#34;&gt;blog&lt;/a&gt; for an end-to-end examples
and further information.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: Designing Lean Operators</title>
      <link>/docs/best-practices/designing-lean-operators/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/best-practices/designing-lean-operators/</guid>
      <description>
        
        
        &lt;h2 id=&#34;overview&#34;&gt;Overview&lt;/h2&gt;
&lt;p&gt;One of the pitfalls that many operators are failing into is that they watch resources with high cardinality like secrets possibly in all namespaces. This has a massive impact on the memory used by the controller on big clusters. Such resources can be filtered by label or fields. The original doc design for &lt;code&gt;Filter cache ListWatch using selectors&lt;/code&gt; can be accessed from &lt;a href=&#34;https://github.com/kubernetes-sigs/controller-runtime/blob/master/designs/use-selectors-at-cache.md&#34;&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;IMPORTANT NOTE&lt;/strong&gt;
Requests to a client backed by a filtered cache for objects that do not match the filter will never return anything. In other words, filtered caches make the filtered-out objects invisible to the client.&lt;/p&gt;
&lt;h2 id=&#34;how-is-this-done-&#34;&gt;How is this done ?&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;When creating the manager, you can add an Options struct to configure the Cache&lt;/li&gt;
&lt;li&gt;Each client.Object can be filtered with labels and fields&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;examples&#34;&gt;Examples&lt;/h2&gt;
&lt;p&gt;In this scenario, the user will configure the Cache to filter the secret object by it&amp;rsquo;s label. This will return a filtered cache for objects that match the filter.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre 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;mgr&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;err&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;=&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;ctrl.NewManager(ctrl.GetConfigOrDie()&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;ctrl.Options{&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;Cache&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;cache.Options{&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;ByObject&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;map&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[&lt;/span&gt;client.Object&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;]&lt;/span&gt;cache.ByObject{&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&amp;amp;corev1.Secret{}:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;cache.ByObject{&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;	&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;Label&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;labels.SelectorFromSet(labels.Set{&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;app&amp;#34;: &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;app-name&amp;#34;&lt;/span&gt;})&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;}&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;}&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;})&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In this scenario, the user will configure the Cache to filter the node object by it&amp;rsquo;s field name. This will return a filtered cache for objects that match the filter.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre 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;mgr&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;err&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;=&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;ctrl.NewManager(ctrl.GetConfigOrDie()&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;ctrl.Options{&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;Cache&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;cache.Options{&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;ByObject&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;map&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[&lt;/span&gt;client.Object&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;]&lt;/span&gt;cache.ByObject{&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&amp;amp;corev1.Node{}:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;cache.ByObject{&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;	&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;Fields&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;labels.SelectorFromSet(fields.Set{&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;metadata.name&amp;#34;: &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;node01&amp;#34;&lt;/span&gt;})&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;}&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;}&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;})&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
      </description>
    </item>
    
    <item>
      <title>Docs: Managing Resources</title>
      <link>/docs/best-practices/managing-resources/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/best-practices/managing-resources/</guid>
      <description>
        
        
        &lt;h2 id=&#34;managing-resources&#34;&gt;Managing Resources&lt;/h2&gt;
&lt;p&gt;Note that pretty much all controllers consume:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;CPU&lt;/code&gt;: largely based on the number of reconciliations they perform, which are generally related to event activity for resources they&amp;rsquo;re watching.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Memory&lt;/code&gt;: largely based on the number of primary resources that exist (multiplied by some factor based on the number of operand resources they need to watch as a result) via informer caches.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And then there is a concern that one Pod or Container could monopolize all available resources and Cluster admins must
consider the effects that one Pod or Container may have on other components.&lt;/p&gt;
&lt;p&gt;In an effort to prevent a container from consuming all the resources on a cluster or affecting other workloads
from being scheduled, many production clusters will define &lt;a href=&#34;https://kubernetes.io/docs/concepts/policy/resource-quotas/&#34;&gt;ResourceQuota&lt;/a&gt; configurations.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&#34;https://kubernetes.io/docs/concepts/policy/resource-quotas/&#34;&gt;ResourceQuota&lt;/a&gt; configuration also applies to tenant workloads that are managed by
your Operator. Cluster administrators will typically set a &lt;a href=&#34;https://kubernetes.io/docs/concepts/policy/resource-quotas/&#34;&gt;ResourceQuota&lt;/a&gt; for each
tenant&amp;rsquo;s namespace as part of the onboarding. If a &lt;a href=&#34;https://kubernetes.io/docs/concepts/policy/limit-range/&#34;&gt;LimitRange&lt;/a&gt; with default values
has &lt;strong&gt;not&lt;/strong&gt; been created in each namespace and your Operator creates Containers inside the tenant
namespace without specifying at least resource requests for CPU and Memory of its Pods then,
the system or quota may reject Pod creation.
Check the following statements obtained from K8s docs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&amp;ldquo;If a LimitRange is activated in a namespace for computing resources like CPU and memory, users must specify requests or limits for those values. Otherwise, the system may reject Pod creation.&amp;quot;&lt;/em&gt; (&lt;a href=&#34;https://kubernetes.io/docs/concepts/policy/limit-range/&#34;&gt;Reference&lt;/a&gt;).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&amp;ldquo;If quota is enabled in a namespace for compute resources like cpu and memory, users must specify requests or limits for those values; otherwise, the quota system may reject pod creation.&amp;quot;&lt;/em&gt; (&lt;a href=&#34;https://kubernetes.io/docs/concepts/policy/resource-quotas/&#34;&gt;Reference&lt;/a&gt;).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In an effort to support clusters with the above configuration, to ensure safe operations and avoid negatively
impacting other workloads: Operators should &lt;strong&gt;always&lt;/strong&gt; include reasonable memory and CPU resource requests for their own deployment as well as for operands they deploy.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;HINT&lt;/strong&gt; Cluster admins might also able to avoid the above scenario by setting default values when they are not specified for each Pod and/or Container in a namespace.&lt;/p&gt;
&lt;p&gt;Therefore, your Operator should &lt;strong&gt;always&lt;/strong&gt; apply at least resource requests for &lt;code&gt;CPU&lt;/code&gt; and
memory for &lt;code&gt;Pods/Deployments&lt;/code&gt; that it creates as part of the reconciliation logic. Ideally your
Operator also applies memory limits to those &lt;code&gt;Pods/Deployments&lt;/code&gt;. You may also consider CPU limits.&lt;/p&gt;
&lt;p&gt;Resource requests and limits for the Operator Deployment can be defined by modifying the&lt;code&gt;config/manager/manager.yaml&lt;/code&gt;
as shown below:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yml&#34; data-lang=&#34;yml&#34;&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;...&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# TODO(user): Configure the resources accordingly based on the project requirements.&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;resources&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;requests&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;cpu&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;10m&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;memory&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;64Mi&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;...&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;how-to-compute-default-values&#34;&gt;How to compute default values&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;IMPORTANT:&lt;/strong&gt; A single configuration that fits all scenarios is not possible.
In this way, Operators authors &lt;strong&gt;MUST&lt;/strong&gt; to ensure that Cluster Admins and its users can change the
resource requests/limits of the Operator/manager, and of its Operands.&lt;/p&gt;
&lt;p&gt;However, you are able to benchmark your Operator by &lt;a href=&#34;https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#monitoring-compute-memory-resource-usage&#34;&gt;Monitoring the resource usage&lt;/a&gt;
to ensure good and reasonable values for the general cases. Kubebuilder and SDK provide some
&lt;a href=&#34;https://book.kubebuilder.io/reference/metrics.html&#34;&gt;metrics&lt;/a&gt; which can help you with.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt; Also, be aware that if the project was generated by Kubebuilder or SDK scaffold
then some values for the &lt;code&gt;Operator/manager&lt;/code&gt;(See &lt;code&gt;config/manager/manager.yaml&lt;/code&gt;)
are populated by default to get you started, however, you ought to optimize them based
on your own tests and the specific needs of your operator.&lt;/p&gt;
&lt;h3 id=&#34;how-to-change-the-operatormanager-resources-values-when-under-olm-management&#34;&gt;How to change the Operator/manager resources values when under OLM management&lt;/h3&gt;
&lt;p&gt;If your operator is managed by OLM, administrators or users can configure your operator&amp;rsquo;s resource requests and limits
via the &lt;a href=&#34;https://github.com/operator-framework/operator-lifecycle-manager/blob/master/doc/design/subscription-config.md#resources&#34;&gt;subscription&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;general-guidelines&#34;&gt;General guidelines&lt;/h3&gt;
&lt;p&gt;Following are some general recommendations to manage the resources:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;MUST&lt;/strong&gt; declare resource requests for both, CPU and Memory, for the &lt;code&gt;Operator/manager&lt;/code&gt;  and any &lt;code&gt;Pod/Deployment&lt;/code&gt; managed by it&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OPTIONALLY&lt;/strong&gt; setting the resources limit for CPU and Memory for the Operator Pod and any &lt;code&gt;Pod/Deployment&lt;/code&gt; managed by it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SHOULD&lt;/strong&gt; provide the mechanisms for &lt;a href=&#34;https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#monitoring-compute-memory-resource-usage&#34;&gt;Monitoring compute &amp;amp; memory resource usage&lt;/a&gt; so that,
Cluster Admins can use these metrics to monitor and resize the Operator and its Operands.&lt;em&gt;&lt;strong&gt;CAVEAT:&lt;/strong&gt; If the Operator
is integrated with OLM and the bundle has a &lt;code&gt;PodMonitor&lt;/code&gt; or a &lt;code&gt;ServiceMonitor&lt;/code&gt; the complete &lt;code&gt;InstallPlan&lt;/code&gt;
will fail on a cluster, which does not have these CRD/the Prometheus operator installed. In this case,
you might want to ensure the dependency requirement with &lt;a href=&#34;https://olm.operatorframework.io/docs/concepts/olm-architecture/dependency-resolution/&#34;&gt;OLM dependency&lt;/a&gt; or make clear
its requirement for the Operator consumers.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SHOULD&lt;/strong&gt; allow admins to customize the &lt;code&gt;requests/limits&lt;/code&gt; amounts defined for the &lt;code&gt;Pod/Deployment&lt;/code&gt;
created by the Operator and not hardcode these values.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SHOULD&lt;/strong&gt; document how your Operator consumer can customize/rightsize the resources requests and limits for the
Operator and Operands &lt;code&gt;Pod/Deployments&lt;/code&gt; or describe how the solution could be configured to automatically adjust these values based on the environment.
the Operator automatically adjust the values to the environment rather than asking its consumers to amend them.
You might also consider leveraging the &lt;a href=&#34;https://github.com/kubernetes/autoscaler/tree/master/vertical-pod-autoscaler&#34;&gt;Vertical Pod Autoscaler&lt;/a&gt; to have the resources requested by the Operator
automatically adjusted to the cluster where it is deployed. You might also
look at allowing &lt;a href=&#34;https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/#support-for-resource-metrics&#34;&gt;horizontal pod autoscaling&lt;/a&gt; for the other &lt;code&gt;Pod/Deployments&lt;/code&gt; created by your Operator.
In this case, be aware that resource requests are also required for horizontal pod autoscaling to work.&lt;em&gt;&lt;strong&gt;CAVEAT:&lt;/strong&gt; If you are using OpenShift as your Kubernetes distribution you might want to check the
doc &lt;a href=&#34;https://docs.openshift.com/container-platform/4.9/nodes/pods/nodes-pods-vertical-autoscaler.html&#34;&gt;Automatically adjust pod resource levels with the vertical pod autoscaler&lt;/a&gt;. Also, if the VPA CRD
is not available in the cluster where the operator gets deployed the InstallPlan will fail.
Please, see how to work with &lt;a href=&#34;https://olm.operatorframework.io/docs/concepts/olm-architecture/dependency-resolution/&#34;&gt;OLM dependency&lt;/a&gt; if your project integrating with it.&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;why-should-you-set-these&#34;&gt;Why should you set these?&lt;/h3&gt;
&lt;h4 id=&#34;resource-requests&#34;&gt;Resource Requests&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;What happens when the resource requests are not set?&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;configurations made by the cluster administrators such as &lt;a href=&#34;https://kubernetes.io/docs/concepts/policy/resource-quotas/&#34;&gt;ResourceQuota&lt;/a&gt; might not work without LimitRanges. The LimitRanger admission controller can provide default values for resource requests and limits when they have not been defined.&lt;/li&gt;
&lt;li&gt;the Operators consumers might face resource shortages on a node when resource usage increases, for example, during a daily peak in request rate.&lt;/li&gt;
&lt;li&gt;the Operator&amp;rsquo;s consumers might be unable to successfully deploy the Operator because it does not have the minimal resources available.&lt;/li&gt;
&lt;li&gt;the scheduler cannot make an informed placement choice when it picks the nodes the operator pods will be running on.&lt;/li&gt;
&lt;li&gt;when there is memory contention on the node the pod is likely to get either evicted or OOM killed.&lt;/li&gt;
&lt;li&gt;when there is CPU contention on the node the pod is likely to get starved of CPU cycles making the operator unresponsive.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;resource-limits&#34;&gt;Resource Limits&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;What happens when the resource limits are not set?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Wrong configurations or code implementations can consume all resources available, affecting other components on cluster.
Also, it might leave the containers more vulnerable such as to Dos Attacks. &lt;a href=&#34;https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html#rule-7-limit-resources-memory-cp%5B%E2%80%A6%5Dle-descriptors-processes-restarts&#34;&gt;More info&lt;/a&gt;. See that when there is memory
contention on a node, pods will start getting evicted and possibly killed according to their OOM score. The node will be flagged with a
MemoryPressure condition and eventually made unschedulable. However, when there is CPU contention on the node, neighbour pods may
get slowed down to the CPU cores they requested.&lt;/p&gt;
&lt;p&gt;However, a popular practice by cluster administrators is to leverage &lt;a href=&#34;https://kubernetes.io/docs/concepts/policy/resource-quotas/&#34;&gt;ResourceQuota&lt;/a&gt; to limit
the total amount of resources that can be requested or allowed in a single namespace.
This may protect against over consumption of resources by operands of a faulty or wrongly configured operator.
On the other hand it also means that the operator may not be able to create additional pods,
limiting its functionality when the limit has been reached.&lt;/p&gt;
&lt;p&gt;Also, see might want to check in the K8s docs the following sections:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://kubernetes.io/docs/tasks/configure-pod-container/assign-cpu-resource/#motivation-for-cpu-requests-and-limits&#34;&gt;Motivation for CPU requests and limits&lt;/a&gt; and &lt;a href=&#34;https://kubernetes.io/docs/tasks/configure-pod-container/assign-cpu-resource/#if-you-do-not-specify-a-cpu-limit&#34;&gt;If you do not specify a CPU limit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kubernetes.io/docs/tasks/configure-pod-container/assign-memory-resource/#motivation-for-memory-requests-and-limits&#34;&gt;Motivation for Memory requests and limits&lt;/a&gt; and &lt;a href=&#34;https://kubernetes.io/docs/tasks/configure-pod-container/assign-memory-resource/#if-you-do-not-specify-a-memory-limit&#34;&gt;If you do not specify a memory limit&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;what-happens-when&#34;&gt;What happens when:&lt;/h3&gt;
&lt;h4 id=&#34;limits-reached&#34;&gt;Limits reached&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;What happens when the resource limits have been reached?&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;For Memory&lt;/code&gt;: the container might be terminated with the reason &lt;code&gt;OOM Killed&lt;/code&gt;. If it is restartable, the kubelet will
restart it, as with any other type of runtime failure.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;For CPU&lt;/code&gt;: the container might or might not be allowed to exceed its CPU limit for extended periods of time. However,
it will not be killed for excessive CPU usage. The &lt;code&gt;CPU&lt;/code&gt; is considered a &amp;ldquo;compressible&amp;rdquo; resource,
and if the &lt;code&gt;Pod&lt;/code&gt; starts hitting the CPU limits, Kubernetes uses kernel to starts throttling the container.
That means the CPU will be artificially restricted, giving a potentially worse performance only.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You might want to check the &lt;a href=&#34;https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#troubleshooting&#34;&gt;Troubleshooting&lt;/a&gt; section in the Kubernetes documents to better
understand how to debug these scenarios.&lt;/p&gt;
&lt;h4 id=&#34;limits-are-specified-but-not-requests&#34;&gt;Limits are specified but not requests&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;What happens when the resource limits are defined but not the requests?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;If you specify a CPU or Memory limit for a Container but do not specify a request,
Kubernetes automatically assigns a CPU or Memory request that matches the limit.
In this way, you will be requesting &lt;strong&gt;always&lt;/strong&gt; the limit and will be allocating
more resources than required. (&lt;strong&gt;NOT RECOMMENDED&lt;/strong&gt;)&lt;/p&gt;
&lt;h4 id=&#34;values-are-too-big&#34;&gt;Values are too big&lt;/h4&gt;
&lt;p&gt;Memory and CPU requests and limits are associated with Containers, but be aware that the Memory and CPU
requests and limits of a Pod are the sum of its specific computing types for all the containers in the Pod.&lt;/p&gt;
&lt;p&gt;If you define that your Pods should have Memory or CPU request too big then, you might not only be allocating and
blocking the usage of more than you ought unnecessarily. Also, your Operator consumers might be able to install
your Operator via OLM, for example, but will be unable to check the Pods/Deployment running successfully
when the amount defined exceeds the capacity available. In these scenarios, the Operator consumers
will check that Pod(s) failed to schedule with event errors like &lt;code&gt;Insufficient cpu&lt;/code&gt; and/or &lt;code&gt;Insufficient memory&lt;/code&gt;.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: Pod Security Standards</title>
      <link>/docs/best-practices/pod-security-standards/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/best-practices/pod-security-standards/</guid>
      <description>
        
        
        &lt;h2 id=&#34;overview&#34;&gt;Overview&lt;/h2&gt;
&lt;p&gt;The &lt;a href=&#34;https://kubernetes.io/blog/2021/04/06/podsecuritypolicy-deprecation-past-present-and-future/#what-is-podsecuritypolicy&#34;&gt;PodSecurityPolicy&lt;/a&gt; API is deprecated and will be removed from Kubernetes in version 1.25.
This API is replaced by a new built-in admission controller (&lt;a href=&#34;https://github.com/kubernetes/enhancements/tree/master/keps/sig-auth/2579-psp-replacement&#34;&gt;KEP-2579: Pod Security Admission Control&lt;/a&gt;) which allows cluster admins to &lt;a href=&#34;https://kubernetes.io/docs/tasks/configure-pod-container/enforce-standards-namespace-labels/&#34;&gt;enforce
Pod Security Standards Labels&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;what-does-that-mean&#34;&gt;What does that mean?&lt;/h3&gt;
&lt;p&gt;Namespace and Pod/Container can be defined with three different policies which are; &lt;strong&gt;Privileged, Baseline and Restricted.&lt;/strong&gt;
(&lt;a href=&#34;https://kubernetes.io/docs/concepts/security/pod-security-standards/&#34;&gt;More info&lt;/a&gt;). Therefore, Pod(s)/Container(s) that
are &lt;strong&gt;not&lt;/strong&gt; configured according to the enforced security standards defined globally or
on the namespace level will &lt;strong&gt;not&lt;/strong&gt; be admitted and it will &lt;strong&gt;not&lt;/strong&gt; be possible to run them.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;As a best practice, you must ensure that workloads (Operators and Operands) are defined to run under
restricted permissions unless they need further privileges. For the cases where Pod/Container(s) requires
escalating permissions, the recommendation is to use the label as described below&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&#34;how-should-i-configure-my-operators-and-operands-to-comply-with-the-criteria&#34;&gt;How should I configure my Operators and Operands to comply with the criteria?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;For common cases that do not require escalating privileges:&lt;/strong&gt; configure all containers to comply with the &lt;a href=&#34;https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted&#34;&gt;restricted&lt;/a&gt; policy as shown in the following the examples:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;IMPORTANT NOTE&lt;/strong&gt; The &lt;code&gt;seccompProfile&lt;/code&gt; field to define that a container is &lt;a href=&#34;https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted&#34;&gt;restricted&lt;/a&gt; was introduced with K8s &lt;code&gt;1.19&lt;/code&gt; and might &lt;strong&gt;not&lt;/strong&gt; be supported on some vendors by default.
Please, do &lt;strong&gt;not&lt;/strong&gt; use this field if you are looking to build Operators that work on K8s versions &amp;lt; &lt;code&gt;1.19&lt;/code&gt; or on vendors that do &lt;strong&gt;not&lt;/strong&gt; support this field. Having this field when it is not supported can result in your Pods/Containers &lt;strong&gt;not&lt;/strong&gt; being allowed to run (i.e. On Openshift versions &amp;lt; &lt;code&gt;4.11&lt;/code&gt; with its default configuration the deployments will fail with errors like &lt;code&gt;Forbidden: seccomp&lt;/code&gt;.)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;In Kubernetes manifests:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre 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;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;spec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;securityContext&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# WARNING: Ensure that the image used defines an UserID in the Dockerfile&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# otherwise the Pod will not run and will fail with `container has runAsNonRoot and image has non-numeric user`.&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# If you want your workloads admitted in namespaces enforced with the restricted mode in OpenShift/OKD vendors&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# then, you MUST ensure that the Dockerfile defines a User ID OR you MUST leave the `RunAsNonRoot` and&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# RunAsUser fields empty.&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;runAsNonRoot&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;true&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# Please ensure that you can use SeccompProfile and do not use&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# if your project must work on old Kubernetes&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# versions &amp;lt; 1.19 or on vendors versions which&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# do NOT support this field by default (i.e. Openshift &amp;lt; 4.11 )&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;seccompProfile&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;type&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;RuntimeDefault&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;...&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;containers&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;controller-manager&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;securityContext&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;allowPrivilegeEscalation&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;false&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;          &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;capabilities&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;            &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;drop&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;            &lt;/span&gt;- ALL&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;        &lt;/span&gt;...&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;On Reconciliations, such as code implementation in Go:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;em&gt;if you are setting the &lt;code&gt;RunAsNonRoot&lt;/code&gt; value to &lt;code&gt;true&lt;/code&gt; in the &lt;code&gt;SecurityContext&lt;/code&gt; you will need to verify that the Pod or Container(s) are running with a numeric user that is not 0 (root). If the Pod or Container(s) do not use a non-zero numeric user, you can use the &lt;code&gt;RunAsUser&lt;/code&gt; value to set the user to a non-zero numeric user. In this example, the memcached container does not use a non-zero numeric user and therefore the &lt;code&gt;RunAsUser&lt;/code&gt; value is set to use a uid of &lt;code&gt;1000&lt;/code&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre 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;color:#000&#34;&gt;dep&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;appsv1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Deployment&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
  &lt;span style=&#34;color:#000&#34;&gt;ObjectMeta&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;metav1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ObjectMeta&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
  &lt;span style=&#34;color:#a40000&#34;&gt;…&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;
  &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
  &lt;span style=&#34;color:#000&#34;&gt;Spec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;appsv1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;DeploymentSpec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
    &lt;span style=&#34;color:#a40000&#34;&gt;…&lt;/span&gt;
     &lt;span style=&#34;color:#000&#34;&gt;Template&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;corev1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;PodTemplateSpec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
       &lt;span style=&#34;color:#a40000&#34;&gt;…&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;
        &lt;span style=&#34;color:#000&#34;&gt;Spec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;corev1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;PodSpec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
           &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Ensure restricted context for the Pod    
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;           &lt;span style=&#34;color:#000&#34;&gt;SecurityContext&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;corev1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;PodSecurityContext&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
              &lt;span style=&#34;color:#000&#34;&gt;RunAsNonRoot&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[]&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;bool&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;true&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}[&lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;],&lt;/span&gt;
			  &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Please ensure that you can use SeccompProfile and do NOT use
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;			  &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// this filed if your project must work on old Kubernetes
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;			  &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// versions &amp;lt; 1.19 or on vendors versions which 
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;			  &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// do NOT support this field by default (i.e. Openshift &amp;lt; 4.11)
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;              &lt;span style=&#34;color:#000&#34;&gt;SeccompProfile&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;corev1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;SeccompProfile&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
                 &lt;span style=&#34;color:#000&#34;&gt;Type&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;corev1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;SeccompProfileTypeRuntimeDefault&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
              &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
           &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
           &lt;span style=&#34;color:#000&#34;&gt;Containers&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[]&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;corev1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Container&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{{&lt;/span&gt;
              &lt;span style=&#34;color:#000&#34;&gt;Image&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;   &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;memcached:1.4.36-alpine&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
              &lt;span style=&#34;color:#000&#34;&gt;Name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;    &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;memcached&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
              &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Ensure restricted context for the container  
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;              &lt;span style=&#34;color:#000&#34;&gt;SecurityContext&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;corev1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;SecurityContext&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
				 &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// WARNING: Ensure that the image used defines an UserID in the Dockerfile
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;				 &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// otherwise the Pod will not run and will fail with `container has runAsNonRoot and image has non-numeric user`.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;				 &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// If you want your workloads admitted in namespaces enforced with the restricted mode in OpenShift/OKD vendors 
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;				 &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// then, you MUST ensure that the Dockerfile defines a User ID OR you MUST leave the `RunAsNonRoot` and
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;				 &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// RunAsUser fields empty. 
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;                 &lt;span style=&#34;color:#000&#34;&gt;RunAsNonRoot&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;  &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[]&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;bool&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;true&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}[&lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;],&lt;/span&gt;
                 &lt;span style=&#34;color:#000&#34;&gt;AllowPrivilegeEscalation&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;  &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[]&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;bool&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;false&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}[&lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;],&lt;/span&gt;
                 &lt;span style=&#34;color:#000&#34;&gt;Capabilities&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;corev1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Capabilities&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
                    &lt;span style=&#34;color:#000&#34;&gt;Drop&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[]&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;corev1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Capability&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
                       &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;ALL&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
                    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
                 &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
              &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
           &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}},&lt;/span&gt;
        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
     &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
  &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;For Ansible and Helm language based Operators:&lt;/strong&gt; Ansible playbooks or Helm charts MUST create manifests that comply
with the requirements in the same way. You can find some examples by looking at the samples under the
&lt;a href=&#34;https://github.com/operator-framework/operator-sdk/tree/master/testdata&#34;&gt;testdata&lt;/a&gt; directory.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;For workloads that need elevated permissions:&lt;/strong&gt; it is recommended that you ensure the namespace containing your
solution is labeled accordingly. You can either update your operator to manage the namespace labels or include
the namespace labeling as part of the manual install instructions.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It is recommended that you provide a description to help cluster admins understand why elevated permissions are required.
You can add this information and the prerequisites to the description of your
Operator Bundle (CSV).&lt;/p&gt;
&lt;p&gt;Following you will find a detailed description of how to configure and test your solutions.
The most straightforward way to ensure if your workloads will work in a restricted namespace is verifying if your solution can run in namespaces enforced as restricted.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: It is recommended that you test the desired behavior as part of an e2e test suite. Examples of an e2e test for this will be shown in a later section.&lt;/p&gt;
&lt;h3 id=&#34;how-the-operator-bundle-csv-must-be-configured-to-apply-the-standards-to-the-podcontainers-which-are-installed-by-olm-operator-itself&#34;&gt;How the Operator bundle (CSV) must be configured to apply the standards to the Pod/Containers which are installed by OLM (Operator itself)?&lt;/h3&gt;
&lt;p&gt;For Operators integrated with OLM, there is an Operator bundle with a CSV where the &lt;code&gt;spec.install.spec.deployments&lt;/code&gt; has a Deployment
which defines the Pod/Container(s) that will be installed by OLM to get your Operator running on the cluster.
In order for the security standards to be followed you will need to ensure the configurations are set correctly.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note: Ensure the configuration is carried to the Pod/Containers on the bundle CSV after running make bundle&lt;/strong&gt;. See that
the Operator bundle generated with the target is built from the manifests under the &lt;code&gt;config&lt;/code&gt; directory. To know more about
the layout of your operator built with Operator-SDK see &lt;a href=&#34;/docs/overview/project-layout&#34;&gt;Project Layout&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To check an example of a CSV which complies with the &lt;a href=&#34;https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted&#34;&gt;restricted&lt;/a&gt; policy, see the Golang sample
under the &lt;a href=&#34;https://github.com/operator-framework/operator-sdk/blob/master/testdata/go/v4/memcached-operator/bundle/manifests/memcached-operator.clusterserviceversion.yaml&#34;&gt;testdata/go/v4/memcached-operator/bundle/manifests/memcached-operator.clusterserviceversion.yaml&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;how-can-i-verify-my-manifest&#34;&gt;How can I verify my manifest?&lt;/h3&gt;
&lt;h4 id=&#34;using-kind&#34;&gt;Using Kind&lt;/h4&gt;
&lt;p&gt;To verify the policy of your Pod/Container(s) you might to use a &lt;a href=&#34;https://kind.sigs.k8s.io/docs/user/quick-start/&#34;&gt;Kind&lt;/a&gt;
cluster as described in the &lt;a href=&#34;https://kubernetes.io/docs/tutorials/security/cluster-level-pss/&#34;&gt;K8s documentation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;First lets create a namespace where we will test the files:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre 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;kubectl create ns mytest
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;Now, let&amp;rsquo;s label the namespace so that we can check our manifest&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre 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; kubectl label --overwrite ns mytest &lt;span style=&#34;color:#4e9a06&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&lt;/span&gt;   pod-security.kubernetes.io/enforce&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;restricted &lt;span style=&#34;color:#4e9a06&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&lt;/span&gt;   pod-security.kubernetes.io/enforce-version&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;v1.24 &lt;span style=&#34;color:#4e9a06&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&lt;/span&gt;   pod-security.kubernetes.io/audit&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;restricted
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;Now, apply the following Pod which is &lt;strong&gt;not&lt;/strong&gt; restricted on the namespace:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre 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;color:#204a87;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;v1&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Pod&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;metadata&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;example&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;namespace&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;mytest&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;spec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;containers&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;test&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;securityContext&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;     &lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# see that we are allowing privilege escalation  &lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;     &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;allowPrivilegeEscalation&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;true&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; 
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;image&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#39;busybox:1.28&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;ports&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;     &lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;containerPort&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;8080&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start=&#34;4&#34;&gt;
&lt;li&gt;Then, when we try to apply the Pod manifest above we should see an error:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre 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;$ kubectl apply -f mypodtest.yaml 
Error from server &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;(&lt;/span&gt;Forbidden&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;)&lt;/span&gt;: error when creating &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;mypodtest.yaml&amp;#34;&lt;/span&gt;: pods &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;example&amp;#34;&lt;/span&gt; is forbidden: violates PodSecurity &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;restricted:v1.24&amp;#34;&lt;/span&gt;: allowPrivilegeEscalation !&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#204a87&#34;&gt;false&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;(&lt;/span&gt;container &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;test&amp;#34;&lt;/span&gt; must &lt;span style=&#34;color:#204a87&#34;&gt;set&lt;/span&gt; securityContext.allowPrivilegeEscalation&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#204a87&#34;&gt;false&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;)&lt;/span&gt;, unrestricted capabilities &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;(&lt;/span&gt;container &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;test&amp;#34;&lt;/span&gt; must &lt;span style=&#34;color:#204a87&#34;&gt;set&lt;/span&gt; securityContext.capabilities.drop&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=[&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;ALL&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;])&lt;/span&gt;, runAsNonRoot !&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#204a87&#34;&gt;true&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;(&lt;/span&gt;pod or container &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;test&amp;#34;&lt;/span&gt; must &lt;span style=&#34;color:#204a87&#34;&gt;set&lt;/span&gt; securityContext.runAsNonRoot&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#204a87&#34;&gt;true&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;)&lt;/span&gt;, seccompProfile &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;(&lt;/span&gt;pod or container &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;test&amp;#34;&lt;/span&gt; must &lt;span style=&#34;color:#204a87&#34;&gt;set&lt;/span&gt; securityContext.seccompProfile.type to &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;RuntimeDefault&amp;#34;&lt;/span&gt; or &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;Localhost&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;how-do-i-check-what-policy-privileged-baseline-and-restricted-is-configured-for-my-operator-and-operands&#34;&gt;How do I check what policy (Privileged, Baseline and Restricted) is configured for my Operator and Operand(s)?&lt;/h4&gt;
&lt;p&gt;An easy way might be using the tool: &lt;a href=&#34;https://github.com/stlaz/psachecker&#34;&gt;psachecker&lt;/a&gt;. This tool is only
able to be used to check locally the &lt;code&gt;Deployments/Pods&lt;/code&gt; manifests and not the CSV.&lt;/p&gt;
&lt;p&gt;Alternatively, you could test the policy enforcement by labeling the namespaces and running your operator or applying the manifests. &lt;a href=&#34;https://kubernetes.io/docs/tasks/configure-pod-container/enforce-standards-namespace-labels/&#34;&gt;More info&lt;/a&gt;.&lt;/p&gt;
&lt;h5 id=&#34;how-do-i-install-psachecker&#34;&gt;How do I install psachecker?&lt;/h5&gt;
&lt;p&gt;The following steps will install &lt;a href=&#34;https://github.com/stlaz/psachecker&#34;&gt;psachecker&lt;/a&gt; in a Golang environment.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre 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;git clone git@github.com:stlaz/psachecker.git &lt;span style=&#34;color:#000&#34;&gt;$GOPATH&lt;/span&gt;/src/github.com/stlaz/psachecker
&lt;span style=&#34;color:#204a87&#34;&gt;cd&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;$GOPATH&lt;/span&gt;/src/github.com/stlaz/psachecker
make build
cp kubectl-psachecker &lt;span style=&#34;color:#000&#34;&gt;$GOPATH&lt;/span&gt;/bin/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;how-do-i-use-psachecker-to-verify-the-policy-of-a-manifests&#34;&gt;How do I use psachecker to verify the policy of a manifests?&lt;/h4&gt;
&lt;p&gt;The following steps will demonstrate how we can use &lt;a href=&#34;https://github.com/stlaz/psachecker&#34;&gt;psachecker&lt;/a&gt; to verify that our Operator and deployments are properly configured in the CSV.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Create a new &lt;code&gt;test.yaml&lt;/code&gt; file&lt;/li&gt;
&lt;li&gt;Add Deployment schema to the file:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre 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;color:#204a87;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;apps/v1&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Deployment&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;metadata&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;test-manifest&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;namespace&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;test&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;spec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;...&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;Now, add the CSV deployment to this test (&lt;code&gt;spec.install.spec.deployments&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Then, you can run the tool and check if its result will be &lt;code&gt;restricted&lt;/code&gt; as expected (i.e.):&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre 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;$ kubectl-psachecker inspect-workloads -f test.yaml
system: restricted
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;can-i-use-the-metrics-to-check-if-my-podcontainers-are-violating-the-podsecurity-policies&#34;&gt;Can I use the metrics to check if my Pod/Containers are violating the PodSecurity policies?&lt;/h3&gt;
&lt;p&gt;Yes, you can. You need to label the namespaces with &lt;code&gt;pod-security.kubernetes.io/audit: restricted&lt;/code&gt;
(i.e. &lt;code&gt;kubectl label --overwrite ns --all pod-security.kubernetes.io/enforce-version=v1.24 pod-security.kubernetes.io/audit=restricted&lt;/code&gt;).
It is important to note that the results may include metrics that do not come from your Operator and Operand(s).
If you are looking to use the metrics to do the checks, ensure that you check the
results before and after performing the tests, for example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre 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;kubectl get --raw /metrics &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&lt;/span&gt; prom2json &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&lt;/span&gt; jq &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#39;[.[] | select(.name==&amp;#34;pod_security_evaluations_total&amp;#34;) ]&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre 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;color:#000;font-weight:bold&#34;&gt;[&lt;/span&gt;
  &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
    &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;pod_security_evaluations_total&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
    &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;help&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;[ALPHA] Number of policy evaluations that occurred, not counting ignored or exempt requests.&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
    &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;COUNTER&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
    &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;metrics&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[&lt;/span&gt;
      &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;labels&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;decision&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;allow&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;mode&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;enforce&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;policy_level&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;privileged&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;policy_version&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;latest&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;request_operation&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;create&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;resource&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;pod&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;subresource&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;
        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;29&amp;#34;&lt;/span&gt;
      &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
      &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;labels&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;decision&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;allow&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;mode&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;enforce&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;policy_level&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;privileged&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;policy_version&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;latest&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;request_operation&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;update&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;resource&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;pod&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;subresource&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;
        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;0&amp;#34;&lt;/span&gt;
      &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
      &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;labels&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;decision&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;deny&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;mode&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;audit&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;policy_level&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;restricted&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;policy_version&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;latest&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;request_operation&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;create&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;resource&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;controller&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;subresource&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;
        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;6&amp;#34;&lt;/span&gt;
      &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
      &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;labels&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;decision&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;deny&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;mode&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;audit&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;policy_level&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;restricted&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;policy_version&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;latest&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;request_operation&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;create&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;resource&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;pod&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;subresource&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;
        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;7&amp;#34;&lt;/span&gt;
      &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
      &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;labels&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;decision&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;deny&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;mode&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;warn&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;policy_level&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;restricted&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;policy_version&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;latest&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;request_operation&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;create&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;resource&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;controller&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;subresource&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;
        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;6&amp;#34;&lt;/span&gt;
      &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
      &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;labels&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;decision&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;deny&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;mode&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;warn&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;policy_level&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;restricted&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;policy_version&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;latest&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;request_operation&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;create&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;resource&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;pod&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;subresource&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;
        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;7&amp;#34;&lt;/span&gt;
      &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;]&lt;/span&gt;
  &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Also, you might be able to create Prometheus alerts such as:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre 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;sum &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;(&lt;/span&gt;increase&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;(&lt;/span&gt;pod_security_evaluations_total&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;{&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;decision&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;deny&amp;#34;&lt;/span&gt;,mode&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;audit&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;}[&lt;/span&gt;1h&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;]))&lt;/span&gt; by &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;(&lt;/span&gt;policy_level&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;recommended-how-can-i-automate-this-check-using-e2e-testing-to-ensure-that-my-solutions-can-run-under-the-policies&#34;&gt;(Recommended) How can I automate this check using e2e testing to ensure that my solutions can run under the policies?&lt;/h3&gt;
&lt;p&gt;In the tests, you can create and label a namespace with the desired policy (i.e. restricted). This would allow you to verify
if any warnings/errors occur and if the Pod(s)/Container(s) are in the &lt;code&gt;Running&lt;/code&gt; state. It can be something like:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt; See the &lt;code&gt;test&lt;/code&gt; directory for the Memcached sample under the &lt;a href=&#34;https://github.com/operator-framework/operator-sdk/tree/master/testdata/go/v4/memcached-operator&#34;&gt;testdata/go/v3/memcached-operator&lt;/a&gt; to see a full example.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre 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;color:#8f5902;font-style:italic&#34;&gt;// namespace store the ns where the Operator and Operand(s) will be executed
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;namespace&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;my-operator-system&amp;#34;&lt;/span&gt;

&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;_&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Describe&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;my operator test&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;func&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
    &lt;span style=&#34;color:#000&#34;&gt;BeforeEach&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;func&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
        &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;
        
        &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Where we will create the namespace for to install the Operator and Operands
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;        &lt;span style=&#34;color:#000&#34;&gt;By&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;creating namespace&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
        &lt;span style=&#34;color:#000&#34;&gt;cmd&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;exec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Command&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;kubectl&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;create&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;ns&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;namespace&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
        &lt;span style=&#34;color:#000&#34;&gt;_&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;_&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;utils&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Run&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;cmd&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
        
        &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// We will label as follows all namespaces so that we can check if warnings will be raised when 
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;		&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// a manifest be applied. (Not that some namespaces might not acced the label, i.e. if it
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;		&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// has a container running with a less restrictive policy )
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;        &lt;span style=&#34;color:#000&#34;&gt;By&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;labeling all namespaces to warn against what can violate the restricted policy&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
        &lt;span style=&#34;color:#000&#34;&gt;cmd&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;exec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Command&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;kubectl&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;label&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;--overwrite&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;ns&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;--all&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
            &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;pod-security.kubernetes.io/audit=restricted&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
            &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;pod-security.kubernetes.io/enforce-version=v1.24&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
            &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;pod-security.kubernetes.io/warn=restricted&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
        &lt;span style=&#34;color:#000&#34;&gt;_&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;utils&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Run&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;cmd&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
        &lt;span style=&#34;color:#000&#34;&gt;ExpectWithOffset&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;).&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;NotTo&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;HaveOccurred&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;())&lt;/span&gt;
        
		&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// We will enforce the restricted policy so that if our Operator
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;		&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// or Operand be unable to run as restricted we will be able to check
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;		&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// it by validating their status
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;        &lt;span style=&#34;color:#000&#34;&gt;By&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;enforcing restricted to the ns where the Operator/Operand(s) will be checked&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
        &lt;span style=&#34;color:#000&#34;&gt;cmd&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;exec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Command&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;kubectl&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;label&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;--overwrite&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;ns&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;namespace&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
            &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;pod-security.kubernetes.io/audit=restricted&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
            &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;pod-security.kubernetes.io/enforce-version=v1.24&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
            &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;pod-security.kubernetes.io/enforce=restricted&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
        &lt;span style=&#34;color:#000&#34;&gt;_&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;utils&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Run&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;cmd&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
        &lt;span style=&#34;color:#000&#34;&gt;Expect&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;).&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;To&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Not&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;HaveOccurred&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;()))&lt;/span&gt;
        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;})&lt;/span&gt;
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;})&lt;/span&gt;
    
    &lt;span style=&#34;color:#000&#34;&gt;AfterEach&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;func&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
        &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;})&lt;/span&gt;

    &lt;span style=&#34;color:#000&#34;&gt;It&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;should successfully run the Operator and Operand(s)&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;func&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
        &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Then, here we build the operator and deploy the
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;        &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// manager as the operand in the namespaces were 
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;        &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// the policy restricted was enforced.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;		
        &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Therefore, we can check the Operator and Operand
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;        &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// status to ensure that all is Running.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;		
        &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Note that we can also verify if warns like with
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;        &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// the message Warning: would violate PodSecurity were 
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;        &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// returned when the manifest were applied on the cluster
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;})&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;after-following-the-recommendations-to-be-restricted-my-workload-is-not-running-createcontainerconfigerror-what-should-i-do&#34;&gt;After following the recommendations to be restricted my workload is not running (CreateContainerConfigError). What should I do?&lt;/h3&gt;
&lt;p&gt;If you are encountering errors similar to &lt;code&gt;Error: container has runAsNonRoot and image has non-numeric user&lt;/code&gt;
or &lt;code&gt;container has runAsNonRoot and image will run as root&lt;/code&gt; that means that the image used does not have a non-zero numeric user defined, i.e.:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre 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;USER 65532:65532 
OR
USER &lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;1001&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Due to the &lt;code&gt;RunAsNonRoot&lt;/code&gt; field being set to &lt;code&gt;true&lt;/code&gt;, we need to force the user in the
container to a non-zero numeric user.
It is recommended that the images used by your operator have a non-zero numeric user set in the image itself (similar to the example above). For further information check the note &lt;a href=&#34;https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#user&#34;&gt;Consider an explicit UID/GID&lt;/a&gt; in the Dockerfile best practices guide.
If your Operator will be distributed and used in vanilla Kubernetes clusters you can also fix the issue by defining the user via the security context configuration). (i.e. &lt;code&gt;RunAsUser: &amp;amp;[]int64{1000}[0],&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt; If your Operator should work with specific vendors please ensure that you check if they have specific rules for Pod Security Admission.  For example, we know that if you use &lt;code&gt;RunAsUser&lt;/code&gt; on OpenShift it will disqualify the Pod from their restricted-v2 SCC.
Therefore, if you want your workloads running in namespaces labeled to enforce restricted you must leave &lt;code&gt;RunAsUser&lt;/code&gt; and &lt;code&gt;RunAsNonRoot&lt;/code&gt; fields empty or if you want set &lt;code&gt;RunAsNonRoot&lt;/code&gt; then, you MUST ensure that the image itself properly defines the UserID.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: Operator Observability Best Practices</title>
      <link>/docs/best-practices/observability-best-practices/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/best-practices/observability-best-practices/</guid>
      <description>
        
        
        &lt;h2 id=&#34;operator-observability-best-practices&#34;&gt;Operator Observability Best Practices&lt;/h2&gt;
&lt;p&gt;In this document, we provide best practices and examples for creating metrics, &lt;a href=&#34;https://prometheus.io/docs/prometheus/latest/configuration/recording_rules/#recording-rules&#34;&gt;recording rules&lt;/a&gt; and alerts. It is based on the general guidelines in &lt;a href=&#34;https://sdk.operatorframework.io/docs/overview/operator-capabilities/&#34;&gt;Operator Capability Levels&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; For technical documentation of how to add metrics to your operator, please read the &lt;a href=&#34;https://book.kubebuilder.io/reference/metrics.html&#34;&gt;Metrics&lt;/a&gt; section of the Kubebuilder documentation.&lt;/p&gt;
&lt;h3 id=&#34;operator-observability-recommended-components&#34;&gt;Operator Observability Recommended Components&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Health and Performance metrics&lt;/strong&gt; - for all of the operator components&lt;br&gt;
1.1. Metrics should be implemented based on the guidelines below.&lt;br&gt;
1.2. &lt;strong&gt;Metrics Documentation&lt;/strong&gt; - All metrics should have documentation.&lt;br&gt;
1.3. &lt;strong&gt;Metrics Tests&lt;/strong&gt; - Metrics should include tests that verify that they exist and that their value is correct.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Alerts&lt;/strong&gt; for when things are not working as expected for each of the operator&amp;rsquo;s components&lt;br&gt;
2.1  Alerts should be implemented based on the guidelines below.&lt;br&gt;
2.2. &lt;strong&gt;Alerts Runbooks&lt;/strong&gt; - Each alert can include a &lt;code&gt;runbook_url&lt;/code&gt; annotation and an alert runbook that describes it. See additional details below.&lt;br&gt;
2.3. &lt;strong&gt;Alerts Tests&lt;/strong&gt; - Alerts should include E2E Testing and unit tests.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Events&lt;/strong&gt; - Custom Resources should emit custom events for the operations taking place.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Additional components would be &lt;code&gt;Dashboards&lt;/code&gt;, &lt;code&gt;Logs&lt;/code&gt; and &lt;code&gt;Traces&lt;/code&gt;, which are not addressed in this document at this point.&lt;/p&gt;
&lt;h3 id=&#34;operators-observability-general-guidelines&#34;&gt;Operators Observability General Guidelines&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; It is highly recommended to separate your monitoring code from your core operator code.&lt;br&gt;
We recommend to create a dedicated &lt;code&gt;/monitoring&lt;/code&gt; subfolder that will include all the code of the &lt;a href=&#34;#operator-observability-recommended-components&#34;&gt;Operator Observability Recommended Components&lt;/a&gt;, that are outlined above. For example, in the &lt;a href=&#34;https://github.com/operator-framework/operator-sdk/tree/master/testdata/go/v4/monitoring/memcached-operator/monitoring&#34;&gt;memcached-operator&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In your core operator code only call the functions that will update the metrics value from your desired location. For example, in the &lt;a href=&#34;https://github.com/operator-framework/operator-sdk/blob/367bd3597c30607099aa73637f5286f7120b847a/testdata/go/v3/monitoring/memcached-operator/controllers/memcached_controller.go#L242&#34;&gt;memcached-operator&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;All operators start small. This separation will help you, as a developer, with easier maintenance of both your operator core code and the monitoring code and for other stakeholders to understand your monitoring code better.&lt;/p&gt;
&lt;h3 id=&#34;metrics-guidelines&#34;&gt;Metrics Guidelines&lt;/h3&gt;
&lt;h4 id=&#34;metrics-naming&#34;&gt;Metrics Naming&lt;/h4&gt;
&lt;p&gt;Kubernetes components emit metrics in &lt;a href=&#34;https://prometheus.io/docs/instrumenting/exposition_formats/&#34;&gt;Prometheus format&lt;/a&gt;. This format is structured plain text, designed so that people and machines can both read it.&lt;/p&gt;
&lt;p&gt;Your operator users should get the same experience when searching for a metric across Kubernetes operators, resources and custom resources.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Check if a similar Kubernetes metric, for node, container or pod, exists and try to align to it.&lt;/li&gt;
&lt;li&gt;The metrics search list, in the Prometheus, Grafana UI and even in the /metrics end point, is sorted in alphabetical order.
When searching for a metric, it should be easy to identify metrics that are related to a specific operator.
That is why we recommend that your operator metrics name will follow this format:
&lt;code&gt;operator name&lt;/code&gt; prefix + the &lt;code&gt;sub-operator name&lt;/code&gt; or &lt;code&gt;entity&lt;/code&gt; + &lt;code&gt;metric name&lt;/code&gt; based on the &lt;a href=&#34;https://prometheus.io/docs/practices/naming/&#34;&gt;Prometheus naming conventions&lt;/a&gt;. For example, in the &lt;a href=&#34;https://github.com/operator-framework/operator-sdk/blob/0d2fa86f0d3cc92c4672cb9e1d246efaefcf7ced/testdata/go/v4-alpha/monitoring/memcached-operator/monitoring/metrics.go#L14&#34;&gt;memcached-operator&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; In &lt;a href=&#34;https://github.com/prometheus/node_exporter&#34;&gt;Prometheus Node Exporter&lt;/a&gt; metrics are separated like this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;node_network_**receive**_packets_total&lt;/li&gt;
&lt;li&gt;node_network_**transmit**_packets_total&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In this example, based on &lt;code&gt;receive&lt;/code&gt; and &lt;code&gt;transmit&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Please follow the same principle and don&amp;rsquo;t put similar metrics details as labels, so the user experience would be fluent.&lt;br&gt;
Example for this in an operator:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;kubevirt_vmi_network_**receive**_errors_total&lt;/li&gt;
&lt;li&gt;kubevirt_vmi_network_**transmit**_bytes_total&lt;/li&gt;
&lt;li&gt;kubevirt_migrate_vmi_**data_processed**_bytes&lt;/li&gt;
&lt;li&gt;kubevirt_migrate_vmi_**data_remaining**_bytes&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;Your metric suffix should indicate the metric unit. For better compatibility, &lt;a href=&#34;https://prometheus.io/docs/practices/naming/#base-units&#34;&gt;Prometheus base units&lt;/a&gt; should be used.&lt;/li&gt;
&lt;li&gt;Prometheus supports four &lt;a href=&#34;https://prometheus.io/docs/concepts/metric_types/#metric-types&#34;&gt;metric types&lt;/a&gt;. &lt;code&gt;Gauge&lt;/code&gt;,&lt;code&gt;Counter&lt;/code&gt;,&lt;code&gt;Histogram&lt;/code&gt; and &lt;code&gt;Summary&lt;/code&gt;. You can read more about the different types here, &lt;a href=&#34;https://prometheus.io/docs/tutorials/understanding_metric_types/#types-of-metrics&#34;&gt;Understanding metrics types&lt;/a&gt;.&lt;br&gt;
The most common types are:&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Counter&lt;/code&gt; - Value can only increase or reset.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Gauge&lt;/code&gt; Value can be increased and decreased as needed.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start=&#34;5&#34;&gt;
&lt;li&gt;&lt;code&gt;_total&lt;/code&gt; suffix should be used for accumulating count. If your metrics has labels with high cardinality, like &lt;code&gt;pod&lt;/code&gt;/&lt;code&gt;container&lt;/code&gt; it usually means that you can aggregate it more, thus it will not require &lt;code&gt;_total&lt;/code&gt; suffix.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;prometheus-labels&#34;&gt;Prometheus Labels&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://prometheus.io/docs/practices/naming/#labels&#34;&gt;Prometheus labels&lt;/a&gt; are used to differentiate the characteristics of the thing that is being measured.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Important&lt;/strong&gt; - Be cautious when adding labels to metrics. Labels can dramatically increase the amount of data stored. Do not use labels to store dimensions with high cardinality (many different label values), such as user IDs, email addresses, or other unbounded sets of values. Note: There are still cases when we will still need to have a high cardinality label like the &lt;code&gt;pod name&lt;/code&gt;, but try to keep this to the minimum.&lt;/li&gt;
&lt;li&gt;When creating a new metric, recording rule or alert, that reports a resource like a &lt;code&gt;pod&lt;/code&gt; or a &lt;code&gt;container&lt;/code&gt;, make sure that the &lt;code&gt;namespace&lt;/code&gt; is included, in order to be able to uniquely identify it.&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;metrics-help-message&#34;&gt;Metrics &lt;code&gt;Help&lt;/code&gt; message&lt;/h4&gt;
&lt;p&gt;Your operator metrics &lt;code&gt;help&lt;/code&gt; message should include the following details:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What does this metric measure?&lt;/li&gt;
&lt;li&gt;What does the output mean?&lt;/li&gt;
&lt;li&gt;What important labels does the metric use? (Optional. If applicable).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The &lt;code&gt;Help&lt;/code&gt; message can be used to create auto-generated documentation, like it&amp;rsquo;s done in &lt;a href=&#34;https://github.com/kubevirt/kubevirt/blob/main/docs/observability/metrics.md&#34;&gt;KubeVirt&lt;/a&gt; and generated by the &lt;a href=&#34;https://github.com/kubevirt/kubevirt/blob/main/tools/doc-generator/doc-generator.go&#34;&gt;KubeVirt metrics doc generator&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We recommend to auto-generated metrics documentation and save it in your operator repository, to a location like &lt;code&gt;/docs/monitoring/&lt;/code&gt;, so that the users can find the information about your operator metrics easily.&lt;/p&gt;
&lt;p&gt;See &lt;a href=&#34;#alerts-metrics-and-recording-rules-tests&#34;&gt;Alerts, Metrics and Recording Rules Tests&lt;/a&gt; section for metrics testing recommendations.&lt;/p&gt;
&lt;h4 id=&#34;prometheus-recording-rules-naming&#34;&gt;Prometheus Recording Rules Naming&lt;/h4&gt;
&lt;p&gt;As per &lt;a href=&#34;https://prometheus.io/docs/prometheus&#34;&gt;Prometheus&lt;/a&gt; documentation, &lt;a href=&#34;https://prometheus.io/docs/prometheus/latest/configuration/recording_rules/#recording-rules&#34;&gt;Recording rules&lt;/a&gt; allow you to pre-compute frequently needed or computationally expensive expressions and save their result as a new set of time series.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The Prometheus recording rules appear in Prometheus UI as metrics.
Recording rule names should follow the &lt;code&gt;level:metric:operations&lt;/code&gt; format as specified in the &lt;a href=&#34;https://prometheus.io/docs/practices/rules/&#34;&gt;Prometheus recording rules best practices&lt;/a&gt;. This naming convention makes it clear that the metric is a recording rule and helps consumers understand they need to examine the underlying query to fully understand what the metric provides.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;level:&lt;/strong&gt; represents the aggregation level and labels of the rule output&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;metric:&lt;/strong&gt; is the metric name&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;operations:&lt;/strong&gt; is a list of operations that were applied to the metric, newest operation first&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For example: &lt;code&gt;job:up:avg_over_time&lt;/code&gt; or &lt;code&gt;instance:node_cpu_utilisation:rate5m&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;In addition to this format, your operator recording rules should also follow the same naming guidelines as metrics for consistency within your operator&amp;rsquo;s observability stack.&lt;/p&gt;
&lt;p&gt;See &lt;a href=&#34;#alerts-metrics-and-recording-rules-tests&#34;&gt;Alerts, Metrics and Recording Rules Tests&lt;/a&gt; section for recording rules testing recommendations.&lt;/p&gt;
&lt;h3 id=&#34;prometheus-alerts-guidelines&#34;&gt;Prometheus Alerts Guidelines&lt;/h3&gt;
&lt;p&gt;Clear and actionable alerts are a key component of a smooth operational experience and will result in a better experience for the end users.&lt;/p&gt;
&lt;p&gt;The following guidances aim to align alert naming, severities, labels, etc., in order to avoid alerts fatigue for administrators.&lt;/p&gt;
&lt;h4 id=&#34;recommended-reading&#34;&gt;Recommended Reading&lt;/h4&gt;
&lt;p&gt;A list of references on good alerting practices:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://sre.google/sre-book/monitoring-distributed-systems/&#34;&gt;Google SRE Book - Monitoring Distributed Systems&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://prometheus.io/docs/practices/alerting/&#34;&gt;Prometheus Alerting Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.usenix.org/sites/default/files/conference/protected-files/srecon16europe_slides_rabenstein.pdf&#34;&gt;Alerting for Distributed Systems&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;alert-ownership&#34;&gt;Alert Ownership&lt;/h4&gt;
&lt;p&gt;Individual operator authors are responsible for writing and maintaining alerting rules for
their components, i.e. their operators and operands.&lt;/p&gt;
&lt;p&gt;Operator authors should also take into consideration how their components interact with
existing monitoring and alerting.&lt;/p&gt;
&lt;p&gt;As an example, if your operator deploys a service which creates one or more &lt;code&gt;PersistentVolume&lt;/code&gt; resources,
and these volumes are expected to be mostly full as part of normal operation, it&amp;rsquo;s likely
that this will cause unnecessary &lt;code&gt;KubePersistentVolumeFillingUp&lt;/code&gt; alerts to fire.&lt;/p&gt;
&lt;p&gt;You should work to find a solution to avoid triggering these alerts if they are not actionable.&lt;/p&gt;
&lt;h4 id=&#34;alerts-style-guide&#34;&gt;Alerts Style Guide&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Alert names MUST be CamelCase, e.g.: &lt;code&gt;PrometheusRuleFailures&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Alert names SHOULD be prefixed with a component, e.g.: &lt;code&gt;AlertmanagerFailedReload&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;There may be exceptions for some broadly scoped alerts, e.g.: &lt;code&gt;TargetDown&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Alerts MUST include a &lt;code&gt;severity&lt;/code&gt; label indicating the alert&amp;rsquo;s urgency.
&lt;ul&gt;
&lt;li&gt;Valid severities are: &lt;code&gt;critical&lt;/code&gt;, &lt;code&gt;warning&lt;/code&gt;, or &lt;code&gt;info&lt;/code&gt; — see below for
guidelines on writing alerts of each severity.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Alerts MUST include &lt;code&gt;summary&lt;/code&gt; and &lt;code&gt;description&lt;/code&gt; annotations.
&lt;ul&gt;
&lt;li&gt;Think of &lt;code&gt;summary&lt;/code&gt; as the first line of a commit message, or an email
subject line.  It should be brief but informative.  The &lt;code&gt;description&lt;/code&gt; is the
longer, more detailed explanation of the alert.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Alerts SHOULD include a &lt;code&gt;namespace&lt;/code&gt; label indicating the source of the alert.
&lt;ul&gt;
&lt;li&gt;Many alerts will include this by virtue of the fact that their PromQL
expressions result in a namespace label.  Others may require a static
namespace label — see for example, the &lt;a href=&#34;https://github.com/openshift/cluster-monitoring-operator/blob/79cdf68/assets/control-plane/prometheus-rule.yaml#L235-L247&#34;&gt;KubeCPUOvercommit&lt;/a&gt; alert.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Optional Alerts Labels and Annotations&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;priority&lt;/code&gt; label indicating the alert&amp;rsquo;s level of importance and the order in which it should be fixed.
&lt;ul&gt;
&lt;li&gt;Valid priorities are: &lt;code&gt;high&lt;/code&gt;, &lt;code&gt;medium&lt;/code&gt;, or &lt;code&gt;low&lt;/code&gt;.
Higher the priority the sooner the alert should be resolved.&lt;/li&gt;
&lt;li&gt;If the alert doesn&amp;rsquo;t include a &lt;code&gt;priority&lt;/code&gt; label, we can assume it is a &lt;code&gt;medium&lt;/code&gt; priority alert.
This label will usually be used for alerts with &lt;code&gt;warning&lt;/code&gt; severity, to indicate the order in which the alert should be addressed by, even though it doesn&amp;rsquo;t require immediate action.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;runbook_url&lt;/code&gt; annotation is a link to an alert runbook which is intended to guide a cluster owner and/or operator through the steps of fixing problems on clusters, which are surfaced by alerts.
&lt;ul&gt;
&lt;li&gt;An example for &lt;a href=&#34;https://github.com/openshift/runbooks/blob/master/example.md&#34;&gt;Runbook style documentation&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Your operator alert runbooks can be saved at your operator repository, to &lt;code&gt;/docs/monitoring/runbooks/&lt;/code&gt; for example,
at &lt;a href=&#34;https://github.com/openshift/runbooks&#34;&gt;OpenShift Runbooks&lt;/a&gt; if your operator is shipped with OpenShift
or another location that fits your operator.&lt;/li&gt;
&lt;li&gt;If you are using Github, you can use &lt;a href=&#34;https://pages.github.com/&#34;&gt;Github Pages&lt;/a&gt; for a better view of the runbooks.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;kubernetes_operator_part_of&lt;/code&gt; label indicating the operator name. Label name is based on the  &lt;a href=&#34;https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/#labels&#34;&gt;Kubernetes Recommended Labels&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;alerts-severity&#34;&gt;Alerts Severity&lt;/h4&gt;
&lt;h5 id=&#34;critical-alerts&#34;&gt;Critical Alerts&lt;/h5&gt;
&lt;p&gt;For alerting current and impending disaster situations. These alerts
page an SRE. The situation should warrant waking someone in the middle of the
night.&lt;/p&gt;
&lt;p&gt;Timeline:  ~5 minutes.&lt;/p&gt;
&lt;p&gt;Reserve critical level alerts only for reporting conditions that may lead to loss of data or inability to deliver service for the cluster as a whole.&lt;br&gt;
Failures of most individual components should not trigger critical level alerts, unless they would result in either of those conditions.&lt;br&gt;
Configure critical level alerts so they fire before the situation becomes irrecoverable.&lt;br&gt;
Expect users to be notified of a critical alert within a short period of time after it fires so
they can respond with corrective action quickly.&lt;/p&gt;
&lt;p&gt;Example critical alert: &lt;a href=&#34;https://github.com/openshift/cluster-monitoring-operator/blob/79cdf68/assets/control-plane/prometheus-rule.yaml#L412-L421&#34;&gt;KubeAPIDown&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre 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;color:#204a87;font-weight:bold&#34;&gt;alert&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;KubeAPIDown&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;annotations&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;summary&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Target&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;disappeared&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;from&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Prometheus&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;target&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;discovery.&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;description&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;KubeAPI&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;has&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;disappeared&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;from&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Prometheus&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;target&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;discovery.&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;runbook_url&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;https&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;//github.com/openshift/runbooks/blob/master/alerts/cluster-monitoring-operator/KubeAPIDown.md&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;expr&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;|
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;    absent(up{job=&amp;#34;apiserver&amp;#34;} == 1)&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;for&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;15m&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;labels&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;severity&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;critical&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This alert fires if no Kubernetes API server instance has reported metrics successfully in the last 15 minutes.&lt;br&gt;
This is a clear example of a critical control-plane issue that represents a threat to the operability of the cluster as a whole, and likely warrants paging someone.&lt;br&gt;
The alert has clear summary and description annotations, and it links to a runbook with information on investigating and resolving the issue.&lt;/p&gt;
&lt;p&gt;The group of critical alerts should be small, very well defined, highly documented, polished and with a high bar set for entry.&lt;/p&gt;
&lt;h5 id=&#34;warning-alerts&#34;&gt;Warning Alerts&lt;/h5&gt;
&lt;p&gt;The vast majority of alerts should use this severity.&lt;br&gt;
Issues at the warning level should be addressed in a timely manner, but don&amp;rsquo;t pose an immediate threat to the operation of the cluster as a whole.&lt;/p&gt;
&lt;p&gt;Timeline:  ~60 minutes&lt;/p&gt;
&lt;p&gt;If your alert does not meet the criteria in &amp;ldquo;Critical Alerts&amp;rdquo; above, it belongs to the warning level or lower.&lt;/p&gt;
&lt;p&gt;Use warning level alerts for reporting conditions that may lead to inability to deliver individual features of the cluster, but not service for the cluster as a
whole. Most alerts are likely to be warnings.&lt;br&gt;
Configure warning level alerts so that they do not fire until components have sufficient time to try to recover from the interruption automatically.&lt;br&gt;
Expect users to be notified of a warning, but for them not to respond with corrective action immediately.&lt;/p&gt;
&lt;p&gt;Example warning alert: &lt;a href=&#34;https://github.com/openshift/cluster-version-operator/blob/513a2fc/install/0000_90_cluster-version-operator_02_servicemonitor.yaml#L68-L76&#34;&gt;ClusterNotUpgradeable&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre 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;color:#204a87;font-weight:bold&#34;&gt;alert&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;ClusterNotUpgradeable&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;annotations&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;summary&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;One&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;or&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;more&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;cluster&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;operators&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;have&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;been&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;blocking&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;minor&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;version&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;cluster&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;upgrades&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;for&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;at&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;least&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;an&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;hour.&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;description&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;In&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;most&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;cases&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;you&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;will&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;still&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;be&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;able&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;to&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;apply&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;patch&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;releases.&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;Reason&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;{{&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;{{ with $cluster_operator_conditions := \&amp;#34;cluster_operator_conditions\&amp;#34; | query}}{{range $value := .}}{{if and (eq (label \&amp;#34;name\&amp;#34; $value) \&amp;#34;version\&amp;#34;) (eq (label \&amp;#34;condition\&amp;#34; $value) \&amp;#34;Upgradeable\&amp;#34;) (eq (label \&amp;#34;endpoint\&amp;#34; $value) \&amp;#34;metrics\&amp;#34;) (eq (value $value) 0.0) (ne (len (label \&amp;#34;reason\&amp;#34; $value)) 0) }}{{label \&amp;#34;reason\&amp;#34; $value}}.{{end}}{{end}}{{end}}&amp;#34;&lt;/span&gt;}}&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;For&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;more&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;information&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;refer&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;to&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#39;oc adm upgrade&amp;#39;&lt;/span&gt;{{&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;{{ with $console_url := \&amp;#34;console_url\&amp;#34; | query }}{{ if ne (len (label \&amp;#34;url\&amp;#34; (first $console_url ) ) ) 0}} or {{ label \&amp;#34;url\&amp;#34; (first $console_url ) }}/settings/cluster/{{ end }}{{ end }}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;}}.&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;expr&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;|
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;      max by (name, condition, endpoint) (cluster_operator_conditions{name=&amp;#34;version&amp;#34;, condition=&amp;#34;Upgradeable&amp;#34;, endpoint=&amp;#34;metrics&amp;#34;} == 0)&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;for&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;60m&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;labels&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;severity&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;warning&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This alert fires if one or more operators have not reported their &lt;code&gt;Upgradeable&lt;/code&gt; condition as true in more than an hour.&lt;br&gt;
The alert has a clear name and informative summary and description annotations.&lt;br&gt;
The timeline is appropriate for allowing the operator a chance to resolve the issue automatically, avoiding the need to alert an administrator.&lt;/p&gt;
&lt;h5 id=&#34;info-alerts&#34;&gt;Info Alerts&lt;/h5&gt;
&lt;p&gt;Info level alerts represent situations an administrator should be aware of, but they don&amp;rsquo;t necessarily require any action.&lt;br&gt;
Use these sparingly, and consider instead reporting this information via Kubernetes events.&lt;/p&gt;
&lt;p&gt;Example info alert: &lt;a href=&#34;https://github.com/openshift/cluster-monitoring-operator/blob/79cdf68/assets/cluster-monitoring-operator/prometheus-rule.yaml#L326-L338&#34;&gt;MultipleContainersOOMKilled&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre 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;color:#204a87;font-weight:bold&#34;&gt;alert&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;MultipleContainersOOMKilled&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;annotations&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;description&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Multiple&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;containers&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;were&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;out&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;of&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;memory&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;killed&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;within&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;the&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;past&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;15&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;minutes.&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;There&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;are&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;many&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;potential&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;causes&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;of&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;OOM&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;errors&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;however&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;issues&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;on&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;a&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;specific&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;node&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;or&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;containers&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;breaching&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;their&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;limits&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;is&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;common.&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;summary&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Containers&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;are&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;being&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;killed&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;due&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;to&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;OOM&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;expr&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;sum(max&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;by(namespace&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;container&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;pod)&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;(increase(kube_pod_container_status_restarts_total&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[&lt;/span&gt;12m&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;]&lt;/span&gt;))&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;and&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;max&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;by(namespace&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;container&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;pod)&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;(kube_pod_container_status_last_terminated_reason{reason=&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;OOMKilled&amp;#34;&lt;/span&gt;})&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;==&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;1&lt;/span&gt;)&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&amp;gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;5&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;for&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;15m&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;labels&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;namespace&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;kube-system&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;severity&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;info&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This alert fires if multiple containers have been terminated due to out of memory conditions in the last 15 minutes.&lt;br&gt;
This is something the administrator should be aware of, but may not require immediate action.&lt;/p&gt;
&lt;h3 id=&#34;alerts-metrics-and-recording-rules-tests&#34;&gt;Alerts, Metrics and Recording Rules Tests&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Add tests for alerts that validate that:
&lt;ul&gt;
&lt;li&gt;Each alert includes all mandatory fields.&lt;/li&gt;
&lt;li&gt;Each &lt;code&gt;runbook_url&lt;/code&gt; link is valid.&lt;/li&gt;
&lt;li&gt;Each alert that includes a &lt;code&gt;pod&lt;/code&gt; or a &lt;code&gt;container&lt;/code&gt; also includes the &lt;code&gt;namespace&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Add e2e tests that inspect the alerts during upgrade and make sure that the alerts don’t fire when they shouldn’t (Zero noise).&lt;/li&gt;
&lt;li&gt;Add tests for metrics and recording rules that validate that:
&lt;ul&gt;
&lt;li&gt;Metric / Recording rule exists.&lt;/li&gt;
&lt;li&gt;Metric / Recording rule value is as expected.&lt;/li&gt;
&lt;li&gt;Metric / Recording rule name follows the best practices guideline.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

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