--- title: How to deploy Polaris on Kubernetes description: Deploy Polaris on Kubernetes to audit your safety, security, and resiliency values_yaml_url: https://github.com/FairwindsOps/charts/blob/master/stable/polaris/values.yaml helm_chart_version: 5.16.x helm_chart_name: polaris helm_chart_repo_name: fairwinds-stable helm_chart_repo_url: https://charts.fairwinds.com/stable helmrelease_name: polaris helmrelease_namespace: polaris kustomization_name: polaris slug: Polaris status: new upstream: https://www.fairwinds.com/polaris links: - name: GitHub Repo uri: https://github.com/FairwindsOps/polaris --- # Polaris on Kubernetes Fairwinds' Polaris is an open-source policy agent, which helps you to ensure that your cluster aligns with best practices, in the areas of security, reliability, networking and efficiency. ![polaris health report](/images/polaris.png){ loading=lazy } ## {{ page.meta.slug }} requirements !!! summary "Ingredients" Already deployed: * [x] A [Kubernetes cluster](/kubernetes/cluster/) * [x] [Flux deployment process](/kubernetes/deployment/flux/) bootstrapped * [x] An [Ingress controller](/kubernetes/ingress/) to route incoming traffic to services Optional: * [ ] [External DNS](/kubernetes/external-dns/) to create an DNS entry the "flux" way {% include 'kubernetes-flux-namespace.md' %} {% include 'kubernetes-flux-helmrepository.md' %} {% include 'kubernetes-flux-kustomization.md' %} {% include 'kubernetes-flux-dnsendpoint.md' %} {% include 'kubernetes-flux-helmrelease.md' %} #### Enable dashboard Initially you'll probably want to use the dashboard, without the webhook, so you'll want to at least enable the ingress for the dashboard (*which, itself, is enabled by default*): ```yaml hl_lines="5" values: dashboard: ingress: # dashboard.ingress.enabled -- Whether to enable ingress to the dashboard enabled: true ``` {% include 'kubernetes-flux-check.md' %} ## Check your score Browse to the URL you configured for your ingress above (*it may take a while for the report to run*), and confirm that Polaris is displaying your cluster overview / score. Now pick yourself up off the floor.. some of the issues are false-positives![^1] ## Improve your score You may not care about some of the checks being applied. For example, you may using a single-node cluster, and so the HA / resilience checks may be immaterial to you. ### Selectively disable checks The [Polaris Documentation](https://polaris.docs.fairwinds.com/customization/checks/) explains how to change the `config` section of `values.yaml`. You can change the priority (*ignore, warning, etc*) of various checks. Here's how it looks on a cluster I manage: ```yaml config: checks: # reliability deploymentMissingReplicas: warning priorityClassNotSet: ignore tagNotSpecified: danger pullPolicyNotAlways: ignore readinessProbeMissing: warning livenessProbeMissing: ignore # Per https://github.com/zegl/kube-score/blob/master/README_PROBES.md, we don't _need_ liveness probes if we have readiness probes pdbDisruptionsIsZero: warning missingPodDisruptionBudget: ignore topologySpreadConstraint: ignore # we don't have complex topology ``` ### Add exceptions You may want a check running, but want to ignore results from a particular namespace[. This can be done using annotations on individual workloads, ](https://polaris.docs.fairwinds.com/customization/exemptions/#annotations), but I prefer to codify these in Polaris' config, so that all my exemptions are stored (*and versioned*) in one place: #### Using config Exemptions are also configured under `config`, as illustrated below: ```yaml config: exemptions: - namespace: kube-system controllerNames: - kube-apiserver - kube-proxy - kube-scheduler - etcd-manager-events - kube-controller-manager - kube-dns - etcd-manager-main rules: - hostPortSet - hostNetworkSet - readinessProbeMissing - cpuRequestsMissing - cpuLimitsMissing - memoryRequestsMissing - memoryLimitsMissing - runAsRootAllowed - runAsPrivileged - notReadOnlyRootFilesystem - hostPIDSet # Special case for Cilium - namespace: kube-system controllerNames: - cilium rules: - runAsRootAllowed ``` #### Using annotations To exempt a controller from all checks via annotations, use the annotation `polaris.fairwinds.com/exempt=true`, e.g. `kubectl annotate deployment my-deployment polaris.fairwinds.com/exempt=true` To exempt a controller from a particular check via annotations, use an annotation in the form of `polaris.fairwinds.com/-exempt=true`, e.g. `kubectl annotate deployment my-deployment polaris.fairwinds.com/cpuRequestsMissing-exempt=true` Here's an example from the clusterRolebinding used for [authentik][k8s/authentik]: ```yaml kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: oidc-group-admin-kube-apiserver annotations: polaris.fairwinds.com/clusterrolebindingPodExecAttach-exempt: "true" polaris.fairwinds.com/clusterrolebindingClusterAdmin-exempt: "true" roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects: - kind: Group name: oidc:admin-kube-apiserver # for authentik - kind: Group name: admin-kube-apiserver # for weave-gitops ``` ## Summary What have we achieved? We've deployed Polaris, which we can use for a point-in-time audit of our cluster's best-practice configuration, or even as a webhook to prevent "uncomplaint" configuration from being applied in the first place! :muscle: !!! summary "Summary" Created: * [X] Polaris deployend and ready to improve our cluster security, resiliency, and efficiency ! Next: * [ ] Work your way through the **legitimate** issues highlighted by Polaris, make improvements, and refresh the report page, gradually working your way up to an A+ "smooth sailing" cluster! :sun: {% include 'recipe-footer.md' %} [^1]: You'd be surprised how many are **not** false positives though - especially workloads deployed from 3rd-party helm charts, which are usually defaulted to the most generally compatible configurations.