diff --git a/docs/images/polaris.png b/docs/images/polaris.png new file mode 100644 index 0000000..7bf0a66 Binary files /dev/null and b/docs/images/polaris.png differ diff --git a/docs/recipes/kubernetes/polaris.md b/docs/recipes/kubernetes/polaris.md new file mode 100644 index 0000000..0189ee5 --- /dev/null +++ b/docs/recipes/kubernetes/polaris.md @@ -0,0 +1,177 @@ +--- +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. \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index 592c027..c26b99f 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -263,6 +263,7 @@ nav: - Authentik: recipes/kubernetes/authentik.md - Invidious: recipes/kubernetes/invidious.md - Mastodon: recipes/kubernetes/mastodon.md + - Polaris: recipes/kubernetes/polaris.md # - Matrix: recipes/kubernetes/matrix.md # - NGINX Ingress: kubernetes/wip.md # - Polaris: kubernetes/wip.md