 Hello, everyone. Welcome to Cloud Native Live, where we dive into the code behind Cloud Native. I am Annie Talastro and I'm a CNCS ambassador, as well as a senior product marketing manager at Camunda, and I will be your host tonight. So, every week we bring a new set of presenters to showcase how to work with Cloud Native technologies. They will build things, they will break things, and they will answer all of your questions. So, you can join us every Wednesday to watch live. And to use what's happening in the Cloud Native world, the co-located event schedules for North America. QCon plus Cloud NativeCon are live, so you can check those out, as well as the CFP so-called papers for Europe, QCon, Cloud NativeCon is also live. So, go ahead and submit those sessions. And as always, really nice to have amazing speakers with us today. So, this week we have Stevie and Andy here with us to talk about implementing communities, card delays, and re-diamination with polarity. And as always, this is an official live stream of the CNCS and as such, it is subject to the CNCS Code of Conduct. Please do not add anything to the chat or questions that will be in violation of that Code of Conduct. So, basically, please be respectful of all of your fellow participants, as well as presenters. So, I'll hand it over to Stevie and Andy to kick off today's presentation. Cool. Thank you, Andy. Hello, everyone. Let's start off by doing a quick intro of who we are, and then I'll talk about what exactly we're going to cover today. Yeah. So, my name is Stevie. I am an SRE tech lead at Fairwinds. I've been working with Kubernetes for a few years. And then, before that, doing all things, you know, SIS admin and network engineering and stuff like that. So, I've been around the block a bit. And Andy. Hi, everybody. I'm Andy. I'm, I like to say sometimes I want to reform SIS admin. I'm author and maintainer of a bunch of our open source projects here at Fairwinds. I'm also our CTO. I've been doing Kubernetes for, gosh, seven and a half, eight years now. And I've been with Fairwinds for four and a half. So, just a huge fan of all things open source. Cool. So, speaking of open source, that's what we're here to discuss today. We at Fairwinds have created a tool called Polaris. And that is a means of implementing Kubernetes guardrails. Guardrails are essentially ways to help developers be able to just concentrate on code and building and deploying their code and providing a safety net to help them avoid some common pitfalls that you could run into in a cluster in regards to compliance, security and cost. So, we're going to demo Polaris today, show you how to install it, show you how it works, so you have to configure it. All that good stuff. Before we get started though, I have an important question for Andy. Andy, what do you call eight hobbits? Eight hobbits? Something along the lines of 16 feet or maybe a bit bite joke going on here. I'm not sure you're going to have to tell me. A hobbite. A hobbite. Nice. That's a good one. Thank you. Thank you. Okay, let's get started. Love the jokes. All right, everybody. Just dive straight into the demo because I think we have a lot to cover today. So the first thing I'm going to do is I'm going to get a Kubernetes cluster going. I'm going to using kind that's Kubernetes and Docker. And we already have a problem. All right, I thought I killed this test cluster earlier, but we can go ahead and try again here. There we go. So I'm spinning up a Kubernetes cluster on v123. And then we're going to install some things. Oh, it does not like this is the beauty of live demos. I've done. Luckily, Andy's really good at what he does. And cool as a cucumber. I shall see. This is what I get for copy pasting commands. That was my problem. I should have just typed the whole shot out, right? All right. So we're going to, we're going to install a couple of things. First thing I'm going to install is a cert manager. As soon as this control point comes up. So I'm just going to install that straight out of the Jetstack repo using home. I'm going to tell it to install the cert manager CRDs. Why are we installing the cert manager CRDs? Great question. So we are going to use Polaris as both a mutating and a validating admission web hook. And so we need certificates to put in the objects that configure those web hooks. And so we're going to let cert manager manage those for us. It's a very convenient way to do it. Rather than generating self-signed certs on the fly or anything like that, we're going to let cert manager just manage those for us. And it'll actually go update the web hook configurations with those certs. So while cert manager is installing, I'm going to start getting ready. Sorry about that. Great question already. I think it's been more for general one though. And you're probably going to give some resources towards the end as well. But there was a question about what are the best resources to learn about the cloud. But another listener already just gave the suggestion for communities that IO is a great starting point as well. Yeah. Great answer. That's a very large topic, the cloud. So I don't know if I can give specific good resources, but communities.io is a great resource. As well as I'm sure many, many pages from the CNCF. So cool. So let's see. We already installed cert manager. And then the other thing I'm going to do is I'm going to create a temporary directory. And I'm going to use the Helm template command to grab some, some YAML manifests. So if we look here, I just did a Helm template to pull down a chart that we have for just running a basic demo in Kubernetes. It's got a deployment, a horizontal pod out of scalar, a PDV and a service. So very simple setup here of something that we might deploy into our cluster. And so I'll have that available for later in the demo to tinker with that code. Oh, that's, hang on. I just, there we go. Do we install? Okay. Yep. Now we're going to install Polaris. Finally. All right. So we're going to install Polaris into the Polaris namesays for passing the create namespace flag. And then again, we're pulling that just straight out of our Fairwind stable repository to get the charts. And I see, so in the, in that Helm command, you have a couple of value set. You're setting a value webhook.enable true and webhook.mutate true. Can you speak a little bit on what those slides do? Yeah, definitely. So as I mentioned before, we're installing both the validating admission webhook and the mutating admission webhook for Polaris in order to show off some of the functionality later on. And those are the flags that will enable that for us. Right. So if we look, we should have a validating webhook configuration and a mutating webhook configuration for Polaris in this cluster now. And just a level set for folks like the difference in terms of these webhooks is that the validating webhook simply will deny or will deny an object being sent to the cluster, or at least print out like a warning to the logs or something. Depending on some things, which we'll talk about a little later, and then the mutating webhook will actually change the aspect of your resource that is opposite the configuration that you have in your webhook. Yeah. Exactly. Great explanation. So what we'll do first is we're going to apply those manifests that I was talking about earlier. So we're just going to apply those to the default namespace. And right off the bat, we're going to see Polaris is already at work here. So I'll full screen this little section here. But Polaris prevented this deployment, because the image tag should be specified. So it's blocking my Polaris demo deployment release, blah, blah, blah, because we haven't specified an image tag. So if we go take a look at that deployment manifest, we go down here to where the image is defined, it says we're using the latest, the latest tag, which is generally not something we want to do. And so I'm going to change that to, I hope that's the right one, one dot one dot out here in order to get past that admission control. Perfect. And then there's someone wondering in the audience how different this is. Is this from gatekeeper open policy agent? Great question. And I will talk about that a little bit in a bit. But the big difference is the language that we're writing the checks in and how we're, just the language that we're using to write those checks. So open policy agent uses Rego. We're actually going to use JSON schema here. But otherwise they're fairly similar in how they function. I will say Polaris came first too. Not that we're counting, but yeah. So as you, but as you said, this immediately flag some things in your cluster. So I'm assuming, you know, Polaris comes with some defaults that automatically take place when you get started. Can we sort of investigate a little bit what those defaults are and why it flat like where it got the information to flag that deployment from. Most definitely. So I'm in the background while you were asking I set up a port forward to the Polaris dashboard. That's going to let us show what checks were running. And get a nicer view of what we just saw. So what we just saw obviously was the admission controller but at the same time the dashboard is running these checks and giving you the ability to see, you know, existing issues or non blocking issues. So by default, we have the default Polaris config, which is linked from the values file here. And we can see, you can configure every check what runs what that's bad link. You can configure every check and its level of What that second link in that doc, the one at the very end. That's the one that I think has the default config.yaml. Yeah, there we go. Okay, so the default config. Pull that up here. So we see the list of checks under each category. These are also listed in the documentation and their level. So by default, the admission controller blocks anything that's a danger level and passes anything that's warning or below. So if we go look back in that dashboard, we're going to see, let's just take a look at the default namespace where we applied that yaml. We're going to see, well, no failing checks here. But if we go back to our other namespaces like cert manager, we're going to see some warnings popping up here. Now, if we click on the little question mark icon, it's going to take you to the documentation for Polaris and you can see all the built in checks under each of the three categories, security, efficiency and reliability, their default levels, and then a description of what they mean, like what's going on here. So that's the default config. And that's all again listed in the repo under the default config, and you can override any of these settings when you go to deploy via helm. And that's what we're going to do here in just a moment. Because we want to focus a little bit on how you develop a strategy around this, not just how it works, because it's one thing to run a policy engine, it's one thing to run some checks, it's another to actually like actively start enforcing things and putting custom checks and things like that. Right. So Polaris out of the box just to just to recap then comes with already configured checks that if you do nothing, it will pull the checks out of that config.yaml. And it also is already configured to check three types of controllers by default deployments, staple set and there's a third. So actually, by default Polaris will check any pod controller because it looks up the pod and then walks up the owner references in order to find the top level controller. The admission controller by default is set up to watch specific resources. So if we go to the values file for Polaris, we go down to the web hook section, and we see the default rules. These are the default rules for the both admission controllers for both the mutating and the validating admission web configurations. So we're looking for Damon sets deployments and stateful sets, any creator update operation, and then also actually current jobs and cron jobs and pods and replication controller. So if you want, you know, to watch for just pod creation and block that which actually I think is what's happening in our cluster right now. So yeah, and you can add any you want to this configuration here. So the default rules rules block up above where you can add additional things to up there, I guess, if you want to. Yeah, you could override the default rules for both or if you wanted to specifically add mutating rules or validating rules, you could do that here. Got it. Okay. Highly configurable that's awesome. Yes, there's a lot of config I dug through a lot of config while building this demo because there's a lot of options there. One thing to note is if you're curious about default checks and what's built in. You can also go to the checks folder in the Polaris repo and see all the different files that define the checks. So if we want to take a look at that tag not specified that we just got blocked on here you're going to see a YAML version of JSON schema which I realize is a little bit weird. You can also specify it in inline JSON strings if you want so you can replace this schema. I think schema with schema string lists in the documentation. But basically we're saying okay, we're looking at the container spec so Polaris will automatically pull just the container spec out of your entire spec. Using a deployment it'll just grab the different containers and run the schema against that so you don't have to write your whole nested JSON schema in order to get down to a field in the container. I'm going to say that the image field inside the container spec has to match this pattern which is just any string colon any other string and then it cannot match the pattern any string colon latest. And so obviously you could expand on this and say it has to match a semver string or something like that if you wanted to get a little bit more specific. It's just a regex pattern match so the sky is the limit if you want to write more regex. We all want to write more regex. I think that was an old ex Casey about I had 99 problems and then I use regex and now I have 100 problems. Anyway, that's what the policy looks like. And this is sort of kind of the starting point for how you begin to write your own custom policy. So, in terms of writing your own custom policies how do those play with, like, since they're already a list of policies to come in and, you know, include it, how do you like either integrate or like how do you actually do that in the config. So, what I have here is I pulled the default values file from the Helm chart for Polaris. Obviously this has all of the different deployment options on how things work, but then it also is going to have the configuration so what I'm going to do is first in order to ease our lives a little bit here. I'm going to change the failure policy of both web hooks to be ignore that way while pods are restarting and the things are failing we're not going to accidentally block our Polaris deployment. And then I'm going to start filling out this config block. And I'm just going to say that's a good that's a good basic pattern to follow whenever you're working with web hooks and the admission controller in general is to start off. Not actively not in an active mode not like blocking things you want to you want to run it sort of in a test mode by having it do ignore or just doing the logging warnings to the logs. So, just to clarify that ignore will only ignore when the when the request to the web hook fails so like if we get a 404 500 from the web hook endpoint, if it actually returns. Whatever the the return code is that we've specified in our configuration to say block this it will still go ahead and block it. And so what we'll actually do here is go if we're testing, we can put all of these different checks into warning mode. And that will prevent actual blocking by the by the web hook itself. And so we can go ahead and do that if we want to do this in test mode. And then, you know, we can also just turn these ignore. But it's nice to see it all in the dashboard. And then the other thing we're going to do here that I haven't talked about yet is mutations. So we do have the ability to to mutate objects if you want to automatically enforce a policy in a specific way, we can just go ahead and do that at admission time, rather than blocking the deployment. We have one of these turned on by default and the default configuration and it's the poll policy not always mutation. If we go back to our policies or checks and Polaris, and we take a look at the poll policy. We have a new section in the check configuration here called mutations. So we're going to do the operation to add the path image poll policy and we're going to set it to always. And that's again on the container target, we have other targets available. And so this will say like, you know, okay, this is our normal policy, we say that we should always use the always poll policy. That was a confusing sentence. But in the case that we're using the admission controller the mutating admission controller. We'll just go ahead and do that because it should be safe to do in most cases in most of your average clusters right. So we're just going to go ahead and do that. And you could do this for all sorts of things. Do all the checks automatically have now that mutating section so if you enable the mutating web hook by default, those mutations will will happen. This particular check does I believe it is the only check currently that we felt was okay to go ahead and add that to the defaults. So most checks will not have a mutation section by default. We are definitely open to ideas on mutations that are valid all of the time but it's a very risky thing to enable by default. So we're trying to be cognizant of that. All right, so let's talk about custom checks because I think that's honestly where things get super interesting. So in our documentation we have lots of examples and documentation of how you write custom checks and how they get added into your configuration because this can be a little bit tricky. So you have to both specify the custom check and then in the check section you have to define how to handle that check. You have to say warning or danger level like we saw earlier. So what I'm going to go ahead and do I have a slightly modified version of this check for checking for image registry. So we want to say all images have to come from a specific registry. So in my config I'm going to add a section called custom checks. And I'm going to put that in here and I'm going to indent it correctly. And so we have an image registry check that says that images should be from allowed registries. And I've written JSON scheme but to say it has to be any of these. And so we have a series of very X patterns. So I'm saying us docker.package.dev docker.io slash kindest because we have some control plane stuff coming from the kind docker registry. Obviously we need kates.gcr.io because all the stuff for Kubernetes is going to come from there. And then we have our quay repo and then the jet stack one for cert manager as well. So all of our images in this cluster should be coming from this particular list of registries. And again we're checking that container target. And so then I have to go add the image registry to my list of checks. And what I like to do is add a section here called custom and then image registry. And I'm going to say danger here because I wanted to get blocked by the admission controller. And I've written this in such a way that that should be safe. But actually let's do this first. Let's let's put it to warning level. And let's go ahead and rerun our helm upgrade Laris. But instead of wait, I do still need those. So and we're going to add a values file and we're going to say default values.yaml. And we're going to go ahead and run that so that should trigger the when I did this before I had slightly bigger text. So too small. That should be okay. So we're going to see all the Polaris pods roll because we just updated their configuration. And we will go ahead and wait for that to happen. Double check for any questions. I don't think we said this before but please feel free to send any questions in. We're happy to answer them as we go here. Getting close. We're going to restart our port forward when this is done. And then what we can do because we put that in warning mode. It'll show up on the dashboard now. So we can rush our dashboard and go see if any of these things are failing that image checks. That image checks that sorry image registries check. That's stuck in a loop there. And I realized I forgot to talk about one interesting thing. So we have this category here called security. We have our built in category security efficiency and reliability. What I'm actually going to do is change that category to fair winds custom. And what that will do is it will put that in this results by category here as its own new category in the dashboard. So now I can see how many of my custom checks are failing. This will allow me to see. Okay. This cluster is currently passing all of these custom checks. Now I'm going to go turn on the admission controller so that any future attempts to violate those checks will be blocked by the admission controller. All right. So we'll wait for it to roll over again. Hear my dog in the background. Yes. Dreaming. Yes. Yes. I was really impressed with your ability to keep going and multitask while listening to that. All right. Let's go take a look at our dashboard again. And now we'll see this fair winds custom policy and this fair winds custom category and we'll see everything's passing. We have no failing checks in this category. So now I feel comfortable going in and saying, okay, let's just let's just turn on the admission controller for that. And now we won't ever be failing that because all requests will get blocked. So we can test that out too. So if I go to my. I can figure and I changed the level of that check to danger and I rerun my home command and I look at my deployment here and I go to where it says quay. Okay. I'm going to change quay.io fair winds to quay.io slash Fargo barbell. And obviously that was not in our list of loud registries. It also doesn't exist, but that's not important right now. So we'll wait for the admission controllers to roll over real quick. And we'll attempt to apply that. Ideally what we will see live demos and all is that this will get blocked by our admission controller. Yep. Image should not be from disallowed registry. So we get that same error. Cool. So that's probably a more reliable sort of process for setting up your checks like create your checks, set it in warning. You know, work on it, work on the reported items until it turns green and then set it to danger so that it will actually block things and keep your cluster clean. Right. Got it. Cool. At the same time, I kind of doubled down on this little piece of the demo here, we can see our, our mutating webhook at in play here. So I have the image pull policy set, if not present here. To get the deployment and look for image poll here. And we'll see that the image pull policy that's actually in the cluster is always that's because our mutating admission webhook picked that up and automatically just kicked that over to always. You don't also won't show up in the dashboard anymore. But also you can see that if you're using infrastructure as code methods. And now we're out of sync with our infrastructures code. And so that's the type of thing that where we have to be really careful with mutating admission webhooks and why we want to be, you know, relatively conservative about where we use those and careful about how we use those. So if you're using both the mutating and validating webhook at the same time, which takes precedence. So does it, does it deny the injection of that resource into the cluster and then change it and then allow it. That's a great question. So in my testing, while building this demo, I did notice that I did not get any admission failures. So I'm guessing mutating webhooks run first and then mission second. I don't actually know the mechanism by which that happens and so that's something I'll have to find out. I'm, I'm, I'm hoping that that's just a built in choice by Kubernetes because that would be the most obvious order to run those two things in but I don't actually know that for sure off hand, but it does seem to work where if I set the poll policy not always check so the built in one for that to danger. And then I also have it mutating on that. It should allow me to apply this YAML that says if not present because it mutates it and then it gets it. All right. So let's talk about other policies that so we've talked about, you know, controlling your image registries we've talked about kind of a strategy for rolling those policies out in your cluster. What are some other policies we can write that might be beneficial to folks that aren't in the custom standard Polaris library of checks. So, I mean, I feel like a thing that we hear about a lot is resource limits. Well, so not allowing a workload to sort of consume all the resources on on a node so like setting limits like maybe namespace limits at the resource at the, sorry, nice space resource limits, or just setting resource limits on on individual levels so saying that you can't go above a certain amount because you know what kind of nodes you're running in your cluster job. Yep. And we built that into pillars. So it's in the docks. So, in order to make it a little bit easier to set minimums and maximums like that without having to write some very complicated JSON schema to handle that we've added an extension to the JSON schema for resource minimums and resource maximums. This also helps you handle the various ways in which you can express those values in Kubernetes, which can be very difficult to handle program programmatically. And so we've gone ahead and added that directly in so we have an example policy here for resource limits to say you have to be within a certain amount on your resource requests and limits. So we can go ahead and and add that to our, our checks list here. Go ahead and try that thing we were talking about a minute ago with the mutating, mutating admission webhook, right. So it went ahead and allowed me to apply that because it mutated it first and then went through the admission controller. So that makes sense. Yeah. Yeah. All right. So default values. We're going to add another custom check and we're going to call it resource limits. And I'm just going to go ahead and grab this one right here from the docs. And so here we're again looking at the container. We're excluding innate containers from this. So we also have an extension that allows you to say only check the main containers, not the innate containers. Very common to have an innate container that just, you know, you don't worry too much about its resource requests and limits. So we're going to set our maximum, you know, I think six gigs is way too high. Let's call it one and 100 millicores and let's call it one whole CPU as your max. I mean, this is running in kind. So it's not unlimited amount of resources in this cluster here. All right. So we're going to, and then we have to go add this to our list of custom checks and resource limits. I'm just going to go ahead and set that straight to danger. And then I'm going to go ahead and change that category again to fair winds custom. And we're going to rerun our home install. All right. And I don't even know what the defaults are on our demo application here. So let's see. So this is at 70 millicores and 10 on the limit in the request, which is outside of bounds for our customer check. So we will go ahead and pop up our dashboard again. I'm going to guess we're going to see face. Still, I wonder if I didn't wait long enough for the dashboard to restart. All right. So we're storing that config and a config map in the cluster. And so that's why we have to restart the pod so that they'll reread in that config map each time. All right. So now we'll see, yep, we've got a couple of fair winds custom ones that are failing. We can filter down to our default namespace again and see that our FW custom deployment here. Resource limits should be within the required range. So that is failing there. And if we apply our deployment again, we should get rejected. Resource limits should be within the required range. I was thinking about this yesterday while I was building this. And I think another possibility because JSON schema is fairly flexible would be to write. And I'm not certain we can do this yet, but we should double check and make sure we can. But setting the resource requests and limits with the mutating web hook in the event that they're not set, but leaving them if they are already set, which I think would be a very interesting mutation we can add. So something to think about maybe double check that we can do that at a later date. But let's talk about some security related ones. So another common thing that we might want to do is block host path mounts. So that's a common vector for container escape vulnerabilities. And so we can and the reason I want to bring this one up is because in all of the checks that we've done so far, we have targeted the container specification. So the target has been container, but the volumes, the volume mounts in a container are not in, volume mounts in a pod are not in the container spec. They're in the pod spec. And so I want to show how we can add those. So I have this check here that I've written for checking for host path mounts. And again, it's in that category for everyone's custom, but now we're going to target the pod spec. And so inside the pod spec, there is the field volumes and it's an array. It's an array of objects actually. And so the array has these items type object and we're saying not any of host path. So anytime we say volume out that the type is host path because that's the key in the volume mount, we're going to block that. So there we can show an example of this in the cube system namespace and take a look at the control plane. The YAML for that. And if we look at the volume tier, right, we have an array of maps. It is the type host path. And so when we apply this rule, we should see this particular workload in error. And I think I need to indent another level here. So indentation aside, I would definitely say that writing these rules using the JSON schema seems a lot better than writing in Reiko. I hear you and I don't disagree necessarily. Like Reiko, it's tricky. It's hard to wrap your head around. I feel like Reiko has a lot of benefits to it as well. You know, we actually, you know, implement Reiko in our alongside Polaris inside of our commercial offering. And like, I think they both have their place. I think if you need to write just like a really quick, like I want to check if there's a label on this workload. JSON scheme is so much quicker and easier. If you want to do something really complex, JSON schema gets ugly in a heartbeat. Just this, this, this host path mount, it took me a little bit to figure out how to do this, not any of key thing in order to write this policy. So they definitely both have their place. And I think, you know, running them side by side is not out of the question, honestly. So, but yes, I, you know, especially getting started, Reiko is really hard to wrap your head around the first few times you write a policy. It's true, but it is super powerful for sure. Just wait for that to restart. And we'll see in our dashboard, we'll see that cube control that was called again. Kind scheduler cube scheduler kind of control plan. So say fast. Hmm. I could say it once fast. Now five times. That one should be violating our policy. So once we get a new dashboard here, we'll click over the dashboard and take a look at that. So right now we're filtered to the default namespace. Let's switch that over to cube system. And we'll see. Again, everyone's custom failing some things and we'll look for that scheduler kind control plane and host path mounts are not permitted right there. And then it's also failing some of our other policies as well. So that brings up, I think, an interesting topic of exemptions that maybe we should cover. Yeah, so I mean, just to sort of wrap this up, at least, you know, where we are now, but seems like a really good practice, right, is that you get this installed. You know, you set it to warning so it's not, you know, doing an eternal the mutating part so it doesn't do anything unexpected. And you clean up your cluster. You like, you know, do all the checks, you make all the changes because that's super easy. We all have tons of time to address things, but you do all that stuff. And then there's also the the CI component to this where you can use it and like your CI setup to then even before you send anything to the cluster. It can fail like a CI check and you have to make that change in your in your deployment before you even get to the cluster part. So you have like a nice, you keep your cluster green by even refusing to, you know, send anything into the cluster to begin with. Yeah. Yeah, definitely great point. I mean, you know, scanning stuff in the cluster is great blocking into mission time is great. And then the third piece of that definitely is shifting that left into your CI pipeline so that before you even deploy or try to deploy, you see these warnings. And so Polaris is also available as a CLI. So if we do a Polaris audits, and we take a look at the help for that, and we do a Polaris audits audit path, and I'm going to point it at the YAML that I have in my repository here. We see, let's do a different format here because nobody wants to read JSON on the fly. We can see all of these checks available here. And then we can also control the exit code. So if we look at set exit code below score or set exit code on danger, we can control the behavior of the exit code there, which you can use in your CI to fail or pass a pipeline. And so and then also we can pass in a configuration just like we do in the cluster. So if we have sort of a, you know, all these custom checks or whatever, we can point it at an existing configuration that we might want to use. So great point there about the, you know, kind of three main points at which we can integrate CI admission and in cluster scanning. You can also run the CLI against your cluster, by the way, you can just do a Polaris audit and that'll hit your whatever cluster you have in your KubeConfig and give you the quick results. If you don't want to run the dashboard and just kind of see what's going on. So then you talked about like, okay, you know, get it running, get it installed, and then clean up your cluster. But if we think if we look at this like that host path now that's great I don't want developers deploying into the cluster with a host path now right there's no real reason that an application shouldn't need that. But that kind control plane needs it, right? My data dog installation is going to need it to be able to pick up container logs, my, you know, whatever's going to need some of that stuff. So we have to be able to create exemptions from these rules. And there's a few different ways we can do that in Polaris. One of them is just with with annotations. So actually, if we go look at the docs again, I really love our docs. I think it's, it's pretty, pretty good. We can annotate with this Polaris.fairwands.com slash exempt equals true. Or we can exempt specific checks on a workload. So if we want to go that route we can just annotate things. And then someone's going to ask me well, if you let people just, you know, exempt their workloads how is this a security thing right how is admission controller working. Well, you can disable that. So when you're running the admission controller you can disable exemptions by annotation, but we still need exemptions. So the next thing that we have is adding them directly to your config in your running cluster. So if you actually go look at the default configuration again. I think that was anybody remember where I was Polaris over to config.yaml sender examples I think. Yeah, config.yaml. We'll scroll down. You'll actually see a bunch of built in exemptions into the default configuration. You can tinker with these and modify these as much as you want. And so you can specify specific controllers, you can specify specific controllers in specific namespaces, and then what rules they're exempt to. And then you can so then you can also go and exempt them from your custom checks in this exemption file. So what I'll show now is I actually worked up a full configuration for this kind cluster that gives us all the different checks we might want, as well as all of the exemptions. Necessary for maybe I don't have the right file here. Oh, I don't. Sorry. There we go Polaris values. If we go to exemptions we now have all the exemptions necessary for this kind cluster. So I have the kind control plan I have the metric server which is also running in this cluster. The kind net which is the CNI for the kind cluster and then some exemptions for cert manager. Now these are some of these are trade offs right I may want to actually go configure CPU limits and memory for for cert manager for the purposes of this demo I just went ahead and ignored those instead of writing up a whole values file for And then some the kind that rules as well but you can see we have our custom checks in here for host path mount and then a couple other exemptions as well. So basically I went through this process of looking at my cluster and saying does it need to pass that check or not adding an exemption doesn't need to pass that check or not adding an exemption and then going through and fixing the other things that may need to be fixed. And then we also have a couple other custom checks in here like I want all of my deployments to have a specific label called team because I use that for cost allocation perhaps in my cluster. A really great use case for guardrails and Kubernetes and forcing cost allocation tags and things like that is I don't think you can have cost allocation without policy and governance. And then we have the image registry check we put in earlier and custom levels for all the different built in checks as well. So we can go ahead and apply that to our cluster. And what we'll hopefully see is that a good number of checks have gone away, because I have exempted them specifically for this cluster. So we're going to wait for that to restart. Jokes to we take jokes. Yes. I'm forcing Andy to take jokes. I mean it's Kendall's goal that if you can make me face palm one time in a day that he's had a good day so if you can get me to grow into the bad joke. We've got a new dashboard up we'll go ahead and take a look at that. The other thing that's cool about exemptions is with the dashboard if you're curious, you know, what what's going on without the exemptions, you can actually click here at the top to view the report with the exemptions. This adds a URL parameter called disallow exemptions. And so now we'll see like the full view without the exemption so if you're curious, you know what that looks like. So here we see now we're down to 113 passing checks three warnings and two dangerous. It looks like dangerous is in our fair ones custom. I'm guessing I don't have image pull policy on cert manager which if I redeployed it would now because we have that mutating web hook. Actually, you know what, let's just go ahead of this. Let's go ahead and just redeploy that. Can't remember if that works on pod level and the deployment level I think it's at the deployment level for that particular one so you do actually have to recreate the deployment. No image pull policy would be per pod so we could do that on the pod spec itself and then it would get mutated every time a pod got created a little more load on the mutating web hook but also potentially a little bit more secure if that's something you're concerned about. So you're saying you could have killed the pod and let the deployment just create a new one and it would have mutated it in this case. I don't think it would based on the way that particular policies written. I think if we go back and look at our image pull policy. Oh it is targeting the container. So it might have yes it may have done that but the deployment in the cluster would still say image pull policy, if not present. Yeah, and so it would still show up in the dashboard. So we really, you know, want to make it at, you know, redo deployment with that. Oh, it looks like our, our, our application is still failing the basic resource requests. So we can go ahead and fix that. I'm pretty sure we just need to bump this to 100 m. And, oh, and we need a team label because I was in. And then I added so in our labels, we're going to add team awesome sauce. And we're going to apply that. And in theory, we go refresh our dashboard. We're going to give an A plus 100%. All right. Done. Done. We're running the perfect cluster. Perfect cluster. Nothing left to do here. Yep. Yep. All right. I think we've, so we've covered. Validating admission. We covered mutating admission. We covered custom policy and Jason schema. We covered customizing your configuration, which controls how you block things with the admission controller and the mutating admission one book. We've also covered exemptions and how you do that. And we've talked about a strategy for rolling out policy in your cluster. And then the three different points at which we can inject that policy CI admission or. In the cluster at runtime. Miss anything. Yeah, so much content and such a good time. That's always awesome. And I guess this is now the time for the Q and a portion. Not that we haven't been taking questions before this, but this is purely for the Q and a. So if anyone in the audience, you have a questions now is the time to ask. So send those questions in. And we'll get them answered. But if anyone misses, you know, you say a few hours after this, they realize, oh, I should have asked that question. Is there any way they can reach out to you later on or Slack channel or something like that. Great question. I am in the Kubernetes and the CNC of Slack. My username is Superman JR. It's the same as my GitHub handle. We also have a community Slack for fair winds. So if you go to any of our open source repos, right at the top, there should be a link to join our slack, maybe not right at the top, but it's in here somewhere. Chat with us on Slack. That should be in all of our open source repos. So feel free to join that slack. And we have channels for each one of our open source projects. Polaris is just one of several that we we maintain. Those are probably the best ways to get a hold of us. Perfect. Next steps. Clear then as far as contacting. That's lovely. And we also have a cloud native live channel in the CNC. Slack where discussion can be continued as well. So that's always an opportunity as well. But going directly towards if you want people to learn more about Polaris, I think that sounds like a great base to open to learn more about those things, particularly. But yeah, still a few minutes for time for questions. So if anyone is typing away, then those questions to us. And I want to ask a question to kick us off. So what is next for Polaris? What does the future look like? Is there any kind of anything cool happening in the future? Great question. We've done a lot of work recently to start working on putting together policy groups for the NSA hardening guide and potentially other benchmarks. So that's one potential area. Other than that, I don't know that we have any major enhancements planned over the next while. The expansion of policy to allow targeting different specs beyond just the container was a huge change we made just recently really so nothing earth shattering on the horizon. But yeah, always open to future requests in the GitHub repo and ideas that folks have for Polaris. Perfect. And still time for questions, but this is most learning the final call. If nothing pops up, we can start wrapping up. But before we do that, if someone's just now typing it away. Any final notes from you, Stevie or Andy, any final learn more resources that you want to share or anything? Stevie. I can't think of anything. I will say, you know, definitely go look at our other open source projects. So we have, you know, Pluto, which is related to deprecated API versions. We have Goldilocks related to right sizing your workloads, setting your course requests and limits was just something that Polaris recommends you do, but it doesn't tell you how. And then we also have Nova, which is about finding outdated things in your cluster like help charts and containers that you might be running. So a whole suite of open source that together puts together a full strategy for managing a Kubernetes cluster over time. Thank you for mentioning Goldilocks. I didn't know if you were allowed to like start bringing in our other open source tools. It's open source. I think it's very good. Yeah, open source works. But yeah, perfect. So thank you so much for speaking. I can see that people are saying good job. Thank you. And whatnot. So awesome demo from my side as well. Thank you so much for that really great. But yeah, let's start back being me up. So thank you everyone for joining the latest episode of cloud day live. It was great to have a session about Polaris today. Really loved the introduction as well as the question from the audience. Really amazing. So as always, we bring you the latest cloud native code every Wednesday. So in the coming weeks, we have a lot more great sessions coming up. So thank you for joining us today and see you next week. Thanks so much for having us. Bye.